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