blob: 439fa337947abd4078612299585a9fb35a4a413e [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
Fred Drake8e6669a2001-07-19 22:27:56 +00009import unittest
Barry Warsaw0bcf6d82001-08-24 18:37:32 +000010
Victor Stinnerbf816222011-06-30 23:25:47 +020011from test.support import run_unittest, create_empty_file
Alexandre Vassalotti1f2ba4b2008-05-16 07:12:44 +000012from reprlib import repr as r # Don't shadow builtin repr
13from reprlib import Repr
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +000014from reprlib import recursive_repr
Fred Drake8e6669a2001-07-19 22:27:56 +000015
16
17def nestedTuple(nesting):
18 t = ()
19 for i in range(nesting):
20 t = (t,)
21 return t
22
23class ReprTests(unittest.TestCase):
24
25 def test_string(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +000026 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +000027 eq(r("abc"), "'abc'")
28 eq(r("abcdefghijklmnop"),"'abcdefghijklmnop'")
29
30 s = "a"*30+"b"*30
Walter Dörwald70a6b492004-02-12 17:35:32 +000031 expected = repr(s)[:13] + "..." + repr(s)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +000032 eq(r(s), expected)
Tim Petersab9ba272001-08-09 21:40:30 +000033
Fred Drake8e6669a2001-07-19 22:27:56 +000034 eq(r("\"'"), repr("\"'"))
35 s = "\""*30+"'"*100
Walter Dörwald70a6b492004-02-12 17:35:32 +000036 expected = repr(s)[:13] + "..." + repr(s)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +000037 eq(r(s), expected)
38
Guido van Rossumcd16bf62007-06-13 18:07:49 +000039 def test_tuple(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +000040 eq = self.assertEqual
Guido van Rossumcd16bf62007-06-13 18:07:49 +000041 eq(r((1,)), "(1,)")
42
43 t3 = (1, 2, 3)
44 eq(r(t3), "(1, 2, 3)")
45
46 r2 = Repr()
47 r2.maxtuple = 2
48 expected = repr(t3)[:-2] + "...)"
49 eq(r2.repr(t3), expected)
50
Fred Drake8e6669a2001-07-19 22:27:56 +000051 def test_container(self):
Tim Peters6ee04802003-02-05 18:29:34 +000052 from array import array
Raymond Hettinger1453e4a2004-05-21 23:01:18 +000053 from collections import deque
Tim Peters6ee04802003-02-05 18:29:34 +000054
Ezio Melottib3aedd42010-11-20 19:04:17 +000055 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +000056 # Tuples give up after 6 elements
57 eq(r(()), "()")
58 eq(r((1,)), "(1,)")
59 eq(r((1, 2, 3)), "(1, 2, 3)")
60 eq(r((1, 2, 3, 4, 5, 6)), "(1, 2, 3, 4, 5, 6)")
61 eq(r((1, 2, 3, 4, 5, 6, 7)), "(1, 2, 3, 4, 5, 6, ...)")
62
63 # Lists give up after 6 as well
64 eq(r([]), "[]")
65 eq(r([1]), "[1]")
66 eq(r([1, 2, 3]), "[1, 2, 3]")
67 eq(r([1, 2, 3, 4, 5, 6]), "[1, 2, 3, 4, 5, 6]")
68 eq(r([1, 2, 3, 4, 5, 6, 7]), "[1, 2, 3, 4, 5, 6, ...]")
69
Raymond Hettingerba6cd362004-05-21 10:00:15 +000070 # Sets give up after 6 as well
71 eq(r(set([])), "set([])")
72 eq(r(set([1])), "set([1])")
73 eq(r(set([1, 2, 3])), "set([1, 2, 3])")
74 eq(r(set([1, 2, 3, 4, 5, 6])), "set([1, 2, 3, 4, 5, 6])")
75 eq(r(set([1, 2, 3, 4, 5, 6, 7])), "set([1, 2, 3, 4, 5, 6, ...])")
76
77 # Frozensets give up after 6 as well
78 eq(r(frozenset([])), "frozenset([])")
79 eq(r(frozenset([1])), "frozenset([1])")
80 eq(r(frozenset([1, 2, 3])), "frozenset([1, 2, 3])")
81 eq(r(frozenset([1, 2, 3, 4, 5, 6])), "frozenset([1, 2, 3, 4, 5, 6])")
82 eq(r(frozenset([1, 2, 3, 4, 5, 6, 7])), "frozenset([1, 2, 3, 4, 5, 6, ...])")
83
Raymond Hettinger1453e4a2004-05-21 23:01:18 +000084 # collections.deque after 6
85 eq(r(deque([1, 2, 3, 4, 5, 6, 7])), "deque([1, 2, 3, 4, 5, 6, ...])")
86
Fred Drake8e6669a2001-07-19 22:27:56 +000087 # Dictionaries give up after 4.
88 eq(r({}), "{}")
89 d = {'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}
90 eq(r(d), "{'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}")
91 d['arthur'] = 1
92 eq(r(d), "{'alice': 1, 'arthur': 1, 'bob': 2, 'charles': 3, ...}")
93
Tim Peters6ee04802003-02-05 18:29:34 +000094 # array.array after 5.
95 eq(r(array('i')), "array('i', [])")
96 eq(r(array('i', [1])), "array('i', [1])")
97 eq(r(array('i', [1, 2])), "array('i', [1, 2])")
98 eq(r(array('i', [1, 2, 3])), "array('i', [1, 2, 3])")
99 eq(r(array('i', [1, 2, 3, 4])), "array('i', [1, 2, 3, 4])")
100 eq(r(array('i', [1, 2, 3, 4, 5])), "array('i', [1, 2, 3, 4, 5])")
101 eq(r(array('i', [1, 2, 3, 4, 5, 6])),
102 "array('i', [1, 2, 3, 4, 5, ...])")
103
Fred Drake8e6669a2001-07-19 22:27:56 +0000104 def test_numbers(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000105 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +0000106 eq(r(123), repr(123))
Guido van Rossume2a383d2007-01-15 16:59:06 +0000107 eq(r(123), repr(123))
Fred Drake8e6669a2001-07-19 22:27:56 +0000108 eq(r(1.0/3), repr(1.0/3))
109
Guido van Rossume2a383d2007-01-15 16:59:06 +0000110 n = 10**100
Walter Dörwald70a6b492004-02-12 17:35:32 +0000111 expected = repr(n)[:18] + "..." + repr(n)[-19:]
Fred Drake8e6669a2001-07-19 22:27:56 +0000112 eq(r(n), expected)
113
114 def test_instance(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000115 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +0000116 i1 = ClassWithRepr("a")
117 eq(r(i1), repr(i1))
Tim Petersab9ba272001-08-09 21:40:30 +0000118
Fred Drake8e6669a2001-07-19 22:27:56 +0000119 i2 = ClassWithRepr("x"*1000)
Walter Dörwald70a6b492004-02-12 17:35:32 +0000120 expected = repr(i2)[:13] + "..." + repr(i2)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +0000121 eq(r(i2), expected)
122
123 i3 = ClassWithFailingRepr()
124 eq(r(i3), ("<ClassWithFailingRepr instance at %x>"%id(i3)))
125
Guido van Rossumcf856f92001-09-05 02:26:26 +0000126 s = r(ClassWithFailingRepr)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000127 self.assertTrue(s.startswith("<class "))
128 self.assertTrue(s.endswith(">"))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000129 self.assertIn(s.find("..."), [12, 13])
Guido van Rossumcf856f92001-09-05 02:26:26 +0000130
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000131 def test_lambda(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000132 self.assertTrue(repr(lambda x: x).startswith(
Neil Schemenauerab541bb2005-10-21 18:11:40 +0000133 "<function <lambda"))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000134 # XXX anonymous functions? see func_repr
135
136 def test_builtin_function(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000137 eq = self.assertEqual
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000138 # Functions
139 eq(repr(hash), '<built-in function hash>')
140 # Methods
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000141 self.assertTrue(repr(''.split).startswith(
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000142 '<built-in method split of str object at 0x'))
143
Guido van Rossum805365e2007-05-07 22:24:25 +0000144 def test_range(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000145 eq = self.assertEqual
Guido van Rossum3353a2e2007-05-21 18:14:54 +0000146 eq(repr(range(1)), 'range(0, 1)')
Guido van Rossum805365e2007-05-07 22:24:25 +0000147 eq(repr(range(1, 2)), 'range(1, 2)')
148 eq(repr(range(1, 4, 3)), 'range(1, 4, 3)')
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000149
Fred Drake8e6669a2001-07-19 22:27:56 +0000150 def test_nesting(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000151 eq = self.assertEqual
Fred Drake8e6669a2001-07-19 22:27:56 +0000152 # everything is meant to give up after 6 levels.
153 eq(r([[[[[[[]]]]]]]), "[[[[[[[]]]]]]]")
154 eq(r([[[[[[[[]]]]]]]]), "[[[[[[[...]]]]]]]")
155
156 eq(r(nestedTuple(6)), "(((((((),),),),),),)")
157 eq(r(nestedTuple(7)), "(((((((...),),),),),),)")
158
159 eq(r({ nestedTuple(5) : nestedTuple(5) }),
160 "{((((((),),),),),): ((((((),),),),),)}")
161 eq(r({ nestedTuple(6) : nestedTuple(6) }),
162 "{((((((...),),),),),): ((((((...),),),),),)}")
163
164 eq(r([[[[[[{}]]]]]]), "[[[[[[{}]]]]]]")
165 eq(r([[[[[[[{}]]]]]]]), "[[[[[[[...]]]]]]]")
166
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000167 def test_cell(self):
168 # XXX Hmm? How to get at a cell object?
169 pass
170
171 def test_descriptors(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000172 eq = self.assertEqual
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000173 # method descriptors
Tim Petersa427a2b2001-10-29 22:25:45 +0000174 eq(repr(dict.items), "<method 'items' of 'dict' objects>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000175 # XXX member descriptors
176 # XXX attribute descriptors
177 # XXX slot descriptors
178 # static and class methods
179 class C:
180 def foo(cls): pass
181 x = staticmethod(C.foo)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000182 self.assertTrue(repr(x).startswith('<staticmethod object at 0x'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000183 x = classmethod(C.foo)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000184 self.assertTrue(repr(x).startswith('<classmethod object at 0x'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000185
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000186 def test_unsortable(self):
187 # Repr.repr() used to call sorted() on sets, frozensets and dicts
188 # without taking into account that not all objects are comparable
189 x = set([1j, 2j, 3j])
190 y = frozenset(x)
191 z = {1j: 1, 2j: 2}
192 r(x)
193 r(y)
194 r(z)
195
Victor Stinnerbf816222011-06-30 23:25:47 +0200196def write_file(path, text):
197 with open(path, 'w', encoding='ASCII') as fp:
198 fp.write(text)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000199
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000200class LongReprTest(unittest.TestCase):
201 def setUp(self):
202 longname = 'areallylongpackageandmodulenametotestreprtruncation'
203 self.pkgname = os.path.join(longname)
204 self.subpkgname = os.path.join(longname, longname)
205 # Make the package and subpackage
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000206 shutil.rmtree(self.pkgname, ignore_errors=True)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000207 os.mkdir(self.pkgname)
Victor Stinnerbf816222011-06-30 23:25:47 +0200208 create_empty_file(os.path.join(self.pkgname, '__init__.py'))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000209 shutil.rmtree(self.subpkgname, ignore_errors=True)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000210 os.mkdir(self.subpkgname)
Victor Stinnerbf816222011-06-30 23:25:47 +0200211 create_empty_file(os.path.join(self.subpkgname, '__init__.py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000212 # Remember where we are
213 self.here = os.getcwd()
214 sys.path.insert(0, self.here)
215
216 def tearDown(self):
217 actions = []
Benjamin Peterson699adb92008-05-08 22:27:58 +0000218 for dirpath, dirnames, filenames in os.walk(self.pkgname):
219 for name in dirnames + filenames:
220 actions.append(os.path.join(dirpath, name))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000221 actions.append(self.pkgname)
222 actions.sort()
223 actions.reverse()
224 for p in actions:
225 if os.path.isdir(p):
226 os.rmdir(p)
227 else:
228 os.remove(p)
229 del sys.path[0]
230
231 def test_module(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000232 eq = self.assertEqual
Victor Stinnerbf816222011-06-30 23:25:47 +0200233 create_empty_file(os.path.join(self.subpkgname, self.pkgname + '.py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000234 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
235 eq(repr(areallylongpackageandmodulenametotestreprtruncation),
Victor Stinnere1ea8292011-02-23 14:14:48 +0000236 "<module %r from %r>" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__))
Neal Norwitz70769012001-12-29 00:25:42 +0000237 eq(repr(sys), "<module 'sys' (built-in)>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000238
239 def test_type(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000240 eq = self.assertEqual
Victor Stinnerbf816222011-06-30 23:25:47 +0200241 write_file(os.path.join(self.subpkgname, 'foo.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000242class foo(object):
243 pass
244''')
245 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
246 eq(repr(foo.foo),
Mark Hammondd800ae12003-01-16 04:56:52 +0000247 "<class '%s.foo'>" % foo.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000248
249 def test_object(self):
250 # XXX Test the repr of a type with a really long tp_name but with no
251 # tp_repr. WIBNI we had ::Inline? :)
252 pass
253
254 def test_class(self):
Victor Stinnerbf816222011-06-30 23:25:47 +0200255 write_file(os.path.join(self.subpkgname, 'bar.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000256class bar:
257 pass
258''')
259 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
Mark Hammondd800ae12003-01-16 04:56:52 +0000260 # Module name may be prefixed with "test.", depending on how run.
Ezio Melottib3aedd42010-11-20 19:04:17 +0000261 self.assertEqual(repr(bar.bar), "<class '%s.bar'>" % bar.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000262
263 def test_instance(self):
Victor Stinnerbf816222011-06-30 23:25:47 +0200264 write_file(os.path.join(self.subpkgname, 'baz.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000265class baz:
266 pass
267''')
268 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
269 ibaz = baz.baz()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000270 self.assertTrue(repr(ibaz).startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000271 "<%s.baz object at 0x" % baz.__name__))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000272
273 def test_method(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000274 eq = self.assertEqual
Victor Stinnerbf816222011-06-30 23:25:47 +0200275 write_file(os.path.join(self.subpkgname, 'qux.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000276class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
277 def amethod(self): pass
278''')
279 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
280 # Unbound methods first
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000281 self.assertTrue(repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod).startswith(
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000282 '<function amethod'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000283 # Bound method next
284 iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000285 self.assertTrue(repr(iqux.amethod).startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000286 '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa object at 0x' \
Mark Hammondd800ae12003-01-16 04:56:52 +0000287 % (qux.__name__,) ))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000288
289 def test_builtin_function(self):
290 # XXX test built-in functions and methods with really long names
291 pass
Fred Drake8e6669a2001-07-19 22:27:56 +0000292
293class ClassWithRepr:
294 def __init__(self, s):
295 self.s = s
296 def __repr__(self):
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000297 return "ClassWithRepr(%r)" % self.s
Fred Drake8e6669a2001-07-19 22:27:56 +0000298
299
300class ClassWithFailingRepr:
301 def __repr__(self):
302 raise Exception("This should be caught by Repr.repr_instance")
303
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000304class MyContainer:
305 'Helper class for TestRecursiveRepr'
306 def __init__(self, values):
307 self.values = list(values)
308 def append(self, value):
309 self.values.append(value)
310 @recursive_repr()
311 def __repr__(self):
312 return '<' + ', '.join(map(str, self.values)) + '>'
313
314class MyContainer2(MyContainer):
315 @recursive_repr('+++')
316 def __repr__(self):
317 return '<' + ', '.join(map(str, self.values)) + '>'
318
319class TestRecursiveRepr(unittest.TestCase):
320 def test_recursive_repr(self):
321 m = MyContainer(list('abcde'))
322 m.append(m)
323 m.append('x')
324 m.append(m)
325 self.assertEqual(repr(m), '<a, b, c, d, e, ..., x, ...>')
326 m = MyContainer2(list('abcde'))
327 m.append(m)
328 m.append('x')
329 m.append(m)
330 self.assertEqual(repr(m), '<a, b, c, d, e, +++, x, +++>')
Fred Drake8e6669a2001-07-19 22:27:56 +0000331
Fred Drake2e2be372001-09-20 21:33:42 +0000332def test_main():
333 run_unittest(ReprTests)
Ronald Oussoren94f25282010-05-05 19:11:21 +0000334 run_unittest(LongReprTest)
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000335 run_unittest(TestRecursiveRepr)
Fred Drake2e2be372001-09-20 21:33:42 +0000336
337
338if __name__ == "__main__":
339 test_main()