This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: The variable __module__ in the class body getting an undesirable value from __prepare__ of the metaclass
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.9
process
Status: closed Resolution: duplicate
Dependencies: Superseder:
Assigned To: Nosy List: Takuo Matsuoka, ethan.furman
Priority: normal Keywords:

Created on 2022-04-05 03:36 by Takuo Matsuoka, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (2)
msg416741 - (view) Author: Takuo Matsuoka (Takuo Matsuoka) Date: 2022-04-05 03:36
Context
-------
Some classes have the variable __name__ in their namespace __dict__ ,
and one may wish to create more such classes with varied values of
__name__ .  Some of those could be created with a metaclass whose
__prepare__ returns a mapping having key "__name__", for which the
value is created depending on the arguments of __prepare__ and can be
updated or deleted in the body of the class to be created.  (See C
below for a very silly example of such a metaclass.)


Problem
-------
The value of __name__ given by __prepare__ becomes not just that in
the class body, but automatically also the value of __module__
there.  As far as I could see, this is not documented, and the
programmer might not notice __module__ was messed up.  I think this
behaviour is unexpected and problematic at least unless a warning is
given on it in the document.


Example
-------
Here's a code which produces a problem.

```
# In this example, the metaclass C is intended to be a class of
# subclasses of:
B = type

class C(type(B)):
    @classmethod
    def __prepare__(cls, /, *args, **kwargs):
        return dict(__name__ = cls._name(*args, **kwargs))
    @classmethod
    def _name(cls, /, *args, **kwargs):
        # The actual value of __name__ doesn't matter much to the
        # issue, so I make this function always return the same silly
        # thing in this example.
        return type.__dict__["__name__"]

class O(B, metaclass=C):
    print(__module__ == __name__) # True
    # Could update or delete __name__ here.
```

Consequently,

>>> O.__module__
<attribute '__name__' of 'type' objects>


Discussion
----------
If the value of __name__ can be read from the scope
outside for the assignment to __module__, then that will erase this
unexpected behaviour and I think it would be a much safer thing to do.


Remarks
-------
The issue was previously

https://bugs.python.org/issue47136

which I'm going to close now since I failed to specify the issue
clearly enough there.  Here I've made the issue more specific.

(The issue is same as https://bugs.python.org/issue47223 which I closed
mistaking it with https://bugs.python.org/issue47136)

The issue is different from but seems related to

https://bugs.python.org/issue28869

I haven't figured out the exact relation.


Thanks.
msg416744 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2022-04-05 03:50
Stop creating new issues for the same problem.

If you didn't specify the first issue well enough, add your specifics to it and continue that conversation.  Splitting the thoughts and feedback across multiple issues is not efficient.

Closing this issue, reopening the original (issue47136).
History
Date User Action Args
2022-04-11 14:59:58adminsetgithub: 91380
2022-04-05 03:50:39ethan.furmansetstatus: open -> closed

nosy: + ethan.furman
messages: + msg416744

resolution: duplicate
stage: resolved
2022-04-05 03:36:25Takuo Matsuokacreate