blob: 4ded4846f6355403bc0414d86c937970abd7bfce [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(">"))
114 self.failUnless(s.find("...") == 8)
115
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.
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000252 self.failUnless(repr(bar.bar).startswith(
Mark Hammondd800ae12003-01-16 04:56:52 +0000253 "<class %s.bar at 0x" % bar.__name__))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000254
255 def test_instance(self):
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000256 touch(os.path.join(self.subpkgname, 'baz'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000257class baz:
258 pass
259''')
260 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
261 ibaz = baz.baz()
262 self.failUnless(repr(ibaz).startswith(
Mark Hammondd800ae12003-01-16 04:56:52 +0000263 "<%s.baz instance at 0x" % baz.__name__))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000264
265 def test_method(self):
266 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000267 touch(os.path.join(self.subpkgname, 'qux'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000268class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
269 def amethod(self): pass
270''')
271 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
272 # Unbound methods first
273 eq(repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod),
274 '<unbound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod>')
275 # Bound method next
276 iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
277 self.failUnless(repr(iqux.amethod).startswith(
Mark Hammondd800ae12003-01-16 04:56:52 +0000278 '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa instance at 0x' \
279 % (qux.__name__,) ))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000280
281 def test_builtin_function(self):
282 # XXX test built-in functions and methods with really long names
283 pass
Fred Drake8e6669a2001-07-19 22:27:56 +0000284
285class ClassWithRepr:
286 def __init__(self, s):
287 self.s = s
288 def __repr__(self):
289 return "ClassWithLongRepr(%r)" % self.s
290
291
292class ClassWithFailingRepr:
293 def __repr__(self):
294 raise Exception("This should be caught by Repr.repr_instance")
295
296
Fred Drake2e2be372001-09-20 21:33:42 +0000297def test_main():
298 run_unittest(ReprTests)
299 if os.name != 'mac':
300 run_unittest(LongReprTest)
301
302
303if __name__ == "__main__":
304 test_main()