diff --git a/Lib/abc.py b/Lib/abc.py index 0358a4696d3..1cbf96a61f2 100644 --- a/Lib/abc.py +++ b/Lib/abc.py @@ -168,7 +168,7 @@ class ABCMeta(type): def _dump_registry(cls, file=None): """Debug helper to print the ABC registry.""" - print("Class: %s.%s" % (cls.__module__, cls.__name__), file=file) + print("Class: %s.%s" % (cls.__module__, cls.__qualname__), file=file) print("Inv.counter: %s" % ABCMeta._abc_invalidation_counter, file=file) for name in sorted(cls.__dict__.keys()): if name.startswith("_abc_"): diff --git a/Lib/asyncore.py b/Lib/asyncore.py index b2ee27817f4..90854b22bb0 100644 --- a/Lib/asyncore.py +++ b/Lib/asyncore.py @@ -255,7 +255,7 @@ class dispatcher: self.socket = None def __repr__(self): - status = [self.__class__.__module__+"."+self.__class__.__name__] + status = [self.__class__.__module__+"."+self.__class__.__qualname__] if self.accepting and self.addr: status.append('listening') elif self.connected: diff --git a/Lib/codecs.py b/Lib/codecs.py index c2065dafa27..993451711af 100644 --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -99,8 +99,8 @@ class CodecInfo(tuple): return self def __repr__(self): - return "<%s.%s object for encoding %s at 0x%x>" % \ - (self.__class__.__module__, self.__class__.__name__, + return "<%s.%s object for encoding %s at %#x>" % \ + (self.__class__.__module__, self.__class__.__qualname__, self.name, id(self)) class Codec: diff --git a/Lib/distutils/extension.py b/Lib/distutils/extension.py index cc04a18a3af..7efbb74f895 100644 --- a/Lib/distutils/extension.py +++ b/Lib/distutils/extension.py @@ -134,7 +134,7 @@ class Extension: def __repr__(self): return '<%s.%s(%r) at %#x>' % ( self.__class__.__module__, - self.__class__.__name__, + self.__class__.__qualname__, self.name, id(self)) diff --git a/Lib/functools.py b/Lib/functools.py index b8463ad2452..453805760b4 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -277,7 +277,7 @@ class partialmethod(object): for k, v in self.keywords.items()) format_string = "{module}.{cls}({func}, {args}, {keywords})" return format_string.format(module=self.__class__.__module__, - cls=self.__class__.__name__, + cls=self.__class__.__qualname__, func=self.func, args=args, keywords=keywords) diff --git a/Lib/inspect.py b/Lib/inspect.py index f6b5badc3f7..da1d4b25857 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1038,8 +1038,8 @@ def getargvalues(frame): def formatannotation(annotation, base_module=None): if isinstance(annotation, type): if annotation.__module__ in ('builtins', base_module): - return annotation.__name__ - return annotation.__module__+'.'+annotation.__name__ + return annotation.__qualname__ + return annotation.__module__+'.'+annotation.__qualname__ return repr(annotation) def formatannotationrelativeto(object): diff --git a/Lib/pdb.py b/Lib/pdb.py index 42e605e682a..a55012f24fb 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -1316,7 +1316,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): return # Is it a class? if value.__class__ is type: - self.message('Class %s.%s' % (value.__module__, value.__name__)) + self.message('Class %s.%s' % (value.__module__, value.__qualname__)) return # None of the above... self.message(type(value)) diff --git a/Lib/socket.py b/Lib/socket.py index cbadff72393..72aa220e6c1 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -141,7 +141,7 @@ class socket(_socket.socket): closed = getattr(self, '_closed', False) s = "<%s.%s%s fd=%i, family=%s, type=%s, proto=%i" \ % (self.__class__.__module__, - self.__class__.__name__, + self.__class__.__qualname__, " [closed]" if closed else "", self.fileno(), self.family, diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 78bd315344c..742b12b4a8a 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -579,7 +579,7 @@ boolean {0[0]} NO return e else: self.fail("expected exception type %s.%s" - % (exc.__module__, exc.__name__)) + % (exc.__module__, exc.__qualname__)) def test_boolean(self): cf = self.fromstring( diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index bda59bb3560..91ba5515447 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -778,7 +778,7 @@ class CommonBufferedTests: def test_repr(self): raw = self.MockRawIO() b = self.tp(raw) - clsname = "%s.%s" % (self.tp.__module__, self.tp.__name__) + clsname = "%s.%s" % (self.tp.__module__, self.tp.__qualname__) self.assertEqual(repr(b), "<%s>" % clsname) raw.name = "dummy" self.assertEqual(repr(b), "<%s name='dummy'>" % clsname) diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index c29556354ef..e3b28bd5515 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -92,9 +92,9 @@ class SyntaxTracebackCases(unittest.TestCase): self.assertEqual(len(err), 1) str_value = '' % X.__name__ if X.__module__ in ('__main__', 'builtins'): - str_name = X.__name__ + str_name = X.__qualname__ else: - str_name = '.'.join([X.__module__, X.__name__]) + str_name = '.'.join([X.__module__, X.__qualname__]) self.assertEqual(err[0], "%s: %s\n" % (str_name, str_value)) def test_without_exception(self): diff --git a/Lib/test/test_zipimport_support.py b/Lib/test/test_zipimport_support.py index 84ba5e047a3..43d0da60404 100644 --- a/Lib/test/test_zipimport_support.py +++ b/Lib/test/test_zipimport_support.py @@ -39,7 +39,7 @@ def _run_object_doctest(obj, module): # Use the object's fully qualified name if it has one # Otherwise, use the module's name try: - name = "%s.%s" % (obj.__module__, obj.__name__) + name = "%s.%s" % (obj.__module__, obj.__qualname__) except AttributeError: name = module.__name__ for example in finder.find(obj, name, module): diff --git a/Lib/traceback.py b/Lib/traceback.py index faf593a7354..c1ab36ec445 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -205,7 +205,7 @@ def _format_exception_only_iter(etype, value): yield _format_final_exc_line(etype, value) return - stype = etype.__name__ + stype = etype.__qualname__ smod = etype.__module__ if smod not in ("__main__", "builtins"): stype = smod + '.' + stype diff --git a/Lib/unittest/test/test_setups.py b/Lib/unittest/test/test_setups.py index 392f95efc07..2df703ed934 100644 --- a/Lib/unittest/test/test_setups.py +++ b/Lib/unittest/test/test_setups.py @@ -111,7 +111,7 @@ class TestSetups(unittest.TestCase): self.assertEqual(len(result.errors), 1) error, _ = result.errors[0] self.assertEqual(str(error), - 'setUpClass (%s.BrokenTest)' % __name__) + 'setUpClass (%s.%s)' % (__name__, BrokenTest.__qualname__)) def test_error_in_teardown_class(self): class Test(unittest.TestCase): @@ -144,7 +144,7 @@ class TestSetups(unittest.TestCase): error, _ = result.errors[0] self.assertEqual(str(error), - 'tearDownClass (%s.Test)' % __name__) + 'tearDownClass (%s.%s)' % (__name__, Test.__qualname__)) def test_class_not_torndown_when_setup_fails(self): class Test(unittest.TestCase): @@ -414,7 +414,8 @@ class TestSetups(unittest.TestCase): self.assertEqual(len(result.errors), 0) self.assertEqual(len(result.skipped), 1) skipped = result.skipped[0][0] - self.assertEqual(str(skipped), 'setUpClass (%s.Test)' % __name__) + self.assertEqual(str(skipped), + 'setUpClass (%s.%s)' % (__name__, Test.__qualname__)) def test_skiptest_in_setupmodule(self): class Test(unittest.TestCase): diff --git a/Lib/unittest/util.py b/Lib/unittest/util.py index aee498fd0be..45485dcb0df 100644 --- a/Lib/unittest/util.py +++ b/Lib/unittest/util.py @@ -52,7 +52,7 @@ def safe_repr(obj, short=False): return result[:_MAX_LENGTH] + ' [truncated]...' def strclass(cls): - return "%s.%s" % (cls.__module__, cls.__name__) + return "%s.%s" % (cls.__module__, cls.__qualname__) def sorted_list_difference(expected, actual): """Finds elements in only one or the other of two, sorted input lists. diff --git a/Misc/NEWS b/Misc/NEWS index 6c64bcf30c7..8fb72eddd30 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -108,6 +108,9 @@ Core and Builtins Library ------- +- Issue #22032: __qualname__ instead of __name__ is now always used to format + fully qualified class names of Python implemented classes. + - Issue #22031: Reprs now always use hexadecimal format with the "0x" prefix when contain an id in form " at 0x...".