#πŸ”’ Strange behavior of __setattr__ in a metaclass

7 messages Β· Page 1 of 1 (latest)

shell cedar
#

I need to be able to pass an extra argument to the __setattr__ method of a child class within a metaclass, but for some reason, the reference to the instance of the child class (self) is not passed in such cases.

However, if I don't override the method from the outside and instead add an additional argument within the class, everything will work fine...

class A:
    def __setattr__(self, key, value, extra_keyword=()):
        super().__setattr__(key, value)

a = A()
a.a = 1

I need to make one of the commented variants work. Is this possible?

def setattr_(self, key, value, *, extra_keyword=()):
    object.__setattr__(self, key, value)

class Setattr:
    def __init__(self, *, extra_keyword=()):
        self.extra = extra_keyword

    def __call__(self, instance, key, value):
        object.__setattr__(instance, key, value)

class Metaclass(type):
    def __new__(mcs, name, bases, attrs):
        attrs["__setattr__"] = setattr_  # works, but I can't pass an extra argument
        
        # !!!
        # attrs["__setattr__"] = Setattr(extra_keyword=(1, 2, 3))
        # TypeError: __call__() missing 1 required positional argument: 'value'

        # attrs["__setattr__"] = functools.partial(setattr_, extra_keyword=(1, 2, 3))
        # TypeError: setattr_() missing 1 required positional argument: 'value'
        # !!!

        return super().__new__(mcs, name, bases, attrs)

class Class(metaclass=Metaclass):
    def __init__(self):
        self.a = 1

Class()
meager shaleBOT
#

@shell cedar

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

shell cedar
#

For now I fixed it by moving the setattr_ function directly into the metaclass

#

!solved

meager shaleBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.