blob: 1281b1f27661bce15288957c54ae133d749aec5c [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
Barry Warsaw0bcf6d82001-08-24 18:37:32 +000081 def test_file(self):
82 fp = open(unittest.__file__)
83 self.failUnless(repr(fp).startswith(
84 "<open file '%s', mode 'r' at 0x" % unittest.__file__))
85 fp.close()
86 self.failUnless(repr(fp).startswith(
87 "<closed file '%s', mode 'r' at 0x" % unittest.__file__))
88
89 def test_lambda(self):
90 self.failUnless(repr(lambda x: x).startswith(
91 "<function <lambda> at 0x"))
92 # XXX anonymous functions? see func_repr
93
94 def test_builtin_function(self):
95 eq = self.assertEquals
96 # Functions
97 eq(repr(hash), '<built-in function hash>')
98 # Methods
99 self.failUnless(repr(''.split).startswith(
100 '<built-in method split of str object at 0x'))
101
102 def test_xrange(self):
103 eq = self.assertEquals
104 eq(repr(xrange(1)), 'xrange(1)')
105 eq(repr(xrange(1, 2)), 'xrange(1, 2)')
106 eq(repr(xrange(1, 2, 3)), 'xrange(1, 4, 3)')
107 # Turn off warnings for deprecated multiplication
108 import warnings
109 warnings.filterwarnings('ignore', category=DeprecationWarning,
110 module=ReprTests.__module__)
111 eq(repr(xrange(1) * 3), '(xrange(1) * 3)')
112
Fred Drake8e6669a2001-07-19 22:27:56 +0000113 def test_nesting(self):
114 eq = self.assertEquals
115 # everything is meant to give up after 6 levels.
116 eq(r([[[[[[[]]]]]]]), "[[[[[[[]]]]]]]")
117 eq(r([[[[[[[[]]]]]]]]), "[[[[[[[...]]]]]]]")
118
119 eq(r(nestedTuple(6)), "(((((((),),),),),),)")
120 eq(r(nestedTuple(7)), "(((((((...),),),),),),)")
121
122 eq(r({ nestedTuple(5) : nestedTuple(5) }),
123 "{((((((),),),),),): ((((((),),),),),)}")
124 eq(r({ nestedTuple(6) : nestedTuple(6) }),
125 "{((((((...),),),),),): ((((((...),),),),),)}")
126
127 eq(r([[[[[[{}]]]]]]), "[[[[[[{}]]]]]]")
128 eq(r([[[[[[[{}]]]]]]]), "[[[[[[[...]]]]]]]")
129
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000130 def test_buffer(self):
131 # XXX doesn't test buffers with no b_base or read-write buffers (see
132 # bufferobject.c). The test is fairly incomplete too. Sigh.
133 x = buffer('foo')
134 self.failUnless(repr(x).startswith('<read-only buffer for 0x'))
135
136 def test_cell(self):
137 # XXX Hmm? How to get at a cell object?
138 pass
139
140 def test_descriptors(self):
141 eq = self.assertEquals
142 # method descriptors
143 eq(repr(dictionary.items), "<method 'items' of 'dictionary' objects>")
144 # XXX member descriptors
145 # XXX attribute descriptors
146 # XXX slot descriptors
147 # static and class methods
148 class C:
149 def foo(cls): pass
150 x = staticmethod(C.foo)
151 self.failUnless(repr(x).startswith('<staticmethod object at 0x'))
152 x = classmethod(C.foo)
153 self.failUnless(repr(x).startswith('<classmethod object at 0x'))
154
155def touch(path, text=''):
156 fp = open(path, 'w')
157 fp.write(text)
158 fp.close()
159
160def zap(actions, dirname, names):
161 for name in names:
162 actions.append(os.path.join(dirname, name))
163
164class LongReprTest(unittest.TestCase):
165 def setUp(self):
166 longname = 'areallylongpackageandmodulenametotestreprtruncation'
167 self.pkgname = os.path.join(longname)
168 self.subpkgname = os.path.join(longname, longname)
169 # Make the package and subpackage
170 os.mkdir(self.pkgname)
171 touch(os.path.join(self.pkgname, '__init__.py'))
172 os.mkdir(self.subpkgname)
173 touch(os.path.join(self.subpkgname, '__init__.py'))
174 # Remember where we are
175 self.here = os.getcwd()
176 sys.path.insert(0, self.here)
177
178 def tearDown(self):
179 actions = []
180 os.path.walk(self.pkgname, zap, actions)
181 actions.append(self.pkgname)
182 actions.sort()
183 actions.reverse()
184 for p in actions:
185 if os.path.isdir(p):
186 os.rmdir(p)
187 else:
188 os.remove(p)
189 del sys.path[0]
190
191 def test_module(self):
192 eq = self.assertEquals
193 touch(os.path.join(self.subpkgname, self.pkgname + '.py'))
194 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
195 eq(repr(areallylongpackageandmodulenametotestreprtruncation),
196 "<module 'areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation' from '%s'>" % areallylongpackageandmodulenametotestreprtruncation.__file__)
197
198 def test_type(self):
199 eq = self.assertEquals
200 touch(os.path.join(self.subpkgname, 'foo.py'), '''\
201class foo(object):
202 pass
203''')
204 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
205 eq(repr(foo.foo),
206 "<type 'areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.foo.foo'>")
207
208 def test_object(self):
209 # XXX Test the repr of a type with a really long tp_name but with no
210 # tp_repr. WIBNI we had ::Inline? :)
211 pass
212
213 def test_class(self):
214 touch(os.path.join(self.subpkgname, 'bar.py'), '''\
215class bar:
216 pass
217''')
218 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
219 self.failUnless(repr(bar.bar).startswith(
220 "<class areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.bar.bar at 0x"))
221
222 def test_instance(self):
223 touch(os.path.join(self.subpkgname, 'baz.py'), '''\
224class baz:
225 pass
226''')
227 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
228 ibaz = baz.baz()
229 self.failUnless(repr(ibaz).startswith(
230 "<areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.baz.baz instance at 0x"))
231
232 def test_method(self):
233 eq = self.assertEquals
234 touch(os.path.join(self.subpkgname, 'qux.py'), '''\
235class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
236 def amethod(self): pass
237''')
238 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
239 # Unbound methods first
240 eq(repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod),
241 '<unbound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod>')
242 # Bound method next
243 iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
244 self.failUnless(repr(iqux.amethod).startswith(
245 '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa instance at 0x'))
246
247 def test_builtin_function(self):
248 # XXX test built-in functions and methods with really long names
249 pass
Fred Drake8e6669a2001-07-19 22:27:56 +0000250
251class ClassWithRepr:
252 def __init__(self, s):
253 self.s = s
254 def __repr__(self):
255 return "ClassWithLongRepr(%r)" % self.s
256
257
258class ClassWithFailingRepr:
259 def __repr__(self):
260 raise Exception("This should be caught by Repr.repr_instance")
261
262
263run_unittest(ReprTests)
Barry Warsaw0bcf6d82001-08-24 18:37:32 +0000264run_unittest(LongReprTest)