ยปCore Development>Code coverage>Lib/test/test_reprlib.py

Python code coverage for Lib/test/test_reprlib.py

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