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

Python code coverage for Lib/test/test_unpack_ex.py

#countcontent
1n/a# Tests for extended unpacking, starred expressions.
2n/a
3n/adoctests = """
4n/a
5n/aUnpack tuple
6n/a
7n/a >>> t = (1, 2, 3)
8n/a >>> a, *b, c = t
9n/a >>> a == 1 and b == [2] and c == 3
10n/a True
11n/a
12n/aUnpack list
13n/a
14n/a >>> l = [4, 5, 6]
15n/a >>> a, *b = l
16n/a >>> a == 4 and b == [5, 6]
17n/a True
18n/a
19n/aUnpack implied tuple
20n/a
21n/a >>> *a, = 7, 8, 9
22n/a >>> a == [7, 8, 9]
23n/a True
24n/a
25n/aUnpack string... fun!
26n/a
27n/a >>> a, *b = 'one'
28n/a >>> a == 'o' and b == ['n', 'e']
29n/a True
30n/a
31n/aUnpack long sequence
32n/a
33n/a >>> a, b, c, *d, e, f, g = range(10)
34n/a >>> (a, b, c, d, e, f, g) == (0, 1, 2, [3, 4, 5, 6], 7, 8, 9)
35n/a True
36n/a
37n/aUnpack short sequence
38n/a
39n/a >>> a, *b, c = (1, 2)
40n/a >>> a == 1 and c == 2 and b == []
41n/a True
42n/a
43n/aUnpack generic sequence
44n/a
45n/a >>> class Seq:
46n/a ... def __getitem__(self, i):
47n/a ... if i >= 0 and i < 3: return i
48n/a ... raise IndexError
49n/a ...
50n/a >>> a, *b = Seq()
51n/a >>> a == 0 and b == [1, 2]
52n/a True
53n/a
54n/aUnpack in for statement
55n/a
56n/a >>> for a, *b, c in [(1,2,3), (4,5,6,7)]:
57n/a ... print(a, b, c)
58n/a ...
59n/a 1 [2] 3
60n/a 4 [5, 6] 7
61n/a
62n/aUnpack in list
63n/a
64n/a >>> [a, *b, c] = range(5)
65n/a >>> a == 0 and b == [1, 2, 3] and c == 4
66n/a True
67n/a
68n/aMultiple targets
69n/a
70n/a >>> a, *b, c = *d, e = range(5)
71n/a >>> a == 0 and b == [1, 2, 3] and c == 4 and d == [0, 1, 2, 3] and e == 4
72n/a True
73n/a
74n/aAssignment unpacking
75n/a
76n/a >>> a, b, *c = range(5)
77n/a >>> a, b, c
78n/a (0, 1, [2, 3, 4])
79n/a >>> *a, b, c = a, b, *c
80n/a >>> a, b, c
81n/a ([0, 1, 2], 3, 4)
82n/a
83n/aSet display element unpacking
84n/a
85n/a >>> a = [1, 2, 3]
86n/a >>> sorted({1, *a, 0, 4})
87n/a [0, 1, 2, 3, 4]
88n/a
89n/a >>> {1, *1, 0, 4}
90n/a Traceback (most recent call last):
91n/a ...
92n/a TypeError: 'int' object is not iterable
93n/a
94n/aDict display element unpacking
95n/a
96n/a >>> kwds = {'z': 0, 'w': 12}
97n/a >>> sorted({'x': 1, 'y': 2, **kwds}.items())
98n/a [('w', 12), ('x', 1), ('y', 2), ('z', 0)]
99n/a
100n/a >>> sorted({**{'x': 1}, 'y': 2, **{'z': 3}}.items())
101n/a [('x', 1), ('y', 2), ('z', 3)]
102n/a
103n/a >>> sorted({**{'x': 1}, 'y': 2, **{'x': 3}}.items())
104n/a [('x', 3), ('y', 2)]
105n/a
106n/a >>> sorted({**{'x': 1}, **{'x': 3}, 'x': 4}.items())
107n/a [('x', 4)]
108n/a
109n/a >>> {**{}}
110n/a {}
111n/a
112n/a >>> a = {}
113n/a >>> {**a}[0] = 1
114n/a >>> a
115n/a {}
116n/a
117n/a >>> {**1}
118n/a Traceback (most recent call last):
119n/a ...
120n/a TypeError: 'int' object is not a mapping
121n/a
122n/a >>> {**[]}
123n/a Traceback (most recent call last):
124n/a ...
125n/a TypeError: 'list' object is not a mapping
126n/a
127n/a >>> len(eval("{" + ", ".join("**{{{}: {}}}".format(i, i)
128n/a ... for i in range(1000)) + "}"))
129n/a 1000
130n/a
131n/a >>> {0:1, **{0:2}, 0:3, 0:4}
132n/a {0: 4}
133n/a
134n/aList comprehension element unpacking
135n/a
136n/a >>> a, b, c = [0, 1, 2], 3, 4
137n/a >>> [*a, b, c]
138n/a [0, 1, 2, 3, 4]
139n/a
140n/a >>> l = [a, (3, 4), {5}, {6: None}, (i for i in range(7, 10))]
141n/a >>> [*item for item in l]
142n/a Traceback (most recent call last):
143n/a ...
144n/a SyntaxError: iterable unpacking cannot be used in comprehension
145n/a
146n/a >>> [*[0, 1] for i in range(10)]
147n/a Traceback (most recent call last):
148n/a ...
149n/a SyntaxError: iterable unpacking cannot be used in comprehension
150n/a
151n/a >>> [*'a' for i in range(10)]
152n/a Traceback (most recent call last):
153n/a ...
154n/a SyntaxError: iterable unpacking cannot be used in comprehension
155n/a
156n/a >>> [*[] for i in range(10)]
157n/a Traceback (most recent call last):
158n/a ...
159n/a SyntaxError: iterable unpacking cannot be used in comprehension
160n/a
161n/aGenerator expression in function arguments
162n/a
163n/a >>> list(*x for x in (range(5) for i in range(3)))
164n/a Traceback (most recent call last):
165n/a ...
166n/a list(*x for x in (range(5) for i in range(3)))
167n/a ^
168n/a SyntaxError: invalid syntax
169n/a
170n/a >>> dict(**x for x in [{1:2}])
171n/a Traceback (most recent call last):
172n/a ...
173n/a dict(**x for x in [{1:2}])
174n/a ^
175n/a SyntaxError: invalid syntax
176n/a
177n/aIterable argument unpacking
178n/a
179n/a >>> print(*[1], *[2], 3)
180n/a 1 2 3
181n/a
182n/aMake sure that they don't corrupt the passed-in dicts.
183n/a
184n/a >>> def f(x, y):
185n/a ... print(x, y)
186n/a ...
187n/a >>> original_dict = {'x': 1}
188n/a >>> f(**original_dict, y=2)
189n/a 1 2
190n/a >>> original_dict
191n/a {'x': 1}
192n/a
193n/aNow for some failures
194n/a
195n/aMake sure the raised errors are right for keyword argument unpackings
196n/a
197n/a >>> from collections.abc import MutableMapping
198n/a >>> class CrazyDict(MutableMapping):
199n/a ... def __init__(self):
200n/a ... self.d = {}
201n/a ...
202n/a ... def __iter__(self):
203n/a ... for x in self.d.__iter__():
204n/a ... if x == 'c':
205n/a ... self.d['z'] = 10
206n/a ... yield x
207n/a ...
208n/a ... def __getitem__(self, k):
209n/a ... return self.d[k]
210n/a ...
211n/a ... def __len__(self):
212n/a ... return len(self.d)
213n/a ...
214n/a ... def __setitem__(self, k, v):
215n/a ... self.d[k] = v
216n/a ...
217n/a ... def __delitem__(self, k):
218n/a ... del self.d[k]
219n/a ...
220n/a >>> d = CrazyDict()
221n/a >>> d.d = {chr(ord('a') + x): x for x in range(5)}
222n/a >>> e = {**d}
223n/a Traceback (most recent call last):
224n/a ...
225n/a RuntimeError: dictionary changed size during iteration
226n/a
227n/a >>> d.d = {chr(ord('a') + x): x for x in range(5)}
228n/a >>> def f(**kwargs): print(kwargs)
229n/a >>> f(**d)
230n/a Traceback (most recent call last):
231n/a ...
232n/a RuntimeError: dictionary changed size during iteration
233n/a
234n/aOverridden parameters
235n/a
236n/a >>> f(x=5, **{'x': 3}, y=2)
237n/a Traceback (most recent call last):
238n/a ...
239n/a TypeError: f() got multiple values for keyword argument 'x'
240n/a
241n/a >>> f(**{'x': 3}, x=5, y=2)
242n/a Traceback (most recent call last):
243n/a ...
244n/a TypeError: f() got multiple values for keyword argument 'x'
245n/a
246n/a >>> f(**{'x': 3}, **{'x': 5}, y=2)
247n/a Traceback (most recent call last):
248n/a ...
249n/a TypeError: f() got multiple values for keyword argument 'x'
250n/a
251n/a >>> f(x=5, **{'x': 3}, **{'x': 2})
252n/a Traceback (most recent call last):
253n/a ...
254n/a TypeError: f() got multiple values for keyword argument 'x'
255n/a
256n/a >>> f(**{1: 3}, **{1: 5})
257n/a Traceback (most recent call last):
258n/a ...
259n/a TypeError: f() keywords must be strings
260n/a
261n/aUnpacking non-sequence
262n/a
263n/a >>> a, *b = 7
264n/a Traceback (most recent call last):
265n/a ...
266n/a TypeError: 'int' object is not iterable
267n/a
268n/aUnpacking sequence too short
269n/a
270n/a >>> a, *b, c, d, e = Seq()
271n/a Traceback (most recent call last):
272n/a ...
273n/a ValueError: not enough values to unpack (expected at least 4, got 3)
274n/a
275n/aUnpacking sequence too short and target appears last
276n/a
277n/a >>> a, b, c, d, *e = Seq()
278n/a Traceback (most recent call last):
279n/a ...
280n/a ValueError: not enough values to unpack (expected at least 4, got 3)
281n/a
282n/aUnpacking a sequence where the test for too long raises a different kind of
283n/aerror
284n/a
285n/a >>> class BozoError(Exception):
286n/a ... pass
287n/a ...
288n/a >>> class BadSeq:
289n/a ... def __getitem__(self, i):
290n/a ... if i >= 0 and i < 3:
291n/a ... return i
292n/a ... elif i == 3:
293n/a ... raise BozoError
294n/a ... else:
295n/a ... raise IndexError
296n/a ...
297n/a
298n/aTrigger code while not expecting an IndexError (unpack sequence too long, wrong
299n/aerror)
300n/a
301n/a >>> a, *b, c, d, e = BadSeq()
302n/a Traceback (most recent call last):
303n/a ...
304n/a test.test_unpack_ex.BozoError
305n/a
306n/aNow some general starred expressions (all fail).
307n/a
308n/a >>> a, *b, c, *d, e = range(10) # doctest:+ELLIPSIS
309n/a Traceback (most recent call last):
310n/a ...
311n/a SyntaxError: two starred expressions in assignment
312n/a
313n/a >>> [*b, *c] = range(10) # doctest:+ELLIPSIS
314n/a Traceback (most recent call last):
315n/a ...
316n/a SyntaxError: two starred expressions in assignment
317n/a
318n/a >>> *a = range(10) # doctest:+ELLIPSIS
319n/a Traceback (most recent call last):
320n/a ...
321n/a SyntaxError: starred assignment target must be in a list or tuple
322n/a
323n/a >>> *a # doctest:+ELLIPSIS
324n/a Traceback (most recent call last):
325n/a ...
326n/a SyntaxError: can't use starred expression here
327n/a
328n/a >>> *1 # doctest:+ELLIPSIS
329n/a Traceback (most recent call last):
330n/a ...
331n/a SyntaxError: can't use starred expression here
332n/a
333n/a >>> x = *a # doctest:+ELLIPSIS
334n/a Traceback (most recent call last):
335n/a ...
336n/a SyntaxError: can't use starred expression here
337n/a
338n/aSome size constraints (all fail.)
339n/a
340n/a >>> s = ", ".join("a%d" % i for i in range(1<<8)) + ", *rest = range(1<<8 + 1)"
341n/a >>> compile(s, 'test', 'exec') # doctest:+ELLIPSIS
342n/a Traceback (most recent call last):
343n/a ...
344n/a SyntaxError: too many expressions in star-unpacking assignment
345n/a
346n/a >>> s = ", ".join("a%d" % i for i in range(1<<8 + 1)) + ", *rest = range(1<<8 + 2)"
347n/a >>> compile(s, 'test', 'exec') # doctest:+ELLIPSIS
348n/a Traceback (most recent call last):
349n/a ...
350n/a SyntaxError: too many expressions in star-unpacking assignment
351n/a
352n/a(there is an additional limit, on the number of expressions after the
353n/a'*rest', but it's 1<<24 and testing it takes too much memory.)
354n/a
355n/a"""
356n/a
357n/a__test__ = {'doctests' : doctests}
358n/a
359n/adef test_main(verbose=False):
360n/a from test import support
361n/a from test import test_unpack_ex
362n/a support.run_doctest(test_unpack_ex, verbose)
363n/a
364n/aif __name__ == "__main__":
365n/a test_main(verbose=True)