blob: 912858539c8ac8cfd15239fa706163589ef9e77c [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
Fred Drake8e6669a2001-07-19 22:27:56 +00008import unittest
Barry Warsaw0bcf6d82001-08-24 18:37:32 +00009
Barry Warsaw04f357c2002-07-23 19:04:11 +000010from test.test_support import run_unittest
Tim Petersab9ba272001-08-09 21:40:30 +000011from repr import repr as r # Don't shadow builtin repr
Fred Drake8e6669a2001-07-19 22:27:56 +000012
13
14def nestedTuple(nesting):
15 t = ()
16 for i in range(nesting):
17 t = (t,)
18 return t
19
20class ReprTests(unittest.TestCase):
21
22 def test_string(self):
23 eq = self.assertEquals
24 eq(r("abc"), "'abc'")
25 eq(r("abcdefghijklmnop"),"'abcdefghijklmnop'")
26
27 s = "a"*30+"b"*30
Walter Dörwald70a6b492004-02-12 17:35:32 +000028 expected = repr(s)[:13] + "..." + repr(s)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +000029 eq(r(s), expected)
Tim Petersab9ba272001-08-09 21:40:30 +000030
Fred Drake8e6669a2001-07-19 22:27:56 +000031 eq(r("\"'"), repr("\"'"))
32 s = "\""*30+"'"*100
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)
35
36 def test_container(self):
Tim Peters6ee04802003-02-05 18:29:34 +000037 from array import array
Raymond Hettinger1453e4a2004-05-21 23:01:18 +000038 from collections import deque
Tim Peters6ee04802003-02-05 18:29:34 +000039
Fred Drake8e6669a2001-07-19 22:27:56 +000040 eq = self.assertEquals
41 # Tuples give up after 6 elements
42 eq(r(()), "()")
43 eq(r((1,)), "(1,)")
44 eq(r((1, 2, 3)), "(1, 2, 3)")
45 eq(r((1, 2, 3, 4, 5, 6)), "(1, 2, 3, 4, 5, 6)")
46 eq(r((1, 2, 3, 4, 5, 6, 7)), "(1, 2, 3, 4, 5, 6, ...)")
47
48 # Lists give up after 6 as well
49 eq(r([]), "[]")
50 eq(r([1]), "[1]")
51 eq(r([1, 2, 3]), "[1, 2, 3]")
52 eq(r([1, 2, 3, 4, 5, 6]), "[1, 2, 3, 4, 5, 6]")
53 eq(r([1, 2, 3, 4, 5, 6, 7]), "[1, 2, 3, 4, 5, 6, ...]")
54
Raymond Hettingerba6cd362004-05-21 10:00:15 +000055 # Sets give up after 6 as well
56 eq(r(set([])), "set([])")
57 eq(r(set([1])), "set([1])")
58 eq(r(set([1, 2, 3])), "set([1, 2, 3])")
59 eq(r(set([1, 2, 3, 4, 5, 6])), "set([1, 2, 3, 4, 5, 6])")
60 eq(r(set([1, 2, 3, 4, 5, 6, 7])), "set([1, 2, 3, 4, 5, 6, ...])")
61
62 # Frozensets give up after 6 as well
63 eq(r(frozenset([])), "frozenset([])")
64 eq(r(frozenset([1])), "frozenset([1])")
65 eq(r(frozenset([1, 2, 3])), "frozenset([1, 2, 3])")
66 eq(r(frozenset([1, 2, 3, 4, 5, 6])), "frozenset([1, 2, 3, 4, 5, 6])")
67 eq(r(frozenset([1, 2, 3, 4, 5, 6, 7])), "frozenset([1, 2, 3, 4, 5, 6, ...])")
68
Raymond Hettinger1453e4a2004-05-21 23:01:18 +000069 # collections.deque after 6
70 eq(r(deque([1, 2, 3, 4, 5, 6, 7])), "deque([1, 2, 3, 4, 5, 6, ...])")
71
Fred Drake8e6669a2001-07-19 22:27:56 +000072 # Dictionaries give up after 4.
73 eq(r({}), "{}")
74 d = {'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}
75 eq(r(d), "{'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}")
76 d['arthur'] = 1
77 eq(r(d), "{'alice': 1, 'arthur': 1, 'bob': 2, 'charles': 3, ...}")
78
Tim Peters6ee04802003-02-05 18:29:34 +000079 # array.array after 5.
80 eq(r(array('i')), "array('i', [])")
81 eq(r(array('i', [1])), "array('i', [1])")
82 eq(r(array('i', [1, 2])), "array('i', [1, 2])")
83 eq(r(array('i', [1, 2, 3])), "array('i', [1, 2, 3])")
84 eq(r(array('i', [1, 2, 3, 4])), "array('i', [1, 2, 3, 4])")
85 eq(r(array('i', [1, 2, 3, 4, 5])), "array('i', [1, 2, 3, 4, 5])")
86 eq(r(array('i', [1, 2, 3, 4, 5, 6])),
87 "array('i', [1, 2, 3, 4, 5, ...])")
88
Fred Drake8e6669a2001-07-19 22:27:56 +000089 def test_numbers(self):
90 eq = self.assertEquals
91 eq(r(123), repr(123))
92 eq(r(123L), repr(123L))
93 eq(r(1.0/3), repr(1.0/3))
94
95 n = 10L**100
Walter Dörwald70a6b492004-02-12 17:35:32 +000096 expected = repr(n)[:18] + "..." + repr(n)[-19:]
Fred Drake8e6669a2001-07-19 22:27:56 +000097 eq(r(n), expected)
98
99 def test_instance(self):
100 eq = self.assertEquals
101 i1 = ClassWithRepr("a")
102 eq(r(i1), repr(i1))
Tim Petersab9ba272001-08-09 21:40:30 +0000103
Fred Drake8e6669a2001-07-19 22:27:56 +0000104 i2 = ClassWithRepr("x"*1000)
Walter Dörwald70a6b492004-02-12 17:35:32 +0000105 expected = repr(i2)[:13] + "..." + repr(i2)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +0000106 eq(r(i2), expected)
107
108 i3 = ClassWithFailingRepr()
109 eq(r(i3), ("<ClassWithFailingRepr instance at %x>"%id(i3)))
110
Guido van Rossumcf856f92001-09-05 02:26:26 +0000111 s = r(ClassWithFailingRepr)
112 self.failUnless(s.startswith("<class "))
113 self.failUnless(s.endswith(">"))
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000114 self.failUnless(s.find("...") in [12, 13])
Guido van Rossumcf856f92001-09-05 02:26:26 +0000115
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000116 def test_file(self):
117 fp = open(unittest.__file__)
118 self.failUnless(repr(fp).startswith(
119 "<open file '%s', mode 'r' at 0x" % unittest.__file__))
120 fp.close()
121 self.failUnless(repr(fp).startswith(
122 "<closed file '%s', mode 'r' at 0x" % unittest.__file__))
123
124 def test_lambda(self):
125 self.failUnless(repr(lambda x: x).startswith(
Neil Schemenauerab541bb2005-10-21 18:11:40 +0000126 "<function <lambda"))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000127 # XXX anonymous functions? see func_repr
128
129 def test_builtin_function(self):
130 eq = self.assertEquals
131 # Functions
132 eq(repr(hash), '<built-in function hash>')
133 # Methods
134 self.failUnless(repr(''.split).startswith(
135 '<built-in method split of str object at 0x'))
136
137 def test_xrange(self):
Tim Petersd3925062002-04-16 01:27:44 +0000138 import warnings
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000139 eq = self.assertEquals
140 eq(repr(xrange(1)), 'xrange(1)')
141 eq(repr(xrange(1, 2)), 'xrange(1, 2)')
142 eq(repr(xrange(1, 2, 3)), 'xrange(1, 4, 3)')
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000143
Fred Drake8e6669a2001-07-19 22:27:56 +0000144 def test_nesting(self):
145 eq = self.assertEquals
146 # everything is meant to give up after 6 levels.
147 eq(r([[[[[[[]]]]]]]), "[[[[[[[]]]]]]]")
148 eq(r([[[[[[[[]]]]]]]]), "[[[[[[[...]]]]]]]")
149
150 eq(r(nestedTuple(6)), "(((((((),),),),),),)")
151 eq(r(nestedTuple(7)), "(((((((...),),),),),),)")
152
153 eq(r({ nestedTuple(5) : nestedTuple(5) }),
154 "{((((((),),),),),): ((((((),),),),),)}")
155 eq(r({ nestedTuple(6) : nestedTuple(6) }),
156 "{((((((...),),),),),): ((((((...),),),),),)}")
157
158 eq(r([[[[[[{}]]]]]]), "[[[[[[{}]]]]]]")
159 eq(r([[[[[[[{}]]]]]]]), "[[[[[[[...]]]]]]]")
160
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000161 def test_buffer(self):
162 # XXX doesn't test buffers with no b_base or read-write buffers (see
163 # bufferobject.c). The test is fairly incomplete too. Sigh.
164 x = buffer('foo')
165 self.failUnless(repr(x).startswith('<read-only buffer for 0x'))
166
167 def test_cell(self):
168 # XXX Hmm? How to get at a cell object?
169 pass
170
171 def test_descriptors(self):
172 eq = self.assertEquals
173 # 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)
182 self.failUnless(repr(x).startswith('<staticmethod object at 0x'))
183 x = classmethod(C.foo)
184 self.failUnless(repr(x).startswith('<classmethod object at 0x'))
185
186def touch(path, text=''):
187 fp = open(path, 'w')
188 fp.write(text)
189 fp.close()
190
191def zap(actions, dirname, names):
192 for name in names:
193 actions.append(os.path.join(dirname, name))
194
195class LongReprTest(unittest.TestCase):
196 def setUp(self):
197 longname = 'areallylongpackageandmodulenametotestreprtruncation'
198 self.pkgname = os.path.join(longname)
199 self.subpkgname = os.path.join(longname, longname)
200 # Make the package and subpackage
201 os.mkdir(self.pkgname)
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000202 touch(os.path.join(self.pkgname, '__init__'+os.extsep+'py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000203 os.mkdir(self.subpkgname)
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000204 touch(os.path.join(self.subpkgname, '__init__'+os.extsep+'py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000205 # Remember where we are
206 self.here = os.getcwd()
207 sys.path.insert(0, self.here)
208
209 def tearDown(self):
210 actions = []
211 os.path.walk(self.pkgname, zap, actions)
212 actions.append(self.pkgname)
213 actions.sort()
214 actions.reverse()
215 for p in actions:
216 if os.path.isdir(p):
217 os.rmdir(p)
218 else:
219 os.remove(p)
220 del sys.path[0]
221
222 def test_module(self):
223 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000224 touch(os.path.join(self.subpkgname, self.pkgname + os.extsep + 'py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000225 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
226 eq(repr(areallylongpackageandmodulenametotestreprtruncation),
Mark Hammondd800ae12003-01-16 04:56:52 +0000227 "<module '%s' from '%s'>" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__))
Neal Norwitz70769012001-12-29 00:25:42 +0000228 eq(repr(sys), "<module 'sys' (built-in)>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000229
230 def test_type(self):
231 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000232 touch(os.path.join(self.subpkgname, 'foo'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000233class foo(object):
234 pass
235''')
236 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
237 eq(repr(foo.foo),
Mark Hammondd800ae12003-01-16 04:56:52 +0000238 "<class '%s.foo'>" % foo.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000239
240 def test_object(self):
241 # XXX Test the repr of a type with a really long tp_name but with no
242 # tp_repr. WIBNI we had ::Inline? :)
243 pass
244
245 def test_class(self):
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000246 touch(os.path.join(self.subpkgname, 'bar'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000247class bar:
248 pass
249''')
250 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
Mark Hammondd800ae12003-01-16 04:56:52 +0000251 # Module name may be prefixed with "test.", depending on how run.
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000252 self.assertEquals(repr(bar.bar), "<class '%s.bar'>" % bar.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000253
254 def test_instance(self):
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000255 touch(os.path.join(self.subpkgname, 'baz'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000256class baz:
257 pass
258''')
259 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
260 ibaz = baz.baz()
261 self.failUnless(repr(ibaz).startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000262 "<%s.baz object at 0x" % baz.__name__))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000263
264 def test_method(self):
265 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000266 touch(os.path.join(self.subpkgname, 'qux'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000267class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
268 def amethod(self): pass
269''')
270 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
271 # Unbound methods first
272 eq(repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod),
273 '<unbound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod>')
274 # Bound method next
275 iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
276 self.failUnless(repr(iqux.amethod).startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000277 '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa object at 0x' \
Mark Hammondd800ae12003-01-16 04:56:52 +0000278 % (qux.__name__,) ))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000279
280 def test_builtin_function(self):
281 # XXX test built-in functions and methods with really long names
282 pass
Fred Drake8e6669a2001-07-19 22:27:56 +0000283
284class ClassWithRepr:
285 def __init__(self, s):
286 self.s = s
287 def __repr__(self):
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000288 return "ClassWithRepr(%r)" % self.s
Fred Drake8e6669a2001-07-19 22:27:56 +0000289
290
291class ClassWithFailingRepr:
292 def __repr__(self):
293 raise Exception("This should be caught by Repr.repr_instance")
294
295
Fred Drake2e2be372001-09-20 21:33:42 +0000296def test_main():
297 run_unittest(ReprTests)
298 if os.name != 'mac':
299 run_unittest(LongReprTest)
300
301
302if __name__ == "__main__":
303 test_main()