I can't understand why the following code behaves a particular way, which is described below:
from abc import ABCMeta
class PackageClass(object):
__metaclass__ = ABCMeta
class MyClass1(PackageClass):
pass
MyClass2 = type('MyClass2', (PackageClass, ), {})
print MyClass1
print MyClass2
>>> <class '__main__.MyClass1'>
>>> <class 'abc.MyClass2'>
Why does repr(MyClass2)
says abc.MyClass2
(which is by the way not true)?
Thank you!
The problem stems from the fact that ABCMeta
overrides __new__
and calls its superclass constructor (type()
) there. type()
derives the __module__
for the new class from its calling context1; in this case, the type
call appears to come from the abc
module. Hence, the new class has __module__
set to abc
(since type()
has no way of knowing that the actual class construction took place in __main__
).
The easy way around is to just set __module__
yourself after creating the type:
MyClass2 = type('MyClass2', (PackageClass, ), {})
MyClass2.__module__ = __name__
I would also recommend filing a bug report.
Related: Base metaclass overriding __new__ generates classes with a wrong __module__, Weird inheritance with metaclasses
1: type
is a type object defined in C. Its new method uses the current global __name__
as the __module__
, unless it calls a metaclass constructor.