~ubuntu-branches/ubuntu/trusty/python3.4/trusty-proposed

« back to all changes in this revision

Viewing changes to Lib/test/test_reprlib.py

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-11-25 09:44:27 UTC
  • Revision ID: package-import@ubuntu.com-20131125094427-lzxj8ap5w01lmo7f
Tags: upstream-3.4~b1
ImportĀ upstreamĀ versionĀ 3.4~b1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
  Test cases for the repr module
 
3
  Nick Mathewson
 
4
"""
 
5
 
 
6
import sys
 
7
import os
 
8
import shutil
 
9
import importlib
 
10
import importlib.util
 
11
import unittest
 
12
 
 
13
from test.support import run_unittest, create_empty_file, verbose
 
14
from reprlib import repr as r # Don't shadow builtin repr
 
15
from reprlib import Repr
 
16
from reprlib import recursive_repr
 
17
 
 
18
 
 
19
def nestedTuple(nesting):
 
20
    t = ()
 
21
    for i in range(nesting):
 
22
        t = (t,)
 
23
    return t
 
24
 
 
25
class ReprTests(unittest.TestCase):
 
26
 
 
27
    def test_string(self):
 
28
        eq = self.assertEqual
 
29
        eq(r("abc"), "'abc'")
 
30
        eq(r("abcdefghijklmnop"),"'abcdefghijklmnop'")
 
31
 
 
32
        s = "a"*30+"b"*30
 
33
        expected = repr(s)[:13] + "..." + repr(s)[-14:]
 
34
        eq(r(s), expected)
 
35
 
 
36
        eq(r("\"'"), repr("\"'"))
 
37
        s = "\""*30+"'"*100
 
38
        expected = repr(s)[:13] + "..." + repr(s)[-14:]
 
39
        eq(r(s), expected)
 
40
 
 
41
    def test_tuple(self):
 
42
        eq = self.assertEqual
 
43
        eq(r((1,)), "(1,)")
 
44
 
 
45
        t3 = (1, 2, 3)
 
46
        eq(r(t3), "(1, 2, 3)")
 
47
 
 
48
        r2 = Repr()
 
49
        r2.maxtuple = 2
 
50
        expected = repr(t3)[:-2] + "...)"
 
51
        eq(r2.repr(t3), expected)
 
52
 
 
53
    def test_container(self):
 
54
        from array import array
 
55
        from collections import deque
 
56
 
 
57
        eq = self.assertEqual
 
58
        # Tuples give up after 6 elements
 
59
        eq(r(()), "()")
 
60
        eq(r((1,)), "(1,)")
 
61
        eq(r((1, 2, 3)), "(1, 2, 3)")
 
62
        eq(r((1, 2, 3, 4, 5, 6)), "(1, 2, 3, 4, 5, 6)")
 
63
        eq(r((1, 2, 3, 4, 5, 6, 7)), "(1, 2, 3, 4, 5, 6, ...)")
 
64
 
 
65
        # Lists give up after 6 as well
 
66
        eq(r([]), "[]")
 
67
        eq(r([1]), "[1]")
 
68
        eq(r([1, 2, 3]), "[1, 2, 3]")
 
69
        eq(r([1, 2, 3, 4, 5, 6]), "[1, 2, 3, 4, 5, 6]")
 
70
        eq(r([1, 2, 3, 4, 5, 6, 7]), "[1, 2, 3, 4, 5, 6, ...]")
 
71
 
 
72
        # Sets give up after 6 as well
 
73
        eq(r(set([])), "set([])")
 
74
        eq(r(set([1])), "set([1])")
 
75
        eq(r(set([1, 2, 3])), "set([1, 2, 3])")
 
76
        eq(r(set([1, 2, 3, 4, 5, 6])), "set([1, 2, 3, 4, 5, 6])")
 
77
        eq(r(set([1, 2, 3, 4, 5, 6, 7])), "set([1, 2, 3, 4, 5, 6, ...])")
 
78
 
 
79
        # Frozensets give up after 6 as well
 
80
        eq(r(frozenset([])), "frozenset([])")
 
81
        eq(r(frozenset([1])), "frozenset([1])")
 
82
        eq(r(frozenset([1, 2, 3])), "frozenset([1, 2, 3])")
 
83
        eq(r(frozenset([1, 2, 3, 4, 5, 6])), "frozenset([1, 2, 3, 4, 5, 6])")
 
84
        eq(r(frozenset([1, 2, 3, 4, 5, 6, 7])), "frozenset([1, 2, 3, 4, 5, 6, ...])")
 
85
 
 
86
        # collections.deque after 6
 
87
        eq(r(deque([1, 2, 3, 4, 5, 6, 7])), "deque([1, 2, 3, 4, 5, 6, ...])")
 
88
 
 
89
        # Dictionaries give up after 4.
 
90
        eq(r({}), "{}")
 
91
        d = {'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}
 
92
        eq(r(d), "{'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}")
 
93
        d['arthur'] = 1
 
94
        eq(r(d), "{'alice': 1, 'arthur': 1, 'bob': 2, 'charles': 3, ...}")
 
95
 
 
96
        # array.array after 5.
 
97
        eq(r(array('i')), "array('i', [])")
 
98
        eq(r(array('i', [1])), "array('i', [1])")
 
99
        eq(r(array('i', [1, 2])), "array('i', [1, 2])")
 
100
        eq(r(array('i', [1, 2, 3])), "array('i', [1, 2, 3])")
 
101
        eq(r(array('i', [1, 2, 3, 4])), "array('i', [1, 2, 3, 4])")
 
102
        eq(r(array('i', [1, 2, 3, 4, 5])), "array('i', [1, 2, 3, 4, 5])")
 
103
        eq(r(array('i', [1, 2, 3, 4, 5, 6])),
 
104
                   "array('i', [1, 2, 3, 4, 5, ...])")
 
105
 
 
106
    def test_numbers(self):
 
107
        eq = self.assertEqual
 
108
        eq(r(123), repr(123))
 
109
        eq(r(123), repr(123))
 
110
        eq(r(1.0/3), repr(1.0/3))
 
111
 
 
112
        n = 10**100
 
113
        expected = repr(n)[:18] + "..." + repr(n)[-19:]
 
114
        eq(r(n), expected)
 
115
 
 
116
    def test_instance(self):
 
117
        eq = self.assertEqual
 
118
        i1 = ClassWithRepr("a")
 
119
        eq(r(i1), repr(i1))
 
120
 
 
121
        i2 = ClassWithRepr("x"*1000)
 
122
        expected = repr(i2)[:13] + "..." + repr(i2)[-14:]
 
123
        eq(r(i2), expected)
 
124
 
 
125
        i3 = ClassWithFailingRepr()
 
126
        eq(r(i3), ("<ClassWithFailingRepr instance at %x>"%id(i3)))
 
127
 
 
128
        s = r(ClassWithFailingRepr)
 
129
        self.assertTrue(s.startswith("<class "))
 
130
        self.assertTrue(s.endswith(">"))
 
131
        self.assertIn(s.find("..."), [12, 13])
 
132
 
 
133
    def test_lambda(self):
 
134
        r = repr(lambda x: x)
 
135
        self.assertTrue(r.startswith("<function ReprTests.test_lambda.<locals>.<lambda"), r)
 
136
        # XXX anonymous functions?  see func_repr
 
137
 
 
138
    def test_builtin_function(self):
 
139
        eq = self.assertEqual
 
140
        # Functions
 
141
        eq(repr(hash), '<built-in function hash>')
 
142
        # Methods
 
143
        self.assertTrue(repr(''.split).startswith(
 
144
            '<built-in method split of str object at 0x'))
 
145
 
 
146
    def test_range(self):
 
147
        eq = self.assertEqual
 
148
        eq(repr(range(1)), 'range(0, 1)')
 
149
        eq(repr(range(1, 2)), 'range(1, 2)')
 
150
        eq(repr(range(1, 4, 3)), 'range(1, 4, 3)')
 
151
 
 
152
    def test_nesting(self):
 
153
        eq = self.assertEqual
 
154
        # everything is meant to give up after 6 levels.
 
155
        eq(r([[[[[[[]]]]]]]), "[[[[[[[]]]]]]]")
 
156
        eq(r([[[[[[[[]]]]]]]]), "[[[[[[[...]]]]]]]")
 
157
 
 
158
        eq(r(nestedTuple(6)), "(((((((),),),),),),)")
 
159
        eq(r(nestedTuple(7)), "(((((((...),),),),),),)")
 
160
 
 
161
        eq(r({ nestedTuple(5) : nestedTuple(5) }),
 
162
           "{((((((),),),),),): ((((((),),),),),)}")
 
163
        eq(r({ nestedTuple(6) : nestedTuple(6) }),
 
164
           "{((((((...),),),),),): ((((((...),),),),),)}")
 
165
 
 
166
        eq(r([[[[[[{}]]]]]]), "[[[[[[{}]]]]]]")
 
167
        eq(r([[[[[[[{}]]]]]]]), "[[[[[[[...]]]]]]]")
 
168
 
 
169
    def test_cell(self):
 
170
        # XXX Hmm? How to get at a cell object?
 
171
        pass
 
172
 
 
173
    def test_descriptors(self):
 
174
        eq = self.assertEqual
 
175
        # method descriptors
 
176
        eq(repr(dict.items), "<method 'items' of 'dict' objects>")
 
177
        # XXX member descriptors
 
178
        # XXX attribute descriptors
 
179
        # XXX slot descriptors
 
180
        # static and class methods
 
181
        class C:
 
182
            def foo(cls): pass
 
183
        x = staticmethod(C.foo)
 
184
        self.assertTrue(repr(x).startswith('<staticmethod object at 0x'))
 
185
        x = classmethod(C.foo)
 
186
        self.assertTrue(repr(x).startswith('<classmethod object at 0x'))
 
187
 
 
188
    def test_unsortable(self):
 
189
        # Repr.repr() used to call sorted() on sets, frozensets and dicts
 
190
        # without taking into account that not all objects are comparable
 
191
        x = set([1j, 2j, 3j])
 
192
        y = frozenset(x)
 
193
        z = {1j: 1, 2j: 2}
 
194
        r(x)
 
195
        r(y)
 
196
        r(z)
 
197
 
 
198
def write_file(path, text):
 
199
    with open(path, 'w', encoding='ASCII') as fp:
 
200
        fp.write(text)
 
201
 
 
202
class LongReprTest(unittest.TestCase):
 
203
    longname = 'areallylongpackageandmodulenametotestreprtruncation'
 
204
 
 
205
    def setUp(self):
 
206
        self.pkgname = os.path.join(self.longname)
 
207
        self.subpkgname = os.path.join(self.longname, self.longname)
 
208
        # Make the package and subpackage
 
209
        shutil.rmtree(self.pkgname, ignore_errors=True)
 
210
        os.mkdir(self.pkgname)
 
211
        create_empty_file(os.path.join(self.pkgname, '__init__.py'))
 
212
        shutil.rmtree(self.subpkgname, ignore_errors=True)
 
213
        os.mkdir(self.subpkgname)
 
214
        create_empty_file(os.path.join(self.subpkgname, '__init__.py'))
 
215
        # Remember where we are
 
216
        self.here = os.getcwd()
 
217
        sys.path.insert(0, self.here)
 
218
        # When regrtest is run with its -j option, this command alone is not
 
219
        # enough.
 
220
        importlib.invalidate_caches()
 
221
 
 
222
    def tearDown(self):
 
223
        actions = []
 
224
        for dirpath, dirnames, filenames in os.walk(self.pkgname):
 
225
            for name in dirnames + filenames:
 
226
                actions.append(os.path.join(dirpath, name))
 
227
        actions.append(self.pkgname)
 
228
        actions.sort()
 
229
        actions.reverse()
 
230
        for p in actions:
 
231
            if os.path.isdir(p):
 
232
                os.rmdir(p)
 
233
            else:
 
234
                os.remove(p)
 
235
        del sys.path[0]
 
236
 
 
237
    def _check_path_limitations(self, module_name):
 
238
        # base directory
 
239
        source_path_len = len(self.here)
 
240
        # a path separator + `longname` (twice)
 
241
        source_path_len += 2 * (len(self.longname) + 1)
 
242
        # a path separator + `module_name` + ".py"
 
243
        source_path_len += len(module_name) + 1 + len(".py")
 
244
        cached_path_len = (source_path_len +
 
245
            len(importlib.util.cache_from_source("x.py")) - len("x.py"))
 
246
        if os.name == 'nt' and cached_path_len >= 258:
 
247
            # Under Windows, the max path len is 260 including C's terminating
 
248
            # NUL character.
 
249
            # (see http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx#maxpath)
 
250
            self.skipTest("test paths too long (%d characters) for Windows' 260 character limit"
 
251
                          % cached_path_len)
 
252
        elif os.name == 'nt' and verbose:
 
253
            print("cached_path_len =", cached_path_len)
 
254
 
 
255
    def test_module(self):
 
256
        self.maxDiff = None
 
257
        self._check_path_limitations(self.pkgname)
 
258
        create_empty_file(os.path.join(self.subpkgname, self.pkgname + '.py'))
 
259
        importlib.invalidate_caches()
 
260
        from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
 
261
        module = areallylongpackageandmodulenametotestreprtruncation
 
262
        self.assertEqual(repr(module), "<module %r from %r>" % (module.__name__, module.__file__))
 
263
        self.assertEqual(repr(sys), "<module 'sys' (built-in)>")
 
264
 
 
265
    def test_type(self):
 
266
        self._check_path_limitations('foo')
 
267
        eq = self.assertEqual
 
268
        write_file(os.path.join(self.subpkgname, 'foo.py'), '''\
 
269
class foo(object):
 
270
    pass
 
271
''')
 
272
        importlib.invalidate_caches()
 
273
        from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
 
274
        eq(repr(foo.foo),
 
275
               "<class '%s.foo'>" % foo.__name__)
 
276
 
 
277
    def test_object(self):
 
278
        # XXX Test the repr of a type with a really long tp_name but with no
 
279
        # tp_repr.  WIBNI we had ::Inline? :)
 
280
        pass
 
281
 
 
282
    def test_class(self):
 
283
        self._check_path_limitations('bar')
 
284
        write_file(os.path.join(self.subpkgname, 'bar.py'), '''\
 
285
class bar:
 
286
    pass
 
287
''')
 
288
        importlib.invalidate_caches()
 
289
        from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
 
290
        # Module name may be prefixed with "test.", depending on how run.
 
291
        self.assertEqual(repr(bar.bar), "<class '%s.bar'>" % bar.__name__)
 
292
 
 
293
    def test_instance(self):
 
294
        self._check_path_limitations('baz')
 
295
        write_file(os.path.join(self.subpkgname, 'baz.py'), '''\
 
296
class baz:
 
297
    pass
 
298
''')
 
299
        importlib.invalidate_caches()
 
300
        from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
 
301
        ibaz = baz.baz()
 
302
        self.assertTrue(repr(ibaz).startswith(
 
303
            "<%s.baz object at 0x" % baz.__name__))
 
304
 
 
305
    def test_method(self):
 
306
        self._check_path_limitations('qux')
 
307
        eq = self.assertEqual
 
308
        write_file(os.path.join(self.subpkgname, 'qux.py'), '''\
 
309
class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
 
310
    def amethod(self): pass
 
311
''')
 
312
        importlib.invalidate_caches()
 
313
        from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
 
314
        # Unbound methods first
 
315
        r = repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod)
 
316
        self.assertTrue(r.startswith('<function aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod'), r)
 
317
        # Bound method next
 
318
        iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
 
319
        r = repr(iqux.amethod)
 
320
        self.assertTrue(r.startswith(
 
321
            '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa object at 0x' \
 
322
            % (qux.__name__,) ), r)
 
323
 
 
324
    def test_builtin_function(self):
 
325
        # XXX test built-in functions and methods with really long names
 
326
        pass
 
327
 
 
328
class ClassWithRepr:
 
329
    def __init__(self, s):
 
330
        self.s = s
 
331
    def __repr__(self):
 
332
        return "ClassWithRepr(%r)" % self.s
 
333
 
 
334
 
 
335
class ClassWithFailingRepr:
 
336
    def __repr__(self):
 
337
        raise Exception("This should be caught by Repr.repr_instance")
 
338
 
 
339
class MyContainer:
 
340
    'Helper class for TestRecursiveRepr'
 
341
    def __init__(self, values):
 
342
        self.values = list(values)
 
343
    def append(self, value):
 
344
        self.values.append(value)
 
345
    @recursive_repr()
 
346
    def __repr__(self):
 
347
        return '<' + ', '.join(map(str, self.values)) + '>'
 
348
 
 
349
class MyContainer2(MyContainer):
 
350
    @recursive_repr('+++')
 
351
    def __repr__(self):
 
352
        return '<' + ', '.join(map(str, self.values)) + '>'
 
353
 
 
354
class TestRecursiveRepr(unittest.TestCase):
 
355
    def test_recursive_repr(self):
 
356
        m = MyContainer(list('abcde'))
 
357
        m.append(m)
 
358
        m.append('x')
 
359
        m.append(m)
 
360
        self.assertEqual(repr(m), '<a, b, c, d, e, ..., x, ...>')
 
361
        m = MyContainer2(list('abcde'))
 
362
        m.append(m)
 
363
        m.append('x')
 
364
        m.append(m)
 
365
        self.assertEqual(repr(m), '<a, b, c, d, e, +++, x, +++>')
 
366
 
 
367
def test_main():
 
368
    run_unittest(ReprTests)
 
369
    run_unittest(LongReprTest)
 
370
    run_unittest(TestRecursiveRepr)
 
371
 
 
372
 
 
373
if __name__ == "__main__":
 
374
    test_main()