Per the 3.6.0 docs:
CPython implementation detail: In CPython 3.6 and later, the
__class__
cell is passed to the metac
The warning is raised if you use super that relies on __class__
being available or reference __class__
inside the class body.
What the text essentially says is that, this is needed if you define a custom meta-class and tamper with the namespace you get before passing it up to type.__new__
. You'll need to be careful and always make sure you pass __classcell__
to type.__new__
in your metaclass.__new__
.
That is, if you create a new fancy namespace to pass up, always check if __classcell__
is defined in the original namespace created and add it:
class MyMeta(type):
def __new__(cls, name, bases, namespace):
my_fancy_new_namespace = {....}
if '__classcell__' in namespace:
my_fancy_new_namespace['__classcell__'] = namespace['__classcell__']
return super().__new__(cls, name, bases, my_fancy_new_namespace)
The file you linked in the comment is actually the first of many attempted patches, issue23722_classcell_reference_validation_v2.diff is the final patch that made it in, from Issue 23722.
An example of doing this correctly can be seen in a pull request made to Django that uses this to fix an issue that was introduced in Python 3.6:
new_attrs = {'__module__': module}
classcell = attrs.pop('__classcell__', None)
if classcell is not None:
new_attrs['__classcell__'] = classcell
new_class = super_new(cls, name, bases, new_attrs)
The __classcell__
is simply added to the new namespace before being passed to type.__new__
.