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