blob: 1dfa2821104c2beb5bc6832b5fbec6cbe6cda200 [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
Barry Warsaw04f357c2002-07-23 19:04:11 +000011from test.test_support import run_unittest
Tim Petersab9ba272001-08-09 21:40:30 +000012from repr import repr as r # Don't shadow builtin repr
Fred Drake8e6669a2001-07-19 22:27:56 +000013
14
15def nestedTuple(nesting):
16 t = ()
17 for i in range(nesting):
18 t = (t,)
19 return t
20
21class ReprTests(unittest.TestCase):
22
23 def test_string(self):
24 eq = self.assertEquals
25 eq(r("abc"), "'abc'")
26 eq(r("abcdefghijklmnop"),"'abcdefghijklmnop'")
27
28 s = "a"*30+"b"*30
Walter Dörwald70a6b492004-02-12 17:35:32 +000029 expected = repr(s)[:13] + "..." + repr(s)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +000030 eq(r(s), expected)
Tim Petersab9ba272001-08-09 21:40:30 +000031
Fred Drake8e6669a2001-07-19 22:27:56 +000032 eq(r("\"'"), repr("\"'"))
33 s = "\""*30+"'"*100
Walter Dörwald70a6b492004-02-12 17:35:32 +000034 expected = repr(s)[:13] + "..." + repr(s)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +000035 eq(r(s), expected)
36
37 def test_container(self):
Tim Peters6ee04802003-02-05 18:29:34 +000038 from array import array
Raymond Hettinger1453e4a2004-05-21 23:01:18 +000039 from collections import deque
Tim Peters6ee04802003-02-05 18:29:34 +000040
Fred Drake8e6669a2001-07-19 22:27:56 +000041 eq = self.assertEquals
42 # Tuples give up after 6 elements
43 eq(r(()), "()")
44 eq(r((1,)), "(1,)")
45 eq(r((1, 2, 3)), "(1, 2, 3)")
46 eq(r((1, 2, 3, 4, 5, 6)), "(1, 2, 3, 4, 5, 6)")
47 eq(r((1, 2, 3, 4, 5, 6, 7)), "(1, 2, 3, 4, 5, 6, ...)")
48
49 # Lists give up after 6 as well
50 eq(r([]), "[]")
51 eq(r([1]), "[1]")
52 eq(r([1, 2, 3]), "[1, 2, 3]")
53 eq(r([1, 2, 3, 4, 5, 6]), "[1, 2, 3, 4, 5, 6]")
54 eq(r([1, 2, 3, 4, 5, 6, 7]), "[1, 2, 3, 4, 5, 6, ...]")
55
Raymond Hettingerba6cd362004-05-21 10:00:15 +000056 # Sets give up after 6 as well
57 eq(r(set([])), "set([])")
58 eq(r(set([1])), "set([1])")
59 eq(r(set([1, 2, 3])), "set([1, 2, 3])")
60 eq(r(set([1, 2, 3, 4, 5, 6])), "set([1, 2, 3, 4, 5, 6])")
61 eq(r(set([1, 2, 3, 4, 5, 6, 7])), "set([1, 2, 3, 4, 5, 6, ...])")
62
63 # Frozensets give up after 6 as well
64 eq(r(frozenset([])), "frozenset([])")
65 eq(r(frozenset([1])), "frozenset([1])")
66 eq(r(frozenset([1, 2, 3])), "frozenset([1, 2, 3])")
67 eq(r(frozenset([1, 2, 3, 4, 5, 6])), "frozenset([1, 2, 3, 4, 5, 6])")
68 eq(r(frozenset([1, 2, 3, 4, 5, 6, 7])), "frozenset([1, 2, 3, 4, 5, 6, ...])")
69
Raymond Hettinger1453e4a2004-05-21 23:01:18 +000070 # collections.deque after 6
71 eq(r(deque([1, 2, 3, 4, 5, 6, 7])), "deque([1, 2, 3, 4, 5, 6, ...])")
72
Fred Drake8e6669a2001-07-19 22:27:56 +000073 # Dictionaries give up after 4.
74 eq(r({}), "{}")
75 d = {'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}
76 eq(r(d), "{'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}")
77 d['arthur'] = 1
78 eq(r(d), "{'alice': 1, 'arthur': 1, 'bob': 2, 'charles': 3, ...}")
79
Tim Peters6ee04802003-02-05 18:29:34 +000080 # array.array after 5.
81 eq(r(array('i')), "array('i', [])")
82 eq(r(array('i', [1])), "array('i', [1])")
83 eq(r(array('i', [1, 2])), "array('i', [1, 2])")
84 eq(r(array('i', [1, 2, 3])), "array('i', [1, 2, 3])")
85 eq(r(array('i', [1, 2, 3, 4])), "array('i', [1, 2, 3, 4])")
86 eq(r(array('i', [1, 2, 3, 4, 5])), "array('i', [1, 2, 3, 4, 5])")
87 eq(r(array('i', [1, 2, 3, 4, 5, 6])),
88 "array('i', [1, 2, 3, 4, 5, ...])")
89
Fred Drake8e6669a2001-07-19 22:27:56 +000090 def test_numbers(self):
91 eq = self.assertEquals
92 eq(r(123), repr(123))
93 eq(r(123L), repr(123L))
94 eq(r(1.0/3), repr(1.0/3))
95
96 n = 10L**100
Walter Dörwald70a6b492004-02-12 17:35:32 +000097 expected = repr(n)[:18] + "..." + repr(n)[-19:]
Fred Drake8e6669a2001-07-19 22:27:56 +000098 eq(r(n), expected)
99
100 def test_instance(self):
101 eq = self.assertEquals
102 i1 = ClassWithRepr("a")
103 eq(r(i1), repr(i1))
Tim Petersab9ba272001-08-09 21:40:30 +0000104
Fred Drake8e6669a2001-07-19 22:27:56 +0000105 i2 = ClassWithRepr("x"*1000)
Walter Dörwald70a6b492004-02-12 17:35:32 +0000106 expected = repr(i2)[:13] + "..." + repr(i2)[-14:]
Fred Drake8e6669a2001-07-19 22:27:56 +0000107 eq(r(i2), expected)
108
109 i3 = ClassWithFailingRepr()
110 eq(r(i3), ("<ClassWithFailingRepr instance at %x>"%id(i3)))
111
Guido van Rossumcf856f92001-09-05 02:26:26 +0000112 s = r(ClassWithFailingRepr)
113 self.failUnless(s.startswith("<class "))
114 self.failUnless(s.endswith(">"))
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000115 self.failUnless(s.find("...") in [12, 13])
Guido van Rossumcf856f92001-09-05 02:26:26 +0000116
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000117 def test_file(self):
118 fp = open(unittest.__file__)
119 self.failUnless(repr(fp).startswith(
120 "<open file '%s', mode 'r' at 0x" % unittest.__file__))
121 fp.close()
122 self.failUnless(repr(fp).startswith(
123 "<closed file '%s', mode 'r' at 0x" % unittest.__file__))
124
125 def test_lambda(self):
126 self.failUnless(repr(lambda x: x).startswith(
Neil Schemenauerab541bb2005-10-21 18:11:40 +0000127 "<function <lambda"))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000128 # XXX anonymous functions? see func_repr
129
130 def test_builtin_function(self):
131 eq = self.assertEquals
132 # Functions
133 eq(repr(hash), '<built-in function hash>')
134 # Methods
135 self.failUnless(repr(''.split).startswith(
136 '<built-in method split of str object at 0x'))
137
138 def test_xrange(self):
Tim Petersd3925062002-04-16 01:27:44 +0000139 import warnings
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000140 eq = self.assertEquals
141 eq(repr(xrange(1)), 'xrange(1)')
142 eq(repr(xrange(1, 2)), 'xrange(1, 2)')
143 eq(repr(xrange(1, 2, 3)), 'xrange(1, 4, 3)')
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000144
Fred Drake8e6669a2001-07-19 22:27:56 +0000145 def test_nesting(self):
146 eq = self.assertEquals
147 # everything is meant to give up after 6 levels.
148 eq(r([[[[[[[]]]]]]]), "[[[[[[[]]]]]]]")
149 eq(r([[[[[[[[]]]]]]]]), "[[[[[[[...]]]]]]]")
150
151 eq(r(nestedTuple(6)), "(((((((),),),),),),)")
152 eq(r(nestedTuple(7)), "(((((((...),),),),),),)")
153
154 eq(r({ nestedTuple(5) : nestedTuple(5) }),
155 "{((((((),),),),),): ((((((),),),),),)}")
156 eq(r({ nestedTuple(6) : nestedTuple(6) }),
157 "{((((((...),),),),),): ((((((...),),),),),)}")
158
159 eq(r([[[[[[{}]]]]]]), "[[[[[[{}]]]]]]")
160 eq(r([[[[[[[{}]]]]]]]), "[[[[[[[...]]]]]]]")
161
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000162 def test_buffer(self):
163 # XXX doesn't test buffers with no b_base or read-write buffers (see
164 # bufferobject.c). The test is fairly incomplete too. Sigh.
165 x = buffer('foo')
166 self.failUnless(repr(x).startswith('<read-only buffer for 0x'))
167
168 def test_cell(self):
169 # XXX Hmm? How to get at a cell object?
170 pass
171
172 def test_descriptors(self):
173 eq = self.assertEquals
174 # method descriptors
Tim Petersa427a2b2001-10-29 22:25:45 +0000175 eq(repr(dict.items), "<method 'items' of 'dict' objects>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000176 # XXX member descriptors
177 # XXX attribute descriptors
178 # XXX slot descriptors
179 # static and class methods
180 class C:
181 def foo(cls): pass
182 x = staticmethod(C.foo)
183 self.failUnless(repr(x).startswith('<staticmethod object at 0x'))
184 x = classmethod(C.foo)
185 self.failUnless(repr(x).startswith('<classmethod object at 0x'))
186
187def touch(path, text=''):
188 fp = open(path, 'w')
189 fp.write(text)
190 fp.close()
191
192def zap(actions, dirname, names):
193 for name in names:
194 actions.append(os.path.join(dirname, name))
195
196class LongReprTest(unittest.TestCase):
197 def setUp(self):
198 longname = 'areallylongpackageandmodulenametotestreprtruncation'
199 self.pkgname = os.path.join(longname)
200 self.subpkgname = os.path.join(longname, longname)
201 # Make the package and subpackage
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000202 shutil.rmtree(self.pkgname, ignore_errors=True)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000203 os.mkdir(self.pkgname)
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000204 touch(os.path.join(self.pkgname, '__init__'+os.extsep+'py'))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000205 shutil.rmtree(self.subpkgname, ignore_errors=True)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000206 os.mkdir(self.subpkgname)
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000207 touch(os.path.join(self.subpkgname, '__init__'+os.extsep+'py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000208 # Remember where we are
209 self.here = os.getcwd()
210 sys.path.insert(0, self.here)
211
212 def tearDown(self):
213 actions = []
214 os.path.walk(self.pkgname, zap, actions)
215 actions.append(self.pkgname)
216 actions.sort()
217 actions.reverse()
218 for p in actions:
219 if os.path.isdir(p):
220 os.rmdir(p)
221 else:
222 os.remove(p)
223 del sys.path[0]
224
225 def test_module(self):
226 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000227 touch(os.path.join(self.subpkgname, self.pkgname + os.extsep + 'py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000228 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
229 eq(repr(areallylongpackageandmodulenametotestreprtruncation),
Mark Hammondd800ae12003-01-16 04:56:52 +0000230 "<module '%s' from '%s'>" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__))
Neal Norwitz70769012001-12-29 00:25:42 +0000231 eq(repr(sys), "<module 'sys' (built-in)>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000232
233 def test_type(self):
234 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000235 touch(os.path.join(self.subpkgname, 'foo'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000236class foo(object):
237 pass
238''')
239 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
240 eq(repr(foo.foo),
Mark Hammondd800ae12003-01-16 04:56:52 +0000241 "<class '%s.foo'>" % foo.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000242
243 def test_object(self):
244 # XXX Test the repr of a type with a really long tp_name but with no
245 # tp_repr. WIBNI we had ::Inline? :)
246 pass
247
248 def test_class(self):
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000249 touch(os.path.join(self.subpkgname, 'bar'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000250class bar:
251 pass
252''')
253 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
Mark Hammondd800ae12003-01-16 04:56:52 +0000254 # Module name may be prefixed with "test.", depending on how run.
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000255 self.assertEquals(repr(bar.bar), "<class '%s.bar'>" % bar.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000256
257 def test_instance(self):
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000258 touch(os.path.join(self.subpkgname, 'baz'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000259class baz:
260 pass
261''')
262 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
263 ibaz = baz.baz()
264 self.failUnless(repr(ibaz).startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000265 "<%s.baz object at 0x" % baz.__name__))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000266
267 def test_method(self):
268 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000269 touch(os.path.join(self.subpkgname, 'qux'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000270class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
271 def amethod(self): pass
272''')
273 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
274 # Unbound methods first
275 eq(repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod),
276 '<unbound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod>')
277 # Bound method next
278 iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
279 self.failUnless(repr(iqux.amethod).startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000280 '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa object at 0x' \
Mark Hammondd800ae12003-01-16 04:56:52 +0000281 % (qux.__name__,) ))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000282
283 def test_builtin_function(self):
284 # XXX test built-in functions and methods with really long names
285 pass
Fred Drake8e6669a2001-07-19 22:27:56 +0000286
287class ClassWithRepr:
288 def __init__(self, s):
289 self.s = s
290 def __repr__(self):
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000291 return "ClassWithRepr(%r)" % self.s
Fred Drake8e6669a2001-07-19 22:27:56 +0000292
293
294class ClassWithFailingRepr:
295 def __repr__(self):
296 raise Exception("This should be caught by Repr.repr_instance")
297
298
Fred Drake2e2be372001-09-20 21:33:42 +0000299def test_main():
300 run_unittest(ReprTests)
301 if os.name != 'mac':
302 run_unittest(LongReprTest)
303
304
305if __name__ == "__main__":
306 test_main()