blob: 120a3cd6f14633e6b1b7ab6119daacd776228681 [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))
Guido van Rossume2a383d2007-01-15 16:59:06 +000093 eq(r(123), repr(123))
Fred Drake8e6669a2001-07-19 22:27:56 +000094 eq(r(1.0/3), repr(1.0/3))
95
Guido van Rossume2a383d2007-01-15 16:59:06 +000096 n = 10**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
Guido van Rossum805365e2007-05-07 22:24:25 +0000138 def test_range(self):
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000139 eq = self.assertEquals
Guido van Rossum805365e2007-05-07 22:24:25 +0000140 eq(repr(range(1)), 'range(1)')
141 eq(repr(range(1, 2)), 'range(1, 2)')
142 eq(repr(range(1, 4, 3)), 'range(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
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000201 shutil.rmtree(self.pkgname, ignore_errors=True)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000202 os.mkdir(self.pkgname)
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000203 touch(os.path.join(self.pkgname, '__init__'+os.extsep+'py'))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000204 shutil.rmtree(self.subpkgname, ignore_errors=True)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000205 os.mkdir(self.subpkgname)
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000206 touch(os.path.join(self.subpkgname, '__init__'+os.extsep+'py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000207 # Remember where we are
208 self.here = os.getcwd()
209 sys.path.insert(0, self.here)
210
211 def tearDown(self):
212 actions = []
213 os.path.walk(self.pkgname, zap, actions)
214 actions.append(self.pkgname)
215 actions.sort()
216 actions.reverse()
217 for p in actions:
218 if os.path.isdir(p):
219 os.rmdir(p)
220 else:
221 os.remove(p)
222 del sys.path[0]
223
224 def test_module(self):
225 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000226 touch(os.path.join(self.subpkgname, self.pkgname + os.extsep + 'py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000227 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
228 eq(repr(areallylongpackageandmodulenametotestreprtruncation),
Mark Hammondd800ae12003-01-16 04:56:52 +0000229 "<module '%s' from '%s'>" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__))
Neal Norwitz70769012001-12-29 00:25:42 +0000230 eq(repr(sys), "<module 'sys' (built-in)>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000231
232 def test_type(self):
233 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000234 touch(os.path.join(self.subpkgname, 'foo'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000235class foo(object):
236 pass
237''')
238 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
239 eq(repr(foo.foo),
Mark Hammondd800ae12003-01-16 04:56:52 +0000240 "<class '%s.foo'>" % foo.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000241
242 def test_object(self):
243 # XXX Test the repr of a type with a really long tp_name but with no
244 # tp_repr. WIBNI we had ::Inline? :)
245 pass
246
247 def test_class(self):
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000248 touch(os.path.join(self.subpkgname, 'bar'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000249class bar:
250 pass
251''')
252 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
Mark Hammondd800ae12003-01-16 04:56:52 +0000253 # Module name may be prefixed with "test.", depending on how run.
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000254 self.assertEquals(repr(bar.bar), "<class '%s.bar'>" % bar.__name__)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000255
256 def test_instance(self):
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000257 touch(os.path.join(self.subpkgname, 'baz'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000258class baz:
259 pass
260''')
261 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
262 ibaz = baz.baz()
263 self.failUnless(repr(ibaz).startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000264 "<%s.baz object at 0x" % baz.__name__))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000265
266 def test_method(self):
267 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000268 touch(os.path.join(self.subpkgname, 'qux'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000269class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
270 def amethod(self): pass
271''')
272 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
273 # Unbound methods first
274 eq(repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod),
275 '<unbound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod>')
276 # Bound method next
277 iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
278 self.failUnless(repr(iqux.amethod).startswith(
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000279 '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa object at 0x' \
Mark Hammondd800ae12003-01-16 04:56:52 +0000280 % (qux.__name__,) ))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000281
282 def test_builtin_function(self):
283 # XXX test built-in functions and methods with really long names
284 pass
Fred Drake8e6669a2001-07-19 22:27:56 +0000285
286class ClassWithRepr:
287 def __init__(self, s):
288 self.s = s
289 def __repr__(self):
Guido van Rossuma48a3b42006-04-20 16:07:39 +0000290 return "ClassWithRepr(%r)" % self.s
Fred Drake8e6669a2001-07-19 22:27:56 +0000291
292
293class ClassWithFailingRepr:
294 def __repr__(self):
295 raise Exception("This should be caught by Repr.repr_instance")
296
297
Fred Drake2e2be372001-09-20 21:33:42 +0000298def test_main():
299 run_unittest(ReprTests)
300 if os.name != 'mac':
301 run_unittest(LongReprTest)
302
303
304if __name__ == "__main__":
305 test_main()