I am upgrading my project from Python 2.7 to Python 3.7 and in my code I have something like this:
class A: class B(Exception): pass pass
now type(A.B())
returns different things in the two Python versions:
In Python 2.7 I get: <class '__main__.B'>
In Python 3.7 I get: <class '__main__.A.B'>
Can anybody explain what happens under the hood that causes this difference?
Thank you very much!
Advertisement
Answer
This is a result of the changes made for PEP 3155: Qualified name for classes and functions. When a class or function is defined inside another class, its __qualname__
attribute includes the information on the class it was defined inside (non-nested cases also get it, but it’s the same as __name__
there). Nothing changed about the behavior of the classes, just the display information; the repr
of classes uses __qualname__
to make the source of the class more obvious to users.
Part of the motivation for it was that it was handy to know when a function was defined inside a class, but Python 3 removed the concept of unbound methods (they’re just plain functions that implement the descriptor protocol to become bound methods when accessed through an instance of the class), so this restored some of the introspection capabilities without reintroducing unbound methods (which were removed for being largely unnecessary, and slowing code).