Branch data Line data Source code
1 : : #include "Python.h"
2 : : #include "pycore_moduleobject.h" // _PyModule_GetState()
3 : : #include "structmember.h" // PyMemberDef
4 : : #include "pycore_runtime.h" // _Py_ID()
5 : : #include "clinic/_operator.c.h"
6 : :
7 : : typedef struct {
8 : : PyObject *itemgetter_type;
9 : : PyObject *attrgetter_type;
10 : : PyObject *methodcaller_type;
11 : : } _operator_state;
12 : :
13 : : static inline _operator_state*
14 : 56102 : get_operator_state(PyObject *module)
15 : : {
16 : 56102 : void *state = _PyModule_GetState(module);
17 : : assert(state != NULL);
18 : 56102 : return (_operator_state *)state;
19 : : }
20 : :
21 : : /*[clinic input]
22 : : module _operator
23 : : [clinic start generated code]*/
24 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=672ecf48487521e7]*/
25 : :
26 : : PyDoc_STRVAR(operator_doc,
27 : : "Operator interface.\n\
28 : : \n\
29 : : This module exports a set of functions implemented in C corresponding\n\
30 : : to the intrinsic operators of Python. For example, operator.add(x, y)\n\
31 : : is equivalent to the expression x+y. The function names are those\n\
32 : : used for special methods; variants without leading and trailing\n\
33 : : '__' are also provided for convenience.");
34 : :
35 : :
36 : : /*[clinic input]
37 : : _operator.truth -> bool
38 : :
39 : : a: object
40 : : /
41 : :
42 : : Return True if a is true, False otherwise.
43 : : [clinic start generated code]*/
44 : :
45 : : static int
46 : 8 : _operator_truth_impl(PyObject *module, PyObject *a)
47 : : /*[clinic end generated code: output=eaf87767234fa5d7 input=bc74a4cd90235875]*/
48 : : {
49 : 8 : return PyObject_IsTrue(a);
50 : : }
51 : :
52 : : /*[clinic input]
53 : : _operator.add
54 : :
55 : : a: object
56 : : b: object
57 : : /
58 : :
59 : : Same as a + b.
60 : : [clinic start generated code]*/
61 : :
62 : : static PyObject *
63 : 47 : _operator_add_impl(PyObject *module, PyObject *a, PyObject *b)
64 : : /*[clinic end generated code: output=8292984204f45164 input=5efe3bff856ac215]*/
65 : : {
66 : 47 : return PyNumber_Add(a, b);
67 : : }
68 : :
69 : : /*[clinic input]
70 : : _operator.sub = _operator.add
71 : :
72 : : Same as a - b.
73 : : [clinic start generated code]*/
74 : :
75 : : static PyObject *
76 : 96 : _operator_sub_impl(PyObject *module, PyObject *a, PyObject *b)
77 : : /*[clinic end generated code: output=4adfc3b888c1ee2e input=6494c6b100b8e795]*/
78 : : {
79 : 96 : return PyNumber_Subtract(a, b);
80 : : }
81 : :
82 : : /*[clinic input]
83 : : _operator.mul = _operator.add
84 : :
85 : : Same as a * b.
86 : : [clinic start generated code]*/
87 : :
88 : : static PyObject *
89 : 1704 : _operator_mul_impl(PyObject *module, PyObject *a, PyObject *b)
90 : : /*[clinic end generated code: output=d24d66f55a01944c input=2368615b4358b70d]*/
91 : : {
92 : 1704 : return PyNumber_Multiply(a, b);
93 : : }
94 : :
95 : : /*[clinic input]
96 : : _operator.matmul = _operator.add
97 : :
98 : : Same as a @ b.
99 : : [clinic start generated code]*/
100 : :
101 : : static PyObject *
102 : 1 : _operator_matmul_impl(PyObject *module, PyObject *a, PyObject *b)
103 : : /*[clinic end generated code: output=a20d917eb35d0101 input=9ab304e37fb42dd4]*/
104 : : {
105 : 1 : return PyNumber_MatrixMultiply(a, b);
106 : : }
107 : :
108 : : /*[clinic input]
109 : : _operator.floordiv = _operator.add
110 : :
111 : : Same as a // b.
112 : : [clinic start generated code]*/
113 : :
114 : : static PyObject *
115 : 7 : _operator_floordiv_impl(PyObject *module, PyObject *a, PyObject *b)
116 : : /*[clinic end generated code: output=df26b71a60589f99 input=bb2e88ba446c612c]*/
117 : : {
118 : 7 : return PyNumber_FloorDivide(a, b);
119 : : }
120 : :
121 : : /*[clinic input]
122 : : _operator.truediv = _operator.add
123 : :
124 : : Same as a / b.
125 : : [clinic start generated code]*/
126 : :
127 : : static PyObject *
128 : 8 : _operator_truediv_impl(PyObject *module, PyObject *a, PyObject *b)
129 : : /*[clinic end generated code: output=0e6a959944d77719 input=ecbb947673f4eb1f]*/
130 : : {
131 : 8 : return PyNumber_TrueDivide(a, b);
132 : : }
133 : :
134 : : /*[clinic input]
135 : : _operator.mod = _operator.add
136 : :
137 : : Same as a % b.
138 : : [clinic start generated code]*/
139 : :
140 : : static PyObject *
141 : 30 : _operator_mod_impl(PyObject *module, PyObject *a, PyObject *b)
142 : : /*[clinic end generated code: output=9519822f0bbec166 input=102e19b422342ac1]*/
143 : : {
144 : 30 : return PyNumber_Remainder(a, b);
145 : : }
146 : :
147 : : /*[clinic input]
148 : : _operator.neg
149 : :
150 : : a: object
151 : : /
152 : :
153 : : Same as -a.
154 : : [clinic start generated code]*/
155 : :
156 : : static PyObject *
157 : 19 : _operator_neg(PyObject *module, PyObject *a)
158 : : /*[clinic end generated code: output=36e08ecfc6a1c08c input=84f09bdcf27c96ec]*/
159 : : {
160 : 19 : return PyNumber_Negative(a);
161 : : }
162 : :
163 : : /*[clinic input]
164 : : _operator.pos = _operator.neg
165 : :
166 : : Same as +a.
167 : : [clinic start generated code]*/
168 : :
169 : : static PyObject *
170 : 5 : _operator_pos(PyObject *module, PyObject *a)
171 : : /*[clinic end generated code: output=dad7a126221dd091 input=b6445b63fddb8772]*/
172 : : {
173 : 5 : return PyNumber_Positive(a);
174 : : }
175 : :
176 : : /*[clinic input]
177 : : _operator.abs = _operator.neg
178 : :
179 : : Same as abs(a).
180 : : [clinic start generated code]*/
181 : :
182 : : static PyObject *
183 : 3 : _operator_abs(PyObject *module, PyObject *a)
184 : : /*[clinic end generated code: output=1389a93ba053ea3e input=341d07ba86f58039]*/
185 : : {
186 : 3 : return PyNumber_Absolute(a);
187 : : }
188 : :
189 : : /*[clinic input]
190 : : _operator.inv = _operator.neg
191 : :
192 : : Same as ~a.
193 : : [clinic start generated code]*/
194 : :
195 : : static PyObject *
196 : 1 : _operator_inv(PyObject *module, PyObject *a)
197 : : /*[clinic end generated code: output=a56875ba075ee06d input=b01a4677739f6eb2]*/
198 : : {
199 : 1 : return PyNumber_Invert(a);
200 : : }
201 : :
202 : : /*[clinic input]
203 : : _operator.invert = _operator.neg
204 : :
205 : : Same as ~a.
206 : : [clinic start generated code]*/
207 : :
208 : : static PyObject *
209 : 1 : _operator_invert(PyObject *module, PyObject *a)
210 : : /*[clinic end generated code: output=406b5aa030545fcc input=7f2d607176672e55]*/
211 : : {
212 : 1 : return PyNumber_Invert(a);
213 : : }
214 : :
215 : : /*[clinic input]
216 : : _operator.lshift = _operator.add
217 : :
218 : : Same as a << b.
219 : : [clinic start generated code]*/
220 : :
221 : : static PyObject *
222 : 4 : _operator_lshift_impl(PyObject *module, PyObject *a, PyObject *b)
223 : : /*[clinic end generated code: output=37f7e52c41435bd8 input=746e8a160cbbc9eb]*/
224 : : {
225 : 4 : return PyNumber_Lshift(a, b);
226 : : }
227 : :
228 : : /*[clinic input]
229 : : _operator.rshift = _operator.add
230 : :
231 : : Same as a >> b.
232 : : [clinic start generated code]*/
233 : :
234 : : static PyObject *
235 : 4 : _operator_rshift_impl(PyObject *module, PyObject *a, PyObject *b)
236 : : /*[clinic end generated code: output=4593c7ef30ec2ee3 input=d2c85bb5a64504c2]*/
237 : : {
238 : 4 : return PyNumber_Rshift(a, b);
239 : : }
240 : :
241 : : /*[clinic input]
242 : : _operator.not_ = _operator.truth
243 : :
244 : : Same as not a.
245 : : [clinic start generated code]*/
246 : :
247 : : static int
248 : 3 : _operator_not__impl(PyObject *module, PyObject *a)
249 : : /*[clinic end generated code: output=743f9c24a09759ef input=854156d50804d9b8]*/
250 : : {
251 : 3 : return PyObject_Not(a);
252 : : }
253 : :
254 : : /*[clinic input]
255 : : _operator.and_ = _operator.add
256 : :
257 : : Same as a & b.
258 : : [clinic start generated code]*/
259 : :
260 : : static PyObject *
261 : 3 : _operator_and__impl(PyObject *module, PyObject *a, PyObject *b)
262 : : /*[clinic end generated code: output=93c4fe88f7b76d9e input=4f3057c90ec4c99f]*/
263 : : {
264 : 3 : return PyNumber_And(a, b);
265 : : }
266 : :
267 : : /*[clinic input]
268 : : _operator.xor = _operator.add
269 : :
270 : : Same as a ^ b.
271 : : [clinic start generated code]*/
272 : :
273 : : static PyObject *
274 : 3 : _operator_xor_impl(PyObject *module, PyObject *a, PyObject *b)
275 : : /*[clinic end generated code: output=b24cd8b79fde0004 input=3c5cfa7253d808dd]*/
276 : : {
277 : 3 : return PyNumber_Xor(a, b);
278 : : }
279 : :
280 : : /*[clinic input]
281 : : _operator.or_ = _operator.add
282 : :
283 : : Same as a | b.
284 : : [clinic start generated code]*/
285 : :
286 : : static PyObject *
287 : 66 : _operator_or__impl(PyObject *module, PyObject *a, PyObject *b)
288 : : /*[clinic end generated code: output=58024867b8d90461 input=b40c6c44f7c79c09]*/
289 : : {
290 : 66 : return PyNumber_Or(a, b);
291 : : }
292 : :
293 : : /*[clinic input]
294 : : _operator.iadd = _operator.add
295 : :
296 : : Same as a += b.
297 : : [clinic start generated code]*/
298 : :
299 : : static PyObject *
300 : 1 : _operator_iadd_impl(PyObject *module, PyObject *a, PyObject *b)
301 : : /*[clinic end generated code: output=07dc627832526eb5 input=d22a91c07ac69227]*/
302 : : {
303 : 1 : return PyNumber_InPlaceAdd(a, b);
304 : : }
305 : :
306 : : /*[clinic input]
307 : : _operator.isub = _operator.add
308 : :
309 : : Same as a -= b.
310 : : [clinic start generated code]*/
311 : :
312 : : static PyObject *
313 : 1 : _operator_isub_impl(PyObject *module, PyObject *a, PyObject *b)
314 : : /*[clinic end generated code: output=4513467d23b5e0b1 input=4591b00d0a0ccafd]*/
315 : : {
316 : 1 : return PyNumber_InPlaceSubtract(a, b);
317 : : }
318 : :
319 : : /*[clinic input]
320 : : _operator.imul = _operator.add
321 : :
322 : : Same as a *= b.
323 : : [clinic start generated code]*/
324 : :
325 : : static PyObject *
326 : 27 : _operator_imul_impl(PyObject *module, PyObject *a, PyObject *b)
327 : : /*[clinic end generated code: output=5e87dacd19a71eab input=0e01fb8631e1b76f]*/
328 : : {
329 : 27 : return PyNumber_InPlaceMultiply(a, b);
330 : : }
331 : :
332 : : /*[clinic input]
333 : : _operator.imatmul = _operator.add
334 : :
335 : : Same as a @= b.
336 : : [clinic start generated code]*/
337 : :
338 : : static PyObject *
339 : 1 : _operator_imatmul_impl(PyObject *module, PyObject *a, PyObject *b)
340 : : /*[clinic end generated code: output=d603cbdf716ce519 input=bb614026372cd542]*/
341 : : {
342 : 1 : return PyNumber_InPlaceMatrixMultiply(a, b);
343 : : }
344 : :
345 : : /*[clinic input]
346 : : _operator.ifloordiv = _operator.add
347 : :
348 : : Same as a //= b.
349 : : [clinic start generated code]*/
350 : :
351 : : static PyObject *
352 : 1 : _operator_ifloordiv_impl(PyObject *module, PyObject *a, PyObject *b)
353 : : /*[clinic end generated code: output=535336048c681794 input=9df3b5021cff4ca1]*/
354 : : {
355 : 1 : return PyNumber_InPlaceFloorDivide(a, b);
356 : : }
357 : :
358 : : /*[clinic input]
359 : : _operator.itruediv = _operator.add
360 : :
361 : : Same as a /= b.
362 : : [clinic start generated code]*/
363 : :
364 : : static PyObject *
365 : 1 : _operator_itruediv_impl(PyObject *module, PyObject *a, PyObject *b)
366 : : /*[clinic end generated code: output=28017fbd3563952f input=9a1ee01608f5f590]*/
367 : : {
368 : 1 : return PyNumber_InPlaceTrueDivide(a, b);
369 : : }
370 : :
371 : : /*[clinic input]
372 : : _operator.imod = _operator.add
373 : :
374 : : Same as a %= b.
375 : : [clinic start generated code]*/
376 : :
377 : : static PyObject *
378 : 1 : _operator_imod_impl(PyObject *module, PyObject *a, PyObject *b)
379 : : /*[clinic end generated code: output=f7c540ae0fc70904 input=d0c384a3ce38e1dd]*/
380 : : {
381 : 1 : return PyNumber_InPlaceRemainder(a, b);
382 : : }
383 : :
384 : : /*[clinic input]
385 : : _operator.ilshift = _operator.add
386 : :
387 : : Same as a <<= b.
388 : : [clinic start generated code]*/
389 : :
390 : : static PyObject *
391 : 1 : _operator_ilshift_impl(PyObject *module, PyObject *a, PyObject *b)
392 : : /*[clinic end generated code: output=e73a8fee1ac18749 input=e21b6b310f54572e]*/
393 : : {
394 : 1 : return PyNumber_InPlaceLshift(a, b);
395 : : }
396 : :
397 : : /*[clinic input]
398 : : _operator.irshift = _operator.add
399 : :
400 : : Same as a >>= b.
401 : : [clinic start generated code]*/
402 : :
403 : : static PyObject *
404 : 1 : _operator_irshift_impl(PyObject *module, PyObject *a, PyObject *b)
405 : : /*[clinic end generated code: output=97f2af6b5ff2ed81 input=6778dbd0f6e1ec16]*/
406 : : {
407 : 1 : return PyNumber_InPlaceRshift(a, b);
408 : : }
409 : :
410 : : /*[clinic input]
411 : : _operator.iand = _operator.add
412 : :
413 : : Same as a &= b.
414 : : [clinic start generated code]*/
415 : :
416 : : static PyObject *
417 : 1 : _operator_iand_impl(PyObject *module, PyObject *a, PyObject *b)
418 : : /*[clinic end generated code: output=4599e9d40cbf7d00 input=71dfd8e70c156a7b]*/
419 : : {
420 : 1 : return PyNumber_InPlaceAnd(a, b);
421 : : }
422 : :
423 : : /*[clinic input]
424 : : _operator.ixor = _operator.add
425 : :
426 : : Same as a ^= b.
427 : : [clinic start generated code]*/
428 : :
429 : : static PyObject *
430 : 1 : _operator_ixor_impl(PyObject *module, PyObject *a, PyObject *b)
431 : : /*[clinic end generated code: output=5ff881766872be03 input=695c32bec0604d86]*/
432 : : {
433 : 1 : return PyNumber_InPlaceXor(a, b);
434 : : }
435 : :
436 : : /*[clinic input]
437 : : _operator.ior = _operator.add
438 : :
439 : : Same as a |= b.
440 : : [clinic start generated code]*/
441 : :
442 : : static PyObject *
443 : 1 : _operator_ior_impl(PyObject *module, PyObject *a, PyObject *b)
444 : : /*[clinic end generated code: output=48aac319445bf759 input=8f01d03eda9920cf]*/
445 : : {
446 : 1 : return PyNumber_InPlaceOr(a, b);
447 : : }
448 : :
449 : : /*[clinic input]
450 : : _operator.concat = _operator.add
451 : :
452 : : Same as a + b, for a and b sequences.
453 : : [clinic start generated code]*/
454 : :
455 : : static PyObject *
456 : 6 : _operator_concat_impl(PyObject *module, PyObject *a, PyObject *b)
457 : : /*[clinic end generated code: output=80028390942c5f11 input=8544ccd5341a3658]*/
458 : : {
459 : 6 : return PySequence_Concat(a, b);
460 : : }
461 : :
462 : : /*[clinic input]
463 : : _operator.iconcat = _operator.add
464 : :
465 : : Same as a += b, for a and b sequences.
466 : : [clinic start generated code]*/
467 : :
468 : : static PyObject *
469 : 1 : _operator_iconcat_impl(PyObject *module, PyObject *a, PyObject *b)
470 : : /*[clinic end generated code: output=3ea0a162ebb2e26d input=8f5fe5722fcd837e]*/
471 : : {
472 : 1 : return PySequence_InPlaceConcat(a, b);
473 : : }
474 : :
475 : : /*[clinic input]
476 : : _operator.contains -> bool
477 : :
478 : : a: object
479 : : b: object
480 : : /
481 : :
482 : : Same as b in a (note reversed operands).
483 : : [clinic start generated code]*/
484 : :
485 : : static int
486 : 7 : _operator_contains_impl(PyObject *module, PyObject *a, PyObject *b)
487 : : /*[clinic end generated code: output=413b4dbe82b6ffc1 input=9122a69b505fde13]*/
488 : : {
489 : 7 : return PySequence_Contains(a, b);
490 : : }
491 : :
492 : : /*[clinic input]
493 : : _operator.indexOf -> Py_ssize_t
494 : :
495 : : a: object
496 : : b: object
497 : : /
498 : :
499 : : Return the first index of b in a.
500 : : [clinic start generated code]*/
501 : :
502 : : static Py_ssize_t
503 : 26 : _operator_indexOf_impl(PyObject *module, PyObject *a, PyObject *b)
504 : : /*[clinic end generated code: output=c6226d8e0fb60fa6 input=8be2e43b6a6fffe3]*/
505 : : {
506 : 26 : return PySequence_Index(a, b);
507 : : }
508 : :
509 : : /*[clinic input]
510 : : _operator.countOf = _operator.indexOf
511 : :
512 : : Return the number of items in a which are, or which equal, b.
513 : : [clinic start generated code]*/
514 : :
515 : : static Py_ssize_t
516 : 23 : _operator_countOf_impl(PyObject *module, PyObject *a, PyObject *b)
517 : : /*[clinic end generated code: output=9e1623197daf3382 input=93ea57f170f3f0bb]*/
518 : : {
519 : 23 : return PySequence_Count(a, b);
520 : : }
521 : :
522 : : /*[clinic input]
523 : : _operator.getitem
524 : :
525 : : a: object
526 : : b: object
527 : : /
528 : :
529 : : Same as a[b].
530 : : [clinic start generated code]*/
531 : :
532 : : static PyObject *
533 : 623 : _operator_getitem_impl(PyObject *module, PyObject *a, PyObject *b)
534 : : /*[clinic end generated code: output=6c8d8101a676e594 input=6682797320e48845]*/
535 : : {
536 : 623 : return PyObject_GetItem(a, b);
537 : : }
538 : :
539 : : /*[clinic input]
540 : : _operator.setitem
541 : :
542 : : a: object
543 : : b: object
544 : : c: object
545 : : /
546 : :
547 : : Same as a[b] = c.
548 : : [clinic start generated code]*/
549 : :
550 : : static PyObject *
551 : 134 : _operator_setitem_impl(PyObject *module, PyObject *a, PyObject *b,
552 : : PyObject *c)
553 : : /*[clinic end generated code: output=1324f9061ae99e25 input=ceaf453c4d3a58df]*/
554 : : {
555 [ + + ]: 134 : if (-1 == PyObject_SetItem(a, b, c))
556 : 23 : return NULL;
557 : 111 : Py_RETURN_NONE;
558 : : }
559 : :
560 : : /*[clinic input]
561 : : _operator.delitem = _operator.getitem
562 : :
563 : : Same as del a[b].
564 : : [clinic start generated code]*/
565 : :
566 : : static PyObject *
567 : 43 : _operator_delitem_impl(PyObject *module, PyObject *a, PyObject *b)
568 : : /*[clinic end generated code: output=db18f61506295799 input=991bec56a0d3ec7f]*/
569 : : {
570 [ + + ]: 43 : if (-1 == PyObject_DelItem(a, b))
571 : 41 : return NULL;
572 : 2 : Py_RETURN_NONE;
573 : : }
574 : :
575 : : /*[clinic input]
576 : : _operator.eq
577 : :
578 : : a: object
579 : : b: object
580 : : /
581 : :
582 : : Same as a == b.
583 : : [clinic start generated code]*/
584 : :
585 : : static PyObject *
586 : 2251 : _operator_eq_impl(PyObject *module, PyObject *a, PyObject *b)
587 : : /*[clinic end generated code: output=8d7d46ed4135677c input=586fca687a95a83f]*/
588 : : {
589 : 2251 : return PyObject_RichCompare(a, b, Py_EQ);
590 : : }
591 : :
592 : : /*[clinic input]
593 : : _operator.ne = _operator.eq
594 : :
595 : : Same as a != b.
596 : : [clinic start generated code]*/
597 : :
598 : : static PyObject *
599 : 422 : _operator_ne_impl(PyObject *module, PyObject *a, PyObject *b)
600 : : /*[clinic end generated code: output=c99bd0c3a4c01297 input=5d88f23d35e9abac]*/
601 : : {
602 : 422 : return PyObject_RichCompare(a, b, Py_NE);
603 : : }
604 : :
605 : : /*[clinic input]
606 : : _operator.lt = _operator.eq
607 : :
608 : : Same as a < b.
609 : : [clinic start generated code]*/
610 : :
611 : : static PyObject *
612 : 1339 : _operator_lt_impl(PyObject *module, PyObject *a, PyObject *b)
613 : : /*[clinic end generated code: output=082d7c45c440e535 input=34a59ad6d39d3a2b]*/
614 : : {
615 : 1339 : return PyObject_RichCompare(a, b, Py_LT);
616 : : }
617 : :
618 : : /*[clinic input]
619 : : _operator.le = _operator.eq
620 : :
621 : : Same as a <= b.
622 : : [clinic start generated code]*/
623 : :
624 : : static PyObject *
625 : 127845 : _operator_le_impl(PyObject *module, PyObject *a, PyObject *b)
626 : : /*[clinic end generated code: output=00970a2923d0ae17 input=b812a7860a0bef44]*/
627 : : {
628 : 127845 : return PyObject_RichCompare(a, b, Py_LE);
629 : : }
630 : :
631 : : /*[clinic input]
632 : : _operator.gt = _operator.eq
633 : :
634 : : Same as a > b.
635 : : [clinic start generated code]*/
636 : :
637 : : static PyObject *
638 : 905 : _operator_gt_impl(PyObject *module, PyObject *a, PyObject *b)
639 : : /*[clinic end generated code: output=8d373349ecf25641 input=9bdb45b995ada35b]*/
640 : : {
641 : 905 : return PyObject_RichCompare(a, b, Py_GT);
642 : : }
643 : :
644 : : /*[clinic input]
645 : : _operator.ge = _operator.eq
646 : :
647 : : Same as a >= b.
648 : : [clinic start generated code]*/
649 : :
650 : : static PyObject *
651 : 442 : _operator_ge_impl(PyObject *module, PyObject *a, PyObject *b)
652 : : /*[clinic end generated code: output=7ce3882256d4b137 input=cf1dc4a5ca9c35f5]*/
653 : : {
654 : 442 : return PyObject_RichCompare(a, b, Py_GE);
655 : : }
656 : :
657 : : /*[clinic input]
658 : : _operator.pow = _operator.add
659 : :
660 : : Same as a ** b.
661 : : [clinic start generated code]*/
662 : :
663 : : static PyObject *
664 : 1404 : _operator_pow_impl(PyObject *module, PyObject *a, PyObject *b)
665 : : /*[clinic end generated code: output=09e668ad50036120 input=690b40f097ab1637]*/
666 : : {
667 : 1404 : return PyNumber_Power(a, b, Py_None);
668 : : }
669 : :
670 : : /*[clinic input]
671 : : _operator.ipow = _operator.add
672 : :
673 : : Same as a **= b.
674 : : [clinic start generated code]*/
675 : :
676 : : static PyObject *
677 : 1 : _operator_ipow_impl(PyObject *module, PyObject *a, PyObject *b)
678 : : /*[clinic end generated code: output=7189ff4d4367c808 input=f00623899d07499a]*/
679 : : {
680 : 1 : return PyNumber_InPlacePower(a, b, Py_None);
681 : : }
682 : :
683 : : /*[clinic input]
684 : : _operator.index
685 : :
686 : : a: object
687 : : /
688 : :
689 : : Same as a.__index__()
690 : : [clinic start generated code]*/
691 : :
692 : : static PyObject *
693 : 5821774 : _operator_index(PyObject *module, PyObject *a)
694 : : /*[clinic end generated code: output=d972b0764ac305fc input=6f54d50ea64a579c]*/
695 : : {
696 : 5821774 : return PyNumber_Index(a);
697 : : }
698 : :
699 : : /*[clinic input]
700 : : _operator.is_ = _operator.add
701 : :
702 : : Same as a is b.
703 : : [clinic start generated code]*/
704 : :
705 : : static PyObject *
706 : 20 : _operator_is__impl(PyObject *module, PyObject *a, PyObject *b)
707 : : /*[clinic end generated code: output=bcd47a402e482e1d input=5fa9b97df03c427f]*/
708 : : {
709 [ + + ]: 20 : PyObject *result = Py_Is(a, b) ? Py_True : Py_False;
710 : 20 : return Py_NewRef(result);
711 : : }
712 : :
713 : : /*[clinic input]
714 : : _operator.is_not = _operator.add
715 : :
716 : : Same as a is not b.
717 : : [clinic start generated code]*/
718 : :
719 : : static PyObject *
720 : 4 : _operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b)
721 : : /*[clinic end generated code: output=491a1f2f81f6c7f9 input=5a93f7e1a93535f1]*/
722 : : {
723 : : PyObject *result;
724 [ + + ]: 4 : result = (a != b) ? Py_True : Py_False;
725 : 4 : Py_INCREF(result);
726 : 4 : return result;
727 : : }
728 : :
729 : : /* compare_digest **********************************************************/
730 : :
731 : : /*
732 : : * timing safe compare
733 : : *
734 : : * Returns 1 of the strings are equal.
735 : : * In case of len(a) != len(b) the function tries to keep the timing
736 : : * dependent on the length of b. CPU cache locally may still alter timing
737 : : * a bit.
738 : : */
739 : : static int
740 : 24 : _tscmp(const unsigned char *a, const unsigned char *b,
741 : : Py_ssize_t len_a, Py_ssize_t len_b)
742 : : {
743 : : /* The volatile type declarations make sure that the compiler has no
744 : : * chance to optimize and fold the code in any way that may change
745 : : * the timing.
746 : : */
747 : : volatile Py_ssize_t length;
748 : : volatile const unsigned char *left;
749 : : volatile const unsigned char *right;
750 : : Py_ssize_t i;
751 : : volatile unsigned char result;
752 : :
753 : : /* loop count depends on length of b */
754 : 24 : length = len_b;
755 : 24 : left = NULL;
756 : 24 : right = b;
757 : :
758 : : /* don't use else here to keep the amount of CPU instructions constant,
759 : : * volatile forces re-evaluation
760 : : * */
761 [ + + ]: 24 : if (len_a == length) {
762 : 18 : left = *((volatile const unsigned char**)&a);
763 : 18 : result = 0;
764 : : }
765 [ + + ]: 24 : if (len_a != length) {
766 : 6 : left = b;
767 : 6 : result = 1;
768 : : }
769 : :
770 [ + + ]: 151 : for (i=0; i < length; i++) {
771 : 127 : result |= *left++ ^ *right++;
772 : : }
773 : :
774 : 24 : return (result == 0);
775 : : }
776 : :
777 : : /*[clinic input]
778 : : _operator.length_hint -> Py_ssize_t
779 : :
780 : : obj: object
781 : : default: Py_ssize_t = 0
782 : : /
783 : :
784 : : Return an estimate of the number of items in obj.
785 : :
786 : : This is useful for presizing containers when building from an iterable.
787 : :
788 : : If the object supports len(), the result will be exact.
789 : : Otherwise, it may over- or under-estimate by an arbitrary amount.
790 : : The result will be an integer >= 0.
791 : : [clinic start generated code]*/
792 : :
793 : : static Py_ssize_t
794 : 199 : _operator_length_hint_impl(PyObject *module, PyObject *obj,
795 : : Py_ssize_t default_value)
796 : : /*[clinic end generated code: output=01d469edc1d612ad input=65ed29f04401e96a]*/
797 : : {
798 : 199 : return PyObject_LengthHint(obj, default_value);
799 : : }
800 : :
801 : : /* NOTE: Keep in sync with _hashopenssl.c implementation. */
802 : :
803 : : /*[clinic input]
804 : : _operator._compare_digest = _operator.eq
805 : :
806 : : Return 'a == b'.
807 : :
808 : : This function uses an approach designed to prevent
809 : : timing analysis, making it appropriate for cryptography.
810 : :
811 : : a and b must both be of the same type: either str (ASCII only),
812 : : or any bytes-like object.
813 : :
814 : : Note: If a and b are of different lengths, or if an error occurs,
815 : : a timing attack could theoretically reveal information about the
816 : : types and lengths of a and b--but not their values.
817 : : [clinic start generated code]*/
818 : :
819 : : static PyObject *
820 : 34 : _operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b)
821 : : /*[clinic end generated code: output=11d452bdd3a23cbc input=9ac7e2c4e30bc356]*/
822 : : {
823 : : int rc;
824 : :
825 : : /* ASCII unicode string */
826 [ + + + + ]: 34 : if(PyUnicode_Check(a) && PyUnicode_Check(b)) {
827 [ + - - + ]: 7 : if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) {
828 : 0 : return NULL;
829 : : }
830 [ + + - + ]: 7 : if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) {
831 : 1 : PyErr_SetString(PyExc_TypeError,
832 : : "comparing strings with non-ASCII characters is "
833 : : "not supported");
834 : 1 : return NULL;
835 : : }
836 : :
837 : 12 : rc = _tscmp(PyUnicode_DATA(a),
838 : 6 : PyUnicode_DATA(b),
839 : : PyUnicode_GET_LENGTH(a),
840 : : PyUnicode_GET_LENGTH(b));
841 : : }
842 : : /* fallback to buffer interface for bytes, bytearray and other */
843 : : else {
844 : : Py_buffer view_a;
845 : : Py_buffer view_b;
846 : :
847 [ + + + + ]: 27 : if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) {
848 : 2 : PyErr_Format(PyExc_TypeError,
849 : : "unsupported operand types(s) or combination of types: "
850 : : "'%.100s' and '%.100s'",
851 : 2 : Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
852 : 9 : return NULL;
853 : : }
854 : :
855 [ + + ]: 25 : if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) {
856 : 3 : return NULL;
857 : : }
858 [ - + ]: 22 : if (view_a.ndim > 1) {
859 : 0 : PyErr_SetString(PyExc_BufferError,
860 : : "Buffer must be single dimension");
861 : 0 : PyBuffer_Release(&view_a);
862 : 0 : return NULL;
863 : : }
864 : :
865 [ + + ]: 22 : if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) {
866 : 4 : PyBuffer_Release(&view_a);
867 : 4 : return NULL;
868 : : }
869 [ - + ]: 18 : if (view_b.ndim > 1) {
870 : 0 : PyErr_SetString(PyExc_BufferError,
871 : : "Buffer must be single dimension");
872 : 0 : PyBuffer_Release(&view_a);
873 : 0 : PyBuffer_Release(&view_b);
874 : 0 : return NULL;
875 : : }
876 : :
877 : 18 : rc = _tscmp((const unsigned char*)view_a.buf,
878 : 18 : (const unsigned char*)view_b.buf,
879 : : view_a.len,
880 : : view_b.len);
881 : :
882 : 18 : PyBuffer_Release(&view_a);
883 : 18 : PyBuffer_Release(&view_b);
884 : : }
885 : :
886 : 24 : return PyBool_FromLong(rc);
887 : : }
888 : :
889 : : PyDoc_STRVAR(_operator_call__doc__,
890 : : "call($module, obj, /, *args, **kwargs)\n"
891 : : "--\n"
892 : : "\n"
893 : : "Same as obj(*args, **kwargs).");
894 : :
895 : : #define _OPERATOR_CALL_METHODDEF \
896 : : {"call", _PyCFunction_CAST(_operator_call), METH_FASTCALL | METH_KEYWORDS, _operator_call__doc__},
897 : :
898 : : static PyObject *
899 : 4 : _operator_call(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
900 : : {
901 [ - + ]: 4 : if (!_PyArg_CheckPositional("call", nargs, 1, PY_SSIZE_T_MAX)) {
902 : 0 : return NULL;
903 : : }
904 : 4 : return PyObject_Vectorcall(
905 : : args[0],
906 : 4 : &args[1], (PyVectorcall_NARGS(nargs) - 1) | PY_VECTORCALL_ARGUMENTS_OFFSET,
907 : : kwnames);
908 : : }
909 : :
910 : : /* operator methods **********************************************************/
911 : :
912 : : static struct PyMethodDef operator_methods[] = {
913 : :
914 : : _OPERATOR_TRUTH_METHODDEF
915 : : _OPERATOR_CONTAINS_METHODDEF
916 : : _OPERATOR_INDEXOF_METHODDEF
917 : : _OPERATOR_COUNTOF_METHODDEF
918 : : _OPERATOR_IS__METHODDEF
919 : : _OPERATOR_IS_NOT_METHODDEF
920 : : _OPERATOR_INDEX_METHODDEF
921 : : _OPERATOR_ADD_METHODDEF
922 : : _OPERATOR_SUB_METHODDEF
923 : : _OPERATOR_MUL_METHODDEF
924 : : _OPERATOR_MATMUL_METHODDEF
925 : : _OPERATOR_FLOORDIV_METHODDEF
926 : : _OPERATOR_TRUEDIV_METHODDEF
927 : : _OPERATOR_MOD_METHODDEF
928 : : _OPERATOR_NEG_METHODDEF
929 : : _OPERATOR_POS_METHODDEF
930 : : _OPERATOR_ABS_METHODDEF
931 : : _OPERATOR_INV_METHODDEF
932 : : _OPERATOR_INVERT_METHODDEF
933 : : _OPERATOR_LSHIFT_METHODDEF
934 : : _OPERATOR_RSHIFT_METHODDEF
935 : : _OPERATOR_NOT__METHODDEF
936 : : _OPERATOR_AND__METHODDEF
937 : : _OPERATOR_XOR_METHODDEF
938 : : _OPERATOR_OR__METHODDEF
939 : : _OPERATOR_IADD_METHODDEF
940 : : _OPERATOR_ISUB_METHODDEF
941 : : _OPERATOR_IMUL_METHODDEF
942 : : _OPERATOR_IMATMUL_METHODDEF
943 : : _OPERATOR_IFLOORDIV_METHODDEF
944 : : _OPERATOR_ITRUEDIV_METHODDEF
945 : : _OPERATOR_IMOD_METHODDEF
946 : : _OPERATOR_ILSHIFT_METHODDEF
947 : : _OPERATOR_IRSHIFT_METHODDEF
948 : : _OPERATOR_IAND_METHODDEF
949 : : _OPERATOR_IXOR_METHODDEF
950 : : _OPERATOR_IOR_METHODDEF
951 : : _OPERATOR_CONCAT_METHODDEF
952 : : _OPERATOR_ICONCAT_METHODDEF
953 : : _OPERATOR_GETITEM_METHODDEF
954 : : _OPERATOR_SETITEM_METHODDEF
955 : : _OPERATOR_DELITEM_METHODDEF
956 : : _OPERATOR_POW_METHODDEF
957 : : _OPERATOR_IPOW_METHODDEF
958 : : _OPERATOR_EQ_METHODDEF
959 : : _OPERATOR_NE_METHODDEF
960 : : _OPERATOR_LT_METHODDEF
961 : : _OPERATOR_LE_METHODDEF
962 : : _OPERATOR_GT_METHODDEF
963 : : _OPERATOR_GE_METHODDEF
964 : : _OPERATOR__COMPARE_DIGEST_METHODDEF
965 : : _OPERATOR_LENGTH_HINT_METHODDEF
966 : : _OPERATOR_CALL_METHODDEF
967 : : {NULL, NULL} /* sentinel */
968 : :
969 : : };
970 : :
971 : : /* itemgetter object **********************************************************/
972 : :
973 : : typedef struct {
974 : : PyObject_HEAD
975 : : Py_ssize_t nitems;
976 : : PyObject *item;
977 : : Py_ssize_t index; // -1 unless *item* is a single non-negative integer index
978 : : vectorcallfunc vectorcall;
979 : : } itemgetterobject;
980 : :
981 : : // Forward declarations
982 : : static PyObject *
983 : : itemgetter_vectorcall(PyObject *, PyObject *const *, size_t, PyObject *);
984 : : static PyObject *
985 : : itemgetter_call_impl(itemgetterobject *, PyObject *);
986 : :
987 : : /* AC 3.5: treats first argument as an iterable, otherwise uses *args */
988 : : static PyObject *
989 : 5674 : itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
990 : : {
991 : : itemgetterobject *ig;
992 : : PyObject *item;
993 : : Py_ssize_t nitems;
994 : : Py_ssize_t index;
995 : :
996 [ + + - + ]: 5674 : if (!_PyArg_NoKeywords("itemgetter", kwds))
997 : 0 : return NULL;
998 : :
999 : 5674 : nitems = PyTuple_GET_SIZE(args);
1000 [ + + ]: 5674 : if (nitems <= 1) {
1001 [ + + ]: 5642 : if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item))
1002 : 1 : return NULL;
1003 : : } else {
1004 : 32 : item = args;
1005 : : }
1006 : 5673 : _operator_state *state = PyType_GetModuleState(type);
1007 : : /* create itemgetterobject structure */
1008 : 5673 : ig = PyObject_GC_New(itemgetterobject, (PyTypeObject *) state->itemgetter_type);
1009 [ - + ]: 5673 : if (ig == NULL) {
1010 : 0 : return NULL;
1011 : : }
1012 : :
1013 : 5673 : Py_INCREF(item);
1014 : 5673 : ig->item = item;
1015 : 5673 : ig->nitems = nitems;
1016 : 5673 : ig->index = -1;
1017 [ + + ]: 5673 : if (PyLong_CheckExact(item)) {
1018 : 5637 : index = PyLong_AsSsize_t(item);
1019 [ + + ]: 5637 : if (index < 0) {
1020 : : /* If we get here, then either the index conversion failed
1021 : : * due to being out of range, or the index was a negative
1022 : : * integer. Either way, we clear any possible exception
1023 : : * and fall back to the slow path, where ig->index is -1.
1024 : : */
1025 : 1 : PyErr_Clear();
1026 : : }
1027 : : else {
1028 : 5636 : ig->index = index;
1029 : : }
1030 : : }
1031 : :
1032 : 5673 : ig->vectorcall = (vectorcallfunc)itemgetter_vectorcall;
1033 : 5673 : PyObject_GC_Track(ig);
1034 : 5673 : return (PyObject *)ig;
1035 : : }
1036 : :
1037 : : static int
1038 : 5673 : itemgetter_clear(itemgetterobject *ig)
1039 : : {
1040 [ + - ]: 5673 : Py_CLEAR(ig->item);
1041 : 5673 : return 0;
1042 : : }
1043 : :
1044 : : static void
1045 : 5673 : itemgetter_dealloc(itemgetterobject *ig)
1046 : : {
1047 : 5673 : PyTypeObject *tp = Py_TYPE(ig);
1048 : 5673 : PyObject_GC_UnTrack(ig);
1049 : 5673 : (void)itemgetter_clear(ig);
1050 : 5673 : tp->tp_free(ig);
1051 : 5673 : Py_DECREF(tp);
1052 : 5673 : }
1053 : :
1054 : : static int
1055 : 236 : itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
1056 : : {
1057 [ + - - + ]: 236 : Py_VISIT(Py_TYPE(ig));
1058 [ + - - + ]: 236 : Py_VISIT(ig->item);
1059 : 236 : return 0;
1060 : : }
1061 : :
1062 : : static PyObject *
1063 : 0 : itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
1064 : : {
1065 : : assert(PyTuple_CheckExact(args));
1066 [ # # # # ]: 0 : if (!_PyArg_NoKeywords("itemgetter", kw))
1067 : 0 : return NULL;
1068 [ # # # # : 0 : if (!_PyArg_CheckPositional("itemgetter", PyTuple_GET_SIZE(args), 1, 1))
# # ]
1069 : 0 : return NULL;
1070 : 0 : return itemgetter_call_impl(ig, PyTuple_GET_ITEM(args, 0));
1071 : : }
1072 : :
1073 : : static PyObject *
1074 : 13059 : itemgetter_vectorcall(PyObject *ig, PyObject *const *args,
1075 : : size_t nargsf, PyObject *kwnames)
1076 : : {
1077 [ + + + - ]: 13059 : if (!_PyArg_NoKwnames("itemgetter", kwnames)) {
1078 : 1 : return NULL;
1079 : : }
1080 : 13058 : Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1081 [ + + + + : 13058 : if (!_PyArg_CheckPositional("itemgetter", nargs, 1, 1)) {
+ - ]
1082 : 2 : return NULL;
1083 : : }
1084 : 13056 : return itemgetter_call_impl((itemgetterobject *)ig, args[0]);
1085 : : }
1086 : :
1087 : : static PyObject *
1088 : 13056 : itemgetter_call_impl(itemgetterobject *ig, PyObject *obj)
1089 : : {
1090 : : PyObject *result;
1091 : 13056 : Py_ssize_t i, nitems=ig->nitems;
1092 [ + + ]: 13056 : if (nitems == 1) {
1093 [ + + ]: 10757 : if (ig->index >= 0
1094 [ + + ]: 10752 : && PyTuple_CheckExact(obj)
1095 [ + - ]: 10722 : && ig->index < PyTuple_GET_SIZE(obj))
1096 : : {
1097 : 10722 : result = PyTuple_GET_ITEM(obj, ig->index);
1098 : 10722 : Py_INCREF(result);
1099 : 10722 : return result;
1100 : : }
1101 : 35 : return PyObject_GetItem(obj, ig->item);
1102 : : }
1103 : :
1104 : : assert(PyTuple_Check(ig->item));
1105 : : assert(PyTuple_GET_SIZE(ig->item) == nitems);
1106 : :
1107 : 2299 : result = PyTuple_New(nitems);
1108 [ - + ]: 2299 : if (result == NULL)
1109 : 0 : return NULL;
1110 : :
1111 [ + + ]: 6929 : for (i=0 ; i < nitems ; i++) {
1112 : : PyObject *item, *val;
1113 : 4631 : item = PyTuple_GET_ITEM(ig->item, i);
1114 : 4631 : val = PyObject_GetItem(obj, item);
1115 [ + + ]: 4631 : if (val == NULL) {
1116 : 1 : Py_DECREF(result);
1117 : 1 : return NULL;
1118 : : }
1119 : 4630 : PyTuple_SET_ITEM(result, i, val);
1120 : : }
1121 : 2298 : return result;
1122 : : }
1123 : :
1124 : : static PyObject *
1125 : 56 : itemgetter_repr(itemgetterobject *ig)
1126 : : {
1127 : : PyObject *repr;
1128 : : const char *reprfmt;
1129 : :
1130 : 56 : int status = Py_ReprEnter((PyObject *)ig);
1131 [ - + ]: 56 : if (status != 0) {
1132 [ # # ]: 0 : if (status < 0)
1133 : 0 : return NULL;
1134 : 0 : return PyUnicode_FromFormat("%s(...)", Py_TYPE(ig)->tp_name);
1135 : : }
1136 : :
1137 [ + + ]: 56 : reprfmt = ig->nitems == 1 ? "%s(%R)" : "%s%R";
1138 : 56 : repr = PyUnicode_FromFormat(reprfmt, Py_TYPE(ig)->tp_name, ig->item);
1139 : 56 : Py_ReprLeave((PyObject *)ig);
1140 : 56 : return repr;
1141 : : }
1142 : :
1143 : : static PyObject *
1144 : 24 : itemgetter_reduce(itemgetterobject *ig, PyObject *Py_UNUSED(ignored))
1145 : : {
1146 [ + + ]: 24 : if (ig->nitems == 1)
1147 : 12 : return Py_BuildValue("O(O)", Py_TYPE(ig), ig->item);
1148 : 12 : return PyTuple_Pack(2, Py_TYPE(ig), ig->item);
1149 : : }
1150 : :
1151 : : PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1152 : :
1153 : : static PyMethodDef itemgetter_methods[] = {
1154 : : {"__reduce__", (PyCFunction)itemgetter_reduce, METH_NOARGS,
1155 : : reduce_doc},
1156 : : {NULL}
1157 : : };
1158 : :
1159 : : static PyMemberDef itemgetter_members[] = {
1160 : : {"__vectorcalloffset__", T_PYSSIZET, offsetof(itemgetterobject, vectorcall), READONLY},
1161 : : {NULL} /* Sentinel */
1162 : : };
1163 : :
1164 : : PyDoc_STRVAR(itemgetter_doc,
1165 : : "itemgetter(item, ...) --> itemgetter object\n\
1166 : : \n\
1167 : : Return a callable object that fetches the given item(s) from its operand.\n\
1168 : : After f = itemgetter(2), the call f(r) returns r[2].\n\
1169 : : After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])");
1170 : :
1171 : : static PyType_Slot itemgetter_type_slots[] = {
1172 : : {Py_tp_doc, (void *)itemgetter_doc},
1173 : : {Py_tp_dealloc, itemgetter_dealloc},
1174 : : {Py_tp_call, itemgetter_call},
1175 : : {Py_tp_traverse, itemgetter_traverse},
1176 : : {Py_tp_clear, itemgetter_clear},
1177 : : {Py_tp_methods, itemgetter_methods},
1178 : : {Py_tp_members, itemgetter_members},
1179 : : {Py_tp_new, itemgetter_new},
1180 : : {Py_tp_getattro, PyObject_GenericGetAttr},
1181 : : {Py_tp_repr, itemgetter_repr},
1182 : : {0, 0}
1183 : : };
1184 : :
1185 : : static PyType_Spec itemgetter_type_spec = {
1186 : : .name = "operator.itemgetter",
1187 : : .basicsize = sizeof(itemgetterobject),
1188 : : .itemsize = 0,
1189 : : .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1190 : : Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_VECTORCALL),
1191 : : .slots = itemgetter_type_slots,
1192 : : };
1193 : :
1194 : : /* attrgetter object **********************************************************/
1195 : :
1196 : : typedef struct {
1197 : : PyObject_HEAD
1198 : : Py_ssize_t nattrs;
1199 : : PyObject *attr;
1200 : : vectorcallfunc vectorcall;
1201 : : } attrgetterobject;
1202 : :
1203 : : // Forward declarations
1204 : : static PyObject *
1205 : : attrgetter_vectorcall(PyObject *, PyObject *const *, size_t, PyObject *);
1206 : : static PyObject *
1207 : : attrgetter_call_impl(attrgetterobject *, PyObject *);
1208 : :
1209 : : /* AC 3.5: treats first argument as an iterable, otherwise uses *args */
1210 : : static PyObject *
1211 : 6247 : attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1212 : : {
1213 : : attrgetterobject *ag;
1214 : : PyObject *attr;
1215 : : Py_ssize_t nattrs, idx, char_idx;
1216 : :
1217 [ + + - + ]: 6247 : if (!_PyArg_NoKeywords("attrgetter", kwds))
1218 : 0 : return NULL;
1219 : :
1220 : 6247 : nattrs = PyTuple_GET_SIZE(args);
1221 [ + + ]: 6247 : if (nattrs <= 1) {
1222 [ + + ]: 6112 : if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
1223 : 1 : return NULL;
1224 : : }
1225 : :
1226 : 6246 : attr = PyTuple_New(nattrs);
1227 [ - + ]: 6246 : if (attr == NULL)
1228 : 0 : return NULL;
1229 : :
1230 : : /* prepare attr while checking args */
1231 [ + + ]: 12812 : for (idx = 0; idx < nattrs; ++idx) {
1232 : 6568 : PyObject *item = PyTuple_GET_ITEM(args, idx);
1233 : : int dot_count;
1234 : :
1235 [ + + ]: 6568 : if (!PyUnicode_Check(item)) {
1236 : 2 : PyErr_SetString(PyExc_TypeError,
1237 : : "attribute name must be a string");
1238 : 2 : Py_DECREF(attr);
1239 : 2 : return NULL;
1240 : : }
1241 [ - + ]: 6566 : if (PyUnicode_READY(item)) {
1242 : 0 : Py_DECREF(attr);
1243 : 0 : return NULL;
1244 : : }
1245 : 6566 : Py_ssize_t item_len = PyUnicode_GET_LENGTH(item);
1246 : 6566 : int kind = PyUnicode_KIND(item);
1247 : 6566 : const void *data = PyUnicode_DATA(item);
1248 : :
1249 : : /* check whether the string is dotted */
1250 : 6566 : dot_count = 0;
1251 [ + + ]: 83188 : for (char_idx = 0; char_idx < item_len; ++char_idx) {
1252 [ + + ]: 76622 : if (PyUnicode_READ(kind, data, char_idx) == '.')
1253 : 4196 : ++dot_count;
1254 : : }
1255 : :
1256 [ + + ]: 6566 : if (dot_count == 0) {
1257 : 2397 : Py_INCREF(item);
1258 : 2397 : PyUnicode_InternInPlace(&item);
1259 : 2397 : PyTuple_SET_ITEM(attr, idx, item);
1260 : : } else { /* make it a tuple of non-dotted attrnames */
1261 : 4169 : PyObject *attr_chain = PyTuple_New(dot_count + 1);
1262 : : PyObject *attr_chain_item;
1263 : 4169 : Py_ssize_t unibuff_from = 0;
1264 : 4169 : Py_ssize_t unibuff_till = 0;
1265 : 4169 : Py_ssize_t attr_chain_idx = 0;
1266 : :
1267 [ - + ]: 4169 : if (attr_chain == NULL) {
1268 : 0 : Py_DECREF(attr);
1269 : 0 : return NULL;
1270 : : }
1271 : :
1272 [ + + ]: 8365 : for (; dot_count > 0; --dot_count) {
1273 [ + + ]: 33243 : while (PyUnicode_READ(kind, data, unibuff_till) != '.') {
1274 : 29047 : ++unibuff_till;
1275 : : }
1276 : 4196 : attr_chain_item = PyUnicode_Substring(item,
1277 : : unibuff_from,
1278 : : unibuff_till);
1279 [ - + ]: 4196 : if (attr_chain_item == NULL) {
1280 : 0 : Py_DECREF(attr_chain);
1281 : 0 : Py_DECREF(attr);
1282 : 0 : return NULL;
1283 : : }
1284 : 4196 : PyUnicode_InternInPlace(&attr_chain_item);
1285 : 4196 : PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
1286 : 4196 : ++attr_chain_idx;
1287 : 4196 : unibuff_till = unibuff_from = unibuff_till + 1;
1288 : : }
1289 : :
1290 : : /* now add the last dotless name */
1291 : 4169 : attr_chain_item = PyUnicode_Substring(item,
1292 : : unibuff_from, item_len);
1293 [ - + ]: 4169 : if (attr_chain_item == NULL) {
1294 : 0 : Py_DECREF(attr_chain);
1295 : 0 : Py_DECREF(attr);
1296 : 0 : return NULL;
1297 : : }
1298 : 4169 : PyUnicode_InternInPlace(&attr_chain_item);
1299 : 4169 : PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
1300 : :
1301 : 4169 : PyTuple_SET_ITEM(attr, idx, attr_chain);
1302 : : }
1303 : : }
1304 : :
1305 : 6244 : _operator_state *state = PyType_GetModuleState(type);
1306 : : /* create attrgetterobject structure */
1307 : 6244 : ag = PyObject_GC_New(attrgetterobject, (PyTypeObject *)state->attrgetter_type);
1308 [ - + ]: 6244 : if (ag == NULL) {
1309 : 0 : Py_DECREF(attr);
1310 : 0 : return NULL;
1311 : : }
1312 : :
1313 : 6244 : ag->attr = attr;
1314 : 6244 : ag->nattrs = nattrs;
1315 : 6244 : ag->vectorcall = (vectorcallfunc)attrgetter_vectorcall;
1316 : :
1317 : 6244 : PyObject_GC_Track(ag);
1318 : 6244 : return (PyObject *)ag;
1319 : : }
1320 : :
1321 : : static int
1322 : 6244 : attrgetter_clear(attrgetterobject *ag)
1323 : : {
1324 [ + - ]: 6244 : Py_CLEAR(ag->attr);
1325 : 6244 : return 0;
1326 : : }
1327 : :
1328 : : static void
1329 : 6244 : attrgetter_dealloc(attrgetterobject *ag)
1330 : : {
1331 : 6244 : PyTypeObject *tp = Py_TYPE(ag);
1332 : 6244 : PyObject_GC_UnTrack(ag);
1333 : 6244 : (void)attrgetter_clear(ag);
1334 : 6244 : tp->tp_free(ag);
1335 : 6244 : Py_DECREF(tp);
1336 : 6244 : }
1337 : :
1338 : : static int
1339 : 75934 : attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
1340 : : {
1341 [ + - - + ]: 75934 : Py_VISIT(ag->attr);
1342 [ + - - + ]: 75934 : Py_VISIT(Py_TYPE(ag));
1343 : 75934 : return 0;
1344 : : }
1345 : :
1346 : : static PyObject *
1347 : 2579 : dotted_getattr(PyObject *obj, PyObject *attr)
1348 : : {
1349 : : PyObject *newobj;
1350 : :
1351 : : /* attr is either a tuple or instance of str.
1352 : : Ensured by the setup code of attrgetter_new */
1353 [ + + ]: 2579 : if (PyTuple_CheckExact(attr)) { /* chained getattr */
1354 : 310 : Py_ssize_t name_idx = 0, name_count;
1355 : : PyObject *attr_name;
1356 : :
1357 : 310 : name_count = PyTuple_GET_SIZE(attr);
1358 : 310 : Py_INCREF(obj);
1359 [ + + ]: 950 : for (name_idx = 0; name_idx < name_count; ++name_idx) {
1360 : 644 : attr_name = PyTuple_GET_ITEM(attr, name_idx);
1361 : 644 : newobj = PyObject_GetAttr(obj, attr_name);
1362 : 644 : Py_DECREF(obj);
1363 [ + + ]: 644 : if (newobj == NULL) {
1364 : 4 : return NULL;
1365 : : }
1366 : : /* here */
1367 : 640 : obj = newobj;
1368 : : }
1369 : : } else { /* single getattr */
1370 : 2269 : newobj = PyObject_GetAttr(obj, attr);
1371 [ + + ]: 2269 : if (newobj == NULL)
1372 : 2 : return NULL;
1373 : 2267 : obj = newobj;
1374 : : }
1375 : :
1376 : 2573 : return obj;
1377 : : }
1378 : :
1379 : : static PyObject *
1380 : 0 : attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
1381 : : {
1382 [ # # # # ]: 0 : if (!_PyArg_NoKeywords("attrgetter", kw))
1383 : 0 : return NULL;
1384 [ # # # # : 0 : if (!_PyArg_CheckPositional("attrgetter", PyTuple_GET_SIZE(args), 1, 1))
# # ]
1385 : 0 : return NULL;
1386 : 0 : return attrgetter_call_impl(ag, PyTuple_GET_ITEM(args, 0));
1387 : : }
1388 : :
1389 : : static PyObject *
1390 : 2000 : attrgetter_vectorcall(PyObject *ag, PyObject *const *args, size_t nargsf, PyObject *kwnames)
1391 : : {
1392 [ + + + - ]: 2000 : if (!_PyArg_NoKwnames("attrgetter", kwnames)) {
1393 : 1 : return NULL;
1394 : : }
1395 : 1999 : Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1396 [ + + + + : 1999 : if (!_PyArg_CheckPositional("attrgetter", nargs, 1, 1)) {
+ - ]
1397 : 2 : return NULL;
1398 : : }
1399 : 1997 : return attrgetter_call_impl((attrgetterobject *)ag, args[0]);
1400 : : }
1401 : :
1402 : : static PyObject *
1403 : 1997 : attrgetter_call_impl(attrgetterobject *ag, PyObject *obj)
1404 : : {
1405 : : PyObject *result;
1406 : 1997 : Py_ssize_t i, nattrs=ag->nattrs;
1407 : :
1408 [ + + ]: 1997 : if (ag->nattrs == 1) {
1409 : : /* ag->attr is always a tuple */
1410 : 1762 : return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0));
1411 : : }
1412 : :
1413 : : assert(PyTuple_Check(ag->attr));
1414 : : assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
1415 : :
1416 : 235 : result = PyTuple_New(nattrs);
1417 [ - + ]: 235 : if (result == NULL)
1418 : 0 : return NULL;
1419 : :
1420 [ + + ]: 1051 : for (i=0 ; i < nattrs ; i++) {
1421 : : PyObject *attr, *val;
1422 : 817 : attr = PyTuple_GET_ITEM(ag->attr, i);
1423 : 817 : val = dotted_getattr(obj, attr);
1424 [ + + ]: 817 : if (val == NULL) {
1425 : 1 : Py_DECREF(result);
1426 : 1 : return NULL;
1427 : : }
1428 : 816 : PyTuple_SET_ITEM(result, i, val);
1429 : : }
1430 : 234 : return result;
1431 : : }
1432 : :
1433 : : static PyObject *
1434 : 191 : dotjoinattr(PyObject *attr, PyObject **attrsep)
1435 : : {
1436 [ + + ]: 191 : if (PyTuple_CheckExact(attr)) {
1437 [ + + ]: 41 : if (*attrsep == NULL) {
1438 : 40 : *attrsep = PyUnicode_FromString(".");
1439 [ - + ]: 40 : if (*attrsep == NULL)
1440 : 0 : return NULL;
1441 : : }
1442 : 41 : return PyUnicode_Join(*attrsep, attr);
1443 : : } else {
1444 : 150 : Py_INCREF(attr);
1445 : 150 : return attr;
1446 : : }
1447 : : }
1448 : :
1449 : : static PyObject *
1450 : 61 : attrgetter_args(attrgetterobject *ag)
1451 : : {
1452 : : Py_ssize_t i;
1453 : 61 : PyObject *attrsep = NULL;
1454 : 61 : PyObject *attrstrings = PyTuple_New(ag->nattrs);
1455 [ - + ]: 61 : if (attrstrings == NULL)
1456 : 0 : return NULL;
1457 : :
1458 [ + + ]: 196 : for (i = 0; i < ag->nattrs; ++i) {
1459 : 135 : PyObject *attr = PyTuple_GET_ITEM(ag->attr, i);
1460 : 135 : PyObject *attrstr = dotjoinattr(attr, &attrsep);
1461 [ - + ]: 135 : if (attrstr == NULL) {
1462 : 0 : Py_XDECREF(attrsep);
1463 : 0 : Py_DECREF(attrstrings);
1464 : 0 : return NULL;
1465 : : }
1466 : 135 : PyTuple_SET_ITEM(attrstrings, i, attrstr);
1467 : : }
1468 : 61 : Py_XDECREF(attrsep);
1469 : 61 : return attrstrings;
1470 : : }
1471 : :
1472 : : static PyObject *
1473 : 81 : attrgetter_repr(attrgetterobject *ag)
1474 : : {
1475 : 81 : PyObject *repr = NULL;
1476 : 81 : int status = Py_ReprEnter((PyObject *)ag);
1477 [ - + ]: 81 : if (status != 0) {
1478 [ # # ]: 0 : if (status < 0)
1479 : 0 : return NULL;
1480 : 0 : return PyUnicode_FromFormat("%s(...)", Py_TYPE(ag)->tp_name);
1481 : : }
1482 : :
1483 [ + + ]: 81 : if (ag->nattrs == 1) {
1484 : 56 : PyObject *attrsep = NULL;
1485 : 56 : PyObject *attr = dotjoinattr(PyTuple_GET_ITEM(ag->attr, 0), &attrsep);
1486 [ + - ]: 56 : if (attr != NULL) {
1487 : 56 : repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(ag)->tp_name, attr);
1488 : 56 : Py_DECREF(attr);
1489 : : }
1490 : 56 : Py_XDECREF(attrsep);
1491 : : }
1492 : : else {
1493 : 25 : PyObject *attrstrings = attrgetter_args(ag);
1494 [ + - ]: 25 : if (attrstrings != NULL) {
1495 : 25 : repr = PyUnicode_FromFormat("%s%R",
1496 : 25 : Py_TYPE(ag)->tp_name, attrstrings);
1497 : 25 : Py_DECREF(attrstrings);
1498 : : }
1499 : : }
1500 : 81 : Py_ReprLeave((PyObject *)ag);
1501 : 81 : return repr;
1502 : : }
1503 : :
1504 : : static PyObject *
1505 : 36 : attrgetter_reduce(attrgetterobject *ag, PyObject *Py_UNUSED(ignored))
1506 : : {
1507 : 36 : PyObject *attrstrings = attrgetter_args(ag);
1508 [ - + ]: 36 : if (attrstrings == NULL)
1509 : 0 : return NULL;
1510 : :
1511 : 36 : return Py_BuildValue("ON", Py_TYPE(ag), attrstrings);
1512 : : }
1513 : :
1514 : : static PyMethodDef attrgetter_methods[] = {
1515 : : {"__reduce__", (PyCFunction)attrgetter_reduce, METH_NOARGS,
1516 : : reduce_doc},
1517 : : {NULL}
1518 : : };
1519 : :
1520 : : static PyMemberDef attrgetter_members[] = {
1521 : : {"__vectorcalloffset__", T_PYSSIZET, offsetof(attrgetterobject, vectorcall), READONLY},
1522 : : {NULL} /* Sentinel*/
1523 : : };
1524 : :
1525 : : PyDoc_STRVAR(attrgetter_doc,
1526 : : "attrgetter(attr, ...) --> attrgetter object\n\
1527 : : \n\
1528 : : Return a callable object that fetches the given attribute(s) from its operand.\n\
1529 : : After f = attrgetter('name'), the call f(r) returns r.name.\n\
1530 : : After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\
1531 : : After h = attrgetter('name.first', 'name.last'), the call h(r) returns\n\
1532 : : (r.name.first, r.name.last).");
1533 : :
1534 : : static PyType_Slot attrgetter_type_slots[] = {
1535 : : {Py_tp_doc, (void *)attrgetter_doc},
1536 : : {Py_tp_dealloc, attrgetter_dealloc},
1537 : : {Py_tp_call, attrgetter_call},
1538 : : {Py_tp_traverse, attrgetter_traverse},
1539 : : {Py_tp_clear, attrgetter_clear},
1540 : : {Py_tp_methods, attrgetter_methods},
1541 : : {Py_tp_members, attrgetter_members},
1542 : : {Py_tp_new, attrgetter_new},
1543 : : {Py_tp_getattro, PyObject_GenericGetAttr},
1544 : : {Py_tp_repr, attrgetter_repr},
1545 : : {0, 0}
1546 : : };
1547 : :
1548 : : static PyType_Spec attrgetter_type_spec = {
1549 : : .name = "operator.attrgetter",
1550 : : .basicsize = sizeof(attrgetterobject),
1551 : : .itemsize = 0,
1552 : : .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1553 : : Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_VECTORCALL),
1554 : : .slots = attrgetter_type_slots,
1555 : : };
1556 : :
1557 : :
1558 : : /* methodcaller object **********************************************************/
1559 : :
1560 : : typedef struct {
1561 : : PyObject_HEAD
1562 : : PyObject *name;
1563 : : PyObject *args;
1564 : : PyObject *kwds;
1565 : : } methodcallerobject;
1566 : :
1567 : : /* AC 3.5: variable number of arguments, not currently support by AC */
1568 : : static PyObject *
1569 : 164 : methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1570 : : {
1571 : : methodcallerobject *mc;
1572 : : PyObject *name;
1573 : :
1574 [ + + ]: 164 : if (PyTuple_GET_SIZE(args) < 1) {
1575 : 1 : PyErr_SetString(PyExc_TypeError, "methodcaller needs at least "
1576 : : "one argument, the method name");
1577 : 1 : return NULL;
1578 : : }
1579 : :
1580 : 163 : name = PyTuple_GET_ITEM(args, 0);
1581 [ + + ]: 163 : if (!PyUnicode_Check(name)) {
1582 : 1 : PyErr_SetString(PyExc_TypeError,
1583 : : "method name must be a string");
1584 : 1 : return NULL;
1585 : : }
1586 : :
1587 : 162 : _operator_state *state = PyType_GetModuleState(type);
1588 : : /* create methodcallerobject structure */
1589 : 162 : mc = PyObject_GC_New(methodcallerobject, (PyTypeObject *)state->methodcaller_type);
1590 [ - + ]: 162 : if (mc == NULL) {
1591 : 0 : return NULL;
1592 : : }
1593 : :
1594 : 162 : name = PyTuple_GET_ITEM(args, 0);
1595 : 162 : Py_INCREF(name);
1596 : 162 : PyUnicode_InternInPlace(&name);
1597 : 162 : mc->name = name;
1598 : :
1599 : 162 : Py_XINCREF(kwds);
1600 : 162 : mc->kwds = kwds;
1601 : :
1602 : 162 : mc->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
1603 [ - + ]: 162 : if (mc->args == NULL) {
1604 : 0 : Py_DECREF(mc);
1605 : 0 : return NULL;
1606 : : }
1607 : :
1608 : 162 : PyObject_GC_Track(mc);
1609 : 162 : return (PyObject *)mc;
1610 : : }
1611 : :
1612 : : static int
1613 : 168 : methodcaller_clear(methodcallerobject *mc)
1614 : : {
1615 [ + + ]: 168 : Py_CLEAR(mc->name);
1616 [ + + ]: 168 : Py_CLEAR(mc->args);
1617 [ + + ]: 168 : Py_CLEAR(mc->kwds);
1618 : 168 : return 0;
1619 : : }
1620 : :
1621 : : static void
1622 : 162 : methodcaller_dealloc(methodcallerobject *mc)
1623 : : {
1624 : 162 : PyTypeObject *tp = Py_TYPE(mc);
1625 : 162 : PyObject_GC_UnTrack(mc);
1626 : 162 : (void)methodcaller_clear(mc);
1627 : 162 : tp->tp_free(mc);
1628 : 162 : Py_DECREF(tp);
1629 : 162 : }
1630 : :
1631 : : static int
1632 : 444 : methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
1633 : : {
1634 [ + - - + ]: 444 : Py_VISIT(mc->name);
1635 [ + - - + ]: 444 : Py_VISIT(mc->args);
1636 [ - + - - ]: 444 : Py_VISIT(mc->kwds);
1637 [ + - - + ]: 444 : Py_VISIT(Py_TYPE(mc));
1638 : 444 : return 0;
1639 : : }
1640 : :
1641 : : static PyObject *
1642 : 116 : methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw)
1643 : : {
1644 : : PyObject *method, *obj, *result;
1645 : :
1646 [ + + + + ]: 116 : if (!_PyArg_NoKeywords("methodcaller", kw))
1647 : 1 : return NULL;
1648 [ + + + + : 115 : if (!_PyArg_CheckPositional("methodcaller", PyTuple_GET_SIZE(args), 1, 1))
+ - ]
1649 : 3 : return NULL;
1650 : 112 : obj = PyTuple_GET_ITEM(args, 0);
1651 : 112 : method = PyObject_GetAttr(obj, mc->name);
1652 [ - + ]: 112 : if (method == NULL)
1653 : 0 : return NULL;
1654 : 112 : result = PyObject_Call(method, mc->args, mc->kwds);
1655 : 112 : Py_DECREF(method);
1656 : 112 : return result;
1657 : : }
1658 : :
1659 : : static PyObject *
1660 : 77 : methodcaller_repr(methodcallerobject *mc)
1661 : : {
1662 : 77 : PyObject *argreprs, *repr = NULL, *sep, *joinedargreprs;
1663 : : Py_ssize_t numtotalargs, numposargs, numkwdargs, i;
1664 : 77 : int status = Py_ReprEnter((PyObject *)mc);
1665 [ - + ]: 77 : if (status != 0) {
1666 [ # # ]: 0 : if (status < 0)
1667 : 0 : return NULL;
1668 : 0 : return PyUnicode_FromFormat("%s(...)", Py_TYPE(mc)->tp_name);
1669 : : }
1670 : :
1671 [ + + ]: 77 : numkwdargs = mc->kwds != NULL ? PyDict_GET_SIZE(mc->kwds) : 0;
1672 : 77 : numposargs = PyTuple_GET_SIZE(mc->args);
1673 : 77 : numtotalargs = numposargs + numkwdargs;
1674 : :
1675 [ + + ]: 77 : if (numtotalargs == 0) {
1676 : 26 : repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(mc)->tp_name, mc->name);
1677 : 26 : Py_ReprLeave((PyObject *)mc);
1678 : 26 : return repr;
1679 : : }
1680 : :
1681 : 51 : argreprs = PyTuple_New(numtotalargs);
1682 [ - + ]: 51 : if (argreprs == NULL) {
1683 : 0 : Py_ReprLeave((PyObject *)mc);
1684 : 0 : return NULL;
1685 : : }
1686 : :
1687 [ + + ]: 105 : for (i = 0; i < numposargs; ++i) {
1688 : 54 : PyObject *onerepr = PyObject_Repr(PyTuple_GET_ITEM(mc->args, i));
1689 [ - + ]: 54 : if (onerepr == NULL)
1690 : 0 : goto done;
1691 : 54 : PyTuple_SET_ITEM(argreprs, i, onerepr);
1692 : : }
1693 : :
1694 [ + + ]: 51 : if (numkwdargs != 0) {
1695 : : PyObject *key, *value;
1696 : 24 : Py_ssize_t pos = 0;
1697 [ + + ]: 48 : while (PyDict_Next(mc->kwds, &pos, &key, &value)) {
1698 : 24 : PyObject *onerepr = PyUnicode_FromFormat("%U=%R", key, value);
1699 [ - + ]: 24 : if (onerepr == NULL)
1700 : 0 : goto done;
1701 [ - + ]: 24 : if (i >= numtotalargs) {
1702 : 0 : i = -1;
1703 : 0 : Py_DECREF(onerepr);
1704 : 0 : break;
1705 : : }
1706 : 24 : PyTuple_SET_ITEM(argreprs, i, onerepr);
1707 : 24 : ++i;
1708 : : }
1709 [ - + ]: 24 : if (i != numtotalargs) {
1710 : 0 : PyErr_SetString(PyExc_RuntimeError,
1711 : : "keywords dict changed size during iteration");
1712 : 0 : goto done;
1713 : : }
1714 : : }
1715 : :
1716 : 51 : sep = PyUnicode_FromString(", ");
1717 [ - + ]: 51 : if (sep == NULL)
1718 : 0 : goto done;
1719 : :
1720 : 51 : joinedargreprs = PyUnicode_Join(sep, argreprs);
1721 : 51 : Py_DECREF(sep);
1722 [ - + ]: 51 : if (joinedargreprs == NULL)
1723 : 0 : goto done;
1724 : :
1725 : 51 : repr = PyUnicode_FromFormat("%s(%R, %U)", Py_TYPE(mc)->tp_name,
1726 : : mc->name, joinedargreprs);
1727 : 51 : Py_DECREF(joinedargreprs);
1728 : :
1729 : 51 : done:
1730 : 51 : Py_DECREF(argreprs);
1731 : 51 : Py_ReprLeave((PyObject *)mc);
1732 : 51 : return repr;
1733 : : }
1734 : :
1735 : : static PyObject *
1736 : 48 : methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored))
1737 : : {
1738 : : PyObject *newargs;
1739 [ + + - + ]: 48 : if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) {
1740 : : Py_ssize_t i;
1741 : 24 : Py_ssize_t callargcount = PyTuple_GET_SIZE(mc->args);
1742 : 24 : newargs = PyTuple_New(1 + callargcount);
1743 [ - + ]: 24 : if (newargs == NULL)
1744 : 0 : return NULL;
1745 : 24 : Py_INCREF(mc->name);
1746 : 24 : PyTuple_SET_ITEM(newargs, 0, mc->name);
1747 [ + + ]: 48 : for (i = 0; i < callargcount; ++i) {
1748 : 24 : PyObject *arg = PyTuple_GET_ITEM(mc->args, i);
1749 : 24 : Py_INCREF(arg);
1750 : 24 : PyTuple_SET_ITEM(newargs, i + 1, arg);
1751 : : }
1752 : 24 : return Py_BuildValue("ON", Py_TYPE(mc), newargs);
1753 : : }
1754 : : else {
1755 : : PyObject *partial;
1756 : : PyObject *constructor;
1757 : : PyObject *newargs[2];
1758 : :
1759 : 24 : partial = _PyImport_GetModuleAttrString("functools", "partial");
1760 [ - + ]: 24 : if (!partial)
1761 : 0 : return NULL;
1762 : :
1763 : 24 : newargs[0] = (PyObject *)Py_TYPE(mc);
1764 : 24 : newargs[1] = mc->name;
1765 : 24 : constructor = PyObject_VectorcallDict(partial, newargs, 2, mc->kwds);
1766 : :
1767 : 24 : Py_DECREF(partial);
1768 : 24 : return Py_BuildValue("NO", constructor, mc->args);
1769 : : }
1770 : : }
1771 : :
1772 : : static PyMethodDef methodcaller_methods[] = {
1773 : : {"__reduce__", (PyCFunction)methodcaller_reduce, METH_NOARGS,
1774 : : reduce_doc},
1775 : : {NULL}
1776 : : };
1777 : : PyDoc_STRVAR(methodcaller_doc,
1778 : : "methodcaller(name, ...) --> methodcaller object\n\
1779 : : \n\
1780 : : Return a callable object that calls the given method on its operand.\n\
1781 : : After f = methodcaller('name'), the call f(r) returns r.name().\n\
1782 : : After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\
1783 : : r.name('date', foo=1).");
1784 : :
1785 : : static PyType_Slot methodcaller_type_slots[] = {
1786 : : {Py_tp_doc, (void *)methodcaller_doc},
1787 : : {Py_tp_dealloc, methodcaller_dealloc},
1788 : : {Py_tp_call, methodcaller_call},
1789 : : {Py_tp_traverse, methodcaller_traverse},
1790 : : {Py_tp_clear, methodcaller_clear},
1791 : : {Py_tp_methods, methodcaller_methods},
1792 : : {Py_tp_new, methodcaller_new},
1793 : : {Py_tp_getattro, PyObject_GenericGetAttr},
1794 : : {Py_tp_repr, methodcaller_repr},
1795 : : {0, 0}
1796 : : };
1797 : :
1798 : : static PyType_Spec methodcaller_type_spec = {
1799 : : .name = "operator.methodcaller",
1800 : : .basicsize = sizeof(methodcallerobject),
1801 : : .itemsize = 0,
1802 : : .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1803 : : Py_TPFLAGS_IMMUTABLETYPE),
1804 : : .slots = methodcaller_type_slots,
1805 : : };
1806 : :
1807 : : static int
1808 : 1990 : operator_exec(PyObject *module)
1809 : : {
1810 : 1990 : _operator_state *state = get_operator_state(module);
1811 : 1990 : state->attrgetter_type = PyType_FromModuleAndSpec(module, &attrgetter_type_spec, NULL);
1812 [ - + ]: 1990 : if (state->attrgetter_type == NULL) {
1813 : 0 : return -1;
1814 : : }
1815 [ - + ]: 1990 : if (PyModule_AddType(module, (PyTypeObject *)state->attrgetter_type) < 0) {
1816 : 0 : return -1;
1817 : : }
1818 : :
1819 : 1990 : state->itemgetter_type = PyType_FromModuleAndSpec(module, &itemgetter_type_spec, NULL);
1820 [ - + ]: 1990 : if (state->itemgetter_type == NULL) {
1821 : 0 : return -1;
1822 : : }
1823 [ - + ]: 1990 : if (PyModule_AddType(module, (PyTypeObject *)state->itemgetter_type) < 0) {
1824 : 0 : return -1;
1825 : : }
1826 : :
1827 : 1990 : state->methodcaller_type = PyType_FromModuleAndSpec(module, &methodcaller_type_spec, NULL);
1828 [ - + ]: 1990 : if (state->methodcaller_type == NULL) {
1829 : 0 : return -1;
1830 : : }
1831 [ - + ]: 1990 : if (PyModule_AddType(module, (PyTypeObject *)state->methodcaller_type) < 0) {
1832 : 0 : return -1;
1833 : : }
1834 : :
1835 : 1990 : return 0;
1836 : : }
1837 : :
1838 : :
1839 : : static struct PyModuleDef_Slot operator_slots[] = {
1840 : : {Py_mod_exec, operator_exec},
1841 : : {0, NULL}
1842 : : };
1843 : :
1844 : : static int
1845 : 50200 : operator_traverse(PyObject *module, visitproc visit, void *arg)
1846 : : {
1847 : 50200 : _operator_state *state = get_operator_state(module);
1848 [ + + - + ]: 50200 : Py_VISIT(state->attrgetter_type);
1849 [ + + - + ]: 50200 : Py_VISIT(state->itemgetter_type);
1850 [ + + - + ]: 50200 : Py_VISIT(state->methodcaller_type);
1851 : 50200 : return 0;
1852 : : }
1853 : :
1854 : : static int
1855 : 3912 : operator_clear(PyObject *module)
1856 : : {
1857 : 3912 : _operator_state *state = get_operator_state(module);
1858 [ + + ]: 3912 : Py_CLEAR(state->attrgetter_type);
1859 [ + + ]: 3912 : Py_CLEAR(state->itemgetter_type);
1860 [ + + ]: 3912 : Py_CLEAR(state->methodcaller_type);
1861 : 3912 : return 0;
1862 : : }
1863 : :
1864 : : static void
1865 : 1956 : operator_free(void *module)
1866 : : {
1867 : 1956 : operator_clear((PyObject *)module);
1868 : 1956 : }
1869 : :
1870 : : static struct PyModuleDef operatormodule = {
1871 : : PyModuleDef_HEAD_INIT,
1872 : : .m_name = "_operator",
1873 : : .m_doc = operator_doc,
1874 : : .m_size = sizeof(_operator_state),
1875 : : .m_methods = operator_methods,
1876 : : .m_slots = operator_slots,
1877 : : .m_traverse = operator_traverse,
1878 : : .m_clear = operator_clear,
1879 : : .m_free = operator_free,
1880 : : };
1881 : :
1882 : : PyMODINIT_FUNC
1883 : 1990 : PyInit__operator(void)
1884 : : {
1885 : 1990 : return PyModuleDef_Init(&operatormodule);
1886 : : }
|