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

Python code coverage for Lib/test/test_extcall.py

#countcontent
1n/a
2n/a"""Doctest for method/function calls.
3n/a
4n/aWe're going the use these types for extra testing
5n/a
6n/a >>> from collections import UserList
7n/a >>> from collections import UserDict
8n/a
9n/aWe're defining four helper functions
10n/a
11n/a >>> def e(a,b):
12n/a ... print(a, b)
13n/a
14n/a >>> def f(*a, **k):
15n/a ... print(a, support.sortdict(k))
16n/a
17n/a >>> def g(x, *y, **z):
18n/a ... print(x, y, support.sortdict(z))
19n/a
20n/a >>> def h(j=1, a=2, h=3):
21n/a ... print(j, a, h)
22n/a
23n/aArgument list examples
24n/a
25n/a >>> f()
26n/a () {}
27n/a >>> f(1)
28n/a (1,) {}
29n/a >>> f(1, 2)
30n/a (1, 2) {}
31n/a >>> f(1, 2, 3)
32n/a (1, 2, 3) {}
33n/a >>> f(1, 2, 3, *(4, 5))
34n/a (1, 2, 3, 4, 5) {}
35n/a >>> f(1, 2, 3, *[4, 5])
36n/a (1, 2, 3, 4, 5) {}
37n/a >>> f(*[1, 2, 3], 4, 5)
38n/a (1, 2, 3, 4, 5) {}
39n/a >>> f(1, 2, 3, *UserList([4, 5]))
40n/a (1, 2, 3, 4, 5) {}
41n/a >>> f(1, 2, 3, *[4, 5], *[6, 7])
42n/a (1, 2, 3, 4, 5, 6, 7) {}
43n/a >>> f(1, *[2, 3], 4, *[5, 6], 7)
44n/a (1, 2, 3, 4, 5, 6, 7) {}
45n/a >>> f(*UserList([1, 2]), *UserList([3, 4]), 5, *UserList([6, 7]))
46n/a (1, 2, 3, 4, 5, 6, 7) {}
47n/a
48n/aHere we add keyword arguments
49n/a
50n/a >>> f(1, 2, 3, **{'a':4, 'b':5})
51n/a (1, 2, 3) {'a': 4, 'b': 5}
52n/a >>> f(1, 2, **{'a': -1, 'b': 5}, **{'a': 4, 'c': 6})
53n/a Traceback (most recent call last):
54n/a ...
55n/a TypeError: f() got multiple values for keyword argument 'a'
56n/a >>> f(1, 2, **{'a': -1, 'b': 5}, a=4, c=6)
57n/a Traceback (most recent call last):
58n/a ...
59n/a TypeError: f() got multiple values for keyword argument 'a'
60n/a >>> f(1, 2, a=3, **{'a': 4}, **{'a': 5})
61n/a Traceback (most recent call last):
62n/a ...
63n/a TypeError: f() got multiple values for keyword argument 'a'
64n/a >>> f(1, 2, 3, *[4, 5], **{'a':6, 'b':7})
65n/a (1, 2, 3, 4, 5) {'a': 6, 'b': 7}
66n/a >>> f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b': 9})
67n/a (1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5}
68n/a >>> f(1, 2, 3, *[4, 5], **{'c': 8}, **{'a':6, 'b':7})
69n/a (1, 2, 3, 4, 5) {'a': 6, 'b': 7, 'c': 8}
70n/a >>> f(1, 2, 3, *(4, 5), x=6, y=7, **{'a':8, 'b': 9})
71n/a (1, 2, 3, 4, 5) {'a': 8, 'b': 9, 'x': 6, 'y': 7}
72n/a
73n/a >>> f(1, 2, 3, **UserDict(a=4, b=5))
74n/a (1, 2, 3) {'a': 4, 'b': 5}
75n/a >>> f(1, 2, 3, *(4, 5), **UserDict(a=6, b=7))
76n/a (1, 2, 3, 4, 5) {'a': 6, 'b': 7}
77n/a >>> f(1, 2, 3, x=4, y=5, *(6, 7), **UserDict(a=8, b=9))
78n/a (1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5}
79n/a >>> f(1, 2, 3, *(4, 5), x=6, y=7, **UserDict(a=8, b=9))
80n/a (1, 2, 3, 4, 5) {'a': 8, 'b': 9, 'x': 6, 'y': 7}
81n/a
82n/aExamples with invalid arguments (TypeErrors). We're also testing the function
83n/anames in the exception messages.
84n/a
85n/aVerify clearing of SF bug #733667
86n/a
87n/a >>> e(c=4)
88n/a Traceback (most recent call last):
89n/a ...
90n/a TypeError: e() got an unexpected keyword argument 'c'
91n/a
92n/a >>> g()
93n/a Traceback (most recent call last):
94n/a ...
95n/a TypeError: g() missing 1 required positional argument: 'x'
96n/a
97n/a >>> g(*())
98n/a Traceback (most recent call last):
99n/a ...
100n/a TypeError: g() missing 1 required positional argument: 'x'
101n/a
102n/a >>> g(*(), **{})
103n/a Traceback (most recent call last):
104n/a ...
105n/a TypeError: g() missing 1 required positional argument: 'x'
106n/a
107n/a >>> g(1)
108n/a 1 () {}
109n/a >>> g(1, 2)
110n/a 1 (2,) {}
111n/a >>> g(1, 2, 3)
112n/a 1 (2, 3) {}
113n/a >>> g(1, 2, 3, *(4, 5))
114n/a 1 (2, 3, 4, 5) {}
115n/a
116n/a >>> class Nothing: pass
117n/a ...
118n/a >>> g(*Nothing())
119n/a Traceback (most recent call last):
120n/a ...
121n/a TypeError: g() argument after * must be an iterable, not Nothing
122n/a
123n/a >>> class Nothing:
124n/a ... def __len__(self): return 5
125n/a ...
126n/a
127n/a >>> g(*Nothing())
128n/a Traceback (most recent call last):
129n/a ...
130n/a TypeError: g() argument after * must be an iterable, not Nothing
131n/a
132n/a >>> class Nothing():
133n/a ... def __len__(self): return 5
134n/a ... def __getitem__(self, i):
135n/a ... if i<3: return i
136n/a ... else: raise IndexError(i)
137n/a ...
138n/a
139n/a >>> g(*Nothing())
140n/a 0 (1, 2) {}
141n/a
142n/a >>> class Nothing:
143n/a ... def __init__(self): self.c = 0
144n/a ... def __iter__(self): return self
145n/a ... def __next__(self):
146n/a ... if self.c == 4:
147n/a ... raise StopIteration
148n/a ... c = self.c
149n/a ... self.c += 1
150n/a ... return c
151n/a ...
152n/a
153n/a >>> g(*Nothing())
154n/a 0 (1, 2, 3) {}
155n/a
156n/aCheck for issue #4806: Does a TypeError in a generator get propagated with the
157n/aright error message? (Also check with other iterables.)
158n/a
159n/a >>> def broken(): raise TypeError("myerror")
160n/a ...
161n/a
162n/a >>> g(*(broken() for i in range(1)))
163n/a Traceback (most recent call last):
164n/a ...
165n/a TypeError: myerror
166n/a
167n/a >>> class BrokenIterable1:
168n/a ... def __iter__(self):
169n/a ... raise TypeError('myerror')
170n/a ...
171n/a >>> g(*BrokenIterable1())
172n/a Traceback (most recent call last):
173n/a ...
174n/a TypeError: myerror
175n/a
176n/a >>> class BrokenIterable2:
177n/a ... def __iter__(self):
178n/a ... yield 0
179n/a ... raise TypeError('myerror')
180n/a ...
181n/a >>> g(*BrokenIterable2())
182n/a Traceback (most recent call last):
183n/a ...
184n/a TypeError: myerror
185n/a
186n/a >>> class BrokenSequence:
187n/a ... def __getitem__(self, idx):
188n/a ... raise TypeError('myerror')
189n/a ...
190n/a >>> g(*BrokenSequence())
191n/a Traceback (most recent call last):
192n/a ...
193n/a TypeError: myerror
194n/a
195n/aMake sure that the function doesn't stomp the dictionary
196n/a
197n/a >>> d = {'a': 1, 'b': 2, 'c': 3}
198n/a >>> d2 = d.copy()
199n/a >>> g(1, d=4, **d)
200n/a 1 () {'a': 1, 'b': 2, 'c': 3, 'd': 4}
201n/a >>> d == d2
202n/a True
203n/a
204n/aWhat about willful misconduct?
205n/a
206n/a >>> def saboteur(**kw):
207n/a ... kw['x'] = 'm'
208n/a ... return kw
209n/a
210n/a >>> d = {}
211n/a >>> kw = saboteur(a=1, **d)
212n/a >>> d
213n/a {}
214n/a
215n/a
216n/a >>> g(1, 2, 3, **{'x': 4, 'y': 5})
217n/a Traceback (most recent call last):
218n/a ...
219n/a TypeError: g() got multiple values for argument 'x'
220n/a
221n/a >>> f(**{1:2})
222n/a Traceback (most recent call last):
223n/a ...
224n/a TypeError: f() keywords must be strings
225n/a
226n/a >>> h(**{'e': 2})
227n/a Traceback (most recent call last):
228n/a ...
229n/a TypeError: h() got an unexpected keyword argument 'e'
230n/a
231n/a >>> h(*h)
232n/a Traceback (most recent call last):
233n/a ...
234n/a TypeError: h() argument after * must be an iterable, not function
235n/a
236n/a >>> h(1, *h)
237n/a Traceback (most recent call last):
238n/a ...
239n/a TypeError: h() argument after * must be an iterable, not function
240n/a
241n/a >>> h(*[1], *h)
242n/a Traceback (most recent call last):
243n/a ...
244n/a TypeError: h() argument after * must be an iterable, not function
245n/a
246n/a >>> dir(*h)
247n/a Traceback (most recent call last):
248n/a ...
249n/a TypeError: dir() argument after * must be an iterable, not function
250n/a
251n/a >>> None(*h)
252n/a Traceback (most recent call last):
253n/a ...
254n/a TypeError: NoneType object argument after * must be an iterable, \
255n/anot function
256n/a
257n/a >>> h(**h)
258n/a Traceback (most recent call last):
259n/a ...
260n/a TypeError: h() argument after ** must be a mapping, not function
261n/a
262n/a >>> h(**[])
263n/a Traceback (most recent call last):
264n/a ...
265n/a TypeError: h() argument after ** must be a mapping, not list
266n/a
267n/a >>> h(a=1, **h)
268n/a Traceback (most recent call last):
269n/a ...
270n/a TypeError: h() argument after ** must be a mapping, not function
271n/a
272n/a >>> h(a=1, **[])
273n/a Traceback (most recent call last):
274n/a ...
275n/a TypeError: h() argument after ** must be a mapping, not list
276n/a
277n/a >>> h(**{'a': 1}, **h)
278n/a Traceback (most recent call last):
279n/a ...
280n/a TypeError: h() argument after ** must be a mapping, not function
281n/a
282n/a >>> h(**{'a': 1}, **[])
283n/a Traceback (most recent call last):
284n/a ...
285n/a TypeError: h() argument after ** must be a mapping, not list
286n/a
287n/a >>> dir(**h)
288n/a Traceback (most recent call last):
289n/a ...
290n/a TypeError: dir() argument after ** must be a mapping, not function
291n/a
292n/a >>> None(**h)
293n/a Traceback (most recent call last):
294n/a ...
295n/a TypeError: NoneType object argument after ** must be a mapping, \
296n/anot function
297n/a
298n/a >>> dir(b=1, **{'b': 1})
299n/a Traceback (most recent call last):
300n/a ...
301n/a TypeError: dir() got multiple values for keyword argument 'b'
302n/a
303n/aAnother helper function
304n/a
305n/a >>> def f2(*a, **b):
306n/a ... return a, b
307n/a
308n/a
309n/a >>> d = {}
310n/a >>> for i in range(512):
311n/a ... key = 'k%d' % i
312n/a ... d[key] = i
313n/a >>> a, b = f2(1, *(2,3), **d)
314n/a >>> len(a), len(b), b == d
315n/a (3, 512, True)
316n/a
317n/a >>> class Foo:
318n/a ... def method(self, arg1, arg2):
319n/a ... return arg1+arg2
320n/a
321n/a >>> x = Foo()
322n/a >>> Foo.method(*(x, 1, 2))
323n/a 3
324n/a >>> Foo.method(x, *(1, 2))
325n/a 3
326n/a >>> Foo.method(*(1, 2, 3))
327n/a 5
328n/a >>> Foo.method(1, *[2, 3])
329n/a 5
330n/a
331n/aA PyCFunction that takes only positional parameters should allow an
332n/aempty keyword dictionary to pass without a complaint, but raise a
333n/aTypeError if te dictionary is not empty
334n/a
335n/a >>> try:
336n/a ... silence = id(1, *{})
337n/a ... True
338n/a ... except:
339n/a ... False
340n/a True
341n/a
342n/a >>> id(1, **{'foo': 1})
343n/a Traceback (most recent call last):
344n/a ...
345n/a TypeError: id() takes no keyword arguments
346n/a
347n/aA corner case of keyword dictionary items being deleted during
348n/athe function call setup. See <http://bugs.python.org/issue2016>.
349n/a
350n/a >>> class Name(str):
351n/a ... def __eq__(self, other):
352n/a ... try:
353n/a ... del x[self]
354n/a ... except KeyError:
355n/a ... pass
356n/a ... return str.__eq__(self, other)
357n/a ... def __hash__(self):
358n/a ... return str.__hash__(self)
359n/a
360n/a >>> x = {Name("a"):1, Name("b"):2}
361n/a >>> def f(a, b):
362n/a ... print(a,b)
363n/a >>> f(**x)
364n/a 1 2
365n/a
366n/aToo many arguments:
367n/a
368n/a >>> def f(): pass
369n/a >>> f(1)
370n/a Traceback (most recent call last):
371n/a ...
372n/a TypeError: f() takes 0 positional arguments but 1 was given
373n/a >>> def f(a): pass
374n/a >>> f(1, 2)
375n/a Traceback (most recent call last):
376n/a ...
377n/a TypeError: f() takes 1 positional argument but 2 were given
378n/a >>> def f(a, b=1): pass
379n/a >>> f(1, 2, 3)
380n/a Traceback (most recent call last):
381n/a ...
382n/a TypeError: f() takes from 1 to 2 positional arguments but 3 were given
383n/a >>> def f(*, kw): pass
384n/a >>> f(1, kw=3)
385n/a Traceback (most recent call last):
386n/a ...
387n/a TypeError: f() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given
388n/a >>> def f(*, kw, b): pass
389n/a >>> f(1, 2, 3, b=3, kw=3)
390n/a Traceback (most recent call last):
391n/a ...
392n/a TypeError: f() takes 0 positional arguments but 3 positional arguments (and 2 keyword-only arguments) were given
393n/a >>> def f(a, b=2, *, kw): pass
394n/a >>> f(2, 3, 4, kw=4)
395n/a Traceback (most recent call last):
396n/a ...
397n/a TypeError: f() takes from 1 to 2 positional arguments but 3 positional arguments (and 1 keyword-only argument) were given
398n/a
399n/aToo few and missing arguments:
400n/a
401n/a >>> def f(a): pass
402n/a >>> f()
403n/a Traceback (most recent call last):
404n/a ...
405n/a TypeError: f() missing 1 required positional argument: 'a'
406n/a >>> def f(a, b): pass
407n/a >>> f()
408n/a Traceback (most recent call last):
409n/a ...
410n/a TypeError: f() missing 2 required positional arguments: 'a' and 'b'
411n/a >>> def f(a, b, c): pass
412n/a >>> f()
413n/a Traceback (most recent call last):
414n/a ...
415n/a TypeError: f() missing 3 required positional arguments: 'a', 'b', and 'c'
416n/a >>> def f(a, b, c, d, e): pass
417n/a >>> f()
418n/a Traceback (most recent call last):
419n/a ...
420n/a TypeError: f() missing 5 required positional arguments: 'a', 'b', 'c', 'd', and 'e'
421n/a >>> def f(a, b=4, c=5, d=5): pass
422n/a >>> f(c=12, b=9)
423n/a Traceback (most recent call last):
424n/a ...
425n/a TypeError: f() missing 1 required positional argument: 'a'
426n/a
427n/aSame with keyword only args:
428n/a
429n/a >>> def f(*, w): pass
430n/a >>> f()
431n/a Traceback (most recent call last):
432n/a ...
433n/a TypeError: f() missing 1 required keyword-only argument: 'w'
434n/a >>> def f(*, a, b, c, d, e): pass
435n/a >>> f()
436n/a Traceback (most recent call last):
437n/a ...
438n/a TypeError: f() missing 5 required keyword-only arguments: 'a', 'b', 'c', 'd', and 'e'
439n/a
440n/a"""
441n/a
442n/aimport sys
443n/afrom test import support
444n/a
445n/adef test_main():
446n/a support.run_doctest(sys.modules[__name__], True)
447n/a
448n/aif __name__ == '__main__':
449n/a test_main()