Closed 040a6c67-9f49-475c-a0fb-294ef5661fed closed 16 years ago
In the following, dir(Node) should include the name 'z', and Node.z should be 'Node'. However, dir(Node) does not include 'z', and Node.z is undefined (AttributeError). This is directly contrary to the Python documentation, which says "metaclasses can modify dict".
class MetaNode(type):
def __init__(cls, name, bases, cdict):
cdict['z'] = name
type.__init__(name, bases, cdict)
class Node(object):
__metaclass__ = MetaNode
print dir(Node) print Node.z
When designing a metaclass, you should override __new, not __init:
class MetaNode(type):
def __new__(cls, name, bases, cdict):
cdict['z'] = name
return type.__new__(cls, name, bases, cdict)
class Node(object):
__metaclass__ = MetaNode
Please reopen this issue as a documentation bug.
The documentation for __new__ in section 3.4.1 says:
__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation.
The documentation for metaclasses in 3.4.3 says nothing about __new vs. __init. It says the metaclass will be "called" for class creation, and it says the metaclass can be any "callable". This would imply the use of __call rather than __new or __init__.
I think 3.4.1 should say:
__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also used for custom metaclasses (q.v.).
I think 3.4.3 should be reviewed in its entirety to replace the misleading language about "called" and "callable" with language that explicitly mentions __new__.
I'll look into it.
Actually, "called" and "callable" are OK, if the documentation says somewhere that the normal effect of "calling" a type object is to invoke __new. The places I looked first (sections 3.1, 3.3, and 3.4.1) do not say this. 5.3.4 does say that the result of calling a class object is a new instance of that class, but it doesn't mention __new. So perhaps it would OK to just add something like the following to 3.4.3:
Note that if a metaclass is a subclass of \<code>type\</code>, it should override \<code>new\</code>, not \<code>call\</code>.
This should now be appropriately explained in the trunk, r59837. I also added an example of using __new__ in a metaclass.
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields: ```python assignee = 'https://github.com/birkenfeld' closed_at =
created_at =
labels = ['interpreter-core']
title = 'documentation on metaclasses is incomplete and misleading'
updated_at =
user = 'https://bugs.python.org/lpd'
```
bugs.python.org fields:
```python
activity =
actor = 'georg.brandl'
assignee = 'georg.brandl'
closed = True
closed_date =
closer = 'georg.brandl'
components = ['Interpreter Core']
creation =
creator = 'lpd'
dependencies = []
files = []
hgrepos = []
issue_num = 1734
keywords = []
message_count = 6.0
messages = ['59216', '59218', '59245', '59302', '59312', '59482']
nosy_count = 3.0
nosy_names = ['georg.brandl', 'lpd', 'amaury.forgeotdarc']
pr_nums = []
priority = 'normal'
resolution = 'fixed'
stage = None
status = 'closed'
superseder = None
type = None
url = 'https://bugs.python.org/issue1734'
versions = ['Python 2.5']
```