blob: a659002e94ab6b10c7b6c9132ffd87d178f85b37 [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):
108 eq = self.assertEquals
109 eq(repr(xrange(1)), 'xrange(1)')
110 eq(repr(xrange(1, 2)), 'xrange(1, 2)')
111 eq(repr(xrange(1, 2, 3)), 'xrange(1, 4, 3)')
112 # Turn off warnings for deprecated multiplication
113 import warnings
114 warnings.filterwarnings('ignore', category=DeprecationWarning,
115 module=ReprTests.__module__)
116 eq(repr(xrange(1) * 3), '(xrange(1) * 3)')
117
Fred Drake8e6669a2001-07-19 22:27:56 +0000118 def test_nesting(self):
119 eq = self.assertEquals
120 # everything is meant to give up after 6 levels.
121 eq(r([[[[[[[]]]]]]]), "[[[[[[[]]]]]]]")
122 eq(r([[[[[[[[]]]]]]]]), "[[[[[[[...]]]]]]]")
123
124 eq(r(nestedTuple(6)), "(((((((),),),),),),)")
125 eq(r(nestedTuple(7)), "(((((((...),),),),),),)")
126
127 eq(r({ nestedTuple(5) : nestedTuple(5) }),
128 "{((((((),),),),),): ((((((),),),),),)}")
129 eq(r({ nestedTuple(6) : nestedTuple(6) }),
130 "{((((((...),),),),),): ((((((...),),),),),)}")
131
132 eq(r([[[[[[{}]]]]]]), "[[[[[[{}]]]]]]")
133 eq(r([[[[[[[{}]]]]]]]), "[[[[[[[...]]]]]]]")
134
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000135 def test_buffer(self):
136 # XXX doesn't test buffers with no b_base or read-write buffers (see
137 # bufferobject.c). The test is fairly incomplete too. Sigh.
138 x = buffer('foo')
139 self.failUnless(repr(x).startswith('<read-only buffer for 0x'))
140
141 def test_cell(self):
142 # XXX Hmm? How to get at a cell object?
143 pass
144
145 def test_descriptors(self):
146 eq = self.assertEquals
147 # method descriptors
Tim Petersa427a2b2001-10-29 22:25:45 +0000148 eq(repr(dict.items), "<method 'items' of 'dict' objects>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000149 # XXX member descriptors
150 # XXX attribute descriptors
151 # XXX slot descriptors
152 # static and class methods
153 class C:
154 def foo(cls): pass
155 x = staticmethod(C.foo)
156 self.failUnless(repr(x).startswith('<staticmethod object at 0x'))
157 x = classmethod(C.foo)
158 self.failUnless(repr(x).startswith('<classmethod object at 0x'))
159
160def touch(path, text=''):
161 fp = open(path, 'w')
162 fp.write(text)
163 fp.close()
164
165def zap(actions, dirname, names):
166 for name in names:
167 actions.append(os.path.join(dirname, name))
168
169class LongReprTest(unittest.TestCase):
170 def setUp(self):
171 longname = 'areallylongpackageandmodulenametotestreprtruncation'
172 self.pkgname = os.path.join(longname)
173 self.subpkgname = os.path.join(longname, longname)
174 # Make the package and subpackage
175 os.mkdir(self.pkgname)
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000176 touch(os.path.join(self.pkgname, '__init__'+os.extsep+'py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000177 os.mkdir(self.subpkgname)
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000178 touch(os.path.join(self.subpkgname, '__init__'+os.extsep+'py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000179 # Remember where we are
180 self.here = os.getcwd()
181 sys.path.insert(0, self.here)
182
183 def tearDown(self):
184 actions = []
185 os.path.walk(self.pkgname, zap, actions)
186 actions.append(self.pkgname)
187 actions.sort()
188 actions.reverse()
189 for p in actions:
190 if os.path.isdir(p):
191 os.rmdir(p)
192 else:
193 os.remove(p)
194 del sys.path[0]
195
196 def test_module(self):
197 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000198 touch(os.path.join(self.subpkgname, self.pkgname + os.extsep + 'py'))
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000199 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
200 eq(repr(areallylongpackageandmodulenametotestreprtruncation),
201 "<module 'areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation' from '%s'>" % areallylongpackageandmodulenametotestreprtruncation.__file__)
202
203 def test_type(self):
204 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000205 touch(os.path.join(self.subpkgname, 'foo'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000206class foo(object):
207 pass
208''')
209 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
210 eq(repr(foo.foo),
Guido van Rossuma4cb7882001-09-25 03:56:29 +0000211 "<class 'areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.foo.foo'>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000212
213 def test_object(self):
214 # XXX Test the repr of a type with a really long tp_name but with no
215 # tp_repr. WIBNI we had ::Inline? :)
216 pass
217
218 def test_class(self):
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000219 touch(os.path.join(self.subpkgname, 'bar'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000220class bar:
221 pass
222''')
223 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
224 self.failUnless(repr(bar.bar).startswith(
225 "<class areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.bar.bar at 0x"))
226
227 def test_instance(self):
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000228 touch(os.path.join(self.subpkgname, 'baz'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000229class baz:
230 pass
231''')
232 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
233 ibaz = baz.baz()
234 self.failUnless(repr(ibaz).startswith(
235 "<areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.baz.baz instance at 0x"))
236
237 def test_method(self):
238 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000239 touch(os.path.join(self.subpkgname, 'qux'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000240class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
241 def amethod(self): pass
242''')
243 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
244 # Unbound methods first
245 eq(repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod),
246 '<unbound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod>')
247 # Bound method next
248 iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
249 self.failUnless(repr(iqux.amethod).startswith(
250 '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa instance at 0x'))
251
252 def test_builtin_function(self):
253 # XXX test built-in functions and methods with really long names
254 pass
Fred Drake8e6669a2001-07-19 22:27:56 +0000255
256class ClassWithRepr:
257 def __init__(self, s):
258 self.s = s
259 def __repr__(self):
260 return "ClassWithLongRepr(%r)" % self.s
261
262
263class ClassWithFailingRepr:
264 def __repr__(self):
265 raise Exception("This should be caught by Repr.repr_instance")
266
267
Fred Drake2e2be372001-09-20 21:33:42 +0000268def test_main():
269 run_unittest(ReprTests)
270 if os.name != 'mac':
271 run_unittest(LongReprTest)
272
273
274if __name__ == "__main__":
275 test_main()