[issue47136] The variable __module__ in the class body getting an undesirable value from __prepare__ of the metaclass

Takuo Matsuoka report at bugs.python.org
Thu Apr 7 01:12:24 EDT 2022


Takuo Matsuoka <motogeomtop at gmail.com> added the comment:

Thank you Ethan for your comments.

Sure, I was not familiar with how you measure the magnitude of the
consequences.  The code in my own work was of the kind of the generic
example I gave, but I have abandoned the approach, and don't seem able
to find it any more.  I think the approach turned out not ideal for
the specific aim I had, which I'm sorry I can't recall now.

I might just say there may be circumstances where a not so thoughtful
programmer might get inclined to implementing a metaclass C in some
manner like:

```
class C(type(B)):
    # Skip __init__ .  It's just to help checking type later.
    def __init__(self, /, *args, **kwargs):
        super().__init__(*args, **kwargs)
        dict_ = self.__dict__
        try:
            name = dict_["__name__"]
        except KeyError:
            pass
        else:
            name._owner = self
    @classmethod
    def __prepare__(cls, /, *args, **kwargs):
        return dict(__name__ = cls._name(*args, **kwargs))
    @classmethod
    class _name:
        def __get__(self, instance, owner=None):
            if instance is None:
                if issubclass(owner, self_owner := self._owner):
                    return self
                else:
                    raise TypeError(f'{owner} is not a subclass of'
                                    f' {self_owner.__qualname__}')
            name = instance._super().__name__ # See the class O
            # below. 
            #
            #
            # Any procedure here, depending on what you'd like to do
            # with the instance of your class...
            #
            return name
        def __init__(self, cls, /, *args, **kwargs): ......
        def __set__(self, instance, value): ......
        def __delete__(self, instance): ......
```

where she creates instances of the metaclass C by inheriting from:

```
class O(B, metaclass=C):
    def _super(self):
        return super()
    def __init_subclass__(cls, /, *args, **kwargs):
        return super().__init_subclass__(*args)
```

Another thing I can say is code that does something like that is not
what I write often or even had written before, I guess.  Still, I
reported the issue thinking some people (possibly including myself)
may come around the kind of code some time in the future again.

If the behaviour is not going to be changed, then I think the
documentation should at least be made sure to warn about it.  I don't
think the behaviour can be expected without documentation.

Thanks.

----------

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue47136>
_______________________________________


More information about the Python-bugs-list mailing list