test_repr.py revision 2e2be3760ccdfd4bdde4afdd66f4078022ba3b61
166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman""" 266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Test cases for the repr module 366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Nick Mathewson 466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman""" 566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanimport sys 766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanimport os 866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanimport unittest 966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 1066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanfrom test_support import run_unittest 1166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanfrom repr import repr as r # Don't shadow builtin repr 1266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 1366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 1466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumandef nestedTuple(nesting): 1566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman t = () 1666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for i in range(nesting): 1766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman t = (t,) 1866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return t 1966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 2066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanclass ReprTests(unittest.TestCase): 2166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 2266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman def test_string(self): 2366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq = self.assertEquals 2466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq(r("abc"), "'abc'") 2566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq(r("abcdefghijklmnop"),"'abcdefghijklmnop'") 2666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 2766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman s = "a"*30+"b"*30 2866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman expected = `s`[:13] + "..." + `s`[-14:] 2966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq(r(s), expected) 3066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 3166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq(r("\"'"), repr("\"'")) 3266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman s = "\""*30+"'"*100 3366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman expected = `s`[:13] + "..." + `s`[-14:] 3466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq(r(s), expected) 3566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 3666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman def test_container(self): 3766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq = self.assertEquals 3866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman # Tuples give up after 6 elements 3966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq(r(()), "()") 4066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq(r((1,)), "(1,)") 4166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq(r((1, 2, 3)), "(1, 2, 3)") 4266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq(r((1, 2, 3, 4, 5, 6)), "(1, 2, 3, 4, 5, 6)") 4366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq(r((1, 2, 3, 4, 5, 6, 7)), "(1, 2, 3, 4, 5, 6, ...)") 4466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 4566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman # Lists give up after 6 as well 4666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq(r([]), "[]") 4766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq(r([1]), "[1]") 4866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman eq(r([1, 2, 3]), "[1, 2, 3]") 4966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 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)) 73 74 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 81 s = r(ClassWithFailingRepr) 82 self.failUnless(s.startswith("<class ")) 83 self.failUnless(s.endswith(">")) 84 self.failUnless(s.find("...") == 8) 85 86 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( 96 "<function <lambda")) 97 # 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 118 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 135 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 148 eq(repr(dictionary.items), "<method 'items' of 'dictionary' objects>") 149 # 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) 176 touch(os.path.join(self.pkgname, '__init__.py')) 177 os.mkdir(self.subpkgname) 178 touch(os.path.join(self.subpkgname, '__init__.py')) 179 # 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 198 touch(os.path.join(self.subpkgname, self.pkgname + '.py')) 199 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 205 touch(os.path.join(self.subpkgname, 'foo.py'), '''\ 206class foo(object): 207 pass 208''') 209 from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo 210 eq(repr(foo.foo), 211 "<type 'areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation.foo.foo'>") 212 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): 219 touch(os.path.join(self.subpkgname, 'bar.py'), '''\ 220class 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): 228 touch(os.path.join(self.subpkgname, 'baz.py'), '''\ 229class 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 239 touch(os.path.join(self.subpkgname, 'qux.py'), '''\ 240class 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 255 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 268def test_main(): 269 run_unittest(ReprTests) 270 if os.name != 'mac': 271 run_unittest(LongReprTest) 272 273 274if __name__ == "__main__": 275 test_main() 276