blob: b0dc4d781348d0712f254271aa79961231c35764 [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
Benjamin Petersonee8712c2008-05-20 21:35:26 +000011from test.support import run_unittest
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
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000196def touch(path, text=''):
197 fp = open(path, 'w')
198 fp.write(text)
199 fp.close()
200
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000201class LongReprTest(unittest.TestCase):
202 def setUp(self):
203 longname = 'areallylongpackageandmodulenametotestreprtruncation'
204 self.pkgname = os.path.join(longname)
205 self.subpkgname = os.path.join(longname, longname)
206 # Make the package and subpackage
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000207 shutil.rmtree(self.pkgname, ignore_errors=True)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000208 os.mkdir(self.pkgname)
Skip Montanaro7a98be22007-08-16 14:35:24 +0000209 touch(os.path.join(self.pkgname, '__init__.py'))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000210 shutil.rmtree(self.subpkgname, ignore_errors=True)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000211 os.mkdir(self.subpkgname)
Skip Montanaro7a98be22007-08-16 14:35:24 +0000212 touch(os.path.join(self.subpkgname, '__init__.py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000213 # Remember where we are
214 self.here = os.getcwd()
215 sys.path.insert(0, self.here)
216
217 def tearDown(self):
218 actions = []
Benjamin Peterson699adb92008-05-08 22:27:58 +0000219 for dirpath, dirnames, filenames in os.walk(self.pkgname):
220 for name in dirnames + filenames:
221 actions.append(os.path.join(dirpath, name))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000222 actions.append(self.pkgname)
223 actions.sort()
224 actions.reverse()
225 for p in actions:
226 if os.path.isdir(p):
227 os.rmdir(p)
228 else:
229 os.remove(p)
230 del sys.path[0]
231
232 def test_module(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000233 eq = self.assertEqual
Skip Montanaro7a98be22007-08-16 14:35:24 +0000234 touch(os.path.join(self.subpkgname, self.pkgname + '.py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000235 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
236 eq(repr(areallylongpackageandmodulenametotestreprtruncation),
Mark Hammondd800ae12003-01-16 04:56:52 +0000237 "<module '%s' from '%s'>" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__))
Neal Norwitz70769012001-12-29 00:25:42 +0000238 eq(repr(sys), "<module 'sys' (built-in)>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000239
240 def test_type(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000241 eq = self.assertEqual
Skip Montanaro7a98be22007-08-16 14:35:24 +0000242 touch(os.path.join(self.subpkgname, 'foo.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000243class foo(object):
244 pass
245''')
246 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
247 eq(repr(foo.foo),
Mark Hammondd800ae12003-01-16 04:56:52 +0000248 "<class '%s.foo'>" % foo.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000249
250 def test_object(self):
251 # XXX Test the repr of a type with a really long tp_name but with no
252 # tp_repr. WIBNI we had ::Inline? :)
253 pass
254
255 def test_class(self):
Skip Montanaro7a98be22007-08-16 14:35:24 +0000256 touch(os.path.join(self.subpkgname, 'bar.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000257class bar:
258 pass
259''')
260 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
Mark Hammondd800ae12003-01-16 04:56:52 +0000261 # Module name may be prefixed with "test.", depending on how run.
Ezio Melottib3aedd42010-11-20 19:04:17 +0000262 self.assertEqual(repr(bar.bar), "<class '%s.bar'>" % bar.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000263
264 def test_instance(self):
Skip Montanaro7a98be22007-08-16 14:35:24 +0000265 touch(os.path.join(self.subpkgname, 'baz.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000266class baz:
267 pass
268''')
269 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
270 ibaz = baz.baz()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000271 self.assertTrue(repr(ibaz).startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000272 "<%s.baz object at 0x" % baz.__name__))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000273
274 def test_method(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000275 eq = self.assertEqual
Skip Montanaro7a98be22007-08-16 14:35:24 +0000276 touch(os.path.join(self.subpkgname, 'qux.py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000277class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
278 def amethod(self): pass
279''')
280 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
281 # Unbound methods first
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000282 self.assertTrue(repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod).startswith(
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000283 '<function amethod'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000284 # Bound method next
285 iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000286 self.assertTrue(repr(iqux.amethod).startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000287 '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa object at 0x' \
Mark Hammondd800ae12003-01-16 04:56:52 +0000288 % (qux.__name__,) ))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000289
290 def test_builtin_function(self):
291 # XXX test built-in functions and methods with really long names
292 pass
Fred Drake8e6669a2001-07-19 22:27:56 +0000293
294class ClassWithRepr:
295 def __init__(self, s):
296 self.s = s
297 def __repr__(self):
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000298 return "ClassWithRepr(%r)" % self.s
Fred Drake8e6669a2001-07-19 22:27:56 +0000299
300
301class ClassWithFailingRepr:
302 def __repr__(self):
303 raise Exception("This should be caught by Repr.repr_instance")
304
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000305class MyContainer:
306 'Helper class for TestRecursiveRepr'
307 def __init__(self, values):
308 self.values = list(values)
309 def append(self, value):
310 self.values.append(value)
311 @recursive_repr()
312 def __repr__(self):
313 return '<' + ', '.join(map(str, self.values)) + '>'
314
315class MyContainer2(MyContainer):
316 @recursive_repr('+++')
317 def __repr__(self):
318 return '<' + ', '.join(map(str, self.values)) + '>'
319
320class TestRecursiveRepr(unittest.TestCase):
321 def test_recursive_repr(self):
322 m = MyContainer(list('abcde'))
323 m.append(m)
324 m.append('x')
325 m.append(m)
326 self.assertEqual(repr(m), '<a, b, c, d, e, ..., x, ...>')
327 m = MyContainer2(list('abcde'))
328 m.append(m)
329 m.append('x')
330 m.append(m)
331 self.assertEqual(repr(m), '<a, b, c, d, e, +++, x, +++>')
Fred Drake8e6669a2001-07-19 22:27:56 +0000332
Fred Drake2e2be372001-09-20 21:33:42 +0000333def test_main():
334 run_unittest(ReprTests)
Ronald Oussoren94f25282010-05-05 19:11:21 +0000335 run_unittest(LongReprTest)
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000336 run_unittest(TestRecursiveRepr)
Fred Drake2e2be372001-09-20 21:33:42 +0000337
338
339if __name__ == "__main__":
340 test_main()