ironpython3
ironpython3 copied to clipboard
PEP 3115 -- Metaclasses in Python 3000
http://www.python.org/dev/peps/pep-3115/
Initial CPython implementation: https://hg.python.org/cpython/rev/19f7ff443718
Very early beginnings of implementation: https://github.com/moto-timo/ironpython3/tree/pep-3115-metaclass-syntax
Getting closer: https://github.com/moto-timo/ironpython3/tree/pep-3115
Revert https://github.com/IronLanguages/ironpython3/pull/169 hack once this is properly implemented.
Originally I intended to remove __classcell__
and replace it with an extra parameter to PythonOps.MakeClass
, but since Python 3.6 introduces it and IronPython 3.4 already implements a number of Python 3.6 behaviour, it is probably not worth it. Instead of it, I plan now to implement the Python 3.6 behaviour fully.
There are two significant changes in Python 3.6 WRT 3.4 related to handling of __class__
:
CPython implementation detail: In CPython 3.6 and later, the
__class__
cell is passed to the metaclass as a__classcell__
entry in the class namespace. If present, this must be propagated up to thetype.__new__
call in order for the class to be initialised correctly. Failing to do so will result in a DeprecationWarning in Python 3.6, and a RuntimeError in Python 3.8.
And:
When a new class is created by
type.__new__
, the object provided as the namespace parameter is copied to a new ordered mapping and the original object is discarded. The new copy is wrapped in a read-only proxy, which becomes the dict attribute of the class object.
At the second step __classcell__
is filtered out rather than deleted from the original namespace dict.
So here is my revised plan:
- [x] ~Remove
__classcell__
or at least do not use classdict to pass it around (doesn't work well with metaclass__prepare__
anyway, which may even not support deletion of attributes).~ Implement CPython 3.6 handling of__classcell__
. Implemented in #1517, #1520. - [x] Replace all class variables with class attributes, except
__class__
. Implemented in #1531. - [x] Change the class lambda to take its context as parameter, rather than the parent context as it is now. This will require moving of class context creation to outside of the class lambda. Implemented in #1542.
- [x] Support arbitrary attribute dict type as classdict. Implemented in #1546.
- [x] Complete implementation of
__prepare__
. At this point, PEP 3115 implementation in WhatsNewInPython30.md can be checked off. _Implemented in #1551.