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