blob: 5fcf815ea3ffc801fdae76f0a6b9fa1647f83467 [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
Neal Norwitz008b8612006-05-30 07:21:10 +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(">"))
115 self.failUnless(s.find("...") == 8)
116
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):
139 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
Neal Norwitz008b8612006-05-30 07:21:10 +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'))
Neal Norwitz008b8612006-05-30 07:21:10 +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.
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000254 self.failUnless(repr(bar.bar).startswith(
Mark Hammondd800ae12003-01-16 04:56:52 +0000255 "<class %s.bar at 0x" % 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(
Mark Hammondd800ae12003-01-16 04:56:52 +0000265 "<%s.baz instance 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(
Mark Hammondd800ae12003-01-16 04:56:52 +0000280 '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa instance at 0x' \
281 % (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):
291 return "ClassWithLongRepr(%r)" % self.s
292
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()