blob: f8aad94f95ccecd7817c50f5d89d9c9f2e2894a5 [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
Fred Drake8e6669a2001-07-19 22:27:56 +000010from 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
28 expected = `s`[:13] + "..." + `s`[-14:]
29 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
33 expected = `s`[:13] + "..." + `s`[-14:]
34 eq(r(s), expected)
35
36 def test_container(self):
37 eq = self.assertEquals
38 # Tuples give up after 6 elements
39 eq(r(()), "()")
40 eq(r((1,)), "(1,)")
41 eq(r((1, 2, 3)), "(1, 2, 3)")
42 eq(r((1, 2, 3, 4, 5, 6)), "(1, 2, 3, 4, 5, 6)")
43 eq(r((1, 2, 3, 4, 5, 6, 7)), "(1, 2, 3, 4, 5, 6, ...)")
44
45 # Lists give up after 6 as well
46 eq(r([]), "[]")
47 eq(r([1]), "[1]")
48 eq(r([1, 2, 3]), "[1, 2, 3]")
49 eq(r([1, 2, 3, 4, 5, 6]), "[1, 2, 3, 4, 5, 6]")
50 eq(r([1, 2, 3, 4, 5, 6, 7]), "[1, 2, 3, 4, 5, 6, ...]")
51
52 # Dictionaries give up after 4.
53 eq(r({}), "{}")
54 d = {'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}
55 eq(r(d), "{'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}")
56 d['arthur'] = 1
57 eq(r(d), "{'alice': 1, 'arthur': 1, 'bob': 2, 'charles': 3, ...}")
58
59 def test_numbers(self):
60 eq = self.assertEquals
61 eq(r(123), repr(123))
62 eq(r(123L), repr(123L))
63 eq(r(1.0/3), repr(1.0/3))
64
65 n = 10L**100
66 expected = `n`[:18] + "..." + `n`[-19:]
67 eq(r(n), expected)
68
69 def test_instance(self):
70 eq = self.assertEquals
71 i1 = ClassWithRepr("a")
72 eq(r(i1), repr(i1))
Tim Petersab9ba272001-08-09 21:40:30 +000073
Fred Drake8e6669a2001-07-19 22:27:56 +000074 i2 = ClassWithRepr("x"*1000)
75 expected = `i2`[:13] + "..." + `i2`[-14:]
76 eq(r(i2), expected)
77
78 i3 = ClassWithFailingRepr()
79 eq(r(i3), ("<ClassWithFailingRepr instance at %x>"%id(i3)))
80
Guido van Rossumcf856f92001-09-05 02:26:26 +000081 s = r(ClassWithFailingRepr)
82 self.failUnless(s.startswith("<class "))
83 self.failUnless(s.endswith(">"))
84 self.failUnless(s.find("...") == 8)
85
Barry Warsaw0bcf6d82001-08-24 18:37:32 +000086 def test_file(self):
87 fp = open(unittest.__file__)
88 self.failUnless(repr(fp).startswith(
89 "<open file '%s', mode 'r' at 0x" % unittest.__file__))
90 fp.close()
91 self.failUnless(repr(fp).startswith(
92 "<closed file '%s', mode 'r' at 0x" % unittest.__file__))
93
94 def test_lambda(self):
95 self.failUnless(repr(lambda x: x).startswith(
Jeremy Hyltondd321382001-09-14 23:01:49 +000096 "<function <lambda"))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +000097 # XXX anonymous functions? see func_repr
98
99 def test_builtin_function(self):
100 eq = self.assertEquals
101 # Functions
102 eq(repr(hash), '<built-in function hash>')
103 # Methods
104 self.failUnless(repr(''.split).startswith(
105 '<built-in method split of str object at 0x'))
106
107 def test_xrange(self):
Tim Petersd3925062002-04-16 01:27:44 +0000108 import warnings
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000109 eq = self.assertEquals
110 eq(repr(xrange(1)), 'xrange(1)')
111 eq(repr(xrange(1, 2)), 'xrange(1, 2)')
112 eq(repr(xrange(1, 2, 3)), 'xrange(1, 4, 3)')
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000113
Fred Drake8e6669a2001-07-19 22:27:56 +0000114 def test_nesting(self):
115 eq = self.assertEquals
116 # everything is meant to give up after 6 levels.
117 eq(r([[[[[[[]]]]]]]), "[[[[[[[]]]]]]]")
118 eq(r([[[[[[[[]]]]]]]]), "[[[[[[[...]]]]]]]")
119
120 eq(r(nestedTuple(6)), "(((((((),),),),),),)")
121 eq(r(nestedTuple(7)), "(((((((...),),),),),),)")
122
123 eq(r({ nestedTuple(5) : nestedTuple(5) }),
124 "{((((((),),),),),): ((((((),),),),),)}")
125 eq(r({ nestedTuple(6) : nestedTuple(6) }),
126 "{((((((...),),),),),): ((((((...),),),),),)}")
127
128 eq(r([[[[[[{}]]]]]]), "[[[[[[{}]]]]]]")
129 eq(r([[[[[[[{}]]]]]]]), "[[[[[[[...]]]]]]]")
130
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000131 def test_buffer(self):
132 # XXX doesn't test buffers with no b_base or read-write buffers (see
133 # bufferobject.c). The test is fairly incomplete too. Sigh.
134 x = buffer('foo')
135 self.failUnless(repr(x).startswith('<read-only buffer for 0x'))
136
137 def test_cell(self):
138 # XXX Hmm? How to get at a cell object?
139 pass
140
141 def test_descriptors(self):
142 eq = self.assertEquals
143 # method descriptors
Tim Petersa427a2b2001-10-29 22:25:45 +0000144 eq(repr(dict.items), "<method 'items' of 'dict' objects>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000145 # XXX member descriptors
146 # XXX attribute descriptors
147 # XXX slot descriptors
148 # static and class methods
149 class C:
150 def foo(cls): pass
151 x = staticmethod(C.foo)
152 self.failUnless(repr(x).startswith('<staticmethod object at 0x'))
153 x = classmethod(C.foo)
154 self.failUnless(repr(x).startswith('<classmethod object at 0x'))
155
156def touch(path, text=''):
157 fp = open(path, 'w')
158 fp.write(text)
159 fp.close()
160
161def zap(actions, dirname, names):
162 for name in names:
163 actions.append(os.path.join(dirname, name))
164
165class LongReprTest(unittest.TestCase):
166 def setUp(self):
167 longname = 'areallylongpackageandmodulenametotestreprtruncation'
168 self.pkgname = os.path.join(longname)
169 self.subpkgname = os.path.join(longname, longname)
170 # Make the package and subpackage
171 os.mkdir(self.pkgname)
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000172 touch(os.path.join(self.pkgname, '__init__'+os.extsep+'py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000173 os.mkdir(self.subpkgname)
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000174 touch(os.path.join(self.subpkgname, '__init__'+os.extsep+'py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000175 # Remember where we are
176 self.here = os.getcwd()
177 sys.path.insert(0, self.here)
178
179 def tearDown(self):
180 actions = []
181 os.path.walk(self.pkgname, zap, actions)
182 actions.append(self.pkgname)
183 actions.sort()
184 actions.reverse()
185 for p in actions:
186 if os.path.isdir(p):
187 os.rmdir(p)
188 else:
189 os.remove(p)
190 del sys.path[0]
191
192 def test_module(self):
193 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000194 touch(os.path.join(self.subpkgname, self.pkgname + os.extsep + 'py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000195 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
196 eq(repr(areallylongpackageandmodulenametotestreprtruncation),
197 "<module 'areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation' from '%s'>" % areallylongpackageandmodulenametotestreprtruncation.__file__)
Neal Norwitz70769012001-12-29 00:25:42 +0000198 eq(repr(sys), "<module 'sys' (built-in)>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000199
200 def test_type(self):
201 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000202 touch(os.path.join(self.subpkgname, 'foo'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000203class foo(object):
204 pass
205''')
206 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
207 eq(repr(foo.foo),
Guido van Rossuma4cb7882001-09-25 03:56:29 +0000208 "<class 'areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.foo.foo'>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000209
210 def test_object(self):
211 # XXX Test the repr of a type with a really long tp_name but with no
212 # tp_repr. WIBNI we had ::Inline? :)
213 pass
214
215 def test_class(self):
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000216 touch(os.path.join(self.subpkgname, 'bar'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000217class bar:
218 pass
219''')
220 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
221 self.failUnless(repr(bar.bar).startswith(
222 "<class areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.bar.bar at 0x"))
223
224 def test_instance(self):
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000225 touch(os.path.join(self.subpkgname, 'baz'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000226class baz:
227 pass
228''')
229 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
230 ibaz = baz.baz()
231 self.failUnless(repr(ibaz).startswith(
232 "<areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.baz.baz instance at 0x"))
233
234 def test_method(self):
235 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000236 touch(os.path.join(self.subpkgname, 'qux'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000237class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
238 def amethod(self): pass
239''')
240 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
241 # Unbound methods first
242 eq(repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod),
243 '<unbound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod>')
244 # Bound method next
245 iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
246 self.failUnless(repr(iqux.amethod).startswith(
247 '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa instance at 0x'))
248
249 def test_builtin_function(self):
250 # XXX test built-in functions and methods with really long names
251 pass
Fred Drake8e6669a2001-07-19 22:27:56 +0000252
253class ClassWithRepr:
254 def __init__(self, s):
255 self.s = s
256 def __repr__(self):
257 return "ClassWithLongRepr(%r)" % self.s
258
259
260class ClassWithFailingRepr:
261 def __repr__(self):
262 raise Exception("This should be caught by Repr.repr_instance")
263
264
Fred Drake2e2be372001-09-20 21:33:42 +0000265def test_main():
266 run_unittest(ReprTests)
267 if os.name != 'mac':
268 run_unittest(LongReprTest)
269
270
271if __name__ == "__main__":
272 test_main()