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

# Python code coverage for Lib/test/test_genexps.py

#countcontent
2n/a
3n/aTest simple loop with conditional
4n/a
5n/a >>> sum(i*i for i in range(100) if i&1 == 1)
6n/a 166650
7n/a
8n/aTest simple nesting
9n/a
10n/a >>> list((i,j) for i in range(3) for j in range(4) )
11n/a [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
12n/a
13n/aTest nesting with the inner expression dependent on the outer
14n/a
15n/a >>> list((i,j) for i in range(4) for j in range(i) )
16n/a [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)]
17n/a
18n/aMake sure the induction variable is not exposed
19n/a
20n/a >>> i = 20
21n/a >>> sum(i*i for i in range(100))
22n/a 328350
23n/a >>> i
24n/a 20
25n/a
26n/aTest first class
27n/a
28n/a >>> g = (i*i for i in range(4))
29n/a >>> type(g)
30n/a <class 'generator'>
31n/a >>> list(g)
32n/a [0, 1, 4, 9]
33n/a
34n/aTest direct calls to next()
35n/a
36n/a >>> g = (i*i for i in range(3))
37n/a >>> next(g)
38n/a 0
39n/a >>> next(g)
40n/a 1
41n/a >>> next(g)
42n/a 4
43n/a >>> next(g)
44n/a Traceback (most recent call last):
45n/a File "<pyshell#21>", line 1, in -toplevel-
46n/a next(g)
47n/a StopIteration
48n/a
50n/a
51n/a >>> next(g)
52n/a Traceback (most recent call last):
53n/a File "<pyshell#21>", line 1, in -toplevel-
54n/a next(g)
55n/a StopIteration
56n/a >>> list(g)
57n/a []
58n/a
59n/aTest running gen when defining function is out of scope
60n/a
61n/a >>> def f(n):
62n/a ... return (i*i for i in range(n))
63n/a >>> list(f(10))
64n/a [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
65n/a
66n/a >>> def f(n):
67n/a ... return ((i,j) for i in range(3) for j in range(n))
68n/a >>> list(f(4))
69n/a [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
70n/a >>> def f(n):
71n/a ... return ((i,j) for i in range(3) for j in range(4) if j in range(n))
72n/a >>> list(f(4))
73n/a [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
74n/a >>> list(f(2))
75n/a [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]
76n/a
77n/aVerify that parenthesis are required in a statement
78n/a
79n/a >>> def f(n):
80n/a ... return i*i for i in range(n)
81n/a Traceback (most recent call last):
82n/a ...
83n/a SyntaxError: invalid syntax
84n/a
85n/aVerify that parenthesis are required when used as a keyword argument value
86n/a
87n/a >>> dict(a = i for i in range(10))
88n/a Traceback (most recent call last):
89n/a ...
90n/a SyntaxError: invalid syntax
91n/a
92n/aVerify that parenthesis are required when used as a keyword argument value
93n/a
94n/a >>> dict(a = (i for i in range(10))) #doctest: +ELLIPSIS
95n/a {'a': <generator object <genexpr> at ...>}
96n/a
97n/aVerify early binding for the outermost for-expression
98n/a
99n/a >>> x=10
100n/a >>> g = (i*i for i in range(x))
101n/a >>> x = 5
102n/a >>> list(g)
103n/a [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
104n/a
105n/aVerify that the outermost for-expression makes an immediate check
106n/afor iterability
107n/a
108n/a >>> (i for i in 6)
109n/a Traceback (most recent call last):
110n/a File "<pyshell#4>", line 1, in -toplevel-
111n/a (i for i in 6)
112n/a TypeError: 'int' object is not iterable
113n/a
114n/aVerify late binding for the outermost if-expression
115n/a
116n/a >>> include = (2,4,6,8)
117n/a >>> g = (i*i for i in range(10) if i in include)
118n/a >>> include = (1,3,5,7,9)
119n/a >>> list(g)
120n/a [1, 9, 25, 49, 81]
121n/a
122n/aVerify late binding for the innermost for-expression
123n/a
124n/a >>> g = ((i,j) for i in range(3) for j in range(x))
125n/a >>> x = 4
126n/a >>> list(g)
127n/a [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
128n/a
129n/aVerify re-use of tuples (a side benefit of using genexps over listcomps)
130n/a
131n/a >>> tupleids = list(map(id, ((i,i) for i in range(10))))
132n/a >>> int(max(tupleids) - min(tupleids))
133n/a 0
134n/a
135n/aVerify that syntax error's are raised for genexps used as lvalues
136n/a
137n/a >>> (y for y in (1,2)) = 10
138n/a Traceback (most recent call last):
139n/a ...
140n/a SyntaxError: can't assign to generator expression
141n/a
142n/a >>> (y for y in (1,2)) += 10
143n/a Traceback (most recent call last):
144n/a ...
145n/a SyntaxError: can't assign to generator expression
146n/a
147n/a
148n/a########### Tests borrowed from or inspired by test_generators.py ############
149n/a
150n/aMake a generator that acts like range()
151n/a
152n/a >>> yrange = lambda n: (i for i in range(n))
153n/a >>> list(yrange(10))
154n/a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
155n/a
157n/a
158n/a >>> def creator():
159n/a ... r = yrange(5)
160n/a ... print("creator", next(r))
161n/a ... return r
162n/a >>> def caller():
163n/a ... r = creator()
164n/a ... for i in r:
165n/a ... print("caller", i)
166n/a >>> caller()
167n/a creator 0
168n/a caller 1
169n/a caller 2
170n/a caller 3
171n/a caller 4
172n/a
173n/aGenerators can call other generators:
174n/a
175n/a >>> def zrange(n):
176n/a ... for i in yrange(n):
177n/a ... yield i
178n/a >>> list(zrange(5))
179n/a [0, 1, 2, 3, 4]
180n/a
181n/a
182n/aVerify that a gen exp cannot be resumed while it is actively running:
183n/a
184n/a >>> g = (next(me) for i in range(10))
185n/a >>> me = g
186n/a >>> next(me)
187n/a Traceback (most recent call last):
188n/a File "<pyshell#30>", line 1, in -toplevel-
189n/a next(me)
190n/a File "<pyshell#28>", line 1, in <generator expression>
191n/a g = (next(me) for i in range(10))
193n/a
194n/aVerify exception propagation
195n/a
196n/a >>> g = (10 // i for i in (5, 0, 2))
197n/a >>> next(g)
198n/a 2
199n/a >>> next(g)
200n/a Traceback (most recent call last):
201n/a File "<pyshell#37>", line 1, in -toplevel-
202n/a next(g)
203n/a File "<pyshell#35>", line 1, in <generator expression>
204n/a g = (10 // i for i in (5, 0, 2))
205n/a ZeroDivisionError: integer division or modulo by zero
206n/a >>> next(g)
207n/a Traceback (most recent call last):
208n/a File "<pyshell#38>", line 1, in -toplevel-
209n/a next(g)
210n/a StopIteration
211n/a
212n/aMake sure that None is a valid return value
213n/a
214n/a >>> list(None for i in range(10))
215n/a [None, None, None, None, None, None, None, None, None, None]
216n/a
217n/aCheck that generator attributes are present
218n/a
219n/a >>> g = (i*i for i in range(3))
220n/a >>> expected = set(['gi_frame', 'gi_running'])
221n/a >>> set(attr for attr in dir(g) if not attr.startswith('__')) >= expected
222n/a True
223n/a
224n/a >>> from test.support import HAVE_DOCSTRINGS
225n/a >>> print(g.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implement next(self).')
226n/a Implement next(self).
227n/a >>> import types
228n/a >>> isinstance(g, types.GeneratorType)
229n/a True
230n/a
231n/aCheck the __iter__ slot is defined to return self
232n/a
233n/a >>> iter(g) is g
234n/a True
235n/a
236n/aVerify that the running flag is set properly
237n/a
238n/a >>> g = (me.gi_running for i in (0,1))
239n/a >>> me = g
240n/a >>> me.gi_running
241n/a 0
242n/a >>> next(me)
243n/a 1
244n/a >>> me.gi_running
245n/a 0
246n/a
247n/aVerify that genexps are weakly referencable
248n/a
249n/a >>> import weakref
250n/a >>> g = (i*i for i in range(4))
251n/a >>> wr = weakref.ref(g)
252n/a >>> wr() is g
253n/a True
254n/a >>> p = weakref.proxy(g)
255n/a >>> list(p)
256n/a [0, 1, 4, 9]
257n/a
258n/a
259n/a"""
260n/a
261n/aimport sys
262n/a
263n/a# Trace function can throw off the tuple reuse test.
264n/aif hasattr(sys, 'gettrace') and sys.gettrace():
265n/a __test__ = {}
266n/aelse:
267n/a __test__ = {'doctests' : doctests}
268n/a
270n/a from test import support
271n/a from test import test_genexps
272n/a support.run_doctest(test_genexps, verbose)
273n/a
274n/a # verify reference counting
275n/a if verbose and hasattr(sys, "gettotalrefcount"):
276n/a import gc
277n/a counts = [None] * 5
278n/a for i in range(len(counts)):
279n/a support.run_doctest(test_genexps, verbose)
280n/a gc.collect()
281n/a counts[i] = sys.gettotalrefcount()
282n/a print(counts)
283n/a
284n/aif __name__ == "__main__":
285n/a test_main(verbose=True)