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