/home/mdboom/Work/builds/cpython/Python/getargs.c
Line | Count | Source (jump to first uncovered line) |
1 | |
2 | /* New getargs implementation */ |
3 | |
4 | #include "Python.h" |
5 | #include "pycore_tuple.h" // _PyTuple_ITEMS() |
6 | #include "pycore_pylifecycle.h" // _PyArg_Fini |
7 | |
8 | #include <ctype.h> |
9 | #include <float.h> |
10 | |
11 | |
12 | #ifdef __cplusplus |
13 | extern "C" { |
14 | #endif |
15 | int PyArg_Parse(PyObject *, const char *, ...); |
16 | int PyArg_ParseTuple(PyObject *, const char *, ...); |
17 | int PyArg_VaParse(PyObject *, const char *, va_list); |
18 | |
19 | int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, |
20 | const char *, char **, ...); |
21 | int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, |
22 | const char *, char **, va_list); |
23 | |
24 | int _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, |
25 | struct _PyArg_Parser *, ...); |
26 | int _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, |
27 | struct _PyArg_Parser *, va_list); |
28 | |
29 | #ifdef HAVE_DECLSPEC_DLL |
30 | /* Export functions */ |
31 | PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...); |
32 | PyAPI_FUNC(int) _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, |
33 | const char *format, ...); |
34 | PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, |
35 | PyObject *kwnames, |
36 | struct _PyArg_Parser *parser, ...); |
37 | PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...); |
38 | PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *, |
39 | const char *, char **, ...); |
40 | PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); |
41 | PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const char *, va_list); |
42 | PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *, |
43 | const char *, char **, va_list); |
44 | |
45 | PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *, |
46 | struct _PyArg_Parser *, ...); |
47 | PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *, |
48 | struct _PyArg_Parser *, va_list); |
49 | #endif |
50 | |
51 | #define FLAG_COMPAT 1 |
52 | #define FLAG_SIZE_T 2 |
53 | |
54 | typedef int (*destr_t)(PyObject *, void *); |
55 | |
56 | |
57 | /* Keep track of "objects" that have been allocated or initialized and |
58 | which will need to be deallocated or cleaned up somehow if overall |
59 | parsing fails. |
60 | */ |
61 | typedef struct { |
62 | void *item; |
63 | destr_t destructor; |
64 | } freelistentry_t; |
65 | |
66 | typedef struct { |
67 | freelistentry_t *entries; |
68 | int first_available; |
69 | int entries_malloced; |
70 | } freelist_t; |
71 | |
72 | #define STATIC_FREELIST_ENTRIES 8 |
73 | |
74 | /* Forward */ |
75 | static int vgetargs1_impl(PyObject *args, PyObject *const *stack, Py_ssize_t nargs, |
76 | const char *format, va_list *p_va, int flags); |
77 | static int vgetargs1(PyObject *, const char *, va_list *, int); |
78 | static void seterror(Py_ssize_t, const char *, int *, const char *, const char *); |
79 | static const char *convertitem(PyObject *, const char **, va_list *, int, int *, |
80 | char *, size_t, freelist_t *); |
81 | static const char *converttuple(PyObject *, const char **, va_list *, int, |
82 | int *, char *, size_t, int, freelist_t *); |
83 | static const char *convertsimple(PyObject *, const char **, va_list *, int, |
84 | char *, size_t, freelist_t *); |
85 | static Py_ssize_t convertbuffer(PyObject *, const void **p, const char **); |
86 | static int getbuffer(PyObject *, Py_buffer *, const char**); |
87 | |
88 | static int vgetargskeywords(PyObject *, PyObject *, |
89 | const char *, char **, va_list *, int); |
90 | static int vgetargskeywordsfast(PyObject *, PyObject *, |
91 | struct _PyArg_Parser *, va_list *, int); |
92 | static int vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, |
93 | PyObject *keywords, PyObject *kwnames, |
94 | struct _PyArg_Parser *parser, |
95 | va_list *p_va, int flags); |
96 | static const char *skipitem(const char **, va_list *, int); |
97 | |
98 | int |
99 | PyArg_Parse(PyObject *args, const char *format, ...) |
100 | { |
101 | int retval; |
102 | va_list va; |
103 |
|
104 | va_start(va, format); |
105 | retval = vgetargs1(args, format, &va, FLAG_COMPAT); |
106 | va_end(va); |
107 | return retval; |
108 | } |
109 | |
110 | PyAPI_FUNC(int) |
111 | _PyArg_Parse_SizeT(PyObject *args, const char *format, ...) |
112 | { |
113 | int retval; |
114 | va_list va; |
115 | |
116 | va_start(va, format); |
117 | retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T); |
118 | va_end(va); |
119 | return retval; |
120 | } |
121 | |
122 | |
123 | int |
124 | PyArg_ParseTuple(PyObject *args, const char *format, ...) |
125 | { |
126 | int retval; |
127 | va_list va; |
128 | |
129 | va_start(va, format); |
130 | retval = vgetargs1(args, format, &va, 0); |
131 | va_end(va); |
132 | return retval; |
133 | } |
134 | |
135 | PyAPI_FUNC(int) |
136 | _PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...) |
137 | { |
138 | int retval; |
139 | va_list va; |
140 | |
141 | va_start(va, format); |
142 | retval = vgetargs1(args, format, &va, FLAG_SIZE_T); |
143 | va_end(va); |
144 | return retval; |
145 | } |
146 | |
147 | |
148 | int |
149 | _PyArg_ParseStack(PyObject *const *args, Py_ssize_t nargs, const char *format, ...) |
150 | { |
151 | int retval; |
152 | va_list va; |
153 | |
154 | va_start(va, format); |
155 | retval = vgetargs1_impl(NULL, args, nargs, format, &va, 0); |
156 | va_end(va); |
157 | return retval; |
158 | } |
159 | |
160 | PyAPI_FUNC(int) |
161 | _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, const char *format, ...) |
162 | { |
163 | int retval; |
164 | va_list va; |
165 | |
166 | va_start(va, format); |
167 | retval = vgetargs1_impl(NULL, args, nargs, format, &va, FLAG_SIZE_T); |
168 | va_end(va); |
169 | return retval; |
170 | } |
171 | |
172 | |
173 | int |
174 | PyArg_VaParse(PyObject *args, const char *format, va_list va) |
175 | { |
176 | va_list lva; |
177 | int retval; |
178 |
|
179 | va_copy(lva, va); |
180 |
|
181 | retval = vgetargs1(args, format, &lva, 0); |
182 | va_end(lva); |
183 | return retval; |
184 | } |
185 | |
186 | PyAPI_FUNC(int) |
187 | _PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va) |
188 | { |
189 | va_list lva; |
190 | int retval; |
191 |
|
192 | va_copy(lva, va); |
193 |
|
194 | retval = vgetargs1(args, format, &lva, FLAG_SIZE_T); |
195 | va_end(lva); |
196 | return retval; |
197 | } |
198 | |
199 | |
200 | /* Handle cleanup of allocated memory in case of exception */ |
201 | |
202 | static int |
203 | cleanup_ptr(PyObject *self, void *ptr) |
204 | { |
205 | if (ptr) { Branch (205:9): [True: 0, False: 0]
|
206 | PyMem_Free(ptr); |
207 | } |
208 | return 0; |
209 | } |
210 | |
211 | static int |
212 | cleanup_buffer(PyObject *self, void *ptr) |
213 | { |
214 | Py_buffer *buf = (Py_buffer *)ptr; |
215 | if (buf) { Branch (215:9): [True: 2, False: 0]
|
216 | PyBuffer_Release(buf); |
217 | } |
218 | return 0; |
219 | } |
220 | |
221 | static int |
222 | addcleanup(void *ptr, freelist_t *freelist, destr_t destructor) |
223 | { |
224 | int index; |
225 | |
226 | index = freelist->first_available; |
227 | freelist->first_available += 1; |
228 | |
229 | freelist->entries[index].item = ptr; |
230 | freelist->entries[index].destructor = destructor; |
231 | |
232 | return 0; |
233 | } |
234 | |
235 | static int |
236 | cleanreturn(int retval, freelist_t *freelist) |
237 | { |
238 | int index; |
239 | |
240 | if (retval == 0) { Branch (240:9): [True: 1.69k, False: 22.5M]
|
241 | /* A failure occurred, therefore execute all of the cleanup |
242 | functions. |
243 | */ |
244 | for (index = 0; index < freelist->first_available; ++index3 ) { Branch (244:23): [True: 3, False: 1.69k]
|
245 | freelist->entries[index].destructor(NULL, |
246 | freelist->entries[index].item); |
247 | } |
248 | } |
249 | if (freelist->entries_malloced) Branch (249:9): [True: 88.9k, False: 22.4M]
|
250 | PyMem_Free(freelist->entries); |
251 | return retval; |
252 | } |
253 | |
254 | |
255 | static int |
256 | vgetargs1_impl(PyObject *compat_args, PyObject *const *stack, Py_ssize_t nargs, const char *format, |
257 | va_list *p_va, int flags) |
258 | { |
259 | char msgbuf[256]; |
260 | int levels[32]; |
261 | const char *fname = NULL; |
262 | const char *message = NULL; |
263 | int min = -1; |
264 | int max = 0; |
265 | int level = 0; |
266 | int endfmt = 0; |
267 | const char *formatsave = format; |
268 | Py_ssize_t i; |
269 | const char *msg; |
270 | int compat = flags & FLAG_COMPAT; |
271 | freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; |
272 | freelist_t freelist; |
273 | |
274 | assert(nargs == 0 || stack != NULL); |
275 | |
276 | freelist.entries = static_entries; |
277 | freelist.first_available = 0; |
278 | freelist.entries_malloced = 0; |
279 | |
280 | flags = flags & ~FLAG_COMPAT; |
281 | |
282 | while (endfmt == 0) { Branch (282:12): [True: 64.5M, False: 14.4M]
|
283 | int c = *format++; |
284 | switch (c) { |
285 | case '(': Branch (285:9): [True: 1.10k, False: 64.5M]
|
286 | if (level == 0) Branch (286:17): [True: 1.10k, False: 0]
|
287 | max++; |
288 | level++; |
289 | if (level >= 30) Branch (289:17): [True: 0, False: 1.10k]
|
290 | Py_FatalError("too many tuple nesting levels " |
291 | "in argument format string"); |
292 | break; |
293 | case ')': Branch (293:9): [True: 1.10k, False: 64.5M]
|
294 | if (level == 0) Branch (294:17): [True: 0, False: 1.10k]
|
295 | Py_FatalError("excess ')' in getargs format"); |
296 | else |
297 | level--; |
298 | break; |
299 | case '\0': Branch (299:9): [True: 2.49M, False: 62.0M]
|
300 | endfmt = 1; |
301 | break; |
302 | case ':': Branch (302:9): [True: 11.4M, False: 53.0M]
|
303 | fname = format; |
304 | endfmt = 1; |
305 | break; |
306 | case ';': Branch (306:9): [True: 447k, False: 64.1M]
|
307 | message = format; |
308 | endfmt = 1; |
309 | break; |
310 | case '|': Branch (310:9): [True: 10.6M, False: 53.9M]
|
311 | if (level == 0) Branch (311:17): [True: 10.6M, False: 0]
|
312 | min = max; |
313 | break; |
314 | default: Branch (314:9): [True: 39.5M, False: 25.0M]
|
315 | if (level == 0) { Branch (315:17): [True: 39.5M, False: 3.80k]
|
316 | if (Py_ISALPHA(c)) |
317 | if (c != 'e') /* skip encoded */ Branch (317:25): [True: 36.5M, False: 617]
|
318 | max++; |
319 | } |
320 | break; |
321 | } |
322 | } |
323 | |
324 | if (level != 0) Branch (324:9): [True: 0, False: 14.4M]
|
325 | Py_FatalError(/* '(' */ "missing ')' in getargs format"); |
326 | |
327 | if (min < 0) Branch (327:9): [True: 3.80M, False: 10.6M]
|
328 | min = max; |
329 | |
330 | format = formatsave; |
331 | |
332 | if (max > STATIC_FREELIST_ENTRIES) { Branch (332:9): [True: 19.9k, False: 14.4M]
|
333 | freelist.entries = PyMem_NEW(freelistentry_t, max); |
334 | if (freelist.entries == NULL) { Branch (334:13): [True: 0, False: 19.9k]
|
335 | PyErr_NoMemory(); |
336 | return 0; |
337 | } |
338 | freelist.entries_malloced = 1; |
339 | } |
340 | |
341 | if (compat) { Branch (341:9): [True: 2.53M, False: 11.8M]
|
342 | if (max == 0) { Branch (342:13): [True: 0, False: 2.53M]
|
343 | if (compat_args == NULL) Branch (343:17): [True: 0, False: 0]
|
344 | return 1; |
345 | PyErr_Format(PyExc_TypeError, |
346 | "%.200s%s takes no arguments", |
347 | fname==NULL ? "function" : fname, Branch (347:26): [True: 0, False: 0]
|
348 | fname==NULL ? "" : "()"); Branch (348:26): [True: 0, False: 0]
|
349 | return cleanreturn(0, &freelist); |
350 | } |
351 | else if (min == 1 && max == 1) { Branch (351:18): [True: 2.53M, False: 0]
Branch (351:30): [True: 2.53M, False: 0]
|
352 | if (compat_args == NULL) { Branch (352:17): [True: 0, False: 2.53M]
|
353 | PyErr_Format(PyExc_TypeError, |
354 | "%.200s%s takes at least one argument", |
355 | fname==NULL ? "function" : fname, Branch (355:30): [True: 0, False: 0]
|
356 | fname==NULL ? "" : "()"); Branch (356:30): [True: 0, False: 0]
|
357 | return cleanreturn(0, &freelist); |
358 | } |
359 | msg = convertitem(compat_args, &format, p_va, flags, levels, |
360 | msgbuf, sizeof(msgbuf), &freelist); |
361 | if (msg == NULL) Branch (361:17): [True: 2.53M, False: 274]
|
362 | return cleanreturn(1, &freelist); |
363 | seterror(levels[0], msg, levels+1, fname, message); |
364 | return cleanreturn(0, &freelist); |
365 | } |
366 | else { |
367 | PyErr_SetString(PyExc_SystemError, |
368 | "old style getargs format uses new features"); |
369 | return cleanreturn(0, &freelist); |
370 | } |
371 | } |
372 | |
373 | if (nargs < min || max < nargs11.8M ) { Branch (373:9): [True: 97, False: 11.8M]
Branch (373:24): [True: 80, False: 11.8M]
|
374 | if (message == NULL) Branch (374:13): [True: 133, False: 44]
|
375 | PyErr_Format(PyExc_TypeError, |
376 | "%.150s%s takes %s %d argument%s (%zd given)", |
377 | fname==NULL ? "function"48 : fname85 , Branch (377:26): [True: 48, False: 85]
|
378 | fname==NULL ? ""48 : "()"85 , Branch (378:26): [True: 48, False: 85]
|
379 | min==max ? "exactly"58 Branch (379:26): [True: 58, False: 75]
|
380 | : nargs < min75 ? "at least"43 : "at most"32 , Branch (380:28): [True: 43, False: 32]
|
381 | nargs < min ? min77 : max56 , Branch (381:26): [True: 77, False: 56]
|
382 | (nargs < min ? min77 : max56 ) == 1 ? ""46 : "s"87 , Branch (382:26): [True: 46, False: 87]
Branch (382:27): [True: 77, False: 56]
|
383 | nargs); |
384 | else |
385 | PyErr_SetString(PyExc_TypeError, message); |
386 | return cleanreturn(0, &freelist); |
387 | } |
388 | |
389 | for (i = 0; 11.8M i < nargs; i++17.9M ) { Branch (389:17): [True: 17.9M, False: 11.8M]
|
390 | if (*format == '|') Branch (390:13): [True: 4.31M, False: 13.6M]
|
391 | format++; |
392 | msg = convertitem(stack[i], &format, p_va, |
393 | flags, levels, msgbuf, |
394 | sizeof(msgbuf), &freelist); |
395 | if (msg) { Branch (395:13): [True: 575, False: 17.9M]
|
396 | seterror(i+1, msg, levels, fname, message); |
397 | return cleanreturn(0, &freelist); |
398 | } |
399 | } |
400 | |
401 | if (*format != '\0' && !11.5M Py_ISALPHA11.5M (*format) && Branch (401:9): [True: 11.5M, False: 354k]
Branch (401:28): [True: 7.80M, False: 3.72M]
|
402 | *format != '('7.80M && Branch (402:9): [True: 7.80M, False: 0]
|
403 | *format != '|'7.80M && *format != ':'1.50M && *format != ';'101k ) { Branch (403:9): [True: 1.50M, False: 6.30M]
Branch (403:27): [True: 101k, False: 1.40M]
Branch (403:45): [True: 1, False: 101k]
|
404 | PyErr_Format(PyExc_SystemError, |
405 | "bad format string: %.200s", formatsave); |
406 | return cleanreturn(0, &freelist); |
407 | } |
408 | |
409 | return cleanreturn(1, &freelist); |
410 | } |
411 | |
412 | static int |
413 | vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) |
414 | { |
415 | PyObject **stack; |
416 | Py_ssize_t nargs; |
417 | |
418 | if (!(flags & FLAG_COMPAT)) { Branch (418:9): [True: 11.7M, False: 2.53M]
|
419 | assert(args != NULL); |
420 | |
421 | if (!PyTuple_Check(args)) { Branch (421:13): [True: 0, False: 11.7M]
|
422 | PyErr_SetString(PyExc_SystemError, |
423 | "new style getargs format but argument is not a tuple"); |
424 | return 0; |
425 | } |
426 | |
427 | stack = _PyTuple_ITEMS(args); |
428 | nargs = PyTuple_GET_SIZE(args); |
429 | } |
430 | else { |
431 | stack = NULL; |
432 | nargs = 0; |
433 | } |
434 | |
435 | return vgetargs1_impl(args, stack, nargs, format, p_va, flags); |
436 | } |
437 | |
438 | |
439 | static void |
440 | seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname, |
441 | const char *message) |
442 | { |
443 | char buf[512]; |
444 | int i; |
445 | char *p = buf; |
446 | |
447 | if (PyErr_Occurred()) Branch (447:9): [True: 594, False: 561]
|
448 | return; |
449 | else if (message == NULL) { Branch (449:14): [True: 528, False: 33]
|
450 | if (fname != NULL) { Branch (450:13): [True: 100, False: 428]
|
451 | PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname); |
452 | p += strlen(p); |
453 | } |
454 | if (iarg != 0) { Branch (454:13): [True: 458, False: 70]
|
455 | PyOS_snprintf(p, sizeof(buf) - (p - buf), |
456 | "argument %zd", iarg); |
457 | i = 0; |
458 | p += strlen(p); |
459 | while (i < 32 && levels[i] > 0 && (int)(p-buf) < 2201 ) { Branch (459:20): [True: 459, False: 0]
Branch (459:30): [True: 1, False: 458]
Branch (459:47): [True: 1, False: 0]
|
460 | PyOS_snprintf(p, sizeof(buf) - (p - buf), |
461 | ", item %d", levels[i]-1); |
462 | p += strlen(p); |
463 | i++; |
464 | } |
465 | } |
466 | else { |
467 | PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument"); |
468 | p += strlen(p); |
469 | } |
470 | PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg); |
471 | message = buf; |
472 | } |
473 | if (msg[0] == '(') { Branch (473:9): [True: 110, False: 451]
|
474 | PyErr_SetString(PyExc_SystemError, message); |
475 | } |
476 | else { |
477 | PyErr_SetString(PyExc_TypeError, message); |
478 | } |
479 | } |
480 | |
481 | |
482 | /* Convert a tuple argument. |
483 | On entry, *p_format points to the character _after_ the opening '('. |
484 | On successful exit, *p_format points to the closing ')'. |
485 | If successful: |
486 | *p_format and *p_va are updated, |
487 | *levels and *msgbuf are untouched, |
488 | and NULL is returned. |
489 | If the argument is invalid: |
490 | *p_format is unchanged, |
491 | *p_va is undefined, |
492 | *levels is a 0-terminated list of item numbers, |
493 | *msgbuf contains an error message, whose format is: |
494 | "must be <typename1>, not <typename2>", where: |
495 | <typename1> is the name of the expected type, and |
496 | <typename2> is the name of the actual type, |
497 | and msgbuf is returned. |
498 | */ |
499 | |
500 | static const char * |
501 | converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, |
502 | int *levels, char *msgbuf, size_t bufsize, int toplevel, |
503 | freelist_t *freelist) |
504 | { |
505 | int level = 0; |
506 | int n = 0; |
507 | const char *format = *p_format; |
508 | int i; |
509 | Py_ssize_t len; |
510 | |
511 | for (;;) { |
512 | int c = *format++; |
513 | if (c == '(') { Branch (513:13): [True: 4, False: 4.98k]
|
514 | if (level == 0) Branch (514:17): [True: 4, False: 0]
|
515 | n++; |
516 | level++; |
517 | } |
518 | else if (c == ')') { Branch (518:18): [True: 1.13k, False: 3.84k]
|
519 | if (level == 0) Branch (519:17): [True: 1.12k, False: 4]
|
520 | break; |
521 | level--; |
522 | } |
523 | else if (c == ':' || c == ';' || c == '\0') Branch (523:18): [True: 0, False: 3.84k]
Branch (523:30): [True: 0, False: 3.84k]
Branch (523:42): [True: 0, False: 3.84k]
|
524 | break; |
525 | else if (level == 0 && Py_ISALPHA3.84k (c)) Branch (525:18): [True: 3.84k, False: 8]
|
526 | n++; |
527 | } |
528 | |
529 | if (!PySequence_Check(arg) || PyBytes_Check1.10k (arg)) { Branch (529:9): [True: 21, False: 1.10k]
|
530 | levels[0] = 0; |
531 | PyOS_snprintf(msgbuf, bufsize, |
532 | toplevel ? "expected %d arguments, not %.50s"0 : Branch (532:23): [True: 0, False: 21]
|
533 | "must be %d-item sequence, not %.50s", |
534 | n, |
535 | arg == Py_None ? "None"0 : Py_TYPE(arg)->tp_name); Branch (535:19): [True: 0, False: 21]
|
536 | return msgbuf; |
537 | } |
538 | |
539 | len = PySequence_Size(arg); |
540 | if (len != n) { Branch (540:9): [True: 14, False: 1.09k]
|
541 | levels[0] = 0; |
542 | if (toplevel) { Branch (542:13): [True: 0, False: 14]
|
543 | PyOS_snprintf(msgbuf, bufsize, |
544 | "expected %d argument%s, not %zd", |
545 | n, |
546 | n == 1 ? "" : "s", Branch (546:27): [True: 0, False: 0]
|
547 | len); |
548 | } |
549 | else { |
550 | PyOS_snprintf(msgbuf, bufsize, |
551 | "must be sequence of length %d, not %zd", |
552 | n, len); |
553 | } |
554 | return msgbuf; |
555 | } |
556 | |
557 | format = *p_format; |
558 | for (i = 0; i < n; i++2.90k ) { Branch (558:17): [True: 2.92k, False: 1.07k]
|
559 | const char *msg; |
560 | PyObject *item; |
561 | item = PySequence_GetItem(arg, i); |
562 | if (item == NULL) { Branch (562:13): [True: 1, False: 2.92k]
|
563 | PyErr_Clear(); |
564 | levels[0] = i+1; |
565 | levels[1] = 0; |
566 | strncpy(msgbuf, "is not retrievable", bufsize); |
567 | return msgbuf; |
568 | } |
569 | msg = convertitem(item, &format, p_va, flags, levels+1, |
570 | msgbuf, bufsize, freelist); |
571 | /* PySequence_GetItem calls tp->sq_item, which INCREFs */ |
572 | Py_XDECREF(item); |
573 | if (msg != NULL) { Branch (573:13): [True: 21, False: 2.90k]
|
574 | levels[0] = i+1; |
575 | return msg; |
576 | } |
577 | } |
578 | |
579 | *p_format = format; |
580 | return NULL; |
581 | } |
582 | |
583 | |
584 | /* Convert a single item. */ |
585 | |
586 | static const char * |
587 | convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags, |
588 | int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist) |
589 | { |
590 | const char *msg; |
591 | const char *format = *p_format; |
592 | |
593 | if (*format == '(' /* ')' */) { Branch (593:9): [True: 1.12k, False: 22.9M]
|
594 | format++; |
595 | msg = converttuple(arg, &format, p_va, flags, levels, msgbuf, |
596 | bufsize, 0, freelist); |
597 | if (msg == NULL) Branch (597:13): [True: 1.07k, False: 57]
|
598 | format++; |
599 | } |
600 | else { |
601 | msg = convertsimple(arg, &format, p_va, flags, |
602 | msgbuf, bufsize, freelist); |
603 | if (msg != NULL) Branch (603:13): [True: 1.11k, False: 22.9M]
|
604 | levels[0] = 0; |
605 | } |
606 | if (msg == NULL) Branch (606:9): [True: 22.9M, False: 1.17k]
|
607 | *p_format = format; |
608 | return msg; |
609 | } |
610 | |
611 | |
612 | |
613 | /* Format an error message generated by convertsimple(). |
614 | displayname must be UTF-8 encoded. |
615 | */ |
616 | |
617 | void |
618 | _PyArg_BadArgument(const char *fname, const char *displayname, |
619 | const char *expected, PyObject *arg) |
620 | { |
621 | PyErr_Format(PyExc_TypeError, |
622 | "%.200s() %.200s must be %.50s, not %.50s", |
623 | fname, displayname, expected, |
624 | arg == Py_None ? "None"14 : Py_TYPE112 (arg)->tp_name112 ); Branch (624:18): [True: 14, False: 112]
|
625 | } |
626 | |
627 | static const char * |
628 | converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize) |
629 | { |
630 | assert(expected != NULL); |
631 | assert(arg != NULL); |
632 | if (expected[0] == '(') { Branch (632:9): [True: 144, False: 488]
|
633 | PyOS_snprintf(msgbuf, bufsize, |
634 | "%.100s", expected); |
635 | } |
636 | else { |
637 | PyOS_snprintf(msgbuf, bufsize, |
638 | "must be %.50s, not %.50s", expected, |
639 | arg == Py_None ? "None"47 : Py_TYPE441 (arg)->tp_name441 ); Branch (639:23): [True: 47, False: 441]
|
640 | } |
641 | return msgbuf; |
642 | } |
643 | |
644 | #define CONV_UNICODE "(unicode conversion error)" |
645 | |
646 | /* Convert a non-tuple argument. Return NULL if conversion went OK, |
647 | or a string with a message describing the failure. The message is |
648 | formatted as "must be <desired type>, not <actual type>". |
649 | When failing, an exception may or may not have been raised. |
650 | Don't call if a tuple is expected. |
651 | |
652 | When you add new format codes, please don't forget poor skipitem() below. |
653 | */ |
654 | |
655 | static const char * |
656 | convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, |
657 | char *msgbuf, size_t bufsize, freelist_t *freelist) |
658 | { |
659 | #define RETURN_ERR_OCCURRED return msgbuf487 |
660 | /* For # codes */ |
661 | #define REQUIRE_PY_SSIZE_T_CLEAN \ |
662 | if (57.2k !(flags & 57.2k FLAG_SIZE_T57.2k )) { \ |
663 | PyErr_SetString(PyExc_SystemError, \ |
664 | "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); \ |
665 | RETURN_ERR_OCCURRED; \ |
666 | } |
667 | |
668 | const char *format = *p_format; |
669 | char c = *format++; |
670 | const char *sarg; |
671 | |
672 | switch (c) { |
673 | |
674 | case 'b': { /* unsigned byte -- very short int */ Branch (674:5): [True: 70.3k, False: 22.8M]
|
675 | char *p = va_arg(*p_va, char *); |
676 | long ival = PyLong_AsLong(arg); |
677 | if (ival == -1 && PyErr_Occurred()17 ) Branch (677:13): [True: 17, False: 70.3k]
Branch (677:27): [True: 12, False: 5]
|
678 | RETURN_ERR_OCCURRED; |
679 | else if (ival < 0) { Branch (679:18): [True: 5, False: 70.3k]
|
680 | PyErr_SetString(PyExc_OverflowError, |
681 | "unsigned byte integer is less than minimum"); |
682 | RETURN_ERR_OCCURRED; |
683 | } |
684 | else if (ival > UCHAR_MAX) { Branch (684:18): [True: 5, False: 70.3k]
|
685 | PyErr_SetString(PyExc_OverflowError, |
686 | "unsigned byte integer is greater than maximum"); |
687 | RETURN_ERR_OCCURRED; |
688 | } |
689 | else |
690 | *p = (unsigned char) ival; |
691 | break; |
692 | } |
693 | |
694 | case 'B': {/* byte sized bitfield - both signed and unsigned Branch (694:5): [True: 73, False: 22.9M]
|
695 | values allowed */ |
696 | char *p = va_arg(*p_va, char *); |
697 | unsigned long ival = PyLong_AsUnsignedLongMask(arg); |
698 | if (ival == (unsigned long)-1 && PyErr_Occurred()6 ) Branch (698:13): [True: 6, False: 67]
Branch (698:42): [True: 5, False: 1]
|
699 | RETURN_ERR_OCCURRED; |
700 | else |
701 | *p = (unsigned char) ival; |
702 | break; |
703 | } |
704 | |
705 | case 'h': {/* signed short int */ Branch (705:5): [True: 42.4k, False: 22.8M]
|
706 | short *p = va_arg(*p_va, short *); |
707 | long ival = PyLong_AsLong(arg); |
708 | if (ival == -1 && PyErr_Occurred()7.79k ) Branch (708:13): [True: 7.79k, False: 34.6k]
Branch (708:27): [True: 16, False: 7.78k]
|
709 | RETURN_ERR_OCCURRED; |
710 | else if (ival < SHRT_MIN) { Branch (710:18): [True: 5, False: 42.4k]
|
711 | PyErr_SetString(PyExc_OverflowError, |
712 | "signed short integer is less than minimum"); |
713 | RETURN_ERR_OCCURRED; |
714 | } |
715 | else if (ival > SHRT_MAX) { Branch (715:18): [True: 5, False: 42.4k]
|
716 | PyErr_SetString(PyExc_OverflowError, |
717 | "signed short integer is greater than maximum"); |
718 | RETURN_ERR_OCCURRED; |
719 | } |
720 | else |
721 | *p = (short) ival; |
722 | break; |
723 | } |
724 | |
725 | case 'H': { /* short int sized bitfield, both signed and Branch (725:5): [True: 19, False: 22.9M]
|
726 | unsigned allowed */ |
727 | unsigned short *p = va_arg(*p_va, unsigned short *); |
728 | unsigned long ival = PyLong_AsUnsignedLongMask(arg); |
729 | if (ival == (unsigned long)-1 && PyErr_Occurred()6 ) Branch (729:13): [True: 6, False: 13]
Branch (729:42): [True: 5, False: 1]
|
730 | RETURN_ERR_OCCURRED; |
731 | else |
732 | *p = (unsigned short) ival; |
733 | break; |
734 | } |
735 | |
736 | case 'i': {/* signed int */ Branch (736:5): [True: 1.94M, False: 20.9M]
|
737 | int *p = va_arg(*p_va, int *); |
738 | long ival = PyLong_AsLong(arg); |
739 | if (ival == -1 && PyErr_Occurred()33.0k ) Branch (739:13): [True: 33.0k, False: 1.91M]
Branch (739:27): [True: 189, False: 32.8k]
|
740 | RETURN_ERR_OCCURRED; |
741 | else if (ival > INT_MAX) { Branch (741:18): [True: 26, False: 1.94M]
|
742 | PyErr_SetString(PyExc_OverflowError, |
743 | "signed integer is greater than maximum"); |
744 | RETURN_ERR_OCCURRED; |
745 | } |
746 | else if (ival < INT_MIN) { Branch (746:18): [True: 7, False: 1.94M]
|
747 | PyErr_SetString(PyExc_OverflowError, |
748 | "signed integer is less than minimum"); |
749 | RETURN_ERR_OCCURRED; |
750 | } |
751 | else |
752 | *p = ival; |
753 | break; |
754 | } |
755 | |
756 | case 'I': { /* int sized bitfield, both signed and Branch (756:5): [True: 522, False: 22.9M]
|
757 | unsigned allowed */ |
758 | unsigned int *p = va_arg(*p_va, unsigned int *); |
759 | unsigned long ival = PyLong_AsUnsignedLongMask(arg); |
760 | if (ival == (unsigned long)-1 && PyErr_Occurred()6 ) Branch (760:13): [True: 6, False: 516]
Branch (760:42): [True: 5, False: 1]
|
761 | RETURN_ERR_OCCURRED; |
762 | else |
763 | *p = (unsigned int) ival; |
764 | break; |
765 | } |
766 | |
767 | case 'n': /* Py_ssize_t */ Branch (767:5): [True: 228k, False: 22.6M]
|
768 | { |
769 | PyObject *iobj; |
770 | Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *); |
771 | Py_ssize_t ival = -1; |
772 | iobj = _PyNumber_Index(arg); |
773 | if (iobj != NULL) { Branch (773:13): [True: 228k, False: 121]
|
774 | ival = PyLong_AsSsize_t(iobj); |
775 | Py_DECREF(iobj); |
776 | } |
777 | if (ival == -1 && PyErr_Occurred()275 ) Branch (777:13): [True: 275, False: 228k]
Branch (777:27): [True: 125, False: 150]
|
778 | RETURN_ERR_OCCURRED; |
779 | *p = ival; |
780 | break; |
781 | } |
782 | case 'l': {/* long int */ Branch (782:5): [True: 21.2k, False: 22.9M]
|
783 | long *p = va_arg(*p_va, long *); |
784 | long ival = PyLong_AsLong(arg); |
785 | if (ival == -1 && PyErr_Occurred()3.91k ) Branch (785:13): [True: 3.91k, False: 17.3k]
Branch (785:27): [True: 23, False: 3.89k]
|
786 | RETURN_ERR_OCCURRED; |
787 | else |
788 | *p = ival; |
789 | break; |
790 | } |
791 | |
792 | case 'k': { /* long sized bitfield */ Branch (792:5): [True: 663, False: 22.9M]
|
793 | unsigned long *p = va_arg(*p_va, unsigned long *); |
794 | unsigned long ival; |
795 | if (PyLong_Check(arg)) |
796 | ival = PyLong_AsUnsignedLongMask(arg); |
797 | else |
798 | return converterr("int", arg, msgbuf, bufsize); |
799 | *p = ival; |
800 | break; |
801 | } |
802 | |
803 | case 'L': {/* long long */ Branch (803:5): [True: 27.8k, False: 22.8M]
|
804 | long long *p = va_arg( *p_va, long long * ); |
805 | long long ival = PyLong_AsLongLong(arg); |
806 | if (ival == (long long)-1 && PyErr_Occurred()3.91k ) Branch (806:13): [True: 3.91k, False: 23.8k]
Branch (806:38): [True: 22, False: 3.89k]
|
807 | RETURN_ERR_OCCURRED; |
808 | else |
809 | *p = ival; |
810 | break; |
811 | } |
812 | |
813 | case 'K': { /* long long sized bitfield */ Branch (813:5): [True: 37.1k, False: 22.8M]
|
814 | unsigned long long *p = va_arg(*p_va, unsigned long long *); |
815 | unsigned long long ival; |
816 | if (PyLong_Check(arg)) |
817 | ival = PyLong_AsUnsignedLongLongMask(arg); |
818 | else |
819 | return converterr("int", arg, msgbuf, bufsize); |
820 | *p = ival; |
821 | break; |
822 | } |
823 | |
824 | case 'f': {/* float */ Branch (824:5): [True: 21.0k, False: 22.9M]
|
825 | float *p = va_arg(*p_va, float *); |
826 | double dval = PyFloat_AsDouble(arg); |
827 | if (dval == -1.0 && PyErr_Occurred()6 ) Branch (827:13): [True: 6, False: 21.0k]
Branch (827:29): [True: 6, False: 0]
|
828 | RETURN_ERR_OCCURRED; |
829 | else |
830 | *p = (float) dval; |
831 | break; |
832 | } |
833 | |
834 | case 'd': {/* double */ Branch (834:5): [True: 86.6k, False: 22.8M]
|
835 | double *p = va_arg(*p_va, double *); |
836 | double dval = PyFloat_AsDouble(arg); |
837 | if (dval == -1.0 && PyErr_Occurred()65.5k ) Branch (837:13): [True: 65.5k, False: 21.0k]
Branch (837:29): [True: 8, False: 65.5k]
|
838 | RETURN_ERR_OCCURRED; |
839 | else |
840 | *p = dval; |
841 | break; |
842 | } |
843 | |
844 | case 'D': {/* complex double */ Branch (844:5): [True: 28, False: 22.9M]
|
845 | Py_complex *p = va_arg(*p_va, Py_complex *); |
846 | Py_complex cval; |
847 | cval = PyComplex_AsCComplex(arg); |
848 | if (PyErr_Occurred()) Branch (848:13): [True: 2, False: 26]
|
849 | RETURN_ERR_OCCURRED; |
850 | else |
851 | *p = cval; |
852 | break; |
853 | } |
854 | |
855 | case 'c': {/* char */ Branch (855:5): [True: 8, False: 22.9M]
|
856 | char *p = va_arg(*p_va, char *); |
857 | if (PyBytes_Check(arg) && PyBytes_Size(arg) == 12 ) Branch (857:35): [True: 1, False: 1]
|
858 | *p = PyBytes_AS_STRING(arg)[0]; |
859 | else if (PyByteArray_Check(arg) && PyByteArray_Size(arg) == 11 ) Branch (859:44): [True: 1, False: 0]
|
860 | *p = PyByteArray_AS_STRING(arg)[0]; |
861 | else |
862 | return converterr("a byte string of length 1", arg, msgbuf, bufsize); |
863 | break; |
864 | } |
865 | |
866 | case 'C': {/* unicode char */ Branch (866:5): [True: 71.7k, False: 22.8M]
|
867 | int *p = va_arg(*p_va, int *); |
868 | int kind; |
869 | const void *data; |
870 | |
871 | if (!PyUnicode_Check(arg)) Branch (871:13): [True: 6, False: 71.7k]
|
872 | return converterr("a unicode character", arg, msgbuf, bufsize); |
873 | |
874 | if (PyUnicode_READY(arg)) |
875 | RETURN_ERR_OCCURRED; |
876 | |
877 | if (PyUnicode_GET_LENGTH(arg) != 1) Branch (877:13): [True: 2, False: 71.7k]
|
878 | return converterr("a unicode character", arg, msgbuf, bufsize); |
879 | |
880 | kind = PyUnicode_KIND(arg); |
881 | data = PyUnicode_DATA(arg); |
882 | *p = PyUnicode_READ(kind, data, 0); |
883 | break; |
884 | } |
885 | |
886 | case 'p': {/* boolean *p*redicate */ Branch (886:5): [True: 53.8k, False: 22.8M]
|
887 | int *p = va_arg(*p_va, int *); |
888 | int val = PyObject_IsTrue(arg); |
889 | if (val > 0) Branch (889:13): [True: 52.3k, False: 1.48k]
|
890 | *p = 1; |
891 | else if (val == 0) Branch (891:18): [True: 1.47k, False: 4]
|
892 | *p = 0; |
893 | else |
894 | RETURN_ERR_OCCURRED; |
895 | break; |
896 | } |
897 | |
898 | /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all |
899 | need to be cleaned up! */ |
900 | |
901 | case 'y': {/* any bytes-like object */ Branch (901:5): [True: 42.2k, False: 22.8M]
|
902 | void **p = (void **)va_arg(*p_va, char **); |
903 | const char *buf; |
904 | Py_ssize_t count; |
905 | if (*format == '*') { Branch (905:13): [True: 42.2k, False: 77]
|
906 | if (getbuffer(arg, (Py_buffer*)p, &buf) < 0) Branch (906:17): [True: 37, False: 42.1k]
|
907 | return converterr(buf, arg, msgbuf, bufsize); |
908 | format++; |
909 | if (addcleanup(p, freelist, cleanup_buffer)) { Branch (909:17): [True: 0, False: 42.1k]
|
910 | return converterr( |
911 | "(cleanup problem)", |
912 | arg, msgbuf, bufsize); |
913 | } |
914 | break; |
915 | } |
916 | count = convertbuffer(arg, (const void **)p, &buf); |
917 | if (count < 0) Branch (917:13): [True: 9, False: 68]
|
918 | return converterr(buf, arg, msgbuf, bufsize); |
919 | if (*format == '#') { Branch (919:13): [True: 48, False: 20]
|
920 | REQUIRE_PY_SSIZE_T_CLEAN; |
921 | Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); |
922 | *psize = count; |
923 | format++; |
924 | } else { |
925 | if (strlen(*p) != (size_t)count) { Branch (925:17): [True: 1, False: 19]
|
926 | PyErr_SetString(PyExc_ValueError, "embedded null byte"); |
927 | RETURN_ERR_OCCURRED; |
928 | } |
929 | } |
930 | break; |
931 | } |
932 | |
933 | case 's': /* text string or bytes-like object */ Branch (933:5): [True: 63.8k, False: 22.8M]
|
934 | case 'z': /* text string, bytes-like object or None */ Branch (934:5): [True: 20, False: 22.9M]
|
935 | { |
936 | if (*format == '*') { Branch (936:13): [True: 22, False: 63.8k]
|
937 | /* "s*" or "z*" */ |
938 | Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *); |
939 | |
940 | if (c == 'z' && arg == 6 Py_None6 ) Branch (940:17): [True: 6, False: 16]
Branch (940:29): [True: 1, False: 5]
|
941 | PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0); |
942 | else if (PyUnicode_Check(arg)) { |
943 | Py_ssize_t len; |
944 | sarg = PyUnicode_AsUTF8AndSize(arg, &len); |
945 | if (sarg == NULL) Branch (945:21): [True: 0, False: 6]
|
946 | return converterr(CONV_UNICODE, |
947 | arg, msgbuf, bufsize); |
948 | PyBuffer_FillInfo(p, arg, (void *)sarg, len, 1, 0); |
949 | } |
950 | else { /* any bytes-like object */ |
951 | const char *buf; |
952 | if (getbuffer(arg, p, &buf) < 0) Branch (952:21): [True: 1, False: 14]
|
953 | return converterr(buf, arg, msgbuf, bufsize); |
954 | } |
955 | if (addcleanup(p, freelist, cleanup_buffer)) { Branch (955:17): [True: 0, False: 21]
|
956 | return converterr( |
957 | "(cleanup problem)", |
958 | arg, msgbuf, bufsize); |
959 | } |
960 | format++; |
961 | } else if (*format == '#') { /* a string or read-only bytes-like object */ Branch (961:20): [True: 57.2k, False: 6.67k]
|
962 | /* "s#" or "z#" */ |
963 | const void **p = (const void **)va_arg(*p_va, const char **); |
964 | REQUIRE_PY_SSIZE_T_CLEAN; |
965 | Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); |
966 | |
967 | if (c == 'z' && arg == 6 Py_None6 ) { Branch (967:17): [True: 6, False: 57.2k]
Branch (967:29): [True: 1, False: 5]
|
968 | *p = NULL; |
969 | *psize = 0; |
970 | } |
971 | else if (PyUnicode_Check(arg)) { |
972 | Py_ssize_t len; |
973 | sarg = PyUnicode_AsUTF8AndSize(arg, &len); |
974 | if (sarg == NULL) Branch (974:21): [True: 0, False: 55.7k]
|
975 | return converterr(CONV_UNICODE, |
976 | arg, msgbuf, bufsize); |
977 | *p = sarg; |
978 | *psize = len; |
979 | } |
980 | else { /* read-only bytes-like object */ |
981 | /* XXX Really? */ |
982 | const char *buf; |
983 | Py_ssize_t count = convertbuffer(arg, p, &buf); |
984 | if (count < 0) Branch (984:21): [True: 34, False: 1.45k]
|
985 | return converterr(buf, arg, msgbuf, bufsize); |
986 | *psize = count; |
987 | } |
988 | format++; |
989 | } else { |
990 | /* "s" or "z" */ |
991 | const char **p = va_arg(*p_va, const char **); |
992 | Py_ssize_t len; |
993 | sarg = NULL; |
994 | |
995 | if (c == 'z' && arg == 8 Py_None8 ) Branch (995:17): [True: 8, False: 6.66k]
Branch (995:29): [True: 1, False: 7]
|
996 | *p = NULL; |
997 | else if (PyUnicode_Check(arg)) { |
998 | sarg = PyUnicode_AsUTF8AndSize(arg, &len); |
999 | if (sarg == NULL) Branch (999:21): [True: 8, False: 6.65k]
|
1000 | return converterr(CONV_UNICODE, |
1001 | arg, msgbuf, bufsize); |
1002 | if (strlen(sarg) != (size_t)len) { Branch (1002:21): [True: 5, False: 6.64k]
|
1003 | PyErr_SetString(PyExc_ValueError, "embedded null character"); |
1004 | RETURN_ERR_OCCURRED; |
1005 | } |
1006 | *p = sarg; |
1007 | } |
1008 | else |
1009 | return converterr(c == 'z' ? "str or None"4 : "str"12 , Branch (1009:35): [True: 4, False: 12]
|
1010 | arg, msgbuf, bufsize); |
1011 | } |
1012 | break; |
1013 | } |
1014 | |
1015 | case 'e': {/* encoded string */ Branch (1015:5): [True: 617, False: 22.9M]
|
1016 | char **buffer; |
1017 | const char *encoding; |
1018 | PyObject *s; |
1019 | int recode_strings; |
1020 | Py_ssize_t size; |
1021 | const char *ptr; |
1022 | |
1023 | /* Get 'e' parameter: the encoding name */ |
1024 | encoding = (const char *)va_arg(*p_va, const char *); |
1025 | if (encoding == NULL) Branch (1025:13): [True: 4, False: 613]
|
1026 | encoding = PyUnicode_GetDefaultEncoding(); |
1027 | |
1028 | /* Get output buffer parameter: |
1029 | 's' (recode all objects via Unicode) or |
1030 | 't' (only recode non-string objects) |
1031 | */ |
1032 | if (*format == 's') Branch (1032:13): [True: 402, False: 215]
|
1033 | recode_strings = 1; |
1034 | else if (*format == 't') Branch (1034:18): [True: 215, False: 0]
|
1035 | recode_strings = 0; |
1036 | else |
1037 | return converterr( |
1038 | "(unknown parser marker combination)", |
1039 | arg, msgbuf, bufsize); |
1040 | buffer = (char **)va_arg(*p_va, char **); |
1041 | format++; |
1042 | if (buffer == NULL) Branch (1042:13): [True: 0, False: 617]
|
1043 | return converterr("(buffer is NULL)", |
1044 | arg, msgbuf, bufsize); |
1045 | |
1046 | /* Encode object */ |
1047 | if (!recode_strings && Branch (1047:13): [True: 215, False: 402]
|
1048 | (215 PyBytes_Check215 (arg) || PyByteArray_Check215 (arg))) { |
1049 | s = arg; |
1050 | Py_INCREF(s); |
1051 | if (PyBytes_Check(arg)) { |
1052 | size = PyBytes_GET_SIZE(s); |
1053 | ptr = PyBytes_AS_STRING(s); |
1054 | } |
1055 | else { |
1056 | size = PyByteArray_GET_SIZE(s); |
1057 | ptr = PyByteArray_AS_STRING(s); |
1058 | } |
1059 | } |
1060 | else if (PyUnicode_Check(arg)) { |
1061 | /* Encode object; use default error handling */ |
1062 | s = PyUnicode_AsEncodedString(arg, |
1063 | encoding, |
1064 | NULL); |
1065 | if (s == NULL) Branch (1065:17): [True: 8, False: 583]
|
1066 | return converterr("(encoding failed)", |
1067 | arg, msgbuf, bufsize); |
1068 | assert(PyBytes_Check(s)); |
1069 | size = PyBytes_GET_SIZE(s); |
1070 | ptr = PyBytes_AS_STRING(s); |
1071 | if (ptr == NULL) Branch (1071:17): [True: 0, False: 583]
|
1072 | ptr = ""; |
1073 | } |
1074 | else { |
1075 | return converterr( |
1076 | recode_strings ? "str"8 : "str, bytes or bytearray"5 , Branch (1076:17): [True: 8, False: 5]
|
1077 | arg, msgbuf, bufsize); |
1078 | } |
1079 | |
1080 | /* Write output; output is guaranteed to be 0-terminated */ |
1081 | if (*format == '#') { Branch (1081:13): [True: 18, False: 578]
|
1082 | /* Using buffer length parameter '#': |
1083 | |
1084 | - if *buffer is NULL, a new buffer of the |
1085 | needed size is allocated and the data |
1086 | copied into it; *buffer is updated to point |
1087 | to the new buffer; the caller is |
1088 | responsible for PyMem_Free()ing it after |
1089 | usage |
1090 | |
1091 | - if *buffer is not NULL, the data is |
1092 | copied to *buffer; *buffer_len has to be |
1093 | set to the size of the buffer on input; |
1094 | buffer overflow is signalled with an error; |
1095 | buffer has to provide enough room for the |
1096 | encoded string plus the trailing 0-byte |
1097 | |
1098 | - in both cases, *buffer_len is updated to |
1099 | the size of the buffer /excluding/ the |
1100 | trailing 0-byte |
1101 | |
1102 | */ |
1103 | REQUIRE_PY_SSIZE_T_CLEAN; |
1104 | Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); |
1105 | |
1106 | format++; |
1107 | if (psize == NULL) { Branch (1107:17): [True: 0, False: 18]
|
1108 | Py_DECREF(s); |
1109 | return converterr( |
1110 | "(buffer_len is NULL)", |
1111 | arg, msgbuf, bufsize); |
1112 | } |
1113 | if (*buffer == NULL) { Branch (1113:17): [True: 10, False: 8]
|
1114 | *buffer = PyMem_NEW(char, size + 1); |
1115 | if (*buffer == NULL) { Branch (1115:21): [True: 0, False: 10]
|
1116 | Py_DECREF(s); |
1117 | PyErr_NoMemory(); |
1118 | RETURN_ERR_OCCURRED; |
1119 | } |
1120 | if (addcleanup(*buffer, freelist, cleanup_ptr)) { Branch (1120:21): [True: 0, False: 10]
|
1121 | Py_DECREF(s); |
1122 | return converterr( |
1123 | "(cleanup problem)", |
1124 | arg, msgbuf, bufsize); |
1125 | } |
1126 | } else { |
1127 | if (size + 1 > *psize) { Branch (1127:21): [True: 4, False: 4]
|
1128 | Py_DECREF(s); |
1129 | PyErr_Format(PyExc_ValueError, |
1130 | "encoded string too long " |
1131 | "(%zd, maximum length %zd)", |
1132 | (Py_ssize_t)size, (Py_ssize_t)(*psize - 1)); |
1133 | RETURN_ERR_OCCURRED; |
1134 | } |
1135 | } |
1136 | memcpy(*buffer, ptr, size+1); |
1137 | |
1138 | *psize = size; |
1139 | } |
1140 | else { |
1141 | /* Using a 0-terminated buffer: |
1142 | |
1143 | - the encoded string has to be 0-terminated |
1144 | for this variant to work; if it is not, an |
1145 | error raised |
1146 | |
1147 | - a new buffer of the needed size is |
1148 | allocated and the data copied into it; |
1149 | *buffer is updated to point to the new |
1150 | buffer; the caller is responsible for |
1151 | PyMem_Free()ing it after usage |
1152 | |
1153 | */ |
1154 | if ((Py_ssize_t)strlen(ptr) != size) { Branch (1154:17): [True: 5, False: 573]
|
1155 | Py_DECREF(s); |
1156 | return converterr( |
1157 | "encoded string without null bytes", |
1158 | arg, msgbuf, bufsize); |
1159 | } |
1160 | *buffer = PyMem_NEW(char, size + 1); |
1161 | if (*buffer == NULL) { Branch (1161:17): [True: 0, False: 573]
|
1162 | Py_DECREF(s); |
1163 | PyErr_NoMemory(); |
1164 | RETURN_ERR_OCCURRED; |
1165 | } |
1166 | if (addcleanup(*buffer, freelist, cleanup_ptr)) { Branch (1166:17): [True: 0, False: 573]
|
1167 | Py_DECREF(s); |
1168 | return converterr("(cleanup problem)", |
1169 | arg, msgbuf, bufsize); |
1170 | } |
1171 | memcpy(*buffer, ptr, size+1); |
1172 | } |
1173 | Py_DECREF(s); |
1174 | break; |
1175 | } |
1176 | |
1177 | case 'S': { /* PyBytes object */ Branch (1177:5): [True: 312, False: 22.9M]
|
1178 | PyObject **p = va_arg(*p_va, PyObject **); |
1179 | if (PyBytes_Check(arg)) |
1180 | *p = arg; |
1181 | else |
1182 | return converterr("bytes", arg, msgbuf, bufsize); |
1183 | break; |
1184 | } |
1185 | |
1186 | case 'Y': { /* PyByteArray object */ Branch (1186:5): [True: 14, False: 22.9M]
|
1187 | PyObject **p = va_arg(*p_va, PyObject **); |
1188 | if (PyByteArray_Check(arg)) |
1189 | *p = arg; |
1190 | else |
1191 | return converterr("bytearray", arg, msgbuf, bufsize); |
1192 | break; |
1193 | } |
1194 | |
1195 | case 'U': { /* PyUnicode object */ Branch (1195:5): [True: 145k, False: 22.7M]
|
1196 | PyObject **p = va_arg(*p_va, PyObject **); |
1197 | if (PyUnicode_Check(arg)) { |
1198 | if (PyUnicode_READY(arg) == -1) Branch (1198:17): [True: 0, False: 145k]
|
1199 | RETURN_ERR_OCCURRED; |
1200 | *p = arg; |
1201 | } |
1202 | else |
1203 | return converterr("str", arg, msgbuf, bufsize); |
1204 | break; |
1205 | } |
1206 | |
1207 | case 'O': { /* object */ Branch (1207:5): [True: 17.9M, False: 5.00M]
|
1208 | PyTypeObject *type; |
1209 | PyObject **p; |
1210 | if (*format == '!') { Branch (1210:13): [True: 381k, False: 17.5M]
|
1211 | type = va_arg(*p_va, PyTypeObject*); |
1212 | p = va_arg(*p_va, PyObject **); |
1213 | format++; |
1214 | if (PyType_IsSubtype(Py_TYPE(arg), type)) Branch (1214:17): [True: 381k, False: 17]
|
1215 | *p = arg; |
1216 | else |
1217 | return converterr(type->tp_name, arg, msgbuf, bufsize); |
1218 | |
1219 | } |
1220 | else if (*format == '&') { Branch (1220:18): [True: 145k, False: 17.3M]
|
1221 | typedef int (*converter)(PyObject *, void *); |
1222 | converter convert = va_arg(*p_va, converter); |
1223 | void *addr = va_arg(*p_va, void *); |
1224 | int res; |
1225 | format++; |
1226 | if (! (res = (*convert)(arg, addr))) Branch (1226:17): [True: 19, False: 145k]
|
1227 | return converterr("(unspecified)", |
1228 | arg, msgbuf, bufsize); |
1229 | if (res == Py_CLEANUP_SUPPORTED && Branch (1229:17): [True: 7.24k, False: 138k]
|
1230 | addcleanup(addr, freelist, convert) == -17.24k ) Branch (1230:17): [True: 0, False: 7.24k]
|
1231 | return converterr("(cleanup problem)", |
1232 | arg, msgbuf, bufsize); |
1233 | } |
1234 | else { |
1235 | p = va_arg(*p_va, PyObject **); |
1236 | *p = arg; |
1237 | } |
1238 | break; |
1239 | } |
1240 | |
1241 | |
1242 | case 'w': { /* "w*": memory buffer, read-write access */ Branch (1242:5): [True: 2.14M, False: 20.7M]
|
1243 | void **p = va_arg(*p_va, void **); |
1244 | |
1245 | if (*format != '*') Branch (1245:13): [True: 1, False: 2.14M]
|
1246 | return converterr( |
1247 | "(invalid use of 'w' format character)", |
1248 | arg, msgbuf, bufsize); |
1249 | format++; |
1250 | |
1251 | /* Caller is interested in Py_buffer, and the object |
1252 | supports it directly. */ |
1253 | if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) { Branch (1253:13): [True: 43, False: 2.14M]
|
1254 | PyErr_Clear(); |
1255 | return converterr("read-write bytes-like object", |
1256 | arg, msgbuf, bufsize); |
1257 | } |
1258 | if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) { Branch (1258:13): [True: 0, False: 2.14M]
|
1259 | PyBuffer_Release((Py_buffer*)p); |
1260 | return converterr("contiguous buffer", arg, msgbuf, bufsize); |
1261 | } |
1262 | if (addcleanup(p, freelist, cleanup_buffer)) { Branch (1262:13): [True: 0, False: 2.14M]
|
1263 | return converterr( |
1264 | "(cleanup problem)", |
1265 | arg, msgbuf, bufsize); |
1266 | } |
1267 | break; |
1268 | } |
1269 | |
1270 | default: Branch (1270:5): [True: 108, False: 22.9M]
|
1271 | return converterr("(impossible<bad format char>)", arg, msgbuf, bufsize); |
1272 | |
1273 | } |
1274 | |
1275 | *p_format = format; |
1276 | return NULL; |
1277 | |
1278 | #undef REQUIRE_PY_SSIZE_T_CLEAN |
1279 | #undef RETURN_ERR_OCCURRED |
1280 | } |
1281 | |
1282 | static Py_ssize_t |
1283 | convertbuffer(PyObject *arg, const void **p, const char **errmsg) |
1284 | { |
1285 | PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer; |
1286 | Py_ssize_t count; |
1287 | Py_buffer view; |
1288 | |
1289 | *errmsg = NULL; |
1290 | *p = NULL; |
1291 | if (pb != NULL && pb->bf_releasebuffer != NULL1.52k ) { Branch (1291:9): [True: 1.52k, False: 35]
Branch (1291:23): [True: 8, False: 1.52k]
|
1292 | *errmsg = "read-only bytes-like object"; |
1293 | return -1; |
1294 | } |
1295 | |
1296 | if (getbuffer(arg, &view, errmsg) < 0) Branch (1296:9): [True: 35, False: 1.52k]
|
1297 | return -1; |
1298 | count = view.len; |
1299 | *p = view.buf; |
1300 | PyBuffer_Release(&view); |
1301 | return count; |
1302 | } |
1303 | |
1304 | static int |
1305 | getbuffer(PyObject *arg, Py_buffer *view, const char **errmsg) |
1306 | { |
1307 | if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) { Branch (1307:9): [True: 73, False: 43.7k]
|
1308 | *errmsg = "bytes-like object"; |
1309 | return -1; |
1310 | } |
1311 | if (!PyBuffer_IsContiguous(view, 'C')) { Branch (1311:9): [True: 0, False: 43.7k]
|
1312 | PyBuffer_Release(view); |
1313 | *errmsg = "contiguous buffer"; |
1314 | return -1; |
1315 | } |
1316 | return 0; |
1317 | } |
1318 | |
1319 | /* Support for keyword arguments donated by |
1320 | Geoff Philbrick <philbric@delphi.hks.com> */ |
1321 | |
1322 | /* Return false (0) for error, else true. */ |
1323 | int |
1324 | PyArg_ParseTupleAndKeywords(PyObject *args, |
1325 | PyObject *keywords, |
1326 | const char *format, |
1327 | char **kwlist, ...) |
1328 | { |
1329 | int retval; |
1330 | va_list va; |
1331 | |
1332 | if ((args == NULL || !PyTuple_Check(args)) || Branch (1332:10): [True: 0, False: 7.34M]
Branch (1332:26): [True: 0, False: 7.34M]
|
1333 | (keywords != NULL && !90.9k PyDict_Check90.9k (keywords)) || Branch (1333:10): [True: 90.9k, False: 7.25M]
Branch (1333:30): [True: 0, False: 90.9k]
|
1334 | format == NULL || Branch (1334:9): [True: 0, False: 7.34M]
|
1335 | kwlist == NULL) Branch (1335:9): [True: 0, False: 7.34M]
|
1336 | { |
1337 | PyErr_BadInternalCall(); |
1338 | return 0; |
1339 | } |
1340 | |
1341 | va_start(va, kwlist); |
1342 | retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0); |
1343 | va_end(va); |
1344 | return retval; |
1345 | } |
1346 | |
1347 | PyAPI_FUNC(int) |
1348 | _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args, |
1349 | PyObject *keywords, |
1350 | const char *format, |
1351 | char **kwlist, ...) |
1352 | { |
1353 | int retval; |
1354 | va_list va; |
1355 | |
1356 | if ((args == NULL || !PyTuple_Check(args)) || Branch (1356:10): [True: 0, False: 753k]
Branch (1356:26): [True: 0, False: 753k]
|
1357 | (keywords != NULL && !199k PyDict_Check199k (keywords)) || Branch (1357:10): [True: 199k, False: 553k]
Branch (1357:30): [True: 0, False: 199k]
|
1358 | format == NULL || Branch (1358:9): [True: 0, False: 753k]
|
1359 | kwlist == NULL) Branch (1359:9): [True: 0, False: 753k]
|
1360 | { |
1361 | PyErr_BadInternalCall(); |
1362 | return 0; |
1363 | } |
1364 | |
1365 | va_start(va, kwlist); |
1366 | retval = vgetargskeywords(args, keywords, format, |
1367 | kwlist, &va, FLAG_SIZE_T); |
1368 | va_end(va); |
1369 | return retval; |
1370 | } |
1371 | |
1372 | |
1373 | int |
1374 | PyArg_VaParseTupleAndKeywords(PyObject *args, |
1375 | PyObject *keywords, |
1376 | const char *format, |
1377 | char **kwlist, va_list va) |
1378 | { |
1379 | int retval; |
1380 | va_list lva; |
1381 |
|
1382 | if ((args == NULL || !PyTuple_Check(args)) || Branch (1382:10): [True: 0, False: 0]
Branch (1382:26): [True: 0, False: 0]
|
1383 | (keywords != NULL && !PyDict_Check(keywords)) || Branch (1383:10): [True: 0, False: 0]
Branch (1383:30): [True: 0, False: 0]
|
1384 | format == NULL || Branch (1384:9): [True: 0, False: 0]
|
1385 | kwlist == NULL) Branch (1385:9): [True: 0, False: 0]
|
1386 | { |
1387 | PyErr_BadInternalCall(); |
1388 | return 0; |
1389 | } |
1390 | |
1391 | va_copy(lva, va); |
1392 |
|
1393 | retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0); |
1394 | va_end(lva); |
1395 | return retval; |
1396 | } |
1397 | |
1398 | PyAPI_FUNC(int) |
1399 | _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args, |
1400 | PyObject *keywords, |
1401 | const char *format, |
1402 | char **kwlist, va_list va) |
1403 | { |
1404 | int retval; |
1405 | va_list lva; |
1406 |
|
1407 | if ((args == NULL || !PyTuple_Check(args)) || Branch (1407:10): [True: 0, False: 0]
Branch (1407:26): [True: 0, False: 0]
|
1408 | (keywords != NULL && !PyDict_Check(keywords)) || Branch (1408:10): [True: 0, False: 0]
Branch (1408:30): [True: 0, False: 0]
|
1409 | format == NULL || Branch (1409:9): [True: 0, False: 0]
|
1410 | kwlist == NULL) Branch (1410:9): [True: 0, False: 0]
|
1411 | { |
1412 | PyErr_BadInternalCall(); |
1413 | return 0; |
1414 | } |
1415 | |
1416 | va_copy(lva, va); |
1417 |
|
1418 | retval = vgetargskeywords(args, keywords, format, |
1419 | kwlist, &lva, FLAG_SIZE_T); |
1420 | va_end(lva); |
1421 | return retval; |
1422 | } |
1423 | |
1424 | PyAPI_FUNC(int) |
1425 | _PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords, |
1426 | struct _PyArg_Parser *parser, ...) |
1427 | { |
1428 | int retval; |
1429 | va_list va; |
1430 |
|
1431 | va_start(va, parser); |
1432 | retval = vgetargskeywordsfast(args, keywords, parser, &va, 0); |
1433 | va_end(va); |
1434 | return retval; |
1435 | } |
1436 | |
1437 | PyAPI_FUNC(int) |
1438 | _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, |
1439 | struct _PyArg_Parser *parser, ...) |
1440 | { |
1441 | int retval; |
1442 | va_list va; |
1443 |
|
1444 | va_start(va, parser); |
1445 | retval = vgetargskeywordsfast(args, keywords, parser, &va, FLAG_SIZE_T); |
1446 | va_end(va); |
1447 | return retval; |
1448 | } |
1449 | |
1450 | PyAPI_FUNC(int) |
1451 | _PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, |
1452 | struct _PyArg_Parser *parser, ...) |
1453 | { |
1454 | int retval; |
1455 | va_list va; |
1456 |
|
1457 | va_start(va, parser); |
1458 | retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, 0); |
1459 | va_end(va); |
1460 | return retval; |
1461 | } |
1462 | |
1463 | PyAPI_FUNC(int) |
1464 | _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, |
1465 | struct _PyArg_Parser *parser, ...) |
1466 | { |
1467 | int retval; |
1468 | va_list va; |
1469 | |
1470 | va_start(va, parser); |
1471 | retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, FLAG_SIZE_T); |
1472 | va_end(va); |
1473 | return retval; |
1474 | } |
1475 | |
1476 | |
1477 | PyAPI_FUNC(int) |
1478 | _PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords, |
1479 | struct _PyArg_Parser *parser, va_list va) |
1480 | { |
1481 | int retval; |
1482 | va_list lva; |
1483 |
|
1484 | va_copy(lva, va); |
1485 |
|
1486 | retval = vgetargskeywordsfast(args, keywords, parser, &lva, 0); |
1487 | va_end(lva); |
1488 | return retval; |
1489 | } |
1490 | |
1491 | PyAPI_FUNC(int) |
1492 | _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, |
1493 | struct _PyArg_Parser *parser, va_list va) |
1494 | { |
1495 | int retval; |
1496 | va_list lva; |
1497 |
|
1498 | va_copy(lva, va); |
1499 |
|
1500 | retval = vgetargskeywordsfast(args, keywords, parser, &lva, FLAG_SIZE_T); |
1501 | va_end(lva); |
1502 | return retval; |
1503 | } |
1504 | |
1505 | int |
1506 | PyArg_ValidateKeywordArguments(PyObject *kwargs) |
1507 | { |
1508 | if (!PyDict_Check(kwargs)) { Branch (1508:9): [True: 0, False: 6.17k]
|
1509 | PyErr_BadInternalCall(); |
1510 | return 0; |
1511 | } |
1512 | if (!_PyDict_HasOnlyStringKeys(kwargs)) { Branch (1512:9): [True: 3, False: 6.17k]
|
1513 | PyErr_SetString(PyExc_TypeError, |
1514 | "keywords must be strings"); |
1515 | return 0; |
1516 | } |
1517 | return 1; |
1518 | } |
1519 | |
1520 | #define IS_END_OF_FORMAT(c) (c == '\0'11.1M || c == ';'11.0M || c == ':'11.0M ) |
1521 | |
1522 | static int |
1523 | vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, |
1524 | char **kwlist, va_list *p_va, int flags) |
1525 | { |
1526 | char msgbuf[512]; |
1527 | int levels[32]; |
1528 | const char *fname, *msg, *custom_msg; |
1529 | int min = INT_MAX; |
1530 | int max = INT_MAX; |
1531 | int i, pos, len; |
1532 | int skip = 0; |
1533 | Py_ssize_t nargs, nkwargs; |
1534 | PyObject *current_arg; |
1535 | freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; |
1536 | freelist_t freelist; |
1537 | |
1538 | freelist.entries = static_entries; |
1539 | freelist.first_available = 0; |
1540 | freelist.entries_malloced = 0; |
1541 | |
1542 | assert(args != NULL && PyTuple_Check(args)); |
1543 | assert(kwargs == NULL || PyDict_Check(kwargs)); |
1544 | assert(format != NULL); |
1545 | assert(kwlist != NULL); |
1546 | assert(p_va != NULL); |
1547 | |
1548 | /* grab the function name or custom error msg first (mutually exclusive) */ |
1549 | fname = strchr(format, ':'); |
1550 | if (fname) { Branch (1550:9): [True: 7.72M, False: 381k]
|
1551 | fname++; |
1552 | custom_msg = NULL; |
1553 | } |
1554 | else { |
1555 | custom_msg = strchr(format,';'); |
1556 | if (custom_msg) Branch (1556:13): [True: 3, False: 381k]
|
1557 | custom_msg++; |
1558 | } |
1559 | |
1560 | /* scan kwlist and count the number of positional-only parameters */ |
1561 | for (pos = 0; kwlist[pos] && !*kwlist[pos]8.10M ; pos++1.16k ) { Branch (1561:19): [True: 8.10M, False: 373]
Branch (1561:34): [True: 1.16k, False: 8.10M]
|
1562 | } |
1563 | /* scan kwlist and get greatest possible nbr of args */ |
1564 | for (len = pos; kwlist[len]; len++17.7M ) { Branch (1564:21): [True: 17.7M, False: 8.10M]
|
1565 | if (!*kwlist[len]) { Branch (1565:13): [True: 2, False: 17.7M]
|
1566 | PyErr_SetString(PyExc_SystemError, |
1567 | "Empty keyword parameter name"); |
1568 | return cleanreturn(0, &freelist); |
1569 | } |
1570 | } |
1571 | |
1572 | if (len > STATIC_FREELIST_ENTRIES) { Branch (1572:9): [True: 68.9k, False: 8.03M]
|
1573 | freelist.entries = PyMem_NEW(freelistentry_t, len); |
1574 | if (freelist.entries == NULL) { Branch (1574:13): [True: 0, False: 68.9k]
|
1575 | PyErr_NoMemory(); |
1576 | return 0; |
1577 | } |
1578 | freelist.entries_malloced = 1; |
1579 | } |
1580 | |
1581 | nargs = PyTuple_GET_SIZE(args); |
1582 | nkwargs = (kwargs == NULL) ? 07.81M : PyDict_GET_SIZE290k (kwargs); Branch (1582:15): [True: 7.81M, False: 290k]
|
1583 | if (nargs + nkwargs > len) { Branch (1583:9): [True: 39, False: 8.10M]
|
1584 | /* Adding "keyword" (when nargs == 0) prevents producing wrong error |
1585 | messages in some special cases (see bpo-31229). */ |
1586 | PyErr_Format(PyExc_TypeError, |
1587 | "%.200s%s takes at most %d %sargument%s (%zd given)", |
1588 | (fname == NULL) ? "function"20 : fname19 , Branch (1588:22): [True: 20, False: 19]
|
1589 | (fname == NULL) ? ""20 : "()"19 , Branch (1589:22): [True: 20, False: 19]
|
1590 | len, |
1591 | (nargs == 0) ? "keyword "3 : ""36 , Branch (1591:22): [True: 3, False: 36]
|
1592 | (len == 1) ? ""25 : "s"14 , Branch (1592:22): [True: 25, False: 14]
|
1593 | nargs + nkwargs); |
1594 | return cleanreturn(0, &freelist); |
1595 | } |
1596 | |
1597 | /* convert tuple args and keyword args in same loop, using kwlist to drive process */ |
1598 | for (i = 0; 8.10M i < len; i++3.08M ) { Branch (1598:17): [True: 10.8M, False: 337k]
|
1599 | if (*format == '|') { Branch (1599:13): [True: 7.96M, False: 2.88M]
|
1600 | if (min != INT_MAX) { Branch (1600:17): [True: 1, False: 7.96M]
|
1601 | PyErr_SetString(PyExc_SystemError, |
1602 | "Invalid format string (| specified twice)"); |
1603 | return cleanreturn(0, &freelist); |
1604 | } |
1605 | |
1606 | min = i; |
1607 | format++; |
1608 | |
1609 | if (max != INT_MAX) { Branch (1609:17): [True: 1, False: 7.96M]
|
1610 | PyErr_SetString(PyExc_SystemError, |
1611 | "Invalid format string ($ before |)"); |
1612 | return cleanreturn(0, &freelist); |
1613 | } |
1614 | } |
1615 | if (*format == '$') { Branch (1615:13): [True: 2.13M, False: 8.71M]
|
1616 | if (max != INT_MAX) { Branch (1616:17): [True: 1, False: 2.13M]
|
1617 | PyErr_SetString(PyExc_SystemError, |
1618 | "Invalid format string ($ specified twice)"); |
1619 | return cleanreturn(0, &freelist); |
1620 | } |
1621 | |
1622 | max = i; |
1623 | format++; |
1624 | |
1625 | if (max < pos) { Branch (1625:17): [True: 2, False: 2.13M]
|
1626 | PyErr_SetString(PyExc_SystemError, |
1627 | "Empty parameter name after $"); |
1628 | return cleanreturn(0, &freelist); |
1629 | } |
1630 | if (skip) { Branch (1630:17): [True: 4, False: 2.13M]
|
1631 | /* Now we know the minimal and the maximal numbers of |
1632 | * positional arguments and can raise an exception with |
1633 | * informative message (see below). */ |
1634 | break; |
1635 | } |
1636 | if (max < nargs) { Branch (1636:17): [True: 8, False: 2.13M]
|
1637 | if (max == 0) { Branch (1637:21): [True: 1, False: 7]
|
1638 | PyErr_Format(PyExc_TypeError, |
1639 | "%.200s%s takes no positional arguments", |
1640 | (fname == NULL) ? "function" : fname0 , Branch (1640:34): [True: 1, False: 0]
|
1641 | (fname == NULL) ? "" : "()"0 ); Branch (1641:34): [True: 1, False: 0]
|
1642 | } |
1643 | else { |
1644 | PyErr_Format(PyExc_TypeError, |
1645 | "%.200s%s takes %s %d positional argument%s" |
1646 | " (%zd given)", |
1647 | (fname == NULL) ? "function"5 : fname2 , Branch (1647:34): [True: 5, False: 2]
|
1648 | (fname == NULL) ? ""5 : "()"2 , Branch (1648:34): [True: 5, False: 2]
|
1649 | (min != INT_MAX) ? "at most" : "exactly"0 , Branch (1649:34): [True: 7, False: 0]
|
1650 | max, |
1651 | max == 1 ? ""1 : "s"6 , Branch (1651:34): [True: 1, False: 6]
|
1652 | nargs); |
1653 | } |
1654 | return cleanreturn(0, &freelist); |
1655 | } |
1656 | } |
1657 | if (IS_END_OF_FORMAT(*format)) { |
1658 | PyErr_Format(PyExc_SystemError, |
1659 | "More keyword list entries (%d) than " |
1660 | "format specifiers (%d)", len, i); |
1661 | return cleanreturn(0, &freelist); |
1662 | } |
1663 | if (!skip) { Branch (1663:13): [True: 10.8M, False: 9]
|
1664 | if (i < nargs) { Branch (1664:17): [True: 1.79M, False: 9.04M]
|
1665 | current_arg = PyTuple_GET_ITEM(args, i); |
1666 | } |
1667 | else if (nkwargs && i >= pos1.28M ) { Branch (1667:22): [True: 1.28M, False: 7.76M]
Branch (1667:33): [True: 1.28M, False: 7]
|
1668 | current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]); |
1669 | if (current_arg) { Branch (1669:21): [True: 631k, False: 652k]
|
1670 | --nkwargs; |
1671 | } |
1672 | else if (PyErr_Occurred()) { Branch (1672:26): [True: 0, False: 652k]
|
1673 | return cleanreturn(0, &freelist); |
1674 | } |
1675 | } |
1676 | else { |
1677 | current_arg = NULL; |
1678 | } |
1679 | |
1680 | if (current_arg) { Branch (1680:17): [True: 2.43M, False: 8.41M]
|
1681 | msg = convertitem(current_arg, &format, p_va, flags, |
1682 | levels, msgbuf, sizeof(msgbuf), &freelist); |
1683 | if (msg) { Branch (1683:21): [True: 306, False: 2.43M]
|
1684 | seterror(i+1, msg, levels, fname, custom_msg); |
1685 | return cleanreturn(0, &freelist); |
1686 | } |
1687 | continue; |
1688 | } |
1689 | |
1690 | if (i < min) { Branch (1690:17): [True: 49, False: 8.41M]
|
1691 | if (i < pos) { Branch (1691:21): [True: 10, False: 39]
|
1692 | assert (min == INT_MAX); |
1693 | assert (max == INT_MAX); |
1694 | skip = 1; |
1695 | /* At that moment we still don't know the minimal and |
1696 | * the maximal numbers of positional arguments. Raising |
1697 | * an exception is deferred until we encounter | and $ |
1698 | * or the end of the format. */ |
1699 | } |
1700 | else { |
1701 | PyErr_Format(PyExc_TypeError, "%.200s%s missing required " |
1702 | "argument '%s' (pos %d)", |
1703 | (fname == NULL) ? "function"25 : fname14 , Branch (1703:34): [True: 25, False: 14]
|
1704 | (fname == NULL) ? ""25 : "()"14 , Branch (1704:34): [True: 25, False: 14]
|
1705 | kwlist[i], i+1); |
1706 | return cleanreturn(0, &freelist); |
1707 | } |
1708 | } |
1709 | /* current code reports success when all required args |
1710 | * fulfilled and no keyword args left, with no further |
1711 | * validation. XXX Maybe skip this in debug build ? |
1712 | */ |
1713 | if (!nkwargs && !skip7.76M ) { Branch (1713:17): [True: 7.76M, False: 652k]
Branch (1713:29): [True: 7.76M, False: 5]
|
1714 | return cleanreturn(1, &freelist); |
1715 | } |
1716 | } |
1717 | |
1718 | /* We are into optional args, skip through to any remaining |
1719 | * keyword args */ |
1720 | msg = skipitem(&format, p_va, flags); |
1721 | if (msg) { Branch (1721:13): [True: 211, False: 652k]
|
1722 | PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, |
1723 | format); |
1724 | return cleanreturn(0, &freelist); |
1725 | } |
1726 | } |
1727 | |
1728 | if (skip) { Branch (1728:9): [True: 10, False: 337k]
|
1729 | PyErr_Format(PyExc_TypeError, |
1730 | "%.200s%s takes %s %d positional argument%s" |
1731 | " (%zd given)", |
1732 | (fname == NULL) ? "function"7 : fname3 , Branch (1732:22): [True: 7, False: 3]
|
1733 | (fname == NULL) ? ""7 : "()"3 , Branch (1733:22): [True: 7, False: 3]
|
1734 | (Py_MIN(pos, min) < i) ? "at least"6 : "exactly"4 , Branch (1734:22): [True: 6, False: 4]
|
1735 | Py_MIN(pos, min), |
1736 | Py_MIN(pos, min) == 1 ? ""8 : "s"2 , Branch (1736:22): [True: 8, False: 2]
|
1737 | nargs); |
1738 | return cleanreturn(0, &freelist); |
1739 | } |
1740 | |
1741 | if (!IS_END_OF_FORMAT(*format) && (*format != '|')2 && (*format != '$')1 ) { Branch (1741:39): [True: 1, False: 1]
Branch (1741:59): [True: 1, False: 0]
|
1742 | PyErr_Format(PyExc_SystemError, |
1743 | "more argument specifiers than keyword list entries " |
1744 | "(remaining format:'%s')", format); |
1745 | return cleanreturn(0, &freelist); |
1746 | } |
1747 | |
1748 | if (nkwargs > 0) { Branch (1748:9): [True: 41, False: 337k]
|
1749 | PyObject *key; |
1750 | Py_ssize_t j; |
1751 | /* make sure there are no arguments given by name and position */ |
1752 | for (i = pos; i < nargs; i++23 ) { Branch (1752:23): [True: 24, False: 40]
|
1753 | current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]); |
1754 | if (current_arg) { Branch (1754:17): [True: 1, False: 23]
|
1755 | /* arg present in tuple and in dict */ |
1756 | PyErr_Format(PyExc_TypeError, |
1757 | "argument for %.200s%s given by name ('%s') " |
1758 | "and position (%d)", |
1759 | (fname == NULL) ? "function" : fname0 , Branch (1759:30): [True: 1, False: 0]
|
1760 | (fname == NULL) ? "" : "()"0 , Branch (1760:30): [True: 1, False: 0]
|
1761 | kwlist[i], i+1); |
1762 | return cleanreturn(0, &freelist); |
1763 | } |
1764 | else if (PyErr_Occurred()) { Branch (1764:22): [True: 0, False: 23]
|
1765 | return cleanreturn(0, &freelist); |
1766 | } |
1767 | } |
1768 | /* make sure there are no extraneous keyword arguments */ |
1769 | j = 0; |
1770 | while (PyDict_Next(kwargs, &j, &key, NULL)) { Branch (1770:16): [True: 56, False: 0]
|
1771 | int match = 0; |
1772 | if (!PyUnicode_Check(key)) { Branch (1772:17): [True: 0, False: 56]
|
1773 | PyErr_SetString(PyExc_TypeError, |
1774 | "keywords must be strings"); |
1775 | return cleanreturn(0, &freelist); |
1776 | } |
1777 | for (i = pos; 56 i < len; i++178 ) { Branch (1777:27): [True: 194, False: 40]
|
1778 | if (_PyUnicode_EqualToASCIIString(key, kwlist[i])) { Branch (1778:21): [True: 16, False: 178]
|
1779 | match = 1; |
1780 | break; |
1781 | } |
1782 | } |
1783 | if (!match) { Branch (1783:17): [True: 40, False: 16]
|
1784 | PyErr_Format(PyExc_TypeError, |
1785 | "'%U' is an invalid keyword " |
1786 | "argument for %.200s%s", |
1787 | key, |
1788 | (fname == NULL) ? "this function"25 : fname15 , Branch (1788:30): [True: 25, False: 15]
|
1789 | (fname == NULL) ? ""25 : "()"15 ); Branch (1789:30): [True: 25, False: 15]
|
1790 | return cleanreturn(0, &freelist); |
1791 | } |
1792 | } |
1793 | } |
1794 | |
1795 | return cleanreturn(1, &freelist); |
1796 | } |
1797 | |
1798 | |
1799 | /* List of static parsers. */ |
1800 | static struct _PyArg_Parser *static_arg_parsers = NULL; |
1801 | |
1802 | static int |
1803 | parser_init(struct _PyArg_Parser *parser) |
1804 | { |
1805 | const char * const *keywords; |
1806 | const char *format, *msg; |
1807 | int i, len, min, max, nkw; |
1808 | PyObject *kwtuple; |
1809 | |
1810 | assert(parser->keywords != NULL); |
1811 | if (parser->kwtuple != NULL) { Branch (1811:9): [True: 1.34M, False: 447]
|
1812 | return 1; |
1813 | } |
1814 | |
1815 | keywords = parser->keywords; |
1816 | /* scan keywords and count the number of positional-only parameters */ |
1817 | for (i = 0; keywords[i] && !*keywords[i]480 ; i++40 ) { Branch (1817:17): [True: 480, False: 7]
Branch (1817:32): [True: 40, False: 440]
|
1818 | } |
1819 | parser->pos = i; |
1820 | /* scan keywords and get greatest possible nbr of args */ |
1821 | for (; keywords[i]; i++1.53k ) { Branch (1821:12): [True: 1.53k, False: 447]
|
1822 | if (!*keywords[i]) { Branch (1822:13): [True: 0, False: 1.53k]
|
1823 | PyErr_SetString(PyExc_SystemError, |
1824 | "Empty keyword parameter name"); |
1825 | return 0; |
1826 | } |
1827 | } |
1828 | len = i; |
1829 | |
1830 | format = parser->format; |
1831 | if (format) { Branch (1831:9): [True: 6, False: 441]
|
1832 | /* grab the function name or custom error msg first (mutually exclusive) */ |
1833 | parser->fname = strchr(parser->format, ':'); |
1834 | if (parser->fname) { Branch (1834:13): [True: 6, False: 0]
|
1835 | parser->fname++; |
1836 | parser->custom_msg = NULL; |
1837 | } |
1838 | else { |
1839 | parser->custom_msg = strchr(parser->format,';'); |
1840 | if (parser->custom_msg) Branch (1840:17): [True: 0, False: 0]
|
1841 | parser->custom_msg++; |
1842 | } |
1843 | |
1844 | min = max = INT_MAX; |
1845 | for (i = 0; i < len; i++10 ) { Branch (1845:21): [True: 10, False: 6]
|
1846 | if (*format == '|') { Branch (1846:17): [True: 3, False: 7]
|
1847 | if (min != INT_MAX) { Branch (1847:21): [True: 0, False: 3]
|
1848 | PyErr_SetString(PyExc_SystemError, |
1849 | "Invalid format string (| specified twice)"); |
1850 | return 0; |
1851 | } |
1852 | if (max != INT_MAX) { Branch (1852:21): [True: 0, False: 3]
|
1853 | PyErr_SetString(PyExc_SystemError, |
1854 | "Invalid format string ($ before |)"); |
1855 | return 0; |
1856 | } |
1857 | min = i; |
1858 | format++; |
1859 | } |
1860 | if (*format == '$') { Branch (1860:17): [True: 0, False: 10]
|
1861 | if (max != INT_MAX) { Branch (1861:21): [True: 0, False: 0]
|
1862 | PyErr_SetString(PyExc_SystemError, |
1863 | "Invalid format string ($ specified twice)"); |
1864 | return 0; |
1865 | } |
1866 | if (i < parser->pos) { Branch (1866:21): [True: 0, False: 0]
|
1867 | PyErr_SetString(PyExc_SystemError, |
1868 | "Empty parameter name after $"); |
1869 | return 0; |
1870 | } |
1871 | max = i; |
1872 | format++; |
1873 | } |
1874 | if (IS_END_OF_FORMAT(*format)) { |
1875 | PyErr_Format(PyExc_SystemError, |
1876 | "More keyword list entries (%d) than " |
1877 | "format specifiers (%d)", len, i); |
1878 | return 0; |
1879 | } |
1880 | |
1881 | msg = skipitem(&format, NULL, 0); |
1882 | if (msg) { Branch (1882:17): [True: 0, False: 10]
|
1883 | PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, |
1884 | format); |
1885 | return 0; |
1886 | } |
1887 | } |
1888 | parser->min = Py_MIN(min, len); |
1889 | parser->max = Py_MIN(max, len); |
1890 | |
1891 | if (!IS_END_OF_FORMAT(*format) && (*format != '|')0 && (*format != '$')0 ) { Branch (1891:43): [True: 0, False: 0]
Branch (1891:63): [True: 0, False: 0]
|
1892 | PyErr_Format(PyExc_SystemError, |
1893 | "more argument specifiers than keyword list entries " |
1894 | "(remaining format:'%s')", format); |
1895 | return 0; |
1896 | } |
1897 | } |
1898 | |
1899 | nkw = len - parser->pos; |
1900 | kwtuple = PyTuple_New(nkw); |
1901 | if (kwtuple == NULL) { Branch (1901:9): [True: 0, False: 447]
|
1902 | return 0; |
1903 | } |
1904 | keywords = parser->keywords + parser->pos; |
1905 | for (i = 0; i < nkw; i++1.53k ) { Branch (1905:17): [True: 1.53k, False: 447]
|
1906 | PyObject *str = PyUnicode_FromString(keywords[i]); |
1907 | if (str == NULL) { Branch (1907:13): [True: 0, False: 1.53k]
|
1908 | Py_DECREF(kwtuple); |
1909 | return 0; |
1910 | } |
1911 | PyUnicode_InternInPlace(&str); |
1912 | PyTuple_SET_ITEM(kwtuple, i, str); |
1913 | } |
1914 | parser->kwtuple = kwtuple; |
1915 | |
1916 | assert(parser->next == NULL); |
1917 | parser->next = static_arg_parsers; |
1918 | static_arg_parsers = parser; |
1919 | return 1; |
1920 | } |
1921 | |
1922 | static void |
1923 | parser_clear(struct _PyArg_Parser *parser) |
1924 | { |
1925 | Py_CLEAR(parser->kwtuple); |
1926 | } |
1927 | |
1928 | static PyObject* |
1929 | find_keyword(PyObject *kwnames, PyObject *const *kwstack, PyObject *key) |
1930 | { |
1931 | Py_ssize_t i, nkwargs; |
1932 | |
1933 | nkwargs = PyTuple_GET_SIZE(kwnames); |
1934 | for (i = 0; i < nkwargs; i++330k ) { Branch (1934:17): [True: 1.63M, False: 236k]
|
1935 | PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); |
1936 | |
1937 | /* kwname == key will normally find a match in since keyword keys |
1938 | should be interned strings; if not retry below in a new loop. */ |
1939 | if (kwname == key) { Branch (1939:13): [True: 1.30M, False: 330k]
|
1940 | return kwstack[i]; |
1941 | } |
1942 | } |
1943 | |
1944 | for (i = 0; 236k i < nkwargs; i++276k ) { Branch (1944:17): [True: 277k, False: 236k]
|
1945 | PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); |
1946 | assert(PyUnicode_Check(kwname)); |
1947 | if (_PyUnicode_EQ(kwname, key)) { Branch (1947:13): [True: 255, False: 276k]
|
1948 | return kwstack[i]; |
1949 | } |
1950 | } |
1951 | return NULL; |
1952 | } |
1953 | |
1954 | static int |
1955 | vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, |
1956 | PyObject *kwargs, PyObject *kwnames, |
1957 | struct _PyArg_Parser *parser, |
1958 | va_list *p_va, int flags) |
1959 | { |
1960 | PyObject *kwtuple; |
1961 | char msgbuf[512]; |
1962 | int levels[32]; |
1963 | const char *format; |
1964 | const char *msg; |
1965 | PyObject *keyword; |
1966 | int i, pos, len; |
1967 | Py_ssize_t nkwargs; |
1968 | PyObject *current_arg; |
1969 | freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; |
1970 | freelist_t freelist; |
1971 | PyObject *const *kwstack = NULL; |
1972 | |
1973 | freelist.entries = static_entries; |
1974 | freelist.first_available = 0; |
1975 | freelist.entries_malloced = 0; |
1976 | |
1977 | assert(kwargs == NULL || PyDict_Check(kwargs)); |
1978 | assert(kwargs == NULL || kwnames == NULL); |
1979 | assert(p_va != NULL); |
1980 | |
1981 | if (parser == NULL) { Branch (1981:9): [True: 0, False: 51]
|
1982 | PyErr_BadInternalCall(); |
1983 | return 0; |
1984 | } |
1985 | |
1986 | if (kwnames != NULL && !0 PyTuple_Check0 (kwnames)) { Branch (1986:9): [True: 0, False: 51]
Branch (1986:28): [True: 0, False: 0]
|
1987 | PyErr_BadInternalCall(); |
1988 | return 0; |
1989 | } |
1990 | |
1991 | if (!parser_init(parser)) { Branch (1991:9): [True: 0, False: 51]
|
1992 | return 0; |
1993 | } |
1994 | |
1995 | kwtuple = parser->kwtuple; |
1996 | pos = parser->pos; |
1997 | len = pos + (int)PyTuple_GET_SIZE(kwtuple); |
1998 | |
1999 | if (len > STATIC_FREELIST_ENTRIES) { Branch (1999:9): [True: 0, False: 51]
|
2000 | freelist.entries = PyMem_NEW(freelistentry_t, len); |
2001 | if (freelist.entries == NULL) { Branch (2001:13): [True: 0, False: 0]
|
2002 | PyErr_NoMemory(); |
2003 | return 0; |
2004 | } |
2005 | freelist.entries_malloced = 1; |
2006 | } |
2007 | |
2008 | if (kwargs != NULL) { Branch (2008:9): [True: 0, False: 51]
|
2009 | nkwargs = PyDict_GET_SIZE(kwargs); |
2010 | } |
2011 | else if (kwnames != NULL) { Branch (2011:14): [True: 0, False: 51]
|
2012 | nkwargs = PyTuple_GET_SIZE(kwnames); |
2013 | kwstack = args + nargs; |
2014 | } |
2015 | else { |
2016 | nkwargs = 0; |
2017 | } |
2018 | if (nargs + nkwargs > len) { Branch (2018:9): [True: 0, False: 51]
|
2019 | /* Adding "keyword" (when nargs == 0) prevents producing wrong error |
2020 | messages in some special cases (see bpo-31229). */ |
2021 | PyErr_Format(PyExc_TypeError, |
2022 | "%.200s%s takes at most %d %sargument%s (%zd given)", |
2023 | (parser->fname == NULL) ? "function" : parser->fname, Branch (2023:22): [True: 0, False: 0]
|
2024 | (parser->fname == NULL) ? "" : "()", Branch (2024:22): [True: 0, False: 0]
|
2025 | len, |
2026 | (nargs == 0) ? "keyword " : "", Branch (2026:22): [True: 0, False: 0]
|
2027 | (len == 1) ? "" : "s", Branch (2027:22): [True: 0, False: 0]
|
2028 | nargs + nkwargs); |
2029 | return cleanreturn(0, &freelist); |
2030 | } |
2031 | if (parser->max < nargs) { Branch (2031:9): [True: 0, False: 51]
|
2032 | if (parser->max == 0) { Branch (2032:13): [True: 0, False: 0]
|
2033 | PyErr_Format(PyExc_TypeError, |
2034 | "%.200s%s takes no positional arguments", |
2035 | (parser->fname == NULL) ? "function" : parser->fname, Branch (2035:26): [True: 0, False: 0]
|
2036 | (parser->fname == NULL) ? "" : "()"); Branch (2036:26): [True: 0, False: 0]
|
2037 | } |
2038 | else { |
2039 | PyErr_Format(PyExc_TypeError, |
2040 | "%.200s%s takes %s %d positional argument%s (%zd given)", |
2041 | (parser->fname == NULL) ? "function" : parser->fname, Branch (2041:26): [True: 0, False: 0]
|
2042 | (parser->fname == NULL) ? "" : "()", Branch (2042:26): [True: 0, False: 0]
|
2043 | (parser->min < parser->max) ? "at most" : "exactly", Branch (2043:26): [True: 0, False: 0]
|
2044 | parser->max, |
2045 | parser->max == 1 ? "" : "s", Branch (2045:26): [True: 0, False: 0]
|
2046 | nargs); |
2047 | } |
2048 | return cleanreturn(0, &freelist); |
2049 | } |
2050 | |
2051 | format = parser->format; |
2052 | /* convert tuple args and keyword args in same loop, using kwtuple to drive process */ |
2053 | for (i = 0; i < len; i++65 ) { Branch (2053:17): [True: 98, False: 18]
|
2054 | if (*format == '|') { Branch (2054:13): [True: 38, False: 60]
|
2055 | format++; |
2056 | } |
2057 | if (*format == '$') { Branch (2057:13): [True: 0, False: 98]
|
2058 | format++; |
2059 | } |
2060 | assert(!IS_END_OF_FORMAT(*format)); |
2061 | |
2062 | if (i < nargs) { Branch (2062:13): [True: 65, False: 33]
|
2063 | current_arg = args[i]; |
2064 | } |
2065 | else if (nkwargs && i >= pos0 ) { Branch (2065:18): [True: 0, False: 33]
Branch (2065:29): [True: 0, False: 0]
|
2066 | keyword = PyTuple_GET_ITEM(kwtuple, i - pos); |
2067 | if (kwargs != NULL) { Branch (2067:17): [True: 0, False: 0]
|
2068 | current_arg = PyDict_GetItemWithError(kwargs, keyword); |
2069 | if (!current_arg && PyErr_Occurred()) { Branch (2069:21): [True: 0, False: 0]
Branch (2069:37): [True: 0, False: 0]
|
2070 | return cleanreturn(0, &freelist); |
2071 | } |
2072 | } |
2073 | else { |
2074 | current_arg = find_keyword(kwnames, kwstack, keyword); |
2075 | } |
2076 | if (current_arg) { Branch (2076:17): [True: 0, False: 0]
|
2077 | --nkwargs; |
2078 | } |
2079 | } |
2080 | else { |
2081 | current_arg = NULL; |
2082 | } |
2083 | |
2084 | if (current_arg) { Branch (2084:13): [True: 65, False: 33]
|
2085 | msg = convertitem(current_arg, &format, p_va, flags, |
2086 | levels, msgbuf, sizeof(msgbuf), &freelist); |
2087 | if (msg) { Branch (2087:17): [True: 0, False: 65]
|
2088 | seterror(i+1, msg, levels, parser->fname, parser->custom_msg); |
2089 | return cleanreturn(0, &freelist); |
2090 | } |
2091 | continue; |
2092 | } |
2093 | |
2094 | if (i < parser->min) { Branch (2094:13): [True: 0, False: 33]
|
2095 | /* Less arguments than required */ |
2096 | if (i < pos) { Branch (2096:17): [True: 0, False: 0]
|
2097 | Py_ssize_t min = Py_MIN(pos, parser->min); |
2098 | PyErr_Format(PyExc_TypeError, |
2099 | "%.200s%s takes %s %d positional argument%s" |
2100 | " (%zd given)", |
2101 | (parser->fname == NULL) ? "function" : parser->fname, Branch (2101:30): [True: 0, False: 0]
|
2102 | (parser->fname == NULL) ? "" : "()", Branch (2102:30): [True: 0, False: 0]
|
2103 | min < parser->max ? "at least" : "exactly", Branch (2103:30): [True: 0, False: 0]
|
2104 | min, |
2105 | min == 1 ? "" : "s", Branch (2105:30): [True: 0, False: 0]
|
2106 | nargs); |
2107 | } |
2108 | else { |
2109 | keyword = PyTuple_GET_ITEM(kwtuple, i - pos); |
2110 | PyErr_Format(PyExc_TypeError, "%.200s%s missing required " |
2111 | "argument '%U' (pos %d)", |
2112 | (parser->fname == NULL) ? "function" : parser->fname, Branch (2112:30): [True: 0, False: 0]
|
2113 | (parser->fname == NULL) ? "" : "()", Branch (2113:30): [True: 0, False: 0]
|
2114 | keyword, i+1); |
2115 | } |
2116 | return cleanreturn(0, &freelist); |
2117 | } |
2118 | /* current code reports success when all required args |
2119 | * fulfilled and no keyword args left, with no further |
2120 | * validation. XXX Maybe skip this in debug build ? |
2121 | */ |
2122 | if (!nkwargs) { Branch (2122:13): [True: 33, False: 0]
|
2123 | return cleanreturn(1, &freelist); |
2124 | } |
2125 | |
2126 | /* We are into optional args, skip through to any remaining |
2127 | * keyword args */ |
2128 | msg = skipitem(&format, p_va, flags); |
2129 | assert(msg == NULL); |
2130 | } |
2131 | |
2132 | assert(IS_END_OF_FORMAT(*format) || (*format == '|') || (*format == '$')); |
2133 | |
2134 | if (nkwargs > 0) { Branch (2134:9): [True: 0, False: 18]
|
2135 | Py_ssize_t j; |
2136 | /* make sure there are no arguments given by name and position */ |
2137 | for (i = pos; i < nargs; i++) { Branch (2137:23): [True: 0, False: 0]
|
2138 | keyword = PyTuple_GET_ITEM(kwtuple, i - pos); |
2139 | if (kwargs != NULL) { Branch (2139:17): [True: 0, False: 0]
|
2140 | current_arg = PyDict_GetItemWithError(kwargs, keyword); |
2141 | if (!current_arg && PyErr_Occurred()) { Branch (2141:21): [True: 0, False: 0]
Branch (2141:37): [True: 0, False: 0]
|
2142 | return cleanreturn(0, &freelist); |
2143 | } |
2144 | } |
2145 | else { |
2146 | current_arg = find_keyword(kwnames, kwstack, keyword); |
2147 | } |
2148 | if (current_arg) { Branch (2148:17): [True: 0, False: 0]
|
2149 | /* arg present in tuple and in dict */ |
2150 | PyErr_Format(PyExc_TypeError, |
2151 | "argument for %.200s%s given by name ('%U') " |
2152 | "and position (%d)", |
2153 | (parser->fname == NULL) ? "function" : parser->fname, Branch (2153:30): [True: 0, False: 0]
|
2154 | (parser->fname == NULL) ? "" : "()", Branch (2154:30): [True: 0, False: 0]
|
2155 | keyword, i+1); |
2156 | return cleanreturn(0, &freelist); |
2157 | } |
2158 | } |
2159 | /* make sure there are no extraneous keyword arguments */ |
2160 | j = 0; |
2161 | while (1) { Branch (2161:16): [Folded - Ignored]
|
2162 | int match; |
2163 | if (kwargs != NULL) { Branch (2163:17): [True: 0, False: 0]
|
2164 | if (!PyDict_Next(kwargs, &j, &keyword, NULL)) Branch (2164:21): [True: 0, False: 0]
|
2165 | break; |
2166 | } |
2167 | else { |
2168 | if (j >= PyTuple_GET_SIZE(kwnames)) Branch (2168:21): [True: 0, False: 0]
|
2169 | break; |
2170 | keyword = PyTuple_GET_ITEM(kwnames, j); |
2171 | j++; |
2172 | } |
2173 | |
2174 | match = PySequence_Contains(kwtuple, keyword); |
2175 | if (match <= 0) { Branch (2175:17): [True: 0, False: 0]
|
2176 | if (!match) { Branch (2176:21): [True: 0, False: 0]
|
2177 | PyErr_Format(PyExc_TypeError, |
2178 | "'%S' is an invalid keyword " |
2179 | "argument for %.200s%s", |
2180 | keyword, |
2181 | (parser->fname == NULL) ? "this function" : parser->fname, Branch (2181:34): [True: 0, False: 0]
|
2182 | (parser->fname == NULL) ? "" : "()"); Branch (2182:34): [True: 0, False: 0]
|
2183 | } |
2184 | return cleanreturn(0, &freelist); |
2185 | } |
2186 | } |
2187 | } |
2188 | |
2189 | return cleanreturn(1, &freelist); |
2190 | } |
2191 | |
2192 | static int |
2193 | vgetargskeywordsfast(PyObject *args, PyObject *keywords, |
2194 | struct _PyArg_Parser *parser, va_list *p_va, int flags) |
2195 | { |
2196 | PyObject **stack; |
2197 | Py_ssize_t nargs; |
2198 |
|
2199 | if (args == NULL Branch (2199:9): [True: 0, False: 0]
|
2200 | || !PyTuple_Check(args) Branch (2200:12): [True: 0, False: 0]
|
2201 | || (keywords != NULL && !PyDict_Check(keywords))) Branch (2201:13): [True: 0, False: 0]
Branch (2201:33): [True: 0, False: 0]
|
2202 | { |
2203 | PyErr_BadInternalCall(); |
2204 | return 0; |
2205 | } |
2206 | |
2207 | stack = _PyTuple_ITEMS(args); |
2208 | nargs = PyTuple_GET_SIZE(args); |
2209 | return vgetargskeywordsfast_impl(stack, nargs, keywords, NULL, |
2210 | parser, p_va, flags); |
2211 | } |
2212 | |
2213 | |
2214 | #undef _PyArg_UnpackKeywords |
2215 | |
2216 | PyObject * const * |
2217 | _PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs, |
2218 | PyObject *kwargs, PyObject *kwnames, |
2219 | struct _PyArg_Parser *parser, |
2220 | int minpos, int maxpos, int minkw, |
2221 | PyObject **buf) |
2222 | { |
2223 | PyObject *kwtuple; |
2224 | PyObject *keyword; |
2225 | int i, posonly, minposonly, maxargs; |
2226 | int reqlimit = minkw ? maxpos + minkw0 : minpos; Branch (2226:20): [True: 0, False: 1.28M]
|
2227 | Py_ssize_t nkwargs; |
2228 | PyObject *current_arg; |
2229 | PyObject * const *kwstack = NULL; |
2230 | |
2231 | assert(kwargs == NULL || PyDict_Check(kwargs)); |
2232 | assert(kwargs == NULL || kwnames == NULL); |
2233 | |
2234 | if (parser == NULL) { Branch (2234:9): [True: 0, False: 1.28M]
|
2235 | PyErr_BadInternalCall(); |
2236 | return NULL; |
2237 | } |
2238 | |
2239 | if (kwnames != NULL && !1.20M PyTuple_Check1.20M (kwnames)) { Branch (2239:9): [True: 1.20M, False: 85.7k]
Branch (2239:28): [True: 0, False: 1.20M]
|
2240 | PyErr_BadInternalCall(); |
2241 | return NULL; |
2242 | } |
2243 | |
2244 | if (args == NULL && nargs == 0672 ) { Branch (2244:9): [True: 672, False: 1.28M]
Branch (2244:25): [True: 672, False: 0]
|
2245 | args = buf; |
2246 | } |
2247 | |
2248 | if (!parser_init(parser)) { Branch (2248:9): [True: 0, False: 1.28M]
|
2249 | return NULL; |
2250 | } |
2251 | |
2252 | kwtuple = parser->kwtuple; |
2253 | posonly = parser->pos; |
2254 | minposonly = Py_MIN(posonly, minpos); |
2255 | maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple); |
2256 | |
2257 | if (kwargs != NULL) { Branch (2257:9): [True: 84.8k, False: 1.20M]
|
2258 | nkwargs = PyDict_GET_SIZE(kwargs); |
2259 | } |
2260 | else if (kwnames != NULL) { Branch (2260:14): [True: 1.20M, False: 854]
|
2261 | nkwargs = PyTuple_GET_SIZE(kwnames); |
2262 | kwstack = args + nargs; |
2263 | } |
2264 | else { |
2265 | nkwargs = 0; |
2266 | } |
2267 | if (nkwargs == 0 && minkw == 043.9k && minpos <= nargs43.9k && nargs <= maxpos43.7k ) { Branch (2267:9): [True: 43.9k, False: 1.24M]
Branch (2267:25): [True: 43.9k, False: 0]
Branch (2267:39): [True: 43.7k, False: 152]
Branch (2267:58): [True: 43.6k, False: 54]
|
2268 | /* Fast path. */ |
2269 | return args; |
2270 | } |
2271 | if (nargs + nkwargs > maxargs) { Branch (2271:9): [True: 39, False: 1.24M]
|
2272 | /* Adding "keyword" (when nargs == 0) prevents producing wrong error |
2273 | messages in some special cases (see bpo-31229). */ |
2274 | PyErr_Format(PyExc_TypeError, |
2275 | "%.200s%s takes at most %d %sargument%s (%zd given)", |
2276 | (parser->fname == NULL) ? "function"0 : parser->fname, Branch (2276:22): [True: 0, False: 39]
|
2277 | (parser->fname == NULL) ? ""0 : "()", Branch (2277:22): [True: 0, False: 39]
|
2278 | maxargs, |
2279 | (nargs == 0) ? "keyword "0 : "", Branch (2279:22): [True: 0, False: 39]
|
2280 | (maxargs == 1) ? ""14 : "s"25 , Branch (2280:22): [True: 14, False: 25]
|
2281 | nargs + nkwargs); |
2282 | return NULL; |
2283 | } |
2284 | if (nargs > maxpos) { Branch (2284:9): [True: 20, False: 1.24M]
|
2285 | if (maxpos == 0) { Branch (2285:13): [True: 7, False: 13]
|
2286 | PyErr_Format(PyExc_TypeError, |
2287 | "%.200s%s takes no positional arguments", |
2288 | (parser->fname == NULL) ? "function"0 : parser->fname, Branch (2288:26): [True: 0, False: 7]
|
2289 | (parser->fname == NULL) ? ""0 : "()"); Branch (2289:26): [True: 0, False: 7]
|
2290 | } |
2291 | else { |
2292 | PyErr_Format(PyExc_TypeError, |
2293 | "%.200s%s takes %s %d positional argument%s (%zd given)", |
2294 | (parser->fname == NULL) ? "function"0 : parser->fname, Branch (2294:26): [True: 0, False: 13]
|
2295 | (parser->fname == NULL) ? ""0 : "()", Branch (2295:26): [True: 0, False: 13]
|
2296 | (minpos < maxpos) ? "at most"4 : "exactly"9 , Branch (2296:26): [True: 4, False: 9]
|
2297 | maxpos, |
2298 | (maxpos == 1) ? ""8 : "s"5 , Branch (2298:26): [True: 8, False: 5]
|
2299 | nargs); |
2300 | } |
2301 | return NULL; |
2302 | } |
2303 | if (nargs < minposonly) { Branch (2303:9): [True: 60, False: 1.24M]
|
2304 | PyErr_Format(PyExc_TypeError, |
2305 | "%.200s%s takes %s %d positional argument%s" |
2306 | " (%zd given)", |
2307 | (parser->fname == NULL) ? "function"0 : parser->fname, Branch (2307:22): [True: 0, False: 60]
|
2308 | (parser->fname == NULL) ? ""0 : "()", Branch (2308:22): [True: 0, False: 60]
|
2309 | minposonly < maxpos ? "at least"7 : "exactly"53 , Branch (2309:22): [True: 7, False: 53]
|
2310 | minposonly, |
2311 | minposonly == 1 ? ""47 : "s"13 , Branch (2311:22): [True: 47, False: 13]
|
2312 | nargs); |
2313 | return NULL; |
2314 | } |
2315 | |
2316 | /* copy tuple args */ |
2317 | for (i = 0; 1.24M i < nargs; i++265k ) { Branch (2317:17): [True: 265k, False: 1.24M]
|
2318 | buf[i] = args[i]; |
2319 | } |
2320 | |
2321 | /* copy keyword args using kwtuple to drive process */ |
2322 | for (i = Py_MAX1.24M ((int)nargs, posonly); i < maxargs; i++1.45M ) { Branch (2322:43): [True: 2.14M, False: 551k]
|
2323 | if (nkwargs) { Branch (2323:13): [True: 1.45M, False: 691k]
|
2324 | keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); |
2325 | if (kwargs != NULL) { Branch (2325:17): [True: 85.4k, False: 1.36M]
|
2326 | current_arg = PyDict_GetItemWithError(kwargs, keyword); |
2327 | if (!current_arg && PyErr_Occurred()25.5k ) { Branch (2327:21): [True: 25.5k, False: 59.8k]
Branch (2327:37): [True: 0, False: 25.5k]
|
2328 | return NULL; |
2329 | } |
2330 | } |
2331 | else { |
2332 | current_arg = find_keyword(kwnames, kwstack, keyword); |
2333 | } |
2334 | } |
2335 | else if (i >= reqlimit) { Branch (2335:18): [True: 691k, False: 95]
|
2336 | break; |
2337 | } |
2338 | else { |
2339 | current_arg = NULL; |
2340 | } |
2341 | |
2342 | buf[i] = current_arg; |
2343 | |
2344 | if (current_arg) { Branch (2344:13): [True: 1.29M, False: 164k]
|
2345 | --nkwargs; |
2346 | } |
2347 | else if (i < minpos || (164k maxpos <= i164k && i < reqlimit40.5k )) { Branch (2347:18): [True: 106, False: 164k]
Branch (2347:33): [True: 40.5k, False: 123k]
Branch (2347:48): [True: 0, False: 40.5k]
|
2348 | /* Less arguments than required */ |
2349 | keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); |
2350 | PyErr_Format(PyExc_TypeError, "%.200s%s missing required " |
2351 | "argument '%U' (pos %d)", |
2352 | (parser->fname == NULL) ? "function"0 : parser->fname, Branch (2352:26): [True: 0, False: 106]
|
2353 | (parser->fname == NULL) ? ""0 : "()", Branch (2353:26): [True: 0, False: 106]
|
2354 | keyword, i+1); |
2355 | return NULL; |
2356 | } |
2357 | } |
2358 | |
2359 | if (nkwargs > 0) { Branch (2359:9): [True: 19, False: 1.24M]
|
2360 | Py_ssize_t j; |
2361 | /* make sure there are no arguments given by name and position */ |
2362 | for (i = posonly; i < nargs; i++1 ) { Branch (2362:27): [True: 3, False: 17]
|
2363 | keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); |
2364 | if (kwargs != NULL) { Branch (2364:17): [True: 1, False: 2]
|
2365 | current_arg = PyDict_GetItemWithError(kwargs, keyword); |
2366 | if (!current_arg && PyErr_Occurred()) { Branch (2366:21): [True: 1, False: 0]
Branch (2366:37): [True: 0, False: 1]
|
2367 | return NULL; |
2368 | } |
2369 | } |
2370 | else { |
2371 | current_arg = find_keyword(kwnames, kwstack, keyword); |
2372 | } |
2373 | if (current_arg) { Branch (2373:17): [True: 2, False: 1]
|
2374 | /* arg present in tuple and in dict */ |
2375 | PyErr_Format(PyExc_TypeError, |
2376 | "argument for %.200s%s given by name ('%U') " |
2377 | "and position (%d)", |
2378 | (parser->fname == NULL) ? "function"0 : parser->fname, Branch (2378:30): [True: 0, False: 2]
|
2379 | (parser->fname == NULL) ? ""0 : "()", Branch (2379:30): [True: 0, False: 2]
|
2380 | keyword, i+1); |
2381 | return NULL; |
2382 | } |
2383 | } |
2384 | /* make sure there are no extraneous keyword arguments */ |
2385 | j = 0; |
2386 | while (1) { Branch (2386:16): [Folded - Ignored]
|
2387 | int match; |
2388 | if (kwargs != NULL) { Branch (2388:17): [True: 15, False: 3]
|
2389 | if (!PyDict_Next(kwargs, &j, &keyword, NULL)) Branch (2389:21): [True: 0, False: 15]
|
2390 | break; |
2391 | } |
2392 | else { |
2393 | if (j >= PyTuple_GET_SIZE(kwnames)) Branch (2393:21): [True: 0, False: 3]
|
2394 | break; |
2395 | keyword = PyTuple_GET_ITEM(kwnames, j); |
2396 | j++; |
2397 | } |
2398 | |
2399 | match = PySequence_Contains(kwtuple, keyword); |
2400 | if (match <= 0) { Branch (2400:17): [True: 17, False: 1]
|
2401 | if (!match) { Branch (2401:21): [True: 17, False: 0]
|
2402 | PyErr_Format(PyExc_TypeError, |
2403 | "'%S' is an invalid keyword " |
2404 | "argument for %.200s%s", |
2405 | keyword, |
2406 | (parser->fname == NULL) ? "this function"0 : parser->fname, Branch (2406:34): [True: 0, False: 17]
|
2407 | (parser->fname == NULL) ? ""0 : "()"); Branch (2407:34): [True: 0, False: 17]
|
2408 | } |
2409 | return NULL; |
2410 | } |
2411 | } |
2412 | } |
2413 | |
2414 | return buf; |
2415 | } |
2416 | |
2417 | PyObject * const * |
2418 | _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs, |
2419 | PyObject *kwargs, PyObject *kwnames, |
2420 | struct _PyArg_Parser *parser, |
2421 | int minpos, int maxpos, int minkw, |
2422 | int vararg, PyObject **buf) |
2423 | { |
2424 | PyObject *kwtuple; |
2425 | PyObject *keyword; |
2426 | Py_ssize_t varargssize = 0; |
2427 | int i, posonly, minposonly, maxargs; |
2428 | int reqlimit = minkw ? maxpos + minkw0 : minpos; Branch (2428:20): [True: 0, False: 60.6k]
|
2429 | Py_ssize_t nkwargs; |
2430 | PyObject *current_arg; |
2431 | PyObject * const *kwstack = NULL; |
2432 | |
2433 | assert(kwargs == NULL || PyDict_Check(kwargs)); |
2434 | assert(kwargs == NULL || kwnames == NULL); |
2435 | |
2436 | if (parser == NULL) { Branch (2436:9): [True: 0, False: 60.6k]
|
2437 | PyErr_BadInternalCall(); |
2438 | return NULL; |
2439 | } |
2440 | |
2441 | if (kwnames != NULL && !56.9k PyTuple_Check56.9k (kwnames)) { Branch (2441:9): [True: 56.9k, False: 3.68k]
Branch (2441:28): [True: 0, False: 56.9k]
|
2442 | PyErr_BadInternalCall(); |
2443 | return NULL; |
2444 | } |
2445 | |
2446 | if (args == NULL && nargs == 00 ) { Branch (2446:9): [True: 0, False: 60.6k]
Branch (2446:25): [True: 0, False: 0]
|
2447 | args = buf; |
2448 | } |
2449 | |
2450 | if (!parser_init(parser)) { Branch (2450:9): [True: 0, False: 60.6k]
|
2451 | return NULL; |
2452 | } |
2453 | |
2454 | kwtuple = parser->kwtuple; |
2455 | posonly = parser->pos; |
2456 | minposonly = Py_MIN(posonly, minpos); |
2457 | maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple); |
2458 | if (kwargs != NULL) { Branch (2458:9): [True: 0, False: 60.6k]
|
2459 | nkwargs = PyDict_GET_SIZE(kwargs); |
2460 | } |
2461 | else if (kwnames != NULL) { Branch (2461:14): [True: 56.9k, False: 3.68k]
|
2462 | nkwargs = PyTuple_GET_SIZE(kwnames); |
2463 | kwstack = args + nargs; |
2464 | } |
2465 | else { |
2466 | nkwargs = 0; |
2467 | } |
2468 | if (nargs < minposonly) { Branch (2468:9): [True: 0, False: 60.6k]
|
2469 | PyErr_Format(PyExc_TypeError, |
2470 | "%.200s%s takes %s %d positional argument%s" |
2471 | " (%zd given)", |
2472 | (parser->fname == NULL) ? "function" : parser->fname, Branch (2472:22): [True: 0, False: 0]
|
2473 | (parser->fname == NULL) ? "" : "()", Branch (2473:22): [True: 0, False: 0]
|
2474 | minposonly < maxpos ? "at least" : "exactly", Branch (2474:22): [True: 0, False: 0]
|
2475 | minposonly, |
2476 | minposonly == 1 ? "" : "s", Branch (2476:22): [True: 0, False: 0]
|
2477 | nargs); |
2478 | return NULL; |
2479 | } |
2480 | |
2481 | /* create varargs tuple */ |
2482 | varargssize = nargs - maxpos; |
2483 | if (varargssize < 0) { Branch (2483:9): [True: 0, False: 60.6k]
|
2484 | varargssize = 0; |
2485 | } |
2486 | buf[vararg] = PyTuple_New(varargssize); |
2487 | if (!buf[vararg]) { Branch (2487:9): [True: 0, False: 60.6k]
|
2488 | return NULL; |
2489 | } |
2490 | |
2491 | /* copy tuple args */ |
2492 | for (i = 0; 60.6k i < nargs; i++59.4k ) { Branch (2492:17): [True: 59.4k, False: 60.6k]
|
2493 | if (i >= vararg) { Branch (2493:13): [True: 59.4k, False: 0]
|
2494 | Py_INCREF(args[i]); |
2495 | PyTuple_SET_ITEM(buf[vararg], i - vararg, args[i]); |
2496 | continue; |
2497 | } |
2498 | else { |
2499 | buf[i] = args[i]; |
2500 | } |
2501 | } |
2502 | |
2503 | /* copy keyword args using kwtuple to drive process */ |
2504 | for (i = Py_MAX((int)nargs, posonly) - |
2505 | Py_SAFE_DOWNCAST60.6k (varargssize, Py_ssize_t, int); i < maxargs; i++242k ) { Branch (2505:58): [True: 242k, False: 60.6k]
|
2506 | if (nkwargs) { Branch (2506:13): [True: 168k, False: 74.0k]
|
2507 | keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); |
2508 | if (kwargs != NULL) { Branch (2508:17): [True: 0, False: 168k]
|
2509 | current_arg = PyDict_GetItemWithError(kwargs, keyword); |
2510 | if (!current_arg && PyErr_Occurred()) { Branch (2510:21): [True: 0, False: 0]
Branch (2510:37): [True: 0, False: 0]
|
2511 | goto exit; |
2512 | } |
2513 | } |
2514 | else { |
2515 | current_arg = find_keyword(kwnames, kwstack, keyword); |
2516 | } |
2517 | } |
2518 | else { |
2519 | current_arg = NULL; |
2520 | } |
2521 | |
2522 | buf[i + vararg + 1] = current_arg; |
2523 | |
2524 | if (current_arg) { Branch (2524:13): [True: 71.0k, False: 171k]
|
2525 | --nkwargs; |
2526 | } |
2527 | else if (i < minpos || (maxpos <= i && i < reqlimit)) { Branch (2527:18): [True: 0, False: 171k]
Branch (2527:33): [True: 171k, False: 0]
Branch (2527:48): [True: 0, False: 171k]
|
2528 | /* Less arguments than required */ |
2529 | keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); |
2530 | PyErr_Format(PyExc_TypeError, "%.200s%s missing required " |
2531 | "argument '%U' (pos %d)", |
2532 | (parser->fname == NULL) ? "function" : parser->fname, Branch (2532:26): [True: 0, False: 0]
|
2533 | (parser->fname == NULL) ? "" : "()", Branch (2533:26): [True: 0, False: 0]
|
2534 | keyword, i+1); |
2535 | goto exit; |
2536 | } |
2537 | } |
2538 | |
2539 | if (nkwargs > 0) { Branch (2539:9): [True: 1, False: 60.6k]
|
2540 | Py_ssize_t j; |
2541 | /* make sure there are no extraneous keyword arguments */ |
2542 | j = 0; |
2543 | while (1) { Branch (2543:16): [Folded - Ignored]
|
2544 | int match; |
2545 | if (kwargs != NULL) { Branch (2545:17): [True: 0, False: 5]
|
2546 | if (!PyDict_Next(kwargs, &j, &keyword, NULL)) Branch (2546:21): [True: 0, False: 0]
|
2547 | break; |
2548 | } |
2549 | else { |
2550 | if (j >= PyTuple_GET_SIZE(kwnames)) Branch (2550:21): [True: 0, False: 5]
|
2551 | break; |
2552 | keyword = PyTuple_GET_ITEM(kwnames, j); |
2553 | j++; |
2554 | } |
2555 | |
2556 | match = PySequence_Contains(kwtuple, keyword); |
2557 | if (match <= 0) { Branch (2557:17): [True: 1, False: 4]
|
2558 | if (!match) { Branch (2558:21): [True: 1, False: 0]
|
2559 | PyErr_Format(PyExc_TypeError, |
2560 | "'%S' is an invalid keyword " |
2561 | "argument for %.200s%s", |
2562 | keyword, |
2563 | (parser->fname == NULL) ? "this function"0 : parser->fname, Branch (2563:34): [True: 0, False: 1]
|
2564 | (parser->fname == NULL) ? ""0 : "()"); Branch (2564:34): [True: 0, False: 1]
|
2565 | } |
2566 | goto exit; |
2567 | } |
2568 | } |
2569 | } |
2570 | |
2571 | return buf; |
2572 | |
2573 | exit: |
2574 | Py_XDECREF(buf[vararg]); |
2575 | return NULL; |
2576 | } |
2577 | |
2578 | |
2579 | static const char * |
2580 | skipitem(const char **p_format, va_list *p_va, int flags) |
2581 | { |
2582 | const char *format = *p_format; |
2583 | char c = *format++; |
2584 | |
2585 | switch (c) { |
2586 | |
2587 | /* |
2588 | * codes that take a single data pointer as an argument |
2589 | * (the type of the pointer is irrelevant) |
2590 | */ |
2591 | |
2592 | case 'b': /* byte -- very short int */ Branch (2592:5): [True: 3, False: 652k]
|
2593 | case 'B': /* byte as bitfield */ Branch (2593:5): [True: 3, False: 652k]
|
2594 | case 'h': /* short int */ Branch (2594:5): [True: 3, False: 652k]
|
2595 | case 'H': /* short int as bitfield */ Branch (2595:5): [True: 3, False: 652k]
|
2596 | case 'i': /* int */ Branch (2596:5): [True: 177k, False: 475k]
|
2597 | case 'I': /* int sized bitfield */ Branch (2597:5): [True: 3, False: 652k]
|
2598 | case 'l': /* long int */ Branch (2598:5): [True: 3, False: 652k]
|
2599 | case 'k': /* long int sized bitfield */ Branch (2599:5): [True: 3, False: 652k]
|
2600 | case 'L': /* long long */ Branch (2600:5): [True: 3, False: 652k]
|
2601 | case 'K': /* long long sized bitfield */ Branch (2601:5): [True: 3, False: 652k]
|
2602 | case 'n': /* Py_ssize_t */ Branch (2602:5): [True: 189k, False: 463k]
|
2603 | case 'f': /* float */ Branch (2603:5): [True: 3, False: 652k]
|
2604 | case 'd': /* double */ Branch (2604:5): [True: 3, False: 652k]
|
2605 | case 'D': /* complex double */ Branch (2605:5): [True: 3, False: 652k]
|
2606 | case 'c': /* char */ Branch (2606:5): [True: 3, False: 652k]
|
2607 | case 'C': /* unicode char */ Branch (2607:5): [True: 192, False: 652k]
|
2608 | case 'p': /* boolean predicate */ Branch (2608:5): [True: 29, False: 652k]
|
2609 | case 'S': /* string object */ Branch (2609:5): [True: 3, False: 652k]
|
2610 | case 'Y': /* string object */ Branch (2610:5): [True: 3, False: 652k]
|
2611 | case 'U': /* unicode string object */ Branch (2611:5): [True: 3, False: 652k]
|
2612 | { |
2613 | if (p_va != NULL) { Branch (2613:17): [True: 366k, False: 4]
|
2614 | (void) va_arg(*p_va, void *); |
2615 | } |
2616 | break; |
2617 | } |
2618 | |
2619 | /* string codes */ |
2620 | |
2621 | case 'e': /* string with encoding */ Branch (2621:5): [True: 98, False: 652k]
|
2622 | { |
2623 | if (p_va != NULL) { Branch (2623:17): [True: 98, False: 0]
|
2624 | (void) va_arg(*p_va, const char *); |
2625 | } |
2626 | if (!(*format == 's' || *format == 't'97 )) Branch (2626:19): [True: 1, False: 97]
Branch (2626:37): [True: 1, False: 96]
|
2627 | /* after 'e', only 's' and 't' is allowed */ |
2628 | goto err; |
2629 | format++; |
2630 | } |
2631 | /* fall through */ |
2632 | |
2633 | case 's': /* string */ Branch (2633:5): [True: 10, False: 652k]
|
2634 | case 'z': /* string or None */ Branch (2634:5): [True: 3, False: 652k]
|
2635 | case 'y': /* bytes */ Branch (2635:5): [True: 5, False: 652k]
|
2636 | case 'w': /* buffer, read-write */ Branch (2636:5): [True: 3, False: 652k]
|
2637 | { |
2638 | if (p_va != NULL) { Branch (2638:17): [True: 20, False: 3]
|
2639 | (void) va_arg(*p_va, char **); |
2640 | } |
2641 | if (*format == '#') { Branch (2641:17): [True: 8, False: 15]
|
2642 | if (p_va != NULL) { Branch (2642:21): [True: 5, False: 3]
|
2643 | if (!(flags & FLAG_SIZE_T)) { Branch (2643:25): [True: 1, False: 4]
|
2644 | PyErr_SetString(PyExc_SystemError, |
2645 | "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); |
2646 | return NULL; |
2647 | } |
2648 | (void) va_arg(*p_va, Py_ssize_t *); |
2649 | } |
2650 | format++; |
2651 | } else if ((c == 's' || c == 'z'10 || c == 'y'8 || c == 'w'4 ) Branch (2651:25): [True: 5, False: 10]
Branch (2651:37): [True: 2, False: 8]
Branch (2651:49): [True: 4, False: 4]
Branch (2651:61): [True: 2, False: 2]
|
2652 | && *format == '*'13 ) Branch (2652:27): [True: 6, False: 7]
|
2653 | { |
2654 | format++; |
2655 | } |
2656 | break; |
2657 | } |
2658 | |
2659 | case 'O': /* object */ Branch (2659:5): [True: 285k, False: 367k]
|
2660 | { |
2661 | if (*format == '!') { Branch (2661:17): [True: 1, False: 285k]
|
2662 | format++; |
2663 | if (p_va != NULL) { Branch (2663:21): [True: 1, False: 0]
|
2664 | (void) va_arg(*p_va, PyTypeObject*); |
2665 | (void) va_arg(*p_va, PyObject **); |
2666 | } |
2667 | } |
2668 | else if (*format == '&') { Branch (2668:22): [True: 39, False: 285k]
|
2669 | typedef int (*converter)(PyObject *, void *); |
2670 | if (p_va != NULL) { Branch (2670:21): [True: 38, False: 1]
|
2671 | (void) va_arg(*p_va, converter); |
2672 | (void) va_arg(*p_va, void *); |
2673 | } |
2674 | format++; |
2675 | } |
2676 | else { |
2677 | if (p_va != NULL) { Branch (2677:21): [True: 285k, False: 2]
|
2678 | (void) va_arg(*p_va, PyObject **); |
2679 | } |
2680 | } |
2681 | break; |
2682 | } |
2683 | |
2684 | case '(': /* bypass tuple, not handled at all previously */ Branch (2684:5): [True: 6, False: 652k]
|
2685 | { |
2686 | const char *msg; |
2687 | for (;;) { |
2688 | if (*format==')') Branch (2688:21): [True: 6, False: 14]
|
2689 | break; |
2690 | if (IS_END_OF_FORMAT(*format)) |
2691 | return "Unmatched left paren in format " |
2692 | "string"; |
2693 | msg = skipitem(&format, p_va, flags); |
2694 | if (msg) Branch (2694:21): [True: 0, False: 14]
|
2695 | return msg; |
2696 | } |
2697 | format++; |
2698 | break; |
2699 | } |
2700 | |
2701 | case ')': Branch (2701:5): [True: 0, False: 652k]
|
2702 | return "Unmatched right paren in format string"; |
2703 | |
2704 | default: Branch (2704:5): [True: 115, False: 652k]
|
2705 | err: |
2706 | return "impossible<bad format char>"; |
2707 | |
2708 | } |
2709 | |
2710 | *p_format = format; |
2711 | return NULL; |
2712 | } |
2713 | |
2714 | |
2715 | #undef _PyArg_CheckPositional |
2716 | |
2717 | int |
2718 | _PyArg_CheckPositional(const char *name, Py_ssize_t nargs, |
2719 | Py_ssize_t min, Py_ssize_t max) |
2720 | { |
2721 | assert(min >= 0); |
2722 | assert(min <= max); |
2723 | |
2724 | if (nargs < min) { Branch (2724:9): [True: 284, False: 6.24M]
|
2725 | if (name != NULL) Branch (2725:13): [True: 284, False: 0]
|
2726 | PyErr_Format( |
2727 | PyExc_TypeError, |
2728 | "%.200s expected %s%zd argument%s, got %zd", |
2729 | name, (min == max ? ""163 : "at least "121 ), min, min == 1 ? ""129 : "s"155 , nargs); Branch (2729:24): [True: 163, False: 121]
Branch (2729:61): [True: 129, False: 155]
|
2730 | else |
2731 | PyErr_Format( |
2732 | PyExc_TypeError, |
2733 | "unpacked tuple should have %s%zd element%s," |
2734 | " but has %zd", |
2735 | (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs); Branch (2735:18): [True: 0, False: 0]
Branch (2735:55): [True: 0, False: 0]
|
2736 | return 0; |
2737 | } |
2738 | |
2739 | if (nargs == 0) { Branch (2739:9): [True: 52.2k, False: 6.19M]
|
2740 | return 1; |
2741 | } |
2742 | |
2743 | if (nargs > max) { Branch (2743:9): [True: 109, False: 6.19M]
|
2744 | if (name != NULL) Branch (2744:13): [True: 109, False: 0]
|
2745 | PyErr_Format( |
2746 | PyExc_TypeError, |
2747 | "%.200s expected %s%zd argument%s, got %zd", |
2748 | name, (min == max ? ""18 : "at most "91 ), max, max == 1 ? ""54 : "s"55 , nargs); Branch (2748:24): [True: 18, False: 91]
Branch (2748:60): [True: 54, False: 55]
|
2749 | else |
2750 | PyErr_Format( |
2751 | PyExc_TypeError, |
2752 | "unpacked tuple should have %s%zd element%s," |
2753 | " but has %zd", |
2754 | (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs); Branch (2754:18): [True: 0, False: 0]
Branch (2754:54): [True: 0, False: 0]
|
2755 | return 0; |
2756 | } |
2757 | |
2758 | return 1; |
2759 | } |
2760 | |
2761 | static int |
2762 | unpack_stack(PyObject *const *args, Py_ssize_t nargs, const char *name, |
2763 | Py_ssize_t min, Py_ssize_t max, va_list vargs) |
2764 | { |
2765 | Py_ssize_t i; |
2766 | PyObject **o; |
2767 | |
2768 | if (!_PyArg_CheckPositional(name, nargs, min, max)) { Branch (2768:9): [True: 61, False: 6.24M]
|
2769 | return 0; |
2770 | } |
2771 | |
2772 | for (i = 0; 6.24M i < nargs; i++11.4M ) { Branch (2772:17): [True: 11.4M, False: 6.24M]
|
2773 | o = va_arg(vargs, PyObject **); |
2774 | *o = args[i]; |
2775 | } |
2776 | return 1; |
2777 | } |
2778 | |
2779 | int |
2780 | PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) |
2781 | { |
2782 | PyObject **stack; |
2783 | Py_ssize_t nargs; |
2784 | int retval; |
2785 | va_list vargs; |
2786 | |
2787 | if (!PyTuple_Check(args)) { Branch (2787:9): [True: 0, False: 5.66M]
|
2788 | PyErr_SetString(PyExc_SystemError, |
2789 | "PyArg_UnpackTuple() argument list is not a tuple"); |
2790 | return 0; |
2791 | } |
2792 | stack = _PyTuple_ITEMS(args); |
2793 | nargs = PyTuple_GET_SIZE(args); |
2794 | |
2795 | va_start(vargs, max); |
2796 | retval = unpack_stack(stack, nargs, name, min, max, vargs); |
2797 | va_end(vargs); |
2798 | return retval; |
2799 | } |
2800 | |
2801 | int |
2802 | _PyArg_UnpackStack(PyObject *const *args, Py_ssize_t nargs, const char *name, |
2803 | Py_ssize_t min, Py_ssize_t max, ...) |
2804 | { |
2805 | int retval; |
2806 | va_list vargs; |
2807 | |
2808 | va_start(vargs, max); |
2809 | retval = unpack_stack(args, nargs, name, min, max, vargs); |
2810 | va_end(vargs); |
2811 | return retval; |
2812 | } |
2813 | |
2814 | |
2815 | #undef _PyArg_NoKeywords |
2816 | #undef _PyArg_NoKwnames |
2817 | #undef _PyArg_NoPositional |
2818 | |
2819 | /* For type constructors that don't take keyword args |
2820 | * |
2821 | * Sets a TypeError and returns 0 if the args/kwargs is |
2822 | * not empty, returns 1 otherwise |
2823 | */ |
2824 | int |
2825 | _PyArg_NoKeywords(const char *funcname, PyObject *kwargs) |
2826 | { |
2827 | if (kwargs == NULL) { Branch (2827:9): [True: 0, False: 58.6k]
|
2828 | return 1; |
2829 | } |
2830 | if (!PyDict_CheckExact(kwargs)) { Branch (2830:9): [True: 0, False: 58.6k]
|
2831 | PyErr_BadInternalCall(); |
2832 | return 0; |
2833 | } |
2834 | if (PyDict_GET_SIZE(kwargs) == 0) { Branch (2834:9): [True: 58.6k, False: 29]
|
2835 | return 1; |
2836 | } |
2837 | |
2838 | PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", |
2839 | funcname); |
2840 | return 0; |
2841 | } |
2842 | |
2843 | int |
2844 | _PyArg_NoPositional(const char *funcname, PyObject *args) |
2845 | { |
2846 | if (args == NULL) Branch (2846:9): [True: 0, False: 11.9k]
|
2847 | return 1; |
2848 | if (!PyTuple_CheckExact(args)) { Branch (2848:9): [True: 0, False: 11.9k]
|
2849 | PyErr_BadInternalCall(); |
2850 | return 0; |
2851 | } |
2852 | if (PyTuple_GET_SIZE(args) == 0) Branch (2852:9): [True: 11.9k, False: 1]
|
2853 | return 1; |
2854 | |
2855 | PyErr_Format(PyExc_TypeError, "%.200s() takes no positional arguments", |
2856 | funcname); |
2857 | return 0; |
2858 | } |
2859 | |
2860 | int |
2861 | _PyArg_NoKwnames(const char *funcname, PyObject *kwnames) |
2862 | { |
2863 | if (kwnames == NULL) { Branch (2863:9): [True: 0, False: 18]
|
2864 | return 1; |
2865 | } |
2866 | |
2867 | assert(PyTuple_CheckExact(kwnames)); |
2868 | |
2869 | if (PyTuple_GET_SIZE(kwnames) == 0) { Branch (2869:9): [True: 0, False: 18]
|
2870 | return 1; |
2871 | } |
2872 | |
2873 | PyErr_Format(PyExc_TypeError, "%s() takes no keyword arguments", funcname); |
2874 | return 0; |
2875 | } |
2876 | |
2877 | void |
2878 | _PyArg_Fini(void) |
2879 | { |
2880 | struct _PyArg_Parser *tmp, *s = static_arg_parsers; |
2881 | while (s) { Branch (2881:12): [True: 441, False: 103]
|
2882 | tmp = s->next; |
2883 | s->next = NULL; |
2884 | parser_clear(s); |
2885 | s = tmp; |
2886 | } |
2887 | static_arg_parsers = NULL; |
2888 | } |
2889 | |
2890 | #ifdef __cplusplus |
2891 | }; |
2892 | #endif |