blob: 89df890fd105b4d423a3264ef64bb46445b993f7 [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__)
Neal Norwitz70769012001-12-29 00:25:42 +0000202 eq(repr(sys), "<module 'sys' (built-in)>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000203
204 def test_type(self):
205 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000206 touch(os.path.join(self.subpkgname, 'foo'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000207class foo(object):
208 pass
209''')
210 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
211 eq(repr(foo.foo),
Guido van Rossuma4cb7882001-09-25 03:56:29 +0000212 "<class 'areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.foo.foo'>")
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000213
214 def test_object(self):
215 # XXX Test the repr of a type with a really long tp_name but with no
216 # tp_repr. WIBNI we had ::Inline? :)
217 pass
218
219 def test_class(self):
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000220 touch(os.path.join(self.subpkgname, 'bar'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000221class bar:
222 pass
223''')
224 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
225 self.failUnless(repr(bar.bar).startswith(
226 "<class areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.bar.bar at 0x"))
227
228 def test_instance(self):
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000229 touch(os.path.join(self.subpkgname, 'baz'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000230class baz:
231 pass
232''')
233 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
234 ibaz = baz.baz()
235 self.failUnless(repr(ibaz).startswith(
236 "<areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.baz.baz instance at 0x"))
237
238 def test_method(self):
239 eq = self.assertEquals
Guido van Rossume2ae77b2001-10-24 20:42:55 +0000240 touch(os.path.join(self.subpkgname, 'qux'+os.extsep+'py'), '''\
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000241class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
242 def amethod(self): pass
243''')
244 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
245 # Unbound methods first
246 eq(repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod),
247 '<unbound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod>')
248 # Bound method next
249 iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
250 self.failUnless(repr(iqux.amethod).startswith(
251 '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa instance at 0x'))
252
253 def test_builtin_function(self):
254 # XXX test built-in functions and methods with really long names
255 pass
Fred Drake8e6669a2001-07-19 22:27:56 +0000256
257class ClassWithRepr:
258 def __init__(self, s):
259 self.s = s
260 def __repr__(self):
261 return "ClassWithLongRepr(%r)" % self.s
262
263
264class ClassWithFailingRepr:
265 def __repr__(self):
266 raise Exception("This should be caught by Repr.repr_instance")
267
268
Fred Drake2e2be372001-09-20 21:33:42 +0000269def test_main():
270 run_unittest(ReprTests)
271 if os.name != 'mac':
272 run_unittest(LongReprTest)
273
274
275if __name__ == "__main__":
276 test_main()