blob: a328810c21ec613dadb81d4dd1faa3aa16fd9471 [file] [log] [blame]
Fred Drake8e6669a2001-07-19 22:27:56 +00001"""
2 Test cases for the repr module
3 Nick Mathewson
4"""
5
Barry Warsaw0bcf6d82001-08-24 18:37:32 +00006import sys
7import os
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00008import shutil
Antoine Pitrouc541f8e2012-02-20 01:48:16 +01009import importlib
Brett Cannon9529fbf2013-06-15 17:11:25 -040010import importlib.util
Fred Drake8e6669a2001-07-19 22:27:56 +000011import unittest
Barry Warsaw0bcf6d82001-08-24 18:37:32 +000012
Hai Shia089d212020-07-06 17:15:08 +080013from test.support import verbose
14from test.support.os_helper import create_empty_file
Alexandre Vassalotti1f2ba4b2008-05-16 07:12:44 +000015from reprlib import repr as r # Don't shadow builtin repr
16from reprlib import Repr
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +000017from reprlib import recursive_repr
Fred Drake8e6669a2001-07-19 22:27:56 +000018
19
20def nestedTuple(nesting):
21 t = ()
22 for i in range(nesting):
23 t = (t,)
24 return t
25
26class ReprTests(unittest.TestCase):
27
28 def test_string(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +000029 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +000030 eq(r("abc"), "'abc'")
31 eq(r("abcdefghijklmnop"),"'abcdefghijklmnop'")
32
33 s = "a"*30+"b"*30
Walter Dörwald70a6b492004-02-12 17:35:32 +000034 expected = repr(s)[:13] + "..." + repr(s)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +000035 eq(r(s), expected)
Tim Petersab9ba272001-08-09 21:40:30 +000036
Fred Drake8e6669a2001-07-19 22:27:56 +000037 eq(r("\"'"), repr("\"'"))
38 s = "\""*30+"'"*100
Walter Dörwald70a6b492004-02-12 17:35:32 +000039 expected = repr(s)[:13] + "..." + repr(s)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +000040 eq(r(s), expected)
41
Guido van Rossumcd16bf62007-06-13 18:07:49 +000042 def test_tuple(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +000043 eq = self.assertEqual
Guido van Rossumcd16bf62007-06-13 18:07:49 +000044 eq(r((1,)), "(1,)")
45
46 t3 = (1, 2, 3)
47 eq(r(t3), "(1, 2, 3)")
48
49 r2 = Repr()
50 r2.maxtuple = 2
51 expected = repr(t3)[:-2] + "...)"
52 eq(r2.repr(t3), expected)
53
Fred Drake8e6669a2001-07-19 22:27:56 +000054 def test_container(self):
Tim Peters6ee04802003-02-05 18:29:34 +000055 from array import array
Raymond Hettinger1453e4a2004-05-21 23:01:18 +000056 from collections import deque
Tim Peters6ee04802003-02-05 18:29:34 +000057
Ezio Melottib3aedd42010-11-20 19:04:17 +000058 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +000059 # Tuples give up after 6 elements
60 eq(r(()), "()")
61 eq(r((1,)), "(1,)")
62 eq(r((1, 2, 3)), "(1, 2, 3)")
63 eq(r((1, 2, 3, 4, 5, 6)), "(1, 2, 3, 4, 5, 6)")
64 eq(r((1, 2, 3, 4, 5, 6, 7)), "(1, 2, 3, 4, 5, 6, ...)")
65
66 # Lists give up after 6 as well
67 eq(r([]), "[]")
68 eq(r([1]), "[1]")
69 eq(r([1, 2, 3]), "[1, 2, 3]")
70 eq(r([1, 2, 3, 4, 5, 6]), "[1, 2, 3, 4, 5, 6]")
71 eq(r([1, 2, 3, 4, 5, 6, 7]), "[1, 2, 3, 4, 5, 6, ...]")
72
Raymond Hettingerba6cd362004-05-21 10:00:15 +000073 # Sets give up after 6 as well
Raymond Hettingerffd842e2014-11-09 22:30:36 -080074 eq(r(set([])), "set()")
75 eq(r(set([1])), "{1}")
76 eq(r(set([1, 2, 3])), "{1, 2, 3}")
77 eq(r(set([1, 2, 3, 4, 5, 6])), "{1, 2, 3, 4, 5, 6}")
78 eq(r(set([1, 2, 3, 4, 5, 6, 7])), "{1, 2, 3, 4, 5, 6, ...}")
Raymond Hettingerba6cd362004-05-21 10:00:15 +000079
80 # Frozensets give up after 6 as well
Raymond Hettingerffd842e2014-11-09 22:30:36 -080081 eq(r(frozenset([])), "frozenset()")
82 eq(r(frozenset([1])), "frozenset({1})")
83 eq(r(frozenset([1, 2, 3])), "frozenset({1, 2, 3})")
84 eq(r(frozenset([1, 2, 3, 4, 5, 6])), "frozenset({1, 2, 3, 4, 5, 6})")
85 eq(r(frozenset([1, 2, 3, 4, 5, 6, 7])), "frozenset({1, 2, 3, 4, 5, 6, ...})")
Raymond Hettingerba6cd362004-05-21 10:00:15 +000086
Raymond Hettinger1453e4a2004-05-21 23:01:18 +000087 # collections.deque after 6
88 eq(r(deque([1, 2, 3, 4, 5, 6, 7])), "deque([1, 2, 3, 4, 5, 6, ...])")
89
Fred Drake8e6669a2001-07-19 22:27:56 +000090 # Dictionaries give up after 4.
91 eq(r({}), "{}")
92 d = {'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}
93 eq(r(d), "{'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}")
94 d['arthur'] = 1
95 eq(r(d), "{'alice': 1, 'arthur': 1, 'bob': 2, 'charles': 3, ...}")
96
Tim Peters6ee04802003-02-05 18:29:34 +000097 # array.array after 5.
Raymond Hettingera34cd0c2014-11-15 10:58:58 -080098 eq(r(array('i')), "array('i')")
Tim Peters6ee04802003-02-05 18:29:34 +000099 eq(r(array('i', [1])), "array('i', [1])")
100 eq(r(array('i', [1, 2])), "array('i', [1, 2])")
101 eq(r(array('i', [1, 2, 3])), "array('i', [1, 2, 3])")
102 eq(r(array('i', [1, 2, 3, 4])), "array('i', [1, 2, 3, 4])")
103 eq(r(array('i', [1, 2, 3, 4, 5])), "array('i', [1, 2, 3, 4, 5])")
104 eq(r(array('i', [1, 2, 3, 4, 5, 6])),
105 "array('i', [1, 2, 3, 4, 5, ...])")
106
Raymond Hettingerffd842e2014-11-09 22:30:36 -0800107 def test_set_literal(self):
108 eq = self.assertEqual
109 eq(r({1}), "{1}")
110 eq(r({1, 2, 3}), "{1, 2, 3}")
111 eq(r({1, 2, 3, 4, 5, 6}), "{1, 2, 3, 4, 5, 6}")
112 eq(r({1, 2, 3, 4, 5, 6, 7}), "{1, 2, 3, 4, 5, 6, ...}")
113
114 def test_frozenset(self):
115 eq = self.assertEqual
116 eq(r(frozenset({1})), "frozenset({1})")
117 eq(r(frozenset({1, 2, 3})), "frozenset({1, 2, 3})")
118 eq(r(frozenset({1, 2, 3, 4, 5, 6})), "frozenset({1, 2, 3, 4, 5, 6})")
119 eq(r(frozenset({1, 2, 3, 4, 5, 6, 7})), "frozenset({1, 2, 3, 4, 5, 6, ...})")
120
Fred Drake8e6669a2001-07-19 22:27:56 +0000121 def test_numbers(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000122 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +0000123 eq(r(123), repr(123))
Guido van Rossume2a383d2007-01-15 16:59:06 +0000124 eq(r(123), repr(123))
Fred Drake8e6669a2001-07-19 22:27:56 +0000125 eq(r(1.0/3), repr(1.0/3))
126
Guido van Rossume2a383d2007-01-15 16:59:06 +0000127 n = 10**100
Walter Dörwald70a6b492004-02-12 17:35:32 +0000128 expected = repr(n)[:18] + "..." + repr(n)[-19:]
Fred Drake8e6669a2001-07-19 22:27:56 +0000129 eq(r(n), expected)
130
131 def test_instance(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000132 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +0000133 i1 = ClassWithRepr("a")
134 eq(r(i1), repr(i1))
Tim Petersab9ba272001-08-09 21:40:30 +0000135
Fred Drake8e6669a2001-07-19 22:27:56 +0000136 i2 = ClassWithRepr("x"*1000)
Walter Dörwald70a6b492004-02-12 17:35:32 +0000137 expected = repr(i2)[:13] + "..." + repr(i2)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +0000138 eq(r(i2), expected)
139
140 i3 = ClassWithFailingRepr()
Serhiy Storchaka0c937b32014-07-22 12:14:52 +0300141 eq(r(i3), ("<ClassWithFailingRepr instance at %#x>"%id(i3)))
Fred Drake8e6669a2001-07-19 22:27:56 +0000142
Guido van Rossumcf856f92001-09-05 02:26:26 +0000143 s = r(ClassWithFailingRepr)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000144 self.assertTrue(s.startswith("<class "))
145 self.assertTrue(s.endswith(">"))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000146 self.assertIn(s.find("..."), [12, 13])
Guido van Rossumcf856f92001-09-05 02:26:26 +0000147
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000148 def test_lambda(self):
Antoine Pitrou86a36b52011-11-25 18:56:07 +0100149 r = repr(lambda x: x)
150 self.assertTrue(r.startswith("<function ReprTests.test_lambda.<locals>.<lambda"), r)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000151 # XXX anonymous functions? see func_repr
152
153 def test_builtin_function(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000154 eq = self.assertEqual
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000155 # Functions
156 eq(repr(hash), '<built-in function hash>')
157 # Methods
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000158 self.assertTrue(repr(''.split).startswith(
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000159 '<built-in method split of str object at 0x'))
160
Guido van Rossum805365e2007-05-07 22:24:25 +0000161 def test_range(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000162 eq = self.assertEqual
Guido van Rossum3353a2e2007-05-21 18:14:54 +0000163 eq(repr(range(1)), 'range(0, 1)')
Guido van Rossum805365e2007-05-07 22:24:25 +0000164 eq(repr(range(1, 2)), 'range(1, 2)')
165 eq(repr(range(1, 4, 3)), 'range(1, 4, 3)')
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000166
Fred Drake8e6669a2001-07-19 22:27:56 +0000167 def test_nesting(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000168 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +0000169 # everything is meant to give up after 6 levels.
170 eq(r([[[[[[[]]]]]]]), "[[[[[[[]]]]]]]")
171 eq(r([[[[[[[[]]]]]]]]), "[[[[[[[...]]]]]]]")
172
173 eq(r(nestedTuple(6)), "(((((((),),),),),),)")
174 eq(r(nestedTuple(7)), "(((((((...),),),),),),)")
175
176 eq(r({ nestedTuple(5) : nestedTuple(5) }),
177 "{((((((),),),),),): ((((((),),),),),)}")
178 eq(r({ nestedTuple(6) : nestedTuple(6) }),
179 "{((((((...),),),),),): ((((((...),),),),),)}")
180
181 eq(r([[[[[[{}]]]]]]), "[[[[[[{}]]]]]]")
182 eq(r([[[[[[[{}]]]]]]]), "[[[[[[[...]]]]]]]")
183
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000184 def test_cell(self):
Serhiy Storchaka1f79cdf2013-12-10 10:20:31 +0200185 def get_cell():
186 x = 42
187 def inner():
188 return x
189 return inner
190 x = get_cell().__closure__[0]
Zachary Wareea6854a2013-12-10 14:17:22 -0600191 self.assertRegex(repr(x), r'<cell at 0x[0-9A-Fa-f]+: '
192 r'int object at 0x[0-9A-Fa-f]+>')
Serhiy Storchaka1f79cdf2013-12-10 10:20:31 +0200193 self.assertRegex(r(x), r'<cell at 0x.*\.\.\..*>')
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000194
195 def test_descriptors(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000196 eq = self.assertEqual
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000197 # method descriptors
Tim Petersa427a2b2001-10-29 22:25:45 +0000198 eq(repr(dict.items), "<method 'items' of 'dict' objects>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000199 # XXX member descriptors
200 # XXX attribute descriptors
201 # XXX slot descriptors
202 # static and class methods
203 class C:
204 def foo(cls): pass
205 x = staticmethod(C.foo)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000206 self.assertTrue(repr(x).startswith('<staticmethod object at 0x'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000207 x = classmethod(C.foo)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000208 self.assertTrue(repr(x).startswith('<classmethod object at 0x'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000209
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000210 def test_unsortable(self):
211 # Repr.repr() used to call sorted() on sets, frozensets and dicts
212 # without taking into account that not all objects are comparable
213 x = set([1j, 2j, 3j])
214 y = frozenset(x)
215 z = {1j: 1, 2j: 2}
216 r(x)
217 r(y)
218 r(z)
219
Victor Stinnerbf816222011-06-30 23:25:47 +0200220def write_file(path, text):
221 with open(path, 'w', encoding='ASCII') as fp:
222 fp.write(text)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000223
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000224class LongReprTest(unittest.TestCase):
Antoine Pitrou01296da2012-04-24 13:55:35 +0200225 longname = 'areallylongpackageandmodulenametotestreprtruncation'
226
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000227 def setUp(self):
Antoine Pitrou01296da2012-04-24 13:55:35 +0200228 self.pkgname = os.path.join(self.longname)
229 self.subpkgname = os.path.join(self.longname, self.longname)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000230 # Make the package and subpackage
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000231 shutil.rmtree(self.pkgname, ignore_errors=True)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000232 os.mkdir(self.pkgname)
Victor Stinnerbf816222011-06-30 23:25:47 +0200233 create_empty_file(os.path.join(self.pkgname, '__init__.py'))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000234 shutil.rmtree(self.subpkgname, ignore_errors=True)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000235 os.mkdir(self.subpkgname)
Victor Stinnerbf816222011-06-30 23:25:47 +0200236 create_empty_file(os.path.join(self.subpkgname, '__init__.py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000237 # Remember where we are
238 self.here = os.getcwd()
239 sys.path.insert(0, self.here)
Brett Cannonceffda82012-04-16 20:48:50 -0400240 # When regrtest is run with its -j option, this command alone is not
241 # enough.
Antoine Pitrouc541f8e2012-02-20 01:48:16 +0100242 importlib.invalidate_caches()
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000243
244 def tearDown(self):
245 actions = []
Benjamin Peterson699adb92008-05-08 22:27:58 +0000246 for dirpath, dirnames, filenames in os.walk(self.pkgname):
247 for name in dirnames + filenames:
248 actions.append(os.path.join(dirpath, name))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000249 actions.append(self.pkgname)
250 actions.sort()
251 actions.reverse()
252 for p in actions:
253 if os.path.isdir(p):
254 os.rmdir(p)
255 else:
256 os.remove(p)
257 del sys.path[0]
258
Antoine Pitrou01296da2012-04-24 13:55:35 +0200259 def _check_path_limitations(self, module_name):
260 # base directory
261 source_path_len = len(self.here)
262 # a path separator + `longname` (twice)
263 source_path_len += 2 * (len(self.longname) + 1)
264 # a path separator + `module_name` + ".py"
265 source_path_len += len(module_name) + 1 + len(".py")
Brett Cannon9529fbf2013-06-15 17:11:25 -0400266 cached_path_len = (source_path_len +
267 len(importlib.util.cache_from_source("x.py")) - len("x.py"))
Antoine Pitrou110ee342012-06-23 22:55:58 +0200268 if os.name == 'nt' and cached_path_len >= 258:
Antoine Pitrou01296da2012-04-24 13:55:35 +0200269 # Under Windows, the max path len is 260 including C's terminating
270 # NUL character.
271 # (see http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx#maxpath)
272 self.skipTest("test paths too long (%d characters) for Windows' 260 character limit"
273 % cached_path_len)
Antoine Pitrou541b7c82012-06-23 00:07:38 +0200274 elif os.name == 'nt' and verbose:
Antoine Pitrouf0f47422012-06-23 00:49:44 +0200275 print("cached_path_len =", cached_path_len)
Antoine Pitrou01296da2012-04-24 13:55:35 +0200276
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000277 def test_module(self):
Eric Snowb523f842013-11-22 09:05:39 -0700278 self.maxDiff = None
Antoine Pitrou01296da2012-04-24 13:55:35 +0200279 self._check_path_limitations(self.pkgname)
Victor Stinnerbf816222011-06-30 23:25:47 +0200280 create_empty_file(os.path.join(self.subpkgname, self.pkgname + '.py'))
Brett Cannonceffda82012-04-16 20:48:50 -0400281 importlib.invalidate_caches()
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000282 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
Brett Cannon7b383c42012-06-11 11:02:36 -0400283 module = areallylongpackageandmodulenametotestreprtruncation
284 self.assertEqual(repr(module), "<module %r from %r>" % (module.__name__, module.__file__))
285 self.assertEqual(repr(sys), "<module 'sys' (built-in)>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000286
287 def test_type(self):
Antoine Pitrou01296da2012-04-24 13:55:35 +0200288 self._check_path_limitations('foo')
Ezio Melottib3aedd42010-11-20 19:04:17 +0000289 eq = self.assertEqual
Victor Stinnerbf816222011-06-30 23:25:47 +0200290 write_file(os.path.join(self.subpkgname, 'foo.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000291class foo(object):
292 pass
293''')
Brett Cannonceffda82012-04-16 20:48:50 -0400294 importlib.invalidate_caches()
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000295 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
Benjamin Petersonab078e92016-07-13 21:13:29 -0700296 eq(repr(foo.foo),
297 "<class '%s.foo'>" % foo.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000298
Zachary Ware9fe6d862013-12-08 00:20:35 -0600299 @unittest.skip('need a suitable object')
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000300 def test_object(self):
301 # XXX Test the repr of a type with a really long tp_name but with no
302 # tp_repr. WIBNI we had ::Inline? :)
303 pass
304
305 def test_class(self):
Antoine Pitrou01296da2012-04-24 13:55:35 +0200306 self._check_path_limitations('bar')
Victor Stinnerbf816222011-06-30 23:25:47 +0200307 write_file(os.path.join(self.subpkgname, 'bar.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000308class bar:
309 pass
310''')
Brett Cannonceffda82012-04-16 20:48:50 -0400311 importlib.invalidate_caches()
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000312 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
Mark Hammondd800ae12003-01-16 04:56:52 +0000313 # Module name may be prefixed with "test.", depending on how run.
Benjamin Petersonab078e92016-07-13 21:13:29 -0700314 self.assertEqual(repr(bar.bar), "<class '%s.bar'>" % bar.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000315
316 def test_instance(self):
Antoine Pitrou01296da2012-04-24 13:55:35 +0200317 self._check_path_limitations('baz')
Victor Stinnerbf816222011-06-30 23:25:47 +0200318 write_file(os.path.join(self.subpkgname, 'baz.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000319class baz:
320 pass
321''')
Brett Cannonceffda82012-04-16 20:48:50 -0400322 importlib.invalidate_caches()
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000323 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
324 ibaz = baz.baz()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000325 self.assertTrue(repr(ibaz).startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000326 "<%s.baz object at 0x" % baz.__name__))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000327
328 def test_method(self):
Antoine Pitrou01296da2012-04-24 13:55:35 +0200329 self._check_path_limitations('qux')
Ezio Melottib3aedd42010-11-20 19:04:17 +0000330 eq = self.assertEqual
Victor Stinnerbf816222011-06-30 23:25:47 +0200331 write_file(os.path.join(self.subpkgname, 'qux.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000332class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
333 def amethod(self): pass
334''')
Brett Cannonceffda82012-04-16 20:48:50 -0400335 importlib.invalidate_caches()
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000336 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
337 # Unbound methods first
Antoine Pitrou86a36b52011-11-25 18:56:07 +0100338 r = repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod)
339 self.assertTrue(r.startswith('<function aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod'), r)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000340 # Bound method next
341 iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
Antoine Pitrou86a36b52011-11-25 18:56:07 +0100342 r = repr(iqux.amethod)
343 self.assertTrue(r.startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000344 '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa object at 0x' \
Antoine Pitrou86a36b52011-11-25 18:56:07 +0100345 % (qux.__name__,) ), r)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000346
Zachary Ware9fe6d862013-12-08 00:20:35 -0600347 @unittest.skip('needs a built-in function with a really long name')
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000348 def test_builtin_function(self):
349 # XXX test built-in functions and methods with really long names
350 pass
Fred Drake8e6669a2001-07-19 22:27:56 +0000351
352class ClassWithRepr:
353 def __init__(self, s):
354 self.s = s
355 def __repr__(self):
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000356 return "ClassWithRepr(%r)" % self.s
Fred Drake8e6669a2001-07-19 22:27:56 +0000357
358
359class ClassWithFailingRepr:
360 def __repr__(self):
361 raise Exception("This should be caught by Repr.repr_instance")
362
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000363class MyContainer:
364 'Helper class for TestRecursiveRepr'
365 def __init__(self, values):
366 self.values = list(values)
367 def append(self, value):
368 self.values.append(value)
369 @recursive_repr()
370 def __repr__(self):
371 return '<' + ', '.join(map(str, self.values)) + '>'
372
373class MyContainer2(MyContainer):
374 @recursive_repr('+++')
375 def __repr__(self):
376 return '<' + ', '.join(map(str, self.values)) + '>'
377
Serhiy Storchakab3b366d2016-04-26 09:30:44 +0300378class MyContainer3:
379 def __repr__(self):
380 'Test document content'
381 pass
382 wrapped = __repr__
383 wrapper = recursive_repr()(wrapped)
384
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000385class TestRecursiveRepr(unittest.TestCase):
386 def test_recursive_repr(self):
387 m = MyContainer(list('abcde'))
388 m.append(m)
389 m.append('x')
390 m.append(m)
391 self.assertEqual(repr(m), '<a, b, c, d, e, ..., x, ...>')
392 m = MyContainer2(list('abcde'))
393 m.append(m)
394 m.append('x')
395 m.append(m)
396 self.assertEqual(repr(m), '<a, b, c, d, e, +++, x, +++>')
Fred Drake8e6669a2001-07-19 22:27:56 +0000397
Serhiy Storchakab3b366d2016-04-26 09:30:44 +0300398 def test_assigned_attributes(self):
399 from functools import WRAPPER_ASSIGNMENTS as assigned
400 wrapped = MyContainer3.wrapped
401 wrapper = MyContainer3.wrapper
402 for name in assigned:
403 self.assertIs(getattr(wrapper, name), getattr(wrapped, name))
404
Fred Drake2e2be372001-09-20 21:33:42 +0000405if __name__ == "__main__":
Raymond Hettingerffd842e2014-11-09 22:30:36 -0800406 unittest.main()