]> granicus.if.org Git - python/commitdiff
Issue #25548: Showing memory address of class objects in repl
authorKushal Das <kushaldas@gmail.com>
Sat, 4 Jun 2016 23:21:13 +0000 (16:21 -0700)
committerKushal Das <kushaldas@gmail.com>
Sat, 4 Jun 2016 23:21:13 +0000 (16:21 -0700)
20 files changed:
Lib/ctypes/test/test_structures.py
Lib/statistics.py
Lib/test/test_class.py
Lib/test/test_cmd_line_script.py
Lib/test/test_defaultdict.py
Lib/test/test_descr.py
Lib/test/test_descrtut.py
Lib/test/test_doctest.py
Lib/test/test_doctest3.txt
Lib/test/test_functools.py
Lib/test/test_generators.py
Lib/test/test_genexps.py
Lib/test/test_metaclass.py
Lib/test/test_pprint.py
Lib/test/test_reprlib.py
Lib/test/test_statistics.py
Lib/test/test_wsgiref.py
Lib/test/test_xmlrpc.py
Misc/NEWS
Objects/typeobject.c

index e00bb046b444137695970b194bccc76496e107c1..736679f630260aeb14c99f591c3242105be73d73 100644 (file)
@@ -320,14 +320,14 @@ class StructureTestCase(unittest.TestCase):
 
         cls, msg = self.get_except(Person, b"Someone", (1, 2))
         self.assertEqual(cls, RuntimeError)
-        self.assertEqual(msg,
-                             "(Phone) <class 'TypeError'>: "
-                             "expected bytes, int found")
+        self.assertRegex(msg,
+                             r"\(Phone\) <class 'TypeError' at 0x.+>: "
+                             r"expected bytes, int found")
 
         cls, msg = self.get_except(Person, b"Someone", (b"a", b"b", b"c"))
         self.assertEqual(cls, RuntimeError)
-        self.assertEqual(msg,
-                             "(Phone) <class 'TypeError'>: too many initializers")
+        self.assertRegex(msg,
+                             r"\(Phone\) <class 'TypeError' at 0x.+>: too many initializers")
 
     def test_huge_field_name(self):
         # issue12881: segfault with large structure field names
index b081b5a00628d34295684588e48d1f0d04e6578d..63adc1a44f859018f815046d61c74ce1ad308de8 100644 (file)
@@ -131,23 +131,23 @@ def _sum(data, start=0):
     --------
 
     >>> _sum([3, 2.25, 4.5, -0.5, 1.0], 0.75)
-    (<class 'float'>, Fraction(11, 1), 5)
+    (<class 'float' ...>, Fraction(11, 1), 5)
 
     Some sources of round-off error will be avoided:
 
     >>> _sum([1e50, 1, -1e50] * 1000)  # Built-in sum returns zero.
-    (<class 'float'>, Fraction(1000, 1), 3000)
+    (<class 'float' ...>, Fraction(1000, 1), 3000)
 
     Fractions and Decimals are also supported:
 
     >>> from fractions import Fraction as F
     >>> _sum([F(2, 3), F(7, 5), F(1, 4), F(5, 6)])
-    (<class 'fractions.Fraction'>, Fraction(63, 20), 4)
+    (<class 'fractions.Fraction' ...>, Fraction(63, 20), 4)
 
     >>> from decimal import Decimal as D
     >>> data = [D("0.1375"), D("0.2108"), D("0.3061"), D("0.0419")]
     >>> _sum(data)
-    (<class 'decimal.Decimal'>, Fraction(6963, 10000), 4)
+    (<class 'decimal.Decimal' ...>, Fraction(6963, 10000), 4)
 
     Mixed types are currently treated as an error, except that int is
     allowed.
index 4d554a397b4a51b307d60aee4baf5aa4a24ff979..e02a3cbb9724b41a0814696e52af1497c460899e 100644 (file)
@@ -568,5 +568,15 @@ class ClassTests(unittest.TestCase):
         a = A(hash(A.f)^(-1))
         hash(a.f)
 
+    def test_class_repr(self):
+        # We should get the address of the object
+        class A:
+            pass
+
+        result = repr(A)
+        self.assertRegex(result,
+            "<class 'test.test_class.ClassTests.test_class_repr.<locals>.A'"
+            " at 0x.+>")
+
 if __name__ == '__main__':
     unittest.main()
index 01fb7dcf4039196bd88b93bd8553f96b5ea85927..e7c6351317f3fcabedff66caf0ae86b20669e5ae 100644 (file)
@@ -127,7 +127,10 @@ class CmdLineTest(unittest.TestCase):
             print(printed_package)
             print(printed_argv0)
             print(printed_cwd)
-        self.assertIn(printed_loader.encode('utf-8'), data)
+        expected = printed_loader.encode('utf-8')
+        idx = expected.find(b"at 0x")
+        expected = expected[:idx]
+        self.assertIn(expected, data)
         self.assertIn(printed_file.encode('utf-8'), data)
         self.assertIn(printed_package.encode('utf-8'), data)
         self.assertIn(printed_argv0.encode('utf-8'), data)
@@ -158,6 +161,8 @@ class CmdLineTest(unittest.TestCase):
     def test_dash_c_loader(self):
         rc, out, err = assert_python_ok("-c", "print(__loader__)")
         expected = repr(importlib.machinery.BuiltinImporter).encode("utf-8")
+        idx = expected.find(b"at 0x")
+        expected = expected[:idx]
         self.assertIn(expected, out)
 
     def test_stdin_loader(self):
@@ -171,6 +176,8 @@ class CmdLineTest(unittest.TestCase):
         finally:
             out = kill_python(p)
         expected = repr(importlib.machinery.BuiltinImporter).encode("utf-8")
+        idx = expected.find(b"at 0x")
+        expected = expected[:idx]
         self.assertIn(expected, out)
 
     @contextlib.contextmanager
index a90bc2b488cfc31b7afa64717e8a1452813a00bd..5bb4e122789f92276e1cecfa3cdee1489147c347 100644 (file)
@@ -65,7 +65,7 @@ class TestDefaultDict(unittest.TestCase):
         d2 = defaultdict(int)
         self.assertEqual(d2.default_factory, int)
         d2[12] = 42
-        self.assertEqual(repr(d2), "defaultdict(<class 'int'>, {12: 42})")
+        self.assertRegex(repr(d2), r"defaultdict\(<class 'int' at 0x.+>, {12: 42}\)")
         def foo(): return 43
         d3 = defaultdict(foo)
         self.assertTrue(d3.default_factory is foo)
index 0a5ecd5a0dc0a30bbf43c4e8a0e22f55c5659feb..954ef2d3b33840eaf0cdf131df820f52ae4e5e26 100644 (file)
@@ -4544,9 +4544,9 @@ order (MRO) for bases """
                 pass
         foo = Foo()
         self.assertRegex(repr(foo.method), # access via instance
-            r"<bound method .*Foo\.method of <class '.*Foo'>>")
+            r"<bound method .*Foo\.method of <class '.*Foo' at 0x.+>>")
         self.assertRegex(repr(Foo.method), # access via the class
-            r"<bound method .*Foo\.method of <class '.*Foo'>>")
+            r"<bound method .*Foo\.method of <class '.*Foo' at 0x.+>>")
 
 
         class MyCallable:
index 506d1abeb6963d67e874adc3b7924553c3737a74..80cfa41ecb748ff7844aa35459ed7405fbe7b95f 100644 (file)
@@ -37,16 +37,16 @@ test_1 = """
 Here's the new type at work:
 
     >>> print(defaultdict)              # show our type
-    <class 'test.test_descrtut.defaultdict'>
+    <class 'test.test_descrtut.defaultdict' ...>
     >>> print(type(defaultdict))        # its metatype
-    <class 'type'>
+    <class 'type' ...>
     >>> a = defaultdict(default=0.0)    # create an instance
     >>> print(a)                        # show the instance
     {}
     >>> print(type(a))                  # show its type
-    <class 'test.test_descrtut.defaultdict'>
+    <class 'test.test_descrtut.defaultdict' ...>
     >>> print(a.__class__)              # show its class
-    <class 'test.test_descrtut.defaultdict'>
+    <class 'test.test_descrtut.defaultdict' ...>
     >>> print(type(a) is a.__class__)   # its type is its class
     True
     >>> a[1] = 3.25                     # modify the instance
@@ -149,11 +149,11 @@ Introspecting instances of built-in types
 For instance of built-in types, x.__class__ is now the same as type(x):
 
     >>> type([])
-    <class 'list'>
+    <class 'list' ...>
     >>> [].__class__
-    <class 'list'>
+    <class 'list' ...>
     >>> list
-    <class 'list'>
+    <class 'list' ...>
     >>> isinstance([], list)
     True
     >>> isinstance([], dict)
@@ -258,19 +258,19 @@ implicit first argument that is the *class* for which they are invoked.
     ...         print("classmethod", cls, y)
 
     >>> C.foo(1)
-    classmethod <class 'test.test_descrtut.C'> 1
+    classmethod <class 'test.test_descrtut.C' ...> 1
     >>> c = C()
     >>> c.foo(1)
-    classmethod <class 'test.test_descrtut.C'> 1
+    classmethod <class 'test.test_descrtut.C' ...> 1
 
     >>> class D(C):
     ...     pass
 
     >>> D.foo(1)
-    classmethod <class 'test.test_descrtut.D'> 1
+    classmethod <class 'test.test_descrtut.D' ...> 1
     >>> d = D()
     >>> d.foo(1)
-    classmethod <class 'test.test_descrtut.D'> 1
+    classmethod <class 'test.test_descrtut.D' ...> 1
 
 This prints "classmethod __main__.D 1" both times; in other words, the
 class passed as the first argument of foo() is the class involved in the
@@ -286,11 +286,11 @@ But notice this:
 
     >>> E.foo(1)
     E.foo() called
-    classmethod <class 'test.test_descrtut.C'> 1
+    classmethod <class 'test.test_descrtut.C' ...> 1
     >>> e = E()
     >>> e.foo(1)
     E.foo() called
-    classmethod <class 'test.test_descrtut.C'> 1
+    classmethod <class 'test.test_descrtut.C' ...> 1
 
 In this example, the call to C.foo() from E.foo() will see class C as its
 first argument, not class E. This is to be expected, since the call
@@ -350,7 +350,7 @@ Hmm -- property is builtin now, so let's try it that way too.
 
     >>> del property  # unmask the builtin
     >>> property
-    <class 'property'>
+    <class 'property' ...>
 
     >>> class C(object):
     ...     def __init__(self):
@@ -478,7 +478,8 @@ def test_main(verbose=None):
     # business is used the name can change depending on how the test is
     # invoked.
     from test import support, test_descrtut
-    support.run_doctest(test_descrtut, verbose)
+    import doctest
+    support.run_doctest(test_descrtut, verbose, optionflags=doctest.ELLIPSIS)
 
 # This part isn't needed for regrtest, but for running the test directly.
 if __name__ == "__main__":
index 2068fb70f82f1a70260e08268b7c5d57692a52ee..ec12fe7372e044635f1497462bda947d69453ee2 100644 (file)
@@ -2338,7 +2338,7 @@ def test_DocFileSuite():
        `__file__` global, which is set to the name of the file
        containing the tests:
 
-         >>> suite = doctest.DocFileSuite('test_doctest3.txt')
+         >>> suite = doctest.DocFileSuite('test_doctest3.txt', optionflags=doctest.ELLIPSIS)
          >>> suite.run(unittest.TestResult())
          <unittest.result.TestResult run=1 errors=0 failures=0>
 
index dd8557e57a509b8cb6bcfe3c689a1f29293c407e..380ea76e4c8bf62483007dae4992f891734a883d 100644 (file)
@@ -2,4 +2,4 @@
 Here we check that `__file__` is provided:
 
   >>> type(__file__)
-  <class 'str'>
+  <class 'str' ...>
index 9cf115d42b1f3171aaba1463c726e373f8538f1e..852173cc0af74257371342abb8835feb8c87b5f6 100644 (file)
@@ -1697,13 +1697,10 @@ class TestSingleDispatch(unittest.TestCase):
         c.Container.register(P)
         with self.assertRaises(RuntimeError) as re_one:
             g(p)
-        self.assertIn(
-            str(re_one.exception),
-            (("Ambiguous dispatch: <class 'collections.abc.Container'> "
-              "or <class 'collections.abc.Iterable'>"),
-             ("Ambiguous dispatch: <class 'collections.abc.Iterable'> "
-              "or <class 'collections.abc.Container'>")),
-        )
+        self.assertIn("Ambiguous dispatch:", str(re_one.exception))
+        self.assertIn("<class 'collections.abc.Container'", str(re_one.exception))
+        self.assertIn("<class 'collections.abc.Iterable'", str(re_one.exception))
+
         class Q(c.Sized):
             def __len__(self):
                 return 0
@@ -1729,13 +1726,10 @@ class TestSingleDispatch(unittest.TestCase):
         # perspective.
         with self.assertRaises(RuntimeError) as re_two:
             h(c.defaultdict(lambda: 0))
-        self.assertIn(
-            str(re_two.exception),
-            (("Ambiguous dispatch: <class 'collections.abc.Container'> "
-              "or <class 'collections.abc.Sized'>"),
-             ("Ambiguous dispatch: <class 'collections.abc.Sized'> "
-              "or <class 'collections.abc.Container'>")),
-        )
+        self.assertIn("Ambiguous dispatch:", str(re_two.exception))
+        self.assertIn("<class 'collections.abc.Container'", str(re_two.exception))
+        self.assertIn("<class 'collections.abc.Sized'", str(re_two.exception))
+
         class R(c.defaultdict):
             pass
         c.MutableSequence.register(R)
@@ -1769,13 +1763,10 @@ class TestSingleDispatch(unittest.TestCase):
         # There is no preference for registered versus inferred ABCs.
         with self.assertRaises(RuntimeError) as re_three:
             h(u)
-        self.assertIn(
-            str(re_three.exception),
-            (("Ambiguous dispatch: <class 'collections.abc.Container'> "
-              "or <class 'collections.abc.Sized'>"),
-             ("Ambiguous dispatch: <class 'collections.abc.Sized'> "
-              "or <class 'collections.abc.Container'>")),
-        )
+        self.assertIn("Ambiguous dispatch:", str(re_three.exception))
+        self.assertIn("<class 'collections.abc.Container'", str(re_three.exception))
+        self.assertIn("<class 'collections.abc.Sized'", str(re_three.exception))
+
         class V(c.Sized, S):
             def __len__(self):
                 return 0
index f4b33afe141a44c4133d20c70a3c7c5411af585d..c193301b27fc26cf4172e407f806dab894fb0207 100644 (file)
@@ -671,10 +671,10 @@ From the Iterators list, about the types of these things.
 ...     yield 1
 ...
 >>> type(g)
-<class 'function'>
+<class 'function' ...>
 >>> i = g()
 >>> type(i)
-<class 'generator'>
+<class 'generator' ...>
 >>> [s for s in dir(i) if not s.startswith('_')]
 ['close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']
 >>> from test.support import HAVE_DOCSTRINGS
@@ -691,7 +691,7 @@ And more, added later.
 >>> i.gi_running
 0
 >>> type(i.gi_frame)
-<class 'frame'>
+<class 'frame' ...>
 >>> i.gi_running = 42
 Traceback (most recent call last):
   ...
@@ -1066,27 +1066,27 @@ These are fine:
 >>> def f():
 ...    yield
 >>> type(f())
-<class 'generator'>
+<class 'generator' ...>
 
 
 >>> def f():
 ...    if 0:
 ...        yield
 >>> type(f())
-<class 'generator'>
+<class 'generator' ...>
 
 
 >>> def f():
 ...     if 0:
 ...         yield 1
 >>> type(f())
-<class 'generator'>
+<class 'generator' ...>
 
 >>> def f():
 ...    if "":
 ...        yield None
 >>> type(f())
-<class 'generator'>
+<class 'generator' ...>
 
 >>> def f():
 ...     return
@@ -1110,7 +1110,7 @@ These are fine:
 ...         x = 1
 ...     return
 >>> type(f())
-<class 'generator'>
+<class 'generator' ...>
 
 >>> def f():
 ...     if 0:
@@ -1118,7 +1118,7 @@ These are fine:
 ...             yield 1
 ...
 >>> type(f())
-<class 'NoneType'>
+<class 'NoneType' ...>
 
 >>> def f():
 ...     if 0:
@@ -1128,7 +1128,7 @@ These are fine:
 ...             def f(self):
 ...                 yield 2
 >>> type(f())
-<class 'NoneType'>
+<class 'NoneType' ...>
 
 >>> def f():
 ...     if 0:
@@ -1136,7 +1136,7 @@ These are fine:
 ...     if 0:
 ...         yield 2
 >>> type(f())
-<class 'generator'>
+<class 'generator' ...>
 
 This one caused a crash (see SF bug 567538):
 
@@ -1791,7 +1791,7 @@ And a more sane, but still weird usage:
 
 >>> def f(): list(i for i in [(yield 26)])
 >>> type(f())
-<class 'generator'>
+<class 'generator' ...>
 
 
 A yield expression with augmented assignment.
@@ -2047,25 +2047,25 @@ enclosing function a generator:
 
 >>> def f(): x += yield
 >>> type(f())
-<class 'generator'>
+<class 'generator' ...>
 
 >>> def f(): x = yield
 >>> type(f())
-<class 'generator'>
+<class 'generator' ...>
 
 >>> def f(): lambda x=(yield): 1
 >>> type(f())
-<class 'generator'>
+<class 'generator' ...>
 
 >>> def f(): x=(i for i in (yield) if (yield))
 >>> type(f())
-<class 'generator'>
+<class 'generator' ...>
 
 >>> def f(d): d[(yield "a")] = d[(yield "b")] = 27
 >>> data = [1,2]
 >>> g = f(data)
 >>> type(g)
-<class 'generator'>
+<class 'generator' ...>
 >>> g.send(None)
 'a'
 >>> data
@@ -2174,8 +2174,9 @@ __test__ = {"tut":      tutorial_tests,
 # so this works as expected in both ways of running regrtest.
 def test_main(verbose=None):
     from test import support, test_generators
+    import doctest
     support.run_unittest(__name__)
-    support.run_doctest(test_generators, verbose)
+    support.run_doctest(test_generators, verbose, optionflags=doctest.ELLIPSIS)
 
 # This part isn't needed for regrtest, but for running the test directly.
 if __name__ == "__main__":
index fb531d6d472b6f05829b9fda75779e24d1048ae1..c5e10dda8c674819b3cb0d4845277aaef6e6bf06 100644 (file)
@@ -27,7 +27,7 @@ Test first class
 
     >>> g = (i*i for i in range(4))
     >>> type(g)
-    <class 'generator'>
+    <class 'generator' ...>
     >>> list(g)
     [0, 1, 4, 9]
 
@@ -269,7 +269,8 @@ else:
 def test_main(verbose=None):
     from test import support
     from test import test_genexps
-    support.run_doctest(test_genexps, verbose)
+    import doctest
+    support.run_doctest(test_genexps, verbose, optionflags=doctest.ELLIPSIS)
 
     # verify reference counting
     if verbose and hasattr(sys, "gettotalrefcount"):
index e6fe20a107c239a64fc1e8bedfda2b159134f56f..be683dd1a149dfb0c307ebe8f0b645a2de0e138a 100644 (file)
@@ -78,7 +78,7 @@ Also pass another keyword.
     >>> class C(object, metaclass=M, other="haha"):
     ...     pass
     ...
-    Prepare called: ('C', (<class 'object'>,)) {'other': 'haha'}
+    Prepare called: ('C', (<class 'object' ...>,)) {'other': 'haha'}
     New called: {'other': 'haha'}
     >>> C.__class__ is M
     True
@@ -104,7 +104,7 @@ Use various combinations of explicit keywords and **kwds.
     >>> kwds = {'metaclass': M, 'other': 'haha'}
     >>> class C(*bases, **kwds): pass
     ...
-    Prepare called: ('C', (<class 'object'>,)) {'other': 'haha'}
+    Prepare called: ('C', (<class 'object' ...>,)) {'other': 'haha'}
     New called: {'other': 'haha'}
     >>> C.__class__ is M
     True
@@ -114,7 +114,7 @@ Use various combinations of explicit keywords and **kwds.
     >>> kwds = {'other': 'haha'}
     >>> class C(B, metaclass=M, *bases, **kwds): pass
     ...
-    Prepare called: ('C', (<class 'test.test_metaclass.B'>, <class 'object'>)) {'other': 'haha'}
+    Prepare called: ('C', (<class 'test.test_metaclass.B' ...>, <class 'object' ...>)) {'other': 'haha'}
     New called: {'other': 'haha'}
     >>> C.__class__ is M
     True
@@ -259,7 +259,8 @@ else:
 def test_main(verbose=False):
     from test import support
     from test import test_metaclass
-    support.run_doctest(test_metaclass, verbose)
+    import doctest
+    support.run_doctest(test_metaclass, verbose, optionflags=doctest.ELLIPSIS)
 
 if __name__ == "__main__":
     test_main(verbose=True)
index 7ebc298337ad5ccac12505161bd790f1c6ea38a0..2283923cee37f504059e94e74d6c70ed62da1801 100644 (file)
@@ -848,12 +848,11 @@ bytearray(b'\\x00\\x01\\x02\\x03'
 
     def test_default_dict(self):
         d = collections.defaultdict(int)
-        self.assertEqual(pprint.pformat(d, width=1), "defaultdict(<class 'int'>, {})")
+        self.assertRegex(pprint.pformat(d, width=1), r"defaultdict\(<class 'int' at 0x.+>, {}\)")
         words = 'the quick brown fox jumped over a lazy dog'.split()
         d = collections.defaultdict(int, zip(words, itertools.count()))
-        self.assertEqual(pprint.pformat(d),
-"""\
-defaultdict(<class 'int'>,
+        self.assertRegex(pprint.pformat(d),
+r"""defaultdict\(<class 'int' at 0x.+>,
             {'a': 6,
              'brown': 2,
              'dog': 8,
@@ -862,7 +861,7 @@ defaultdict(<class 'int'>,
              'lazy': 7,
              'over': 5,
              'quick': 1,
-             'the': 0})""")
+             'the': 0}\)""")
 
     def test_counter(self):
         d = collections.Counter()
index 4bf91945ea4f4ae3ea8c31ec07a35ca97fcd16c1..2ecea0221e966a83d2d0e20ebd5c45b653da1116 100644 (file)
@@ -292,8 +292,8 @@ class foo(object):
 ''')
         importlib.invalidate_caches()
         from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
-        eq(repr(foo.foo),
-               "<class '%s.foo'>" % foo.__name__)
+        self.assertRegex(repr(foo.foo),
+               r"<class '%s.foo' at 0x.+>" % foo.__name__)
 
     @unittest.skip('need a suitable object')
     def test_object(self):
@@ -310,7 +310,7 @@ class bar:
         importlib.invalidate_caches()
         from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
         # Module name may be prefixed with "test.", depending on how run.
-        self.assertEqual(repr(bar.bar), "<class '%s.bar'>" % bar.__name__)
+        self.assertRegex(repr(bar.bar), r"<class '%s.bar' at 0x.+>" % bar.__name__)
 
     def test_instance(self):
         self._check_path_limitations('baz')
index 5275cb681d3dd0bc055c6dc86fc84037d2647c07..5dd50483f2033c1b4b18f0b040c3b451f3e87913 100644 (file)
@@ -659,7 +659,7 @@ class DocTests(unittest.TestCase):
     @unittest.skipIf(sys.flags.optimize >= 2,
                      "Docstrings are omitted with -OO and above")
     def test_doc_tests(self):
-        failed, tried = doctest.testmod(statistics)
+        failed, tried = doctest.testmod(statistics, optionflags=doctest.ELLIPSIS)
         self.assertGreater(tried, 0)
         self.assertEqual(failed, 0)
 
index b7d02e868c9ffa3fdf1205567098924b35e2ca7d..3977e230b0442895de404bf92f11dadeca3bef2a 100644 (file)
@@ -161,10 +161,10 @@ class IntegrationTests(TestCase):
         self.assertTrue(out.endswith(
             b"A server error occurred.  Please contact the administrator."
         ))
-        self.assertEqual(
+        self.assertRegex(
             err.splitlines()[-2],
-            "AssertionError: Headers (('Content-Type', 'text/plain')) must"
-            " be of type list: <class 'tuple'>"
+            r"AssertionError: Headers \(\('Content-Type', 'text/plain'\)\) must"
+            r" be of type list: <class 'tuple' at 0x.+>"
         )
 
     def test_status_validation_errors(self):
@@ -704,3 +704,4 @@ class HandlerTests(TestCase):
 
 if __name__ == "__main__":
     unittest.main()
+
index 0773a86984a0f9ac1aada513dccb4aed9d36725b..f2fdc44cbe02408fba298fac500d7a0e0d39d5eb 100644 (file)
@@ -775,8 +775,8 @@ class SimpleServerTestCase(BaseServerTestCase):
             #   'method "this_is_not_exists" is not supported'>}]
 
             self.assertEqual(result.results[0]['faultCode'], 1)
-            self.assertEqual(result.results[0]['faultString'],
-                '<class \'Exception\'>:method "this_is_not_exists" '
+            self.assertRegex(result.results[0]['faultString'],
+                '<class \'Exception\' at 0x.+>:method "this_is_not_exists" '
                 'is not supported')
         except (xmlrpclib.ProtocolError, OSError) as e:
             # ignore failures due to non-blocking socket 'unavailable' errors
index 9a02894676d06193eca3fd7db45e83b8d6b9d78f..4b82ccd2dc78f922203da78f230b39a75ec4376c 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -73,6 +73,8 @@ Library
 
 - Issue #21271: New keyword only parameters in reset_mock call.
 
+- Issue #25548: Showing memory address of class objects in repl.
+
 IDLE
 ----
 
index a64779177c0ddee05127a231ac6f0a94ee1deca0..78d5c1ee516e83aca4ea085071ad4fdee9a21dc4 100644 (file)
@@ -859,9 +859,9 @@ type_repr(PyTypeObject *type)
     }
 
     if (mod != NULL && _PyUnicode_CompareWithId(mod, &PyId_builtins))
-        rtn = PyUnicode_FromFormat("<class '%U.%U'>", mod, name);
-    else
-        rtn = PyUnicode_FromFormat("<class '%s'>", type->tp_name);
+        rtn = PyUnicode_FromFormat("<class '%U.%U' at %p>", mod, name, type);
+    else    
+        rtn = PyUnicode_FromFormat("<class '%s' at %p>", type->tp_name, type);
 
     Py_XDECREF(mod);
     Py_DECREF(name);