blob: 4bf91945ea4f4ae3ea8c31ec07a35ca97fcd16c1 [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
Raymond Hettingerffd842e2014-11-09 22:30:36 -080013from test.support import create_empty_file, verbose
Alexandre Vassalotti1f2ba4b2008-05-16 07:12:44 +000014from reprlib import repr as r # Don't shadow builtin repr
15from reprlib import Repr
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +000016from reprlib import recursive_repr
Fred Drake8e6669a2001-07-19 22:27:56 +000017
18
19def nestedTuple(nesting):
20 t = ()
21 for i in range(nesting):
22 t = (t,)
23 return t
24
25class ReprTests(unittest.TestCase):
26
27 def test_string(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +000028 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +000029 eq(r("abc"), "'abc'")
30 eq(r("abcdefghijklmnop"),"'abcdefghijklmnop'")
31
32 s = "a"*30+"b"*30
Walter Dörwald70a6b492004-02-12 17:35:32 +000033 expected = repr(s)[:13] + "..." + repr(s)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +000034 eq(r(s), expected)
Tim Petersab9ba272001-08-09 21:40:30 +000035
Fred Drake8e6669a2001-07-19 22:27:56 +000036 eq(r("\"'"), repr("\"'"))
37 s = "\""*30+"'"*100
Walter Dörwald70a6b492004-02-12 17:35:32 +000038 expected = repr(s)[:13] + "..." + repr(s)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +000039 eq(r(s), expected)
40
Guido van Rossumcd16bf62007-06-13 18:07:49 +000041 def test_tuple(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +000042 eq = self.assertEqual
Guido van Rossumcd16bf62007-06-13 18:07:49 +000043 eq(r((1,)), "(1,)")
44
45 t3 = (1, 2, 3)
46 eq(r(t3), "(1, 2, 3)")
47
48 r2 = Repr()
49 r2.maxtuple = 2
50 expected = repr(t3)[:-2] + "...)"
51 eq(r2.repr(t3), expected)
52
Fred Drake8e6669a2001-07-19 22:27:56 +000053 def test_container(self):
Tim Peters6ee04802003-02-05 18:29:34 +000054 from array import array
Raymond Hettinger1453e4a2004-05-21 23:01:18 +000055 from collections import deque
Tim Peters6ee04802003-02-05 18:29:34 +000056
Ezio Melottib3aedd42010-11-20 19:04:17 +000057 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +000058 # Tuples give up after 6 elements
59 eq(r(()), "()")
60 eq(r((1,)), "(1,)")
61 eq(r((1, 2, 3)), "(1, 2, 3)")
62 eq(r((1, 2, 3, 4, 5, 6)), "(1, 2, 3, 4, 5, 6)")
63 eq(r((1, 2, 3, 4, 5, 6, 7)), "(1, 2, 3, 4, 5, 6, ...)")
64
65 # Lists give up after 6 as well
66 eq(r([]), "[]")
67 eq(r([1]), "[1]")
68 eq(r([1, 2, 3]), "[1, 2, 3]")
69 eq(r([1, 2, 3, 4, 5, 6]), "[1, 2, 3, 4, 5, 6]")
70 eq(r([1, 2, 3, 4, 5, 6, 7]), "[1, 2, 3, 4, 5, 6, ...]")
71
Raymond Hettingerba6cd362004-05-21 10:00:15 +000072 # Sets give up after 6 as well
Raymond Hettingerffd842e2014-11-09 22:30:36 -080073 eq(r(set([])), "set()")
74 eq(r(set([1])), "{1}")
75 eq(r(set([1, 2, 3])), "{1, 2, 3}")
76 eq(r(set([1, 2, 3, 4, 5, 6])), "{1, 2, 3, 4, 5, 6}")
77 eq(r(set([1, 2, 3, 4, 5, 6, 7])), "{1, 2, 3, 4, 5, 6, ...}")
Raymond Hettingerba6cd362004-05-21 10:00:15 +000078
79 # Frozensets give up after 6 as well
Raymond Hettingerffd842e2014-11-09 22:30:36 -080080 eq(r(frozenset([])), "frozenset()")
81 eq(r(frozenset([1])), "frozenset({1})")
82 eq(r(frozenset([1, 2, 3])), "frozenset({1, 2, 3})")
83 eq(r(frozenset([1, 2, 3, 4, 5, 6])), "frozenset({1, 2, 3, 4, 5, 6})")
84 eq(r(frozenset([1, 2, 3, 4, 5, 6, 7])), "frozenset({1, 2, 3, 4, 5, 6, ...})")
Raymond Hettingerba6cd362004-05-21 10:00:15 +000085
Raymond Hettinger1453e4a2004-05-21 23:01:18 +000086 # collections.deque after 6
87 eq(r(deque([1, 2, 3, 4, 5, 6, 7])), "deque([1, 2, 3, 4, 5, 6, ...])")
88
Fred Drake8e6669a2001-07-19 22:27:56 +000089 # Dictionaries give up after 4.
90 eq(r({}), "{}")
91 d = {'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}
92 eq(r(d), "{'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}")
93 d['arthur'] = 1
94 eq(r(d), "{'alice': 1, 'arthur': 1, 'bob': 2, 'charles': 3, ...}")
95
Tim Peters6ee04802003-02-05 18:29:34 +000096 # array.array after 5.
Raymond Hettingera34cd0c2014-11-15 10:58:58 -080097 eq(r(array('i')), "array('i')")
Tim Peters6ee04802003-02-05 18:29:34 +000098 eq(r(array('i', [1])), "array('i', [1])")
99 eq(r(array('i', [1, 2])), "array('i', [1, 2])")
100 eq(r(array('i', [1, 2, 3])), "array('i', [1, 2, 3])")
101 eq(r(array('i', [1, 2, 3, 4])), "array('i', [1, 2, 3, 4])")
102 eq(r(array('i', [1, 2, 3, 4, 5])), "array('i', [1, 2, 3, 4, 5])")
103 eq(r(array('i', [1, 2, 3, 4, 5, 6])),
104 "array('i', [1, 2, 3, 4, 5, ...])")
105
Raymond Hettingerffd842e2014-11-09 22:30:36 -0800106 def test_set_literal(self):
107 eq = self.assertEqual
108 eq(r({1}), "{1}")
109 eq(r({1, 2, 3}), "{1, 2, 3}")
110 eq(r({1, 2, 3, 4, 5, 6}), "{1, 2, 3, 4, 5, 6}")
111 eq(r({1, 2, 3, 4, 5, 6, 7}), "{1, 2, 3, 4, 5, 6, ...}")
112
113 def test_frozenset(self):
114 eq = self.assertEqual
115 eq(r(frozenset({1})), "frozenset({1})")
116 eq(r(frozenset({1, 2, 3})), "frozenset({1, 2, 3})")
117 eq(r(frozenset({1, 2, 3, 4, 5, 6})), "frozenset({1, 2, 3, 4, 5, 6})")
118 eq(r(frozenset({1, 2, 3, 4, 5, 6, 7})), "frozenset({1, 2, 3, 4, 5, 6, ...})")
119
Fred Drake8e6669a2001-07-19 22:27:56 +0000120 def test_numbers(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000121 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +0000122 eq(r(123), repr(123))
Guido van Rossume2a383d2007-01-15 16:59:06 +0000123 eq(r(123), repr(123))
Fred Drake8e6669a2001-07-19 22:27:56 +0000124 eq(r(1.0/3), repr(1.0/3))
125
Guido van Rossume2a383d2007-01-15 16:59:06 +0000126 n = 10**100
Walter Dörwald70a6b492004-02-12 17:35:32 +0000127 expected = repr(n)[:18] + "..." + repr(n)[-19:]
Fred Drake8e6669a2001-07-19 22:27:56 +0000128 eq(r(n), expected)
129
130 def test_instance(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000131 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +0000132 i1 = ClassWithRepr("a")
133 eq(r(i1), repr(i1))
Tim Petersab9ba272001-08-09 21:40:30 +0000134
Fred Drake8e6669a2001-07-19 22:27:56 +0000135 i2 = ClassWithRepr("x"*1000)
Walter Dörwald70a6b492004-02-12 17:35:32 +0000136 expected = repr(i2)[:13] + "..." + repr(i2)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +0000137 eq(r(i2), expected)
138
139 i3 = ClassWithFailingRepr()
Serhiy Storchaka0c937b32014-07-22 12:14:52 +0300140 eq(r(i3), ("<ClassWithFailingRepr instance at %#x>"%id(i3)))
Fred Drake8e6669a2001-07-19 22:27:56 +0000141
Guido van Rossumcf856f92001-09-05 02:26:26 +0000142 s = r(ClassWithFailingRepr)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000143 self.assertTrue(s.startswith("<class "))
144 self.assertTrue(s.endswith(">"))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000145 self.assertIn(s.find("..."), [12, 13])
Guido van Rossumcf856f92001-09-05 02:26:26 +0000146
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000147 def test_lambda(self):
Antoine Pitrou86a36b52011-11-25 18:56:07 +0100148 r = repr(lambda x: x)
149 self.assertTrue(r.startswith("<function ReprTests.test_lambda.<locals>.<lambda"), r)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000150 # XXX anonymous functions? see func_repr
151
152 def test_builtin_function(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000153 eq = self.assertEqual
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000154 # Functions
155 eq(repr(hash), '<built-in function hash>')
156 # Methods
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000157 self.assertTrue(repr(''.split).startswith(
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000158 '<built-in method split of str object at 0x'))
159
Guido van Rossum805365e2007-05-07 22:24:25 +0000160 def test_range(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000161 eq = self.assertEqual
Guido van Rossum3353a2e2007-05-21 18:14:54 +0000162 eq(repr(range(1)), 'range(0, 1)')
Guido van Rossum805365e2007-05-07 22:24:25 +0000163 eq(repr(range(1, 2)), 'range(1, 2)')
164 eq(repr(range(1, 4, 3)), 'range(1, 4, 3)')
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000165
Fred Drake8e6669a2001-07-19 22:27:56 +0000166 def test_nesting(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000167 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +0000168 # everything is meant to give up after 6 levels.
169 eq(r([[[[[[[]]]]]]]), "[[[[[[[]]]]]]]")
170 eq(r([[[[[[[[]]]]]]]]), "[[[[[[[...]]]]]]]")
171
172 eq(r(nestedTuple(6)), "(((((((),),),),),),)")
173 eq(r(nestedTuple(7)), "(((((((...),),),),),),)")
174
175 eq(r({ nestedTuple(5) : nestedTuple(5) }),
176 "{((((((),),),),),): ((((((),),),),),)}")
177 eq(r({ nestedTuple(6) : nestedTuple(6) }),
178 "{((((((...),),),),),): ((((((...),),),),),)}")
179
180 eq(r([[[[[[{}]]]]]]), "[[[[[[{}]]]]]]")
181 eq(r([[[[[[[{}]]]]]]]), "[[[[[[[...]]]]]]]")
182
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000183 def test_cell(self):
Serhiy Storchaka1f79cdf2013-12-10 10:20:31 +0200184 def get_cell():
185 x = 42
186 def inner():
187 return x
188 return inner
189 x = get_cell().__closure__[0]
Zachary Wareea6854a2013-12-10 14:17:22 -0600190 self.assertRegex(repr(x), r'<cell at 0x[0-9A-Fa-f]+: '
191 r'int object at 0x[0-9A-Fa-f]+>')
Serhiy Storchaka1f79cdf2013-12-10 10:20:31 +0200192 self.assertRegex(r(x), r'<cell at 0x.*\.\.\..*>')
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000193
194 def test_descriptors(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000195 eq = self.assertEqual
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000196 # method descriptors
Tim Petersa427a2b2001-10-29 22:25:45 +0000197 eq(repr(dict.items), "<method 'items' of 'dict' objects>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000198 # XXX member descriptors
199 # XXX attribute descriptors
200 # XXX slot descriptors
201 # static and class methods
202 class C:
203 def foo(cls): pass
204 x = staticmethod(C.foo)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000205 self.assertTrue(repr(x).startswith('<staticmethod object at 0x'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000206 x = classmethod(C.foo)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000207 self.assertTrue(repr(x).startswith('<classmethod object at 0x'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000208
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000209 def test_unsortable(self):
210 # Repr.repr() used to call sorted() on sets, frozensets and dicts
211 # without taking into account that not all objects are comparable
212 x = set([1j, 2j, 3j])
213 y = frozenset(x)
214 z = {1j: 1, 2j: 2}
215 r(x)
216 r(y)
217 r(z)
218
Victor Stinnerbf816222011-06-30 23:25:47 +0200219def write_file(path, text):
220 with open(path, 'w', encoding='ASCII') as fp:
221 fp.write(text)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000222
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000223class LongReprTest(unittest.TestCase):
Antoine Pitrou01296da2012-04-24 13:55:35 +0200224 longname = 'areallylongpackageandmodulenametotestreprtruncation'
225
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000226 def setUp(self):
Antoine Pitrou01296da2012-04-24 13:55:35 +0200227 self.pkgname = os.path.join(self.longname)
228 self.subpkgname = os.path.join(self.longname, self.longname)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000229 # Make the package and subpackage
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000230 shutil.rmtree(self.pkgname, ignore_errors=True)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000231 os.mkdir(self.pkgname)
Victor Stinnerbf816222011-06-30 23:25:47 +0200232 create_empty_file(os.path.join(self.pkgname, '__init__.py'))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000233 shutil.rmtree(self.subpkgname, ignore_errors=True)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000234 os.mkdir(self.subpkgname)
Victor Stinnerbf816222011-06-30 23:25:47 +0200235 create_empty_file(os.path.join(self.subpkgname, '__init__.py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000236 # Remember where we are
237 self.here = os.getcwd()
238 sys.path.insert(0, self.here)
Brett Cannonceffda82012-04-16 20:48:50 -0400239 # When regrtest is run with its -j option, this command alone is not
240 # enough.
Antoine Pitrouc541f8e2012-02-20 01:48:16 +0100241 importlib.invalidate_caches()
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000242
243 def tearDown(self):
244 actions = []
Benjamin Peterson699adb92008-05-08 22:27:58 +0000245 for dirpath, dirnames, filenames in os.walk(self.pkgname):
246 for name in dirnames + filenames:
247 actions.append(os.path.join(dirpath, name))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000248 actions.append(self.pkgname)
249 actions.sort()
250 actions.reverse()
251 for p in actions:
252 if os.path.isdir(p):
253 os.rmdir(p)
254 else:
255 os.remove(p)
256 del sys.path[0]
257
Antoine Pitrou01296da2012-04-24 13:55:35 +0200258 def _check_path_limitations(self, module_name):
259 # base directory
260 source_path_len = len(self.here)
261 # a path separator + `longname` (twice)
262 source_path_len += 2 * (len(self.longname) + 1)
263 # a path separator + `module_name` + ".py"
264 source_path_len += len(module_name) + 1 + len(".py")
Brett Cannon9529fbf2013-06-15 17:11:25 -0400265 cached_path_len = (source_path_len +
266 len(importlib.util.cache_from_source("x.py")) - len("x.py"))
Antoine Pitrou110ee342012-06-23 22:55:58 +0200267 if os.name == 'nt' and cached_path_len >= 258:
Antoine Pitrou01296da2012-04-24 13:55:35 +0200268 # Under Windows, the max path len is 260 including C's terminating
269 # NUL character.
270 # (see http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx#maxpath)
271 self.skipTest("test paths too long (%d characters) for Windows' 260 character limit"
272 % cached_path_len)
Antoine Pitrou541b7c82012-06-23 00:07:38 +0200273 elif os.name == 'nt' and verbose:
Antoine Pitrouf0f47422012-06-23 00:49:44 +0200274 print("cached_path_len =", cached_path_len)
Antoine Pitrou01296da2012-04-24 13:55:35 +0200275
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000276 def test_module(self):
Eric Snowb523f842013-11-22 09:05:39 -0700277 self.maxDiff = None
Antoine Pitrou01296da2012-04-24 13:55:35 +0200278 self._check_path_limitations(self.pkgname)
Victor Stinnerbf816222011-06-30 23:25:47 +0200279 create_empty_file(os.path.join(self.subpkgname, self.pkgname + '.py'))
Brett Cannonceffda82012-04-16 20:48:50 -0400280 importlib.invalidate_caches()
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000281 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
Brett Cannon7b383c42012-06-11 11:02:36 -0400282 module = areallylongpackageandmodulenametotestreprtruncation
283 self.assertEqual(repr(module), "<module %r from %r>" % (module.__name__, module.__file__))
284 self.assertEqual(repr(sys), "<module 'sys' (built-in)>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000285
286 def test_type(self):
Antoine Pitrou01296da2012-04-24 13:55:35 +0200287 self._check_path_limitations('foo')
Ezio Melottib3aedd42010-11-20 19:04:17 +0000288 eq = self.assertEqual
Victor Stinnerbf816222011-06-30 23:25:47 +0200289 write_file(os.path.join(self.subpkgname, 'foo.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000290class foo(object):
291 pass
292''')
Brett Cannonceffda82012-04-16 20:48:50 -0400293 importlib.invalidate_caches()
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000294 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
Benjamin Petersonab078e92016-07-13 21:13:29 -0700295 eq(repr(foo.foo),
296 "<class '%s.foo'>" % foo.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000297
Zachary Ware9fe6d862013-12-08 00:20:35 -0600298 @unittest.skip('need a suitable object')
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000299 def test_object(self):
300 # XXX Test the repr of a type with a really long tp_name but with no
301 # tp_repr. WIBNI we had ::Inline? :)
302 pass
303
304 def test_class(self):
Antoine Pitrou01296da2012-04-24 13:55:35 +0200305 self._check_path_limitations('bar')
Victor Stinnerbf816222011-06-30 23:25:47 +0200306 write_file(os.path.join(self.subpkgname, 'bar.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000307class bar:
308 pass
309''')
Brett Cannonceffda82012-04-16 20:48:50 -0400310 importlib.invalidate_caches()
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000311 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
Mark Hammondd800ae12003-01-16 04:56:52 +0000312 # Module name may be prefixed with "test.", depending on how run.
Benjamin Petersonab078e92016-07-13 21:13:29 -0700313 self.assertEqual(repr(bar.bar), "<class '%s.bar'>" % bar.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000314
315 def test_instance(self):
Antoine Pitrou01296da2012-04-24 13:55:35 +0200316 self._check_path_limitations('baz')
Victor Stinnerbf816222011-06-30 23:25:47 +0200317 write_file(os.path.join(self.subpkgname, 'baz.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000318class baz:
319 pass
320''')
Brett Cannonceffda82012-04-16 20:48:50 -0400321 importlib.invalidate_caches()
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000322 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
323 ibaz = baz.baz()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000324 self.assertTrue(repr(ibaz).startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000325 "<%s.baz object at 0x" % baz.__name__))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000326
327 def test_method(self):
Antoine Pitrou01296da2012-04-24 13:55:35 +0200328 self._check_path_limitations('qux')
Ezio Melottib3aedd42010-11-20 19:04:17 +0000329 eq = self.assertEqual
Victor Stinnerbf816222011-06-30 23:25:47 +0200330 write_file(os.path.join(self.subpkgname, 'qux.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000331class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
332 def amethod(self): pass
333''')
Brett Cannonceffda82012-04-16 20:48:50 -0400334 importlib.invalidate_caches()
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000335 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
336 # Unbound methods first
Antoine Pitrou86a36b52011-11-25 18:56:07 +0100337 r = repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod)
338 self.assertTrue(r.startswith('<function aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod'), r)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000339 # Bound method next
340 iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
Antoine Pitrou86a36b52011-11-25 18:56:07 +0100341 r = repr(iqux.amethod)
342 self.assertTrue(r.startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000343 '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa object at 0x' \
Antoine Pitrou86a36b52011-11-25 18:56:07 +0100344 % (qux.__name__,) ), r)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000345
Zachary Ware9fe6d862013-12-08 00:20:35 -0600346 @unittest.skip('needs a built-in function with a really long name')
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000347 def test_builtin_function(self):
348 # XXX test built-in functions and methods with really long names
349 pass
Fred Drake8e6669a2001-07-19 22:27:56 +0000350
351class ClassWithRepr:
352 def __init__(self, s):
353 self.s = s
354 def __repr__(self):
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000355 return "ClassWithRepr(%r)" % self.s
Fred Drake8e6669a2001-07-19 22:27:56 +0000356
357
358class ClassWithFailingRepr:
359 def __repr__(self):
360 raise Exception("This should be caught by Repr.repr_instance")
361
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000362class MyContainer:
363 'Helper class for TestRecursiveRepr'
364 def __init__(self, values):
365 self.values = list(values)
366 def append(self, value):
367 self.values.append(value)
368 @recursive_repr()
369 def __repr__(self):
370 return '<' + ', '.join(map(str, self.values)) + '>'
371
372class MyContainer2(MyContainer):
373 @recursive_repr('+++')
374 def __repr__(self):
375 return '<' + ', '.join(map(str, self.values)) + '>'
376
Serhiy Storchakab3b366d2016-04-26 09:30:44 +0300377class MyContainer3:
378 def __repr__(self):
379 'Test document content'
380 pass
381 wrapped = __repr__
382 wrapper = recursive_repr()(wrapped)
383
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000384class TestRecursiveRepr(unittest.TestCase):
385 def test_recursive_repr(self):
386 m = MyContainer(list('abcde'))
387 m.append(m)
388 m.append('x')
389 m.append(m)
390 self.assertEqual(repr(m), '<a, b, c, d, e, ..., x, ...>')
391 m = MyContainer2(list('abcde'))
392 m.append(m)
393 m.append('x')
394 m.append(m)
395 self.assertEqual(repr(m), '<a, b, c, d, e, +++, x, +++>')
Fred Drake8e6669a2001-07-19 22:27:56 +0000396
Serhiy Storchakab3b366d2016-04-26 09:30:44 +0300397 def test_assigned_attributes(self):
398 from functools import WRAPPER_ASSIGNMENTS as assigned
399 wrapped = MyContainer3.wrapped
400 wrapper = MyContainer3.wrapper
401 for name in assigned:
402 self.assertIs(getattr(wrapper, name), getattr(wrapped, name))
403
Fred Drake2e2be372001-09-20 21:33:42 +0000404if __name__ == "__main__":
Raymond Hettingerffd842e2014-11-09 22:30:36 -0800405 unittest.main()