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: __name__ inconsistently applied in class definition
Type: enhancement Stage:
Components: Interpreter Core Versions: Python 3.3
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: benjamin.peterson, eukreign, terry.reedy
Priority: normal Keywords:

Created on 2012-02-22 23:29 by eukreign, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (8)
msg154013 - (view) Author: Lex Berezhny (eukreign) Date: 2012-02-22 23:29
The following behavior doesn't make sense, especially since it works correctly for other special attributes:

>>> class F:
	__name__ = "Foo"

>>> F.__name__
'F'
>>> F().__name__
'Foo'
>>> F.__name__ = 'Foo'
>>> F.__name__
'Foo'


Works fine for __module__ and others:

>>> class F:
	__module__ = "mod"
	
>>> F.__module__
'mod'
>>> F
<class mod.F at 0x0212B360>
msg154027 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2012-02-23 01:09
I don't think this is actually incorrect. Basically setting something in the class body is not equivalent to setting it as an attribute on the class.

This happens with other attributes. Consider

>>> class X:
...     __class__ = list
... 
>>> X.__class__
<class 'type'>
>>> X().__class__
<class 'list'>
msg154032 - (view) Author: Lex Berezhny (eukreign) Date: 2012-02-23 01:38
I think for __class__ it might make sense but for __name__ it seems not intuitive.
msg154033 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2012-02-23 01:43
Well, what do you expect the name of the class to be? The one you assign __name__ to or the one you pass to type()?
msg154034 - (view) Author: Lex Berezhny (eukreign) Date: 2012-02-23 02:01
The one in __name__ since logically that happens after the class declaration ('class X' line) and should overwrite the name in the class declaration.
msg154035 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2012-02-23 02:06
It can be implemented but I'm skeptical that it's correct. You might try convincing Python-dev.
msg154040 - (view) Author: Lex Berezhny (eukreign) Date: 2012-02-23 02:54
I don't particularly need this functionality. It was just something that seemed  counter intuitive to me.

I discovered this while working on a python to javascript compiler. I'll probably implement the compiler to allow overriding with __name__ as it seems more intuitive to me that way.

Hopefully cpython will be changed to work that way too.
msg154178 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2012-02-25 01:15
This is not a bug report, as Python works as documented. 
Double underscore names are defined as *reserved* for the interpreter, with the ones actually in use having defined meanings.

type.__new__ sets several internally used attributes on new classes. The attribute look-up mechanism for classes looks at them first before looking in __dict__, which is for attributes of both the class and its instances. Here is another example similar to yours.

>>> class C: __dict__ = 1

>>> C.__dict__
dict_proxy({'__dict__': 1, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None})
>>> C().__dict__
1

__dict__ is not writable, but __class__ is. You can already rename a class if you really want:

>>> C.__name__ = 'bizarre'
>>> C.__name__
'bizarre'

Conceptually, this seems the right way as one normally would not want the name of the class to be the default name for every instance.

>>> C().__name__
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    C().__name__
AttributeError: 'bizarre' object has no attribute '__name__'

If you really want instances to have that also, then also do as you did.

There are other class-only, not for instances, attributes:
__mro__ and __subclasses__ and perhaps others.
History
Date User Action Args
2022-04-11 14:57:27adminsetgithub: 58300
2012-02-25 01:15:32terry.reedysetstatus: open -> closed

type: behavior -> enhancement
versions: - Python 2.6, Python 3.1, Python 2.7, Python 3.2
nosy: + terry.reedy

messages: + msg154178
resolution: rejected
2012-02-23 02:54:29eukreignsetmessages: + msg154040
2012-02-23 02:06:18benjamin.petersonsetmessages: + msg154035
2012-02-23 02:01:32eukreignsetmessages: + msg154034
2012-02-23 01:43:23benjamin.petersonsetmessages: + msg154033
2012-02-23 01:38:20eukreignsetmessages: + msg154032
2012-02-23 01:09:43benjamin.petersonsetnosy: + benjamin.peterson
messages: + msg154027
2012-02-22 23:37:11eukreignsetversions: + Python 3.3
2012-02-22 23:29:07eukreigncreate