IronLanguages / ironpython3

Implementation of Python 3.x for .NET Framework that is built on top of the Dynamic Language Runtime.
Apache License 2.0
2.5k stars 287 forks source link

PEP 3115 -- Metaclasses in Python 3000 #20

Closed jdhardy closed 2 years ago

jdhardy commented 10 years ago

http://www.python.org/dev/peps/pep-3115/

moto-timo commented 7 years ago

Initial CPython implementation: https://hg.python.org/cpython/rev/19f7ff443718

moto-timo commented 7 years ago

Very early beginnings of implementation: https://github.com/moto-timo/ironpython3/tree/pep-3115-metaclass-syntax

moto-timo commented 7 years ago

Getting closer: https://github.com/moto-timo/ironpython3/tree/pep-3115

slozier commented 6 years ago

Revert https://github.com/IronLanguages/ironpython3/pull/169 hack once this is properly implemented.

BCSharp commented 2 years ago

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 the type.__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: