blob: da1e43158ee0ac2e30ada9d03a9eea89ea6a075f [file] [log] [blame]
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001
2#include "Python.h"
3
Serhiy Storchakab813a0e2017-01-19 17:44:13 +02004#include "clinic/_operator.c.h"
5
Dong-hee Na31967fd2020-08-26 17:22:27 +00006typedef struct {
7 PyObject *itemgetter_type;
8 PyObject *attrgetter_type;
9 PyObject *methodcaller_type;
10} _operator_state;
11
12static inline _operator_state*
13get_operator_state(PyObject *module)
14{
15 void *state = PyModule_GetState(module);
16 assert(state != NULL);
17 return (_operator_state *)state;
18}
19
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020020/*[clinic input]
21module _operator
22[clinic start generated code]*/
23/*[clinic end generated code: output=da39a3ee5e6b4b0d input=672ecf48487521e7]*/
24
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000025PyDoc_STRVAR(operator_doc,
26"Operator interface.\n\
Guido van Rossum037b9401996-07-30 16:55:54 +000027\n\
28This module exports a set of functions implemented in C corresponding\n\
29to the intrinsic operators of Python. For example, operator.add(x, y)\n\
30is equivalent to the expression x+y. The function names are those\n\
Benjamin Petersona0dfa822009-11-13 02:25:08 +000031used for special methods; variants without leading and trailing\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000032'__' are also provided for convenience.");
Guido van Rossum037b9401996-07-30 16:55:54 +000033
Guido van Rossum037b9401996-07-30 16:55:54 +000034
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020035/*[clinic input]
36_operator.truth -> bool
Guido van Rossum037b9401996-07-30 16:55:54 +000037
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020038 a: object
39 /
Guido van Rossum037b9401996-07-30 16:55:54 +000040
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020041Return True if a is true, False otherwise.
42[clinic start generated code]*/
Guido van Rossum037b9401996-07-30 16:55:54 +000043
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020044static int
45_operator_truth_impl(PyObject *module, PyObject *a)
46/*[clinic end generated code: output=eaf87767234fa5d7 input=bc74a4cd90235875]*/
Raymond Hettinger5959c552002-08-19 03:19:09 +000047{
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020048 return PyObject_IsTrue(a);
Raymond Hettinger5959c552002-08-19 03:19:09 +000049}
50
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020051/*[clinic input]
52_operator.add
53
54 a: object
55 b: object
56 /
57
58Same as a + b.
59[clinic start generated code]*/
Armin Rigof5bd3b42005-12-29 16:50:42 +000060
Guido van Rossum38fff8c2006-03-07 18:50:55 +000061static PyObject *
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020062_operator_add_impl(PyObject *module, PyObject *a, PyObject *b)
63/*[clinic end generated code: output=8292984204f45164 input=5efe3bff856ac215]*/
64{
65 return PyNumber_Add(a, b);
66}
67
68/*[clinic input]
69_operator.sub = _operator.add
70
71Same as a - b.
72[clinic start generated code]*/
73
74static PyObject *
75_operator_sub_impl(PyObject *module, PyObject *a, PyObject *b)
76/*[clinic end generated code: output=4adfc3b888c1ee2e input=6494c6b100b8e795]*/
77{
78 return PyNumber_Subtract(a, b);
79}
80
81/*[clinic input]
82_operator.mul = _operator.add
83
84Same as a * b.
85[clinic start generated code]*/
86
87static PyObject *
88_operator_mul_impl(PyObject *module, PyObject *a, PyObject *b)
89/*[clinic end generated code: output=d24d66f55a01944c input=2368615b4358b70d]*/
90{
91 return PyNumber_Multiply(a, b);
92}
93
94/*[clinic input]
95_operator.matmul = _operator.add
96
97Same as a @ b.
98[clinic start generated code]*/
99
100static PyObject *
101_operator_matmul_impl(PyObject *module, PyObject *a, PyObject *b)
102/*[clinic end generated code: output=a20d917eb35d0101 input=9ab304e37fb42dd4]*/
103{
104 return PyNumber_MatrixMultiply(a, b);
105}
106
107/*[clinic input]
108_operator.floordiv = _operator.add
109
110Same as a // b.
111[clinic start generated code]*/
112
113static PyObject *
114_operator_floordiv_impl(PyObject *module, PyObject *a, PyObject *b)
115/*[clinic end generated code: output=df26b71a60589f99 input=bb2e88ba446c612c]*/
116{
117 return PyNumber_FloorDivide(a, b);
118}
119
120/*[clinic input]
121_operator.truediv = _operator.add
122
123Same as a / b.
124[clinic start generated code]*/
125
126static PyObject *
127_operator_truediv_impl(PyObject *module, PyObject *a, PyObject *b)
128/*[clinic end generated code: output=0e6a959944d77719 input=ecbb947673f4eb1f]*/
129{
130 return PyNumber_TrueDivide(a, b);
131}
132
133/*[clinic input]
134_operator.mod = _operator.add
135
136Same as a % b.
137[clinic start generated code]*/
138
139static PyObject *
140_operator_mod_impl(PyObject *module, PyObject *a, PyObject *b)
141/*[clinic end generated code: output=9519822f0bbec166 input=102e19b422342ac1]*/
142{
143 return PyNumber_Remainder(a, b);
144}
145
146/*[clinic input]
147_operator.neg
148
149 a: object
150 /
151
152Same as -a.
153[clinic start generated code]*/
154
155static PyObject *
156_operator_neg(PyObject *module, PyObject *a)
157/*[clinic end generated code: output=36e08ecfc6a1c08c input=84f09bdcf27c96ec]*/
158{
159 return PyNumber_Negative(a);
160}
161
162/*[clinic input]
163_operator.pos = _operator.neg
164
165Same as +a.
166[clinic start generated code]*/
167
168static PyObject *
169_operator_pos(PyObject *module, PyObject *a)
170/*[clinic end generated code: output=dad7a126221dd091 input=b6445b63fddb8772]*/
171{
172 return PyNumber_Positive(a);
173}
174
175/*[clinic input]
176_operator.abs = _operator.neg
177
178Same as abs(a).
179[clinic start generated code]*/
180
181static PyObject *
182_operator_abs(PyObject *module, PyObject *a)
183/*[clinic end generated code: output=1389a93ba053ea3e input=341d07ba86f58039]*/
184{
185 return PyNumber_Absolute(a);
186}
187
188/*[clinic input]
189_operator.inv = _operator.neg
190
191Same as ~a.
192[clinic start generated code]*/
193
194static PyObject *
195_operator_inv(PyObject *module, PyObject *a)
196/*[clinic end generated code: output=a56875ba075ee06d input=b01a4677739f6eb2]*/
197{
198 return PyNumber_Invert(a);
199}
200
201/*[clinic input]
202_operator.invert = _operator.neg
203
204Same as ~a.
205[clinic start generated code]*/
206
207static PyObject *
208_operator_invert(PyObject *module, PyObject *a)
209/*[clinic end generated code: output=406b5aa030545fcc input=7f2d607176672e55]*/
210{
211 return PyNumber_Invert(a);
212}
213
214/*[clinic input]
215_operator.lshift = _operator.add
216
217Same as a << b.
218[clinic start generated code]*/
219
220static PyObject *
221_operator_lshift_impl(PyObject *module, PyObject *a, PyObject *b)
222/*[clinic end generated code: output=37f7e52c41435bd8 input=746e8a160cbbc9eb]*/
223{
224 return PyNumber_Lshift(a, b);
225}
226
227/*[clinic input]
228_operator.rshift = _operator.add
229
230Same as a >> b.
231[clinic start generated code]*/
232
233static PyObject *
234_operator_rshift_impl(PyObject *module, PyObject *a, PyObject *b)
235/*[clinic end generated code: output=4593c7ef30ec2ee3 input=d2c85bb5a64504c2]*/
236{
237 return PyNumber_Rshift(a, b);
238}
239
240/*[clinic input]
241_operator.not_ = _operator.truth
242
243Same as not a.
244[clinic start generated code]*/
245
246static int
247_operator_not__impl(PyObject *module, PyObject *a)
248/*[clinic end generated code: output=743f9c24a09759ef input=854156d50804d9b8]*/
249{
250 return PyObject_Not(a);
251}
252
253/*[clinic input]
254_operator.and_ = _operator.add
255
256Same as a & b.
257[clinic start generated code]*/
258
259static PyObject *
260_operator_and__impl(PyObject *module, PyObject *a, PyObject *b)
261/*[clinic end generated code: output=93c4fe88f7b76d9e input=4f3057c90ec4c99f]*/
262{
263 return PyNumber_And(a, b);
264}
265
266/*[clinic input]
267_operator.xor = _operator.add
268
269Same as a ^ b.
270[clinic start generated code]*/
271
272static PyObject *
273_operator_xor_impl(PyObject *module, PyObject *a, PyObject *b)
274/*[clinic end generated code: output=b24cd8b79fde0004 input=3c5cfa7253d808dd]*/
275{
276 return PyNumber_Xor(a, b);
277}
278
279/*[clinic input]
280_operator.or_ = _operator.add
281
282Same as a | b.
283[clinic start generated code]*/
284
285static PyObject *
286_operator_or__impl(PyObject *module, PyObject *a, PyObject *b)
287/*[clinic end generated code: output=58024867b8d90461 input=b40c6c44f7c79c09]*/
288{
289 return PyNumber_Or(a, b);
290}
291
292/*[clinic input]
293_operator.iadd = _operator.add
294
295Same as a += b.
296[clinic start generated code]*/
297
298static PyObject *
299_operator_iadd_impl(PyObject *module, PyObject *a, PyObject *b)
300/*[clinic end generated code: output=07dc627832526eb5 input=d22a91c07ac69227]*/
301{
302 return PyNumber_InPlaceAdd(a, b);
303}
304
305/*[clinic input]
306_operator.isub = _operator.add
307
308Same as a -= b.
309[clinic start generated code]*/
310
311static PyObject *
312_operator_isub_impl(PyObject *module, PyObject *a, PyObject *b)
313/*[clinic end generated code: output=4513467d23b5e0b1 input=4591b00d0a0ccafd]*/
314{
315 return PyNumber_InPlaceSubtract(a, b);
316}
317
318/*[clinic input]
319_operator.imul = _operator.add
320
321Same as a *= b.
322[clinic start generated code]*/
323
324static PyObject *
325_operator_imul_impl(PyObject *module, PyObject *a, PyObject *b)
326/*[clinic end generated code: output=5e87dacd19a71eab input=0e01fb8631e1b76f]*/
327{
328 return PyNumber_InPlaceMultiply(a, b);
329}
330
331/*[clinic input]
332_operator.imatmul = _operator.add
333
334Same as a @= b.
335[clinic start generated code]*/
336
337static PyObject *
338_operator_imatmul_impl(PyObject *module, PyObject *a, PyObject *b)
339/*[clinic end generated code: output=d603cbdf716ce519 input=bb614026372cd542]*/
340{
341 return PyNumber_InPlaceMatrixMultiply(a, b);
342}
343
344/*[clinic input]
345_operator.ifloordiv = _operator.add
346
347Same as a //= b.
348[clinic start generated code]*/
349
350static PyObject *
351_operator_ifloordiv_impl(PyObject *module, PyObject *a, PyObject *b)
352/*[clinic end generated code: output=535336048c681794 input=9df3b5021cff4ca1]*/
353{
354 return PyNumber_InPlaceFloorDivide(a, b);
355}
356
357/*[clinic input]
358_operator.itruediv = _operator.add
359
360Same as a /= b.
361[clinic start generated code]*/
362
363static PyObject *
364_operator_itruediv_impl(PyObject *module, PyObject *a, PyObject *b)
365/*[clinic end generated code: output=28017fbd3563952f input=9a1ee01608f5f590]*/
366{
367 return PyNumber_InPlaceTrueDivide(a, b);
368}
369
370/*[clinic input]
371_operator.imod = _operator.add
372
373Same as a %= b.
374[clinic start generated code]*/
375
376static PyObject *
377_operator_imod_impl(PyObject *module, PyObject *a, PyObject *b)
378/*[clinic end generated code: output=f7c540ae0fc70904 input=d0c384a3ce38e1dd]*/
379{
380 return PyNumber_InPlaceRemainder(a, b);
381}
382
383/*[clinic input]
384_operator.ilshift = _operator.add
385
386Same as a <<= b.
387[clinic start generated code]*/
388
389static PyObject *
390_operator_ilshift_impl(PyObject *module, PyObject *a, PyObject *b)
391/*[clinic end generated code: output=e73a8fee1ac18749 input=e21b6b310f54572e]*/
392{
393 return PyNumber_InPlaceLshift(a, b);
394}
395
396/*[clinic input]
397_operator.irshift = _operator.add
398
399Same as a >>= b.
400[clinic start generated code]*/
401
402static PyObject *
403_operator_irshift_impl(PyObject *module, PyObject *a, PyObject *b)
404/*[clinic end generated code: output=97f2af6b5ff2ed81 input=6778dbd0f6e1ec16]*/
405{
406 return PyNumber_InPlaceRshift(a, b);
407}
408
409/*[clinic input]
410_operator.iand = _operator.add
411
412Same as a &= b.
413[clinic start generated code]*/
414
415static PyObject *
416_operator_iand_impl(PyObject *module, PyObject *a, PyObject *b)
417/*[clinic end generated code: output=4599e9d40cbf7d00 input=71dfd8e70c156a7b]*/
418{
419 return PyNumber_InPlaceAnd(a, b);
420}
421
422/*[clinic input]
423_operator.ixor = _operator.add
424
425Same as a ^= b.
426[clinic start generated code]*/
427
428static PyObject *
429_operator_ixor_impl(PyObject *module, PyObject *a, PyObject *b)
430/*[clinic end generated code: output=5ff881766872be03 input=695c32bec0604d86]*/
431{
432 return PyNumber_InPlaceXor(a, b);
433}
434
435/*[clinic input]
436_operator.ior = _operator.add
437
438Same as a |= b.
439[clinic start generated code]*/
440
441static PyObject *
442_operator_ior_impl(PyObject *module, PyObject *a, PyObject *b)
443/*[clinic end generated code: output=48aac319445bf759 input=8f01d03eda9920cf]*/
444{
445 return PyNumber_InPlaceOr(a, b);
446}
447
448/*[clinic input]
449_operator.concat = _operator.add
450
451Same as a + b, for a and b sequences.
452[clinic start generated code]*/
453
454static PyObject *
455_operator_concat_impl(PyObject *module, PyObject *a, PyObject *b)
456/*[clinic end generated code: output=80028390942c5f11 input=8544ccd5341a3658]*/
457{
458 return PySequence_Concat(a, b);
459}
460
461/*[clinic input]
462_operator.iconcat = _operator.add
463
464Same as a += b, for a and b sequences.
465[clinic start generated code]*/
466
467static PyObject *
468_operator_iconcat_impl(PyObject *module, PyObject *a, PyObject *b)
469/*[clinic end generated code: output=3ea0a162ebb2e26d input=8f5fe5722fcd837e]*/
470{
471 return PySequence_InPlaceConcat(a, b);
472}
473
474/*[clinic input]
475_operator.contains -> bool
476
477 a: object
478 b: object
479 /
480
481Same as b in a (note reversed operands).
482[clinic start generated code]*/
483
484static int
485_operator_contains_impl(PyObject *module, PyObject *a, PyObject *b)
486/*[clinic end generated code: output=413b4dbe82b6ffc1 input=9122a69b505fde13]*/
487{
488 return PySequence_Contains(a, b);
489}
490
491/*[clinic input]
492_operator.indexOf -> Py_ssize_t
493
494 a: object
495 b: object
496 /
497
498Return the first index of b in a.
499[clinic start generated code]*/
500
501static Py_ssize_t
502_operator_indexOf_impl(PyObject *module, PyObject *a, PyObject *b)
503/*[clinic end generated code: output=c6226d8e0fb60fa6 input=8be2e43b6a6fffe3]*/
504{
505 return PySequence_Index(a, b);
506}
507
508/*[clinic input]
509_operator.countOf = _operator.indexOf
510
511Return the number of times b occurs in a.
512[clinic start generated code]*/
513
514static Py_ssize_t
515_operator_countOf_impl(PyObject *module, PyObject *a, PyObject *b)
516/*[clinic end generated code: output=9e1623197daf3382 input=0c3a2656add252db]*/
517{
518 return PySequence_Count(a, b);
519}
520
521/*[clinic input]
522_operator.getitem
523
524 a: object
525 b: object
526 /
527
528Same as a[b].
529[clinic start generated code]*/
530
531static PyObject *
532_operator_getitem_impl(PyObject *module, PyObject *a, PyObject *b)
533/*[clinic end generated code: output=6c8d8101a676e594 input=6682797320e48845]*/
534{
535 return PyObject_GetItem(a, b);
536}
537
538/*[clinic input]
539_operator.setitem
540
541 a: object
542 b: object
543 c: object
544 /
545
546Same as a[b] = c.
547[clinic start generated code]*/
548
549static PyObject *
550_operator_setitem_impl(PyObject *module, PyObject *a, PyObject *b,
551 PyObject *c)
552/*[clinic end generated code: output=1324f9061ae99e25 input=ceaf453c4d3a58df]*/
553{
554 if (-1 == PyObject_SetItem(a, b, c))
555 return NULL;
556 Py_RETURN_NONE;
557}
558
559/*[clinic input]
560_operator.delitem = _operator.getitem
561
562Same as del a[b].
563[clinic start generated code]*/
564
565static PyObject *
566_operator_delitem_impl(PyObject *module, PyObject *a, PyObject *b)
567/*[clinic end generated code: output=db18f61506295799 input=991bec56a0d3ec7f]*/
568{
569 if (-1 == PyObject_DelItem(a, b))
570 return NULL;
571 Py_RETURN_NONE;
572}
573
574/*[clinic input]
575_operator.eq
576
577 a: object
578 b: object
579 /
580
581Same as a == b.
582[clinic start generated code]*/
583
584static PyObject *
585_operator_eq_impl(PyObject *module, PyObject *a, PyObject *b)
586/*[clinic end generated code: output=8d7d46ed4135677c input=586fca687a95a83f]*/
587{
588 return PyObject_RichCompare(a, b, Py_EQ);
589}
590
591/*[clinic input]
592_operator.ne = _operator.eq
593
594Same as a != b.
595[clinic start generated code]*/
596
597static PyObject *
598_operator_ne_impl(PyObject *module, PyObject *a, PyObject *b)
599/*[clinic end generated code: output=c99bd0c3a4c01297 input=5d88f23d35e9abac]*/
600{
601 return PyObject_RichCompare(a, b, Py_NE);
602}
603
604/*[clinic input]
605_operator.lt = _operator.eq
606
607Same as a < b.
608[clinic start generated code]*/
609
610static PyObject *
611_operator_lt_impl(PyObject *module, PyObject *a, PyObject *b)
612/*[clinic end generated code: output=082d7c45c440e535 input=34a59ad6d39d3a2b]*/
613{
614 return PyObject_RichCompare(a, b, Py_LT);
615}
616
617/*[clinic input]
618_operator.le = _operator.eq
619
620Same as a <= b.
621[clinic start generated code]*/
622
623static PyObject *
624_operator_le_impl(PyObject *module, PyObject *a, PyObject *b)
625/*[clinic end generated code: output=00970a2923d0ae17 input=b812a7860a0bef44]*/
626{
627 return PyObject_RichCompare(a, b, Py_LE);
628}
629
630/*[clinic input]
631_operator.gt = _operator.eq
632
633Same as a > b.
634[clinic start generated code]*/
635
636static PyObject *
637_operator_gt_impl(PyObject *module, PyObject *a, PyObject *b)
638/*[clinic end generated code: output=8d373349ecf25641 input=9bdb45b995ada35b]*/
639{
640 return PyObject_RichCompare(a, b, Py_GT);
641}
642
643/*[clinic input]
644_operator.ge = _operator.eq
645
646Same as a >= b.
647[clinic start generated code]*/
648
649static PyObject *
650_operator_ge_impl(PyObject *module, PyObject *a, PyObject *b)
651/*[clinic end generated code: output=7ce3882256d4b137 input=cf1dc4a5ca9c35f5]*/
652{
653 return PyObject_RichCompare(a, b, Py_GE);
654}
655
656/*[clinic input]
657_operator.pow = _operator.add
658
659Same as a ** b.
660[clinic start generated code]*/
661
662static PyObject *
663_operator_pow_impl(PyObject *module, PyObject *a, PyObject *b)
664/*[clinic end generated code: output=09e668ad50036120 input=690b40f097ab1637]*/
665{
666 return PyNumber_Power(a, b, Py_None);
667}
668
669/*[clinic input]
670_operator.ipow = _operator.add
671
672Same as a **= b.
673[clinic start generated code]*/
674
675static PyObject *
676_operator_ipow_impl(PyObject *module, PyObject *a, PyObject *b)
677/*[clinic end generated code: output=7189ff4d4367c808 input=f00623899d07499a]*/
678{
679 return PyNumber_InPlacePower(a, b, Py_None);
680}
681
682/*[clinic input]
683_operator.index
684
685 a: object
686 /
687
688Same as a.__index__()
689[clinic start generated code]*/
690
691static PyObject *
692_operator_index(PyObject *module, PyObject *a)
693/*[clinic end generated code: output=d972b0764ac305fc input=6f54d50ea64a579c]*/
Guido van Rossum38fff8c2006-03-07 18:50:55 +0000694{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 return PyNumber_Index(a);
Guido van Rossum38fff8c2006-03-07 18:50:55 +0000696}
697
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200698/*[clinic input]
699_operator.is_ = _operator.add
700
701Same as a is b.
702[clinic start generated code]*/
703
704static PyObject *
705_operator_is__impl(PyObject *module, PyObject *a, PyObject *b)
706/*[clinic end generated code: output=bcd47a402e482e1d input=5fa9b97df03c427f]*/
Raymond Hettinger9543b342003-01-18 23:22:20 +0000707{
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200708 PyObject *result;
709 result = (a == b) ? Py_True : Py_False;
710 Py_INCREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 return result;
Raymond Hettinger9543b342003-01-18 23:22:20 +0000712}
713
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200714/*[clinic input]
715_operator.is_not = _operator.add
716
717Same as a is not b.
718[clinic start generated code]*/
719
720static PyObject *
721_operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b)
722/*[clinic end generated code: output=491a1f2f81f6c7f9 input=5a93f7e1a93535f1]*/
Raymond Hettinger9543b342003-01-18 23:22:20 +0000723{
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200724 PyObject *result;
725 result = (a != b) ? Py_True : Py_False;
726 Py_INCREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 return result;
Raymond Hettinger9543b342003-01-18 23:22:20 +0000728}
729
Christian Heimes6cea6552012-06-24 13:48:32 +0200730/* compare_digest **********************************************************/
731
732/*
733 * timing safe compare
734 *
735 * Returns 1 of the strings are equal.
736 * In case of len(a) != len(b) the function tries to keep the timing
737 * dependent on the length of b. CPU cache locally may still alter timing
738 * a bit.
739 */
740static int
741_tscmp(const unsigned char *a, const unsigned char *b,
742 Py_ssize_t len_a, Py_ssize_t len_b)
743{
744 /* The volatile type declarations make sure that the compiler has no
745 * chance to optimize and fold the code in any way that may change
746 * the timing.
747 */
748 volatile Py_ssize_t length;
749 volatile const unsigned char *left;
750 volatile const unsigned char *right;
751 Py_ssize_t i;
Devin Jeanpierre31729362020-11-21 01:55:23 -0700752 volatile unsigned char result;
Christian Heimes6cea6552012-06-24 13:48:32 +0200753
754 /* loop count depends on length of b */
755 length = len_b;
756 left = NULL;
757 right = b;
758
759 /* don't use else here to keep the amount of CPU instructions constant,
760 * volatile forces re-evaluation
761 * */
762 if (len_a == length) {
763 left = *((volatile const unsigned char**)&a);
764 result = 0;
765 }
766 if (len_a != length) {
767 left = b;
768 result = 1;
769 }
770
771 for (i=0; i < length; i++) {
772 result |= *left++ ^ *right++;
773 }
774
775 return (result == 0);
776}
777
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200778/*[clinic input]
779_operator.length_hint -> Py_ssize_t
Armin Ronacheraa9a79d2012-10-06 14:03:24 +0200780
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200781 obj: object
782 default: Py_ssize_t = 0
783 /
784
785Return an estimate of the number of items in obj.
786
787This is useful for presizing containers when building from an iterable.
788
789If the object supports len(), the result will be exact.
790Otherwise, it may over- or under-estimate by an arbitrary amount.
791The result will be an integer >= 0.
792[clinic start generated code]*/
793
794static Py_ssize_t
795_operator_length_hint_impl(PyObject *module, PyObject *obj,
796 Py_ssize_t default_value)
797/*[clinic end generated code: output=01d469edc1d612ad input=65ed29f04401e96a]*/
Armin Ronacheraa9a79d2012-10-06 14:03:24 +0200798{
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200799 return PyObject_LengthHint(obj, default_value);
Armin Ronacheraa9a79d2012-10-06 14:03:24 +0200800}
801
Christian Heimesdb5aed92020-05-27 21:50:06 +0200802/* NOTE: Keep in sync with _hashopenssl.c implementation. */
803
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200804/*[clinic input]
805_operator._compare_digest = _operator.eq
Armin Ronacheraa9a79d2012-10-06 14:03:24 +0200806
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200807Return 'a == b'.
Christian Heimes6cea6552012-06-24 13:48:32 +0200808
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200809This function uses an approach designed to prevent
810timing analysis, making it appropriate for cryptography.
811
812a and b must both be of the same type: either str (ASCII only),
813or any bytes-like object.
814
815Note: If a and b are of different lengths, or if an error occurs,
816a timing attack could theoretically reveal information about the
817types and lengths of a and b--but not their values.
818[clinic start generated code]*/
819
820static PyObject *
821_operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b)
822/*[clinic end generated code: output=11d452bdd3a23cbc input=9ac7e2c4e30bc356]*/
Christian Heimes6cea6552012-06-24 13:48:32 +0200823{
Christian Heimes6cea6552012-06-24 13:48:32 +0200824 int rc;
Christian Heimes6cea6552012-06-24 13:48:32 +0200825
Christian Heimes6cea6552012-06-24 13:48:32 +0200826 /* ASCII unicode string */
827 if(PyUnicode_Check(a) && PyUnicode_Check(b)) {
828 if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) {
829 return NULL;
830 }
831 if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) {
832 PyErr_SetString(PyExc_TypeError,
833 "comparing strings with non-ASCII characters is "
834 "not supported");
835 return NULL;
836 }
837
838 rc = _tscmp(PyUnicode_DATA(a),
839 PyUnicode_DATA(b),
840 PyUnicode_GET_LENGTH(a),
841 PyUnicode_GET_LENGTH(b));
842 }
843 /* fallback to buffer interface for bytes, bytesarray and other */
844 else {
845 Py_buffer view_a;
846 Py_buffer view_b;
847
Benjamin Peterson23a192d2014-05-11 16:17:02 -0700848 if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) {
Christian Heimes6cea6552012-06-24 13:48:32 +0200849 PyErr_Format(PyExc_TypeError,
850 "unsupported operand types(s) or combination of types: "
851 "'%.100s' and '%.100s'",
852 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
853 return NULL;
854 }
855
856 if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) {
857 return NULL;
858 }
859 if (view_a.ndim > 1) {
860 PyErr_SetString(PyExc_BufferError,
861 "Buffer must be single dimension");
862 PyBuffer_Release(&view_a);
863 return NULL;
864 }
865
866 if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) {
867 PyBuffer_Release(&view_a);
868 return NULL;
869 }
870 if (view_b.ndim > 1) {
871 PyErr_SetString(PyExc_BufferError,
872 "Buffer must be single dimension");
873 PyBuffer_Release(&view_a);
874 PyBuffer_Release(&view_b);
875 return NULL;
876 }
877
878 rc = _tscmp((const unsigned char*)view_a.buf,
879 (const unsigned char*)view_b.buf,
880 view_a.len,
881 view_b.len);
882
883 PyBuffer_Release(&view_a);
884 PyBuffer_Release(&view_b);
885 }
886
Georg Brandl93b7d7e2012-06-24 13:54:51 +0200887 return PyBool_FromLong(rc);
Christian Heimes6cea6552012-06-24 13:48:32 +0200888}
889
890/* operator methods **********************************************************/
891
Guido van Rossum037b9401996-07-30 16:55:54 +0000892static struct PyMethodDef operator_methods[] = {
Guido van Rossum037b9401996-07-30 16:55:54 +0000893
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200894 _OPERATOR_TRUTH_METHODDEF
895 _OPERATOR_CONTAINS_METHODDEF
896 _OPERATOR_INDEXOF_METHODDEF
897 _OPERATOR_COUNTOF_METHODDEF
898 _OPERATOR_IS__METHODDEF
899 _OPERATOR_IS_NOT_METHODDEF
900 _OPERATOR_INDEX_METHODDEF
901 _OPERATOR_ADD_METHODDEF
902 _OPERATOR_SUB_METHODDEF
903 _OPERATOR_MUL_METHODDEF
904 _OPERATOR_MATMUL_METHODDEF
905 _OPERATOR_FLOORDIV_METHODDEF
906 _OPERATOR_TRUEDIV_METHODDEF
907 _OPERATOR_MOD_METHODDEF
908 _OPERATOR_NEG_METHODDEF
909 _OPERATOR_POS_METHODDEF
910 _OPERATOR_ABS_METHODDEF
911 _OPERATOR_INV_METHODDEF
912 _OPERATOR_INVERT_METHODDEF
913 _OPERATOR_LSHIFT_METHODDEF
914 _OPERATOR_RSHIFT_METHODDEF
915 _OPERATOR_NOT__METHODDEF
916 _OPERATOR_AND__METHODDEF
917 _OPERATOR_XOR_METHODDEF
918 _OPERATOR_OR__METHODDEF
919 _OPERATOR_IADD_METHODDEF
920 _OPERATOR_ISUB_METHODDEF
921 _OPERATOR_IMUL_METHODDEF
922 _OPERATOR_IMATMUL_METHODDEF
923 _OPERATOR_IFLOORDIV_METHODDEF
924 _OPERATOR_ITRUEDIV_METHODDEF
925 _OPERATOR_IMOD_METHODDEF
926 _OPERATOR_ILSHIFT_METHODDEF
927 _OPERATOR_IRSHIFT_METHODDEF
928 _OPERATOR_IAND_METHODDEF
929 _OPERATOR_IXOR_METHODDEF
930 _OPERATOR_IOR_METHODDEF
931 _OPERATOR_CONCAT_METHODDEF
932 _OPERATOR_ICONCAT_METHODDEF
933 _OPERATOR_GETITEM_METHODDEF
934 _OPERATOR_SETITEM_METHODDEF
935 _OPERATOR_DELITEM_METHODDEF
936 _OPERATOR_POW_METHODDEF
937 _OPERATOR_IPOW_METHODDEF
938 _OPERATOR_EQ_METHODDEF
939 _OPERATOR_NE_METHODDEF
940 _OPERATOR_LT_METHODDEF
941 _OPERATOR_LE_METHODDEF
942 _OPERATOR_GT_METHODDEF
943 _OPERATOR_GE_METHODDEF
944 _OPERATOR__COMPARE_DIGEST_METHODDEF
945 _OPERATOR_LENGTH_HINT_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 {NULL, NULL} /* sentinel */
Guido van Rossum037b9401996-07-30 16:55:54 +0000947
Guido van Rossum037b9401996-07-30 16:55:54 +0000948};
949
Raymond Hettinger166958b2003-12-01 13:18:39 +0000950/* itemgetter object **********************************************************/
Guido van Rossum037b9401996-07-30 16:55:54 +0000951
Raymond Hettinger166958b2003-12-01 13:18:39 +0000952typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000953 PyObject_HEAD
954 Py_ssize_t nitems;
955 PyObject *item;
Raymond Hettinger2d53bed2019-01-07 09:38:41 -0700956 Py_ssize_t index; // -1 unless *item* is a single non-negative integer index
Raymond Hettinger166958b2003-12-01 13:18:39 +0000957} itemgetterobject;
958
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200959/* AC 3.5: treats first argument as an iterable, otherwise uses *args */
Raymond Hettinger166958b2003-12-01 13:18:39 +0000960static PyObject *
961itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
962{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 itemgetterobject *ig;
964 PyObject *item;
965 Py_ssize_t nitems;
Raymond Hettinger2d53bed2019-01-07 09:38:41 -0700966 Py_ssize_t index;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000967
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +0300968 if (!_PyArg_NoKeywords("itemgetter", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +0000970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 nitems = PyTuple_GET_SIZE(args);
972 if (nitems <= 1) {
973 if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item))
974 return NULL;
Dong-hee Na31967fd2020-08-26 17:22:27 +0000975 } else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 item = args;
Dong-hee Na31967fd2020-08-26 17:22:27 +0000977 }
978 _operator_state *state = PyType_GetModuleState(type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 /* create itemgetterobject structure */
Dong-hee Na31967fd2020-08-26 17:22:27 +0000980 ig = PyObject_GC_New(itemgetterobject, (PyTypeObject *) state->itemgetter_type);
981 if (ig == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 return NULL;
Dong-hee Na31967fd2020-08-26 17:22:27 +0000983 }
Raymond Hettinger166958b2003-12-01 13:18:39 +0000984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 Py_INCREF(item);
986 ig->item = item;
987 ig->nitems = nitems;
Raymond Hettinger2d53bed2019-01-07 09:38:41 -0700988 ig->index = -1;
989 if (PyLong_CheckExact(item)) {
990 index = PyLong_AsSsize_t(item);
991 if (index < 0) {
992 /* If we get here, then either the index conversion failed
993 * due to being out of range, or the index was a negative
994 * integer. Either way, we clear any possible exception
995 * and fall back to the slow path, where ig->index is -1.
996 */
997 PyErr_Clear();
998 }
999 else {
1000 ig->index = index;
1001 }
1002 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003
1004 PyObject_GC_Track(ig);
1005 return (PyObject *)ig;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001006}
1007
1008static void
1009itemgetter_dealloc(itemgetterobject *ig)
1010{
Dong-hee Na31967fd2020-08-26 17:22:27 +00001011 PyTypeObject *tp = Py_TYPE(ig);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 PyObject_GC_UnTrack(ig);
1013 Py_XDECREF(ig->item);
Dong-hee Na31967fd2020-08-26 17:22:27 +00001014 tp->tp_free(ig);
1015 Py_DECREF(tp);
Raymond Hettinger166958b2003-12-01 13:18:39 +00001016}
1017
1018static int
1019itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
1020{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 Py_VISIT(ig->item);
1022 return 0;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001023}
1024
1025static PyObject *
1026itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
1027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 PyObject *obj, *result;
1029 Py_ssize_t i, nitems=ig->nitems;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001030
Raymond Hettinger2d53bed2019-01-07 09:38:41 -07001031 assert(PyTuple_CheckExact(args));
Serhiy Storchaka79342662019-01-12 08:25:41 +02001032 if (!_PyArg_NoKeywords("itemgetter", kw))
1033 return NULL;
1034 if (!_PyArg_CheckPositional("itemgetter", PyTuple_GET_SIZE(args), 1, 1))
1035 return NULL;
1036
1037 obj = PyTuple_GET_ITEM(args, 0);
Raymond Hettinger2d53bed2019-01-07 09:38:41 -07001038 if (nitems == 1) {
1039 if (ig->index >= 0
1040 && PyTuple_CheckExact(obj)
1041 && ig->index < PyTuple_GET_SIZE(obj))
1042 {
1043 result = PyTuple_GET_ITEM(obj, ig->index);
1044 Py_INCREF(result);
1045 return result;
1046 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 return PyObject_GetItem(obj, ig->item);
Raymond Hettinger2d53bed2019-01-07 09:38:41 -07001048 }
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001050 assert(PyTuple_Check(ig->item));
1051 assert(PyTuple_GET_SIZE(ig->item) == nitems);
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 result = PyTuple_New(nitems);
1054 if (result == NULL)
1055 return NULL;
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 for (i=0 ; i < nitems ; i++) {
1058 PyObject *item, *val;
1059 item = PyTuple_GET_ITEM(ig->item, i);
1060 val = PyObject_GetItem(obj, item);
1061 if (val == NULL) {
1062 Py_DECREF(result);
1063 return NULL;
1064 }
1065 PyTuple_SET_ITEM(result, i, val);
1066 }
1067 return result;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001068}
1069
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001070static PyObject *
1071itemgetter_repr(itemgetterobject *ig)
1072{
1073 PyObject *repr;
1074 const char *reprfmt;
1075
1076 int status = Py_ReprEnter((PyObject *)ig);
1077 if (status != 0) {
1078 if (status < 0)
1079 return NULL;
1080 return PyUnicode_FromFormat("%s(...)", Py_TYPE(ig)->tp_name);
1081 }
1082
1083 reprfmt = ig->nitems == 1 ? "%s(%R)" : "%s%R";
1084 repr = PyUnicode_FromFormat(reprfmt, Py_TYPE(ig)->tp_name, ig->item);
1085 Py_ReprLeave((PyObject *)ig);
1086 return repr;
1087}
1088
1089static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301090itemgetter_reduce(itemgetterobject *ig, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001091{
1092 if (ig->nitems == 1)
1093 return Py_BuildValue("O(O)", Py_TYPE(ig), ig->item);
1094 return PyTuple_Pack(2, Py_TYPE(ig), ig->item);
1095}
1096
1097PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1098
1099static PyMethodDef itemgetter_methods[] = {
1100 {"__reduce__", (PyCFunction)itemgetter_reduce, METH_NOARGS,
1101 reduce_doc},
1102 {NULL}
1103};
1104
Raymond Hettinger166958b2003-12-01 13:18:39 +00001105PyDoc_STRVAR(itemgetter_doc,
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001106"itemgetter(item, ...) --> itemgetter object\n\
Raymond Hettinger166958b2003-12-01 13:18:39 +00001107\n\
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001108Return a callable object that fetches the given item(s) from its operand.\n\
Ezio Melottibabc8222013-05-08 10:53:11 +03001109After f = itemgetter(2), the call f(r) returns r[2].\n\
1110After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])");
Raymond Hettinger166958b2003-12-01 13:18:39 +00001111
Dong-hee Na31967fd2020-08-26 17:22:27 +00001112static PyType_Slot itemgetter_type_slots[] = {
1113 {Py_tp_doc, (void *)itemgetter_doc},
1114 {Py_tp_dealloc, itemgetter_dealloc},
1115 {Py_tp_call, itemgetter_call},
1116 {Py_tp_traverse, itemgetter_traverse},
1117 {Py_tp_methods, itemgetter_methods},
1118 {Py_tp_new, itemgetter_new},
1119 {Py_tp_getattro, PyObject_GenericGetAttr},
1120 {Py_tp_repr, itemgetter_repr},
1121 {0, 0}
Raymond Hettinger166958b2003-12-01 13:18:39 +00001122};
1123
Dong-hee Na31967fd2020-08-26 17:22:27 +00001124static PyType_Spec itemgetter_type_spec = {
1125 .name = "operator.itemgetter",
1126 .basicsize = sizeof(itemgetterobject),
1127 .itemsize = 0,
1128 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1129 .slots = itemgetter_type_slots,
1130};
Raymond Hettinger166958b2003-12-01 13:18:39 +00001131
1132/* attrgetter object **********************************************************/
1133
1134typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 PyObject_HEAD
1136 Py_ssize_t nattrs;
1137 PyObject *attr;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001138} attrgetterobject;
1139
Serhiy Storchakab813a0e2017-01-19 17:44:13 +02001140/* AC 3.5: treats first argument as an iterable, otherwise uses *args */
Raymond Hettinger166958b2003-12-01 13:18:39 +00001141static PyObject *
1142attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 attrgetterobject *ag;
1145 PyObject *attr;
Antoine Pitroue9745712010-10-31 15:26:04 +00001146 Py_ssize_t nattrs, idx, char_idx;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001147
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001148 if (!_PyArg_NoKeywords("attrgetter", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 nattrs = PyTuple_GET_SIZE(args);
1152 if (nattrs <= 1) {
1153 if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
1154 return NULL;
Antoine Pitroue9745712010-10-31 15:26:04 +00001155 }
1156
1157 attr = PyTuple_New(nattrs);
1158 if (attr == NULL)
1159 return NULL;
1160
1161 /* prepare attr while checking args */
1162 for (idx = 0; idx < nattrs; ++idx) {
1163 PyObject *item = PyTuple_GET_ITEM(args, idx);
1164 Py_ssize_t item_len;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +03001165 const void *data;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001166 unsigned int kind;
Antoine Pitroue9745712010-10-31 15:26:04 +00001167 int dot_count;
1168
1169 if (!PyUnicode_Check(item)) {
1170 PyErr_SetString(PyExc_TypeError,
1171 "attribute name must be a string");
1172 Py_DECREF(attr);
1173 return NULL;
1174 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001175 if (PyUnicode_READY(item)) {
1176 Py_DECREF(attr);
1177 return NULL;
1178 }
1179 item_len = PyUnicode_GET_LENGTH(item);
1180 kind = PyUnicode_KIND(item);
1181 data = PyUnicode_DATA(item);
Antoine Pitroue9745712010-10-31 15:26:04 +00001182
1183 /* check whethere the string is dotted */
1184 dot_count = 0;
1185 for (char_idx = 0; char_idx < item_len; ++char_idx) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001186 if (PyUnicode_READ(kind, data, char_idx) == '.')
Antoine Pitroue9745712010-10-31 15:26:04 +00001187 ++dot_count;
1188 }
1189
1190 if (dot_count == 0) {
1191 Py_INCREF(item);
1192 PyUnicode_InternInPlace(&item);
1193 PyTuple_SET_ITEM(attr, idx, item);
1194 } else { /* make it a tuple of non-dotted attrnames */
1195 PyObject *attr_chain = PyTuple_New(dot_count + 1);
1196 PyObject *attr_chain_item;
Antoine Pitrou87298c42010-10-31 21:03:01 +00001197 Py_ssize_t unibuff_from = 0;
1198 Py_ssize_t unibuff_till = 0;
1199 Py_ssize_t attr_chain_idx = 0;
Antoine Pitroue9745712010-10-31 15:26:04 +00001200
1201 if (attr_chain == NULL) {
1202 Py_DECREF(attr);
1203 return NULL;
1204 }
1205
Antoine Pitroue9745712010-10-31 15:26:04 +00001206 for (; dot_count > 0; --dot_count) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001207 while (PyUnicode_READ(kind, data, unibuff_till) != '.') {
Antoine Pitroue9745712010-10-31 15:26:04 +00001208 ++unibuff_till;
1209 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001210 attr_chain_item = PyUnicode_Substring(item,
1211 unibuff_from,
1212 unibuff_till);
Antoine Pitroue9745712010-10-31 15:26:04 +00001213 if (attr_chain_item == NULL) {
1214 Py_DECREF(attr_chain);
1215 Py_DECREF(attr);
1216 return NULL;
1217 }
1218 PyUnicode_InternInPlace(&attr_chain_item);
1219 PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
1220 ++attr_chain_idx;
1221 unibuff_till = unibuff_from = unibuff_till + 1;
1222 }
1223
1224 /* now add the last dotless name */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001225 attr_chain_item = PyUnicode_Substring(item,
1226 unibuff_from, item_len);
Antoine Pitroue9745712010-10-31 15:26:04 +00001227 if (attr_chain_item == NULL) {
1228 Py_DECREF(attr_chain);
1229 Py_DECREF(attr);
1230 return NULL;
1231 }
1232 PyUnicode_InternInPlace(&attr_chain_item);
1233 PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
1234
1235 PyTuple_SET_ITEM(attr, idx, attr_chain);
1236 }
1237 }
Raymond Hettinger166958b2003-12-01 13:18:39 +00001238
Dong-hee Na31967fd2020-08-26 17:22:27 +00001239 _operator_state *state = PyType_GetModuleState(type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 /* create attrgetterobject structure */
Dong-hee Na31967fd2020-08-26 17:22:27 +00001241 ag = PyObject_GC_New(attrgetterobject, (PyTypeObject *)state->attrgetter_type);
Antoine Pitroue9745712010-10-31 15:26:04 +00001242 if (ag == NULL) {
1243 Py_DECREF(attr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 return NULL;
Antoine Pitroue9745712010-10-31 15:26:04 +00001245 }
Raymond Hettinger166958b2003-12-01 13:18:39 +00001246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 ag->attr = attr;
1248 ag->nattrs = nattrs;
1249
1250 PyObject_GC_Track(ag);
1251 return (PyObject *)ag;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001252}
1253
1254static void
1255attrgetter_dealloc(attrgetterobject *ag)
1256{
Dong-hee Na31967fd2020-08-26 17:22:27 +00001257 PyTypeObject *tp = Py_TYPE(ag);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 PyObject_GC_UnTrack(ag);
1259 Py_XDECREF(ag->attr);
Dong-hee Na31967fd2020-08-26 17:22:27 +00001260 tp->tp_free(ag);
1261 Py_DECREF(tp);
Raymond Hettinger166958b2003-12-01 13:18:39 +00001262}
1263
1264static int
1265attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
1266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 Py_VISIT(ag->attr);
1268 return 0;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001269}
1270
1271static PyObject *
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001272dotted_getattr(PyObject *obj, PyObject *attr)
1273{
Antoine Pitroue9745712010-10-31 15:26:04 +00001274 PyObject *newobj;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001275
Antoine Pitroue9745712010-10-31 15:26:04 +00001276 /* attr is either a tuple or instance of str.
1277 Ensured by the setup code of attrgetter_new */
1278 if (PyTuple_CheckExact(attr)) { /* chained getattr */
1279 Py_ssize_t name_idx = 0, name_count;
1280 PyObject *attr_name;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001281
Antoine Pitroue9745712010-10-31 15:26:04 +00001282 name_count = PyTuple_GET_SIZE(attr);
1283 Py_INCREF(obj);
1284 for (name_idx = 0; name_idx < name_count; ++name_idx) {
1285 attr_name = PyTuple_GET_ITEM(attr, name_idx);
1286 newobj = PyObject_GetAttr(obj, attr_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 Py_DECREF(obj);
Antoine Pitroue9745712010-10-31 15:26:04 +00001288 if (newobj == NULL) {
1289 return NULL;
1290 }
1291 /* here */
1292 obj = newobj;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 }
Antoine Pitroue9745712010-10-31 15:26:04 +00001294 } else { /* single getattr */
1295 newobj = PyObject_GetAttr(obj, attr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 if (newobj == NULL)
1297 return NULL;
1298 obj = newobj;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 }
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 return obj;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001302}
1303
1304static PyObject *
Raymond Hettinger166958b2003-12-01 13:18:39 +00001305attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
1306{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 PyObject *obj, *result;
1308 Py_ssize_t i, nattrs=ag->nattrs;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001309
Serhiy Storchaka68a001d2017-02-06 10:41:46 +02001310 if (!_PyArg_NoKeywords("attrgetter", kw))
Serhiy Storchakac2a2a752016-04-23 10:51:39 +03001311 return NULL;
Serhiy Storchaka79342662019-01-12 08:25:41 +02001312 if (!_PyArg_CheckPositional("attrgetter", PyTuple_GET_SIZE(args), 1, 1))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 return NULL;
Serhiy Storchaka79342662019-01-12 08:25:41 +02001314 obj = PyTuple_GET_ITEM(args, 0);
Antoine Pitroue9745712010-10-31 15:26:04 +00001315 if (ag->nattrs == 1) /* ag->attr is always a tuple */
1316 return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0));
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 assert(PyTuple_Check(ag->attr));
1319 assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 result = PyTuple_New(nattrs);
1322 if (result == NULL)
1323 return NULL;
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 for (i=0 ; i < nattrs ; i++) {
1326 PyObject *attr, *val;
1327 attr = PyTuple_GET_ITEM(ag->attr, i);
1328 val = dotted_getattr(obj, attr);
1329 if (val == NULL) {
1330 Py_DECREF(result);
1331 return NULL;
1332 }
1333 PyTuple_SET_ITEM(result, i, val);
1334 }
1335 return result;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001336}
1337
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001338static PyObject *
1339dotjoinattr(PyObject *attr, PyObject **attrsep)
1340{
1341 if (PyTuple_CheckExact(attr)) {
1342 if (*attrsep == NULL) {
1343 *attrsep = PyUnicode_FromString(".");
1344 if (*attrsep == NULL)
1345 return NULL;
1346 }
1347 return PyUnicode_Join(*attrsep, attr);
1348 } else {
1349 Py_INCREF(attr);
1350 return attr;
1351 }
1352}
1353
1354static PyObject *
1355attrgetter_args(attrgetterobject *ag)
1356{
1357 Py_ssize_t i;
1358 PyObject *attrsep = NULL;
1359 PyObject *attrstrings = PyTuple_New(ag->nattrs);
1360 if (attrstrings == NULL)
1361 return NULL;
1362
1363 for (i = 0; i < ag->nattrs; ++i) {
1364 PyObject *attr = PyTuple_GET_ITEM(ag->attr, i);
1365 PyObject *attrstr = dotjoinattr(attr, &attrsep);
1366 if (attrstr == NULL) {
1367 Py_XDECREF(attrsep);
1368 Py_DECREF(attrstrings);
1369 return NULL;
1370 }
1371 PyTuple_SET_ITEM(attrstrings, i, attrstr);
1372 }
1373 Py_XDECREF(attrsep);
1374 return attrstrings;
1375}
1376
1377static PyObject *
1378attrgetter_repr(attrgetterobject *ag)
1379{
1380 PyObject *repr = NULL;
1381 int status = Py_ReprEnter((PyObject *)ag);
1382 if (status != 0) {
1383 if (status < 0)
1384 return NULL;
1385 return PyUnicode_FromFormat("%s(...)", Py_TYPE(ag)->tp_name);
1386 }
1387
1388 if (ag->nattrs == 1) {
1389 PyObject *attrsep = NULL;
1390 PyObject *attr = dotjoinattr(PyTuple_GET_ITEM(ag->attr, 0), &attrsep);
Serhiy Storchaka548de2b2015-05-21 14:19:20 +03001391 if (attr != NULL) {
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001392 repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(ag)->tp_name, attr);
Serhiy Storchaka548de2b2015-05-21 14:19:20 +03001393 Py_DECREF(attr);
1394 }
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001395 Py_XDECREF(attrsep);
1396 }
1397 else {
1398 PyObject *attrstrings = attrgetter_args(ag);
1399 if (attrstrings != NULL) {
1400 repr = PyUnicode_FromFormat("%s%R",
1401 Py_TYPE(ag)->tp_name, attrstrings);
1402 Py_DECREF(attrstrings);
1403 }
1404 }
1405 Py_ReprLeave((PyObject *)ag);
1406 return repr;
1407}
1408
1409static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301410attrgetter_reduce(attrgetterobject *ag, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001411{
1412 PyObject *attrstrings = attrgetter_args(ag);
1413 if (attrstrings == NULL)
1414 return NULL;
1415
1416 return Py_BuildValue("ON", Py_TYPE(ag), attrstrings);
1417}
1418
1419static PyMethodDef attrgetter_methods[] = {
1420 {"__reduce__", (PyCFunction)attrgetter_reduce, METH_NOARGS,
1421 reduce_doc},
1422 {NULL}
1423};
1424
Raymond Hettinger166958b2003-12-01 13:18:39 +00001425PyDoc_STRVAR(attrgetter_doc,
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001426"attrgetter(attr, ...) --> attrgetter object\n\
Raymond Hettinger166958b2003-12-01 13:18:39 +00001427\n\
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001428Return a callable object that fetches the given attribute(s) from its operand.\n\
Ezio Melottibabc8222013-05-08 10:53:11 +03001429After f = attrgetter('name'), the call f(r) returns r.name.\n\
1430After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\
1431After h = attrgetter('name.first', 'name.last'), the call h(r) returns\n\
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001432(r.name.first, r.name.last).");
Raymond Hettinger166958b2003-12-01 13:18:39 +00001433
Dong-hee Na31967fd2020-08-26 17:22:27 +00001434static PyType_Slot attrgetter_type_slots[] = {
1435 {Py_tp_doc, (void *)attrgetter_doc},
1436 {Py_tp_dealloc, attrgetter_dealloc},
1437 {Py_tp_call, attrgetter_call},
1438 {Py_tp_traverse, attrgetter_traverse},
1439 {Py_tp_methods, attrgetter_methods},
1440 {Py_tp_new, attrgetter_new},
1441 {Py_tp_getattro, PyObject_GenericGetAttr},
1442 {Py_tp_repr, attrgetter_repr},
1443 {0, 0}
1444};
1445
1446static PyType_Spec attrgetter_type_spec = {
1447 .name = "operator.attrgetter",
1448 .basicsize = sizeof(attrgetterobject),
1449 .itemsize = 0,
1450 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1451 .slots = attrgetter_type_slots,
Raymond Hettinger166958b2003-12-01 13:18:39 +00001452};
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001453
1454
1455/* methodcaller object **********************************************************/
1456
1457typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 PyObject_HEAD
1459 PyObject *name;
1460 PyObject *args;
1461 PyObject *kwds;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001462} methodcallerobject;
1463
Serhiy Storchakab813a0e2017-01-19 17:44:13 +02001464/* AC 3.5: variable number of arguments, not currently support by AC */
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001465static PyObject *
1466methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 methodcallerobject *mc;
Benjamin Peterson1f0e7c92016-08-16 23:35:35 -07001469 PyObject *name;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 if (PyTuple_GET_SIZE(args) < 1) {
1472 PyErr_SetString(PyExc_TypeError, "methodcaller needs at least "
1473 "one argument, the method name");
1474 return NULL;
1475 }
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001476
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001477 name = PyTuple_GET_ITEM(args, 0);
1478 if (!PyUnicode_Check(name)) {
1479 PyErr_SetString(PyExc_TypeError,
1480 "method name must be a string");
1481 return NULL;
1482 }
1483
Dong-hee Na31967fd2020-08-26 17:22:27 +00001484 _operator_state *state = PyType_GetModuleState(type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 /* create methodcallerobject structure */
Dong-hee Na31967fd2020-08-26 17:22:27 +00001486 mc = PyObject_GC_New(methodcallerobject, (PyTypeObject *)state->methodcaller_type);
1487 if (mc == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 return NULL;
Dong-hee Na31967fd2020-08-26 17:22:27 +00001489 }
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 name = PyTuple_GET_ITEM(args, 0);
1492 Py_INCREF(name);
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001493 PyUnicode_InternInPlace(&name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 mc->name = name;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 Py_XINCREF(kwds);
1497 mc->kwds = kwds;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001498
Benjamin Peterson1f0e7c92016-08-16 23:35:35 -07001499 mc->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
1500 if (mc->args == NULL) {
1501 Py_DECREF(mc);
1502 return NULL;
1503 }
1504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 PyObject_GC_Track(mc);
1506 return (PyObject *)mc;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001507}
1508
1509static void
1510methodcaller_dealloc(methodcallerobject *mc)
1511{
Dong-hee Na31967fd2020-08-26 17:22:27 +00001512 PyTypeObject *tp = Py_TYPE(mc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 PyObject_GC_UnTrack(mc);
1514 Py_XDECREF(mc->name);
1515 Py_XDECREF(mc->args);
1516 Py_XDECREF(mc->kwds);
Dong-hee Na31967fd2020-08-26 17:22:27 +00001517 tp->tp_free(mc);
1518 Py_DECREF(tp);
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001519}
1520
1521static int
1522methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
1523{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 Py_VISIT(mc->args);
1525 Py_VISIT(mc->kwds);
1526 return 0;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001527}
1528
1529static PyObject *
1530methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw)
1531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 PyObject *method, *obj, *result;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001533
Serhiy Storchaka68a001d2017-02-06 10:41:46 +02001534 if (!_PyArg_NoKeywords("methodcaller", kw))
Serhiy Storchakac2a2a752016-04-23 10:51:39 +03001535 return NULL;
Serhiy Storchaka79342662019-01-12 08:25:41 +02001536 if (!_PyArg_CheckPositional("methodcaller", PyTuple_GET_SIZE(args), 1, 1))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 return NULL;
Serhiy Storchaka79342662019-01-12 08:25:41 +02001538 obj = PyTuple_GET_ITEM(args, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 method = PyObject_GetAttr(obj, mc->name);
1540 if (method == NULL)
1541 return NULL;
1542 result = PyObject_Call(method, mc->args, mc->kwds);
1543 Py_DECREF(method);
1544 return result;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001545}
1546
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001547static PyObject *
1548methodcaller_repr(methodcallerobject *mc)
1549{
1550 PyObject *argreprs, *repr = NULL, *sep, *joinedargreprs;
1551 Py_ssize_t numtotalargs, numposargs, numkwdargs, i;
1552 int status = Py_ReprEnter((PyObject *)mc);
1553 if (status != 0) {
1554 if (status < 0)
1555 return NULL;
1556 return PyUnicode_FromFormat("%s(...)", Py_TYPE(mc)->tp_name);
1557 }
1558
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02001559 numkwdargs = mc->kwds != NULL ? PyDict_GET_SIZE(mc->kwds) : 0;
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001560 numposargs = PyTuple_GET_SIZE(mc->args);
1561 numtotalargs = numposargs + numkwdargs;
1562
1563 if (numtotalargs == 0) {
1564 repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(mc)->tp_name, mc->name);
1565 Py_ReprLeave((PyObject *)mc);
1566 return repr;
1567 }
1568
1569 argreprs = PyTuple_New(numtotalargs);
1570 if (argreprs == NULL) {
1571 Py_ReprLeave((PyObject *)mc);
1572 return NULL;
1573 }
1574
1575 for (i = 0; i < numposargs; ++i) {
1576 PyObject *onerepr = PyObject_Repr(PyTuple_GET_ITEM(mc->args, i));
1577 if (onerepr == NULL)
1578 goto done;
1579 PyTuple_SET_ITEM(argreprs, i, onerepr);
1580 }
1581
1582 if (numkwdargs != 0) {
1583 PyObject *key, *value;
1584 Py_ssize_t pos = 0;
1585 while (PyDict_Next(mc->kwds, &pos, &key, &value)) {
1586 PyObject *onerepr = PyUnicode_FromFormat("%U=%R", key, value);
1587 if (onerepr == NULL)
1588 goto done;
1589 if (i >= numtotalargs) {
1590 i = -1;
Zackery Spytz5b83ef72018-11-23 12:26:46 -07001591 Py_DECREF(onerepr);
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001592 break;
1593 }
1594 PyTuple_SET_ITEM(argreprs, i, onerepr);
1595 ++i;
1596 }
1597 if (i != numtotalargs) {
1598 PyErr_SetString(PyExc_RuntimeError,
1599 "keywords dict changed size during iteration");
1600 goto done;
1601 }
1602 }
1603
1604 sep = PyUnicode_FromString(", ");
1605 if (sep == NULL)
1606 goto done;
1607
1608 joinedargreprs = PyUnicode_Join(sep, argreprs);
1609 Py_DECREF(sep);
1610 if (joinedargreprs == NULL)
1611 goto done;
1612
1613 repr = PyUnicode_FromFormat("%s(%R, %U)", Py_TYPE(mc)->tp_name,
1614 mc->name, joinedargreprs);
1615 Py_DECREF(joinedargreprs);
1616
1617done:
1618 Py_DECREF(argreprs);
1619 Py_ReprLeave((PyObject *)mc);
1620 return repr;
1621}
1622
1623static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301624methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001625{
1626 PyObject *newargs;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02001627 if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) {
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001628 Py_ssize_t i;
1629 Py_ssize_t callargcount = PyTuple_GET_SIZE(mc->args);
1630 newargs = PyTuple_New(1 + callargcount);
1631 if (newargs == NULL)
1632 return NULL;
1633 Py_INCREF(mc->name);
1634 PyTuple_SET_ITEM(newargs, 0, mc->name);
1635 for (i = 0; i < callargcount; ++i) {
1636 PyObject *arg = PyTuple_GET_ITEM(mc->args, i);
1637 Py_INCREF(arg);
1638 PyTuple_SET_ITEM(newargs, i + 1, arg);
1639 }
1640 return Py_BuildValue("ON", Py_TYPE(mc), newargs);
1641 }
1642 else {
1643 PyObject *functools;
1644 PyObject *partial;
1645 PyObject *constructor;
Victor Stinner7e7823a2016-08-23 00:23:23 +02001646 PyObject *newargs[2];
1647
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001648 _Py_IDENTIFIER(partial);
1649 functools = PyImport_ImportModule("functools");
1650 if (!functools)
1651 return NULL;
1652 partial = _PyObject_GetAttrId(functools, &PyId_partial);
1653 Py_DECREF(functools);
1654 if (!partial)
1655 return NULL;
Victor Stinner7e7823a2016-08-23 00:23:23 +02001656
1657 newargs[0] = (PyObject *)Py_TYPE(mc);
1658 newargs[1] = mc->name;
Petr Viktorinffd97532020-02-11 17:46:57 +01001659 constructor = PyObject_VectorcallDict(partial, newargs, 2, mc->kwds);
Victor Stinner7e7823a2016-08-23 00:23:23 +02001660
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001661 Py_DECREF(partial);
1662 return Py_BuildValue("NO", constructor, mc->args);
1663 }
1664}
1665
1666static PyMethodDef methodcaller_methods[] = {
1667 {"__reduce__", (PyCFunction)methodcaller_reduce, METH_NOARGS,
1668 reduce_doc},
1669 {NULL}
1670};
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001671PyDoc_STRVAR(methodcaller_doc,
1672"methodcaller(name, ...) --> methodcaller object\n\
1673\n\
1674Return a callable object that calls the given method on its operand.\n\
Antoine Pitroua85017f2013-04-20 19:21:44 +02001675After f = methodcaller('name'), the call f(r) returns r.name().\n\
1676After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001677r.name('date', foo=1).");
1678
Dong-hee Na31967fd2020-08-26 17:22:27 +00001679static PyType_Slot methodcaller_type_slots[] = {
1680 {Py_tp_doc, (void *)methodcaller_doc},
1681 {Py_tp_dealloc, methodcaller_dealloc},
1682 {Py_tp_call, methodcaller_call},
1683 {Py_tp_traverse, methodcaller_traverse},
1684 {Py_tp_methods, methodcaller_methods},
1685 {Py_tp_new, methodcaller_new},
1686 {Py_tp_getattro, PyObject_GenericGetAttr},
1687 {Py_tp_repr, methodcaller_repr},
1688 {0, 0}
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001689};
1690
Dong-hee Na31967fd2020-08-26 17:22:27 +00001691static PyType_Spec methodcaller_type_spec = {
1692 .name = "operator.methodcaller",
1693 .basicsize = sizeof(methodcallerobject),
1694 .itemsize = 0,
1695 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1696 .slots = methodcaller_type_slots,
1697};
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001698
Paulo Henrique Silvaf3d5ac42020-03-24 23:18:47 -03001699static int
1700operator_exec(PyObject *module)
1701{
Dong-hee Na31967fd2020-08-26 17:22:27 +00001702 _operator_state *state = get_operator_state(module);
1703 state->attrgetter_type = PyType_FromModuleAndSpec(module, &attrgetter_type_spec, NULL);
1704 if (state->attrgetter_type == NULL) {
1705 return -1;
1706 }
1707 if (PyModule_AddType(module, (PyTypeObject *)state->attrgetter_type) < 0) {
1708 return -1;
1709 }
Paulo Henrique Silvaf3d5ac42020-03-24 23:18:47 -03001710
Dong-hee Na31967fd2020-08-26 17:22:27 +00001711 state->itemgetter_type = PyType_FromModuleAndSpec(module, &itemgetter_type_spec, NULL);
1712 if (state->itemgetter_type == NULL) {
1713 return -1;
1714 }
1715 if (PyModule_AddType(module, (PyTypeObject *)state->itemgetter_type) < 0) {
1716 return -1;
1717 }
1718
1719 state->methodcaller_type = PyType_FromModuleAndSpec(module, &methodcaller_type_spec, NULL);
1720 if (state->methodcaller_type == NULL) {
1721 return -1;
1722 }
1723 if (PyModule_AddType(module, (PyTypeObject *)state->methodcaller_type) < 0) {
1724 return -1;
Paulo Henrique Silvaf3d5ac42020-03-24 23:18:47 -03001725 }
1726
1727 return 0;
1728}
1729
1730
1731static struct PyModuleDef_Slot operator_slots[] = {
1732 {Py_mod_exec, operator_exec},
1733 {0, NULL}
1734};
Martin v. Löwis1a214512008-06-11 05:26:20 +00001735
Dong-hee Na31967fd2020-08-26 17:22:27 +00001736static int
1737operator_traverse(PyObject *module, visitproc visit, void *arg)
1738{
1739 _operator_state *state = get_operator_state(module);
1740 Py_VISIT(state->attrgetter_type);
1741 Py_VISIT(state->itemgetter_type);
1742 Py_VISIT(state->methodcaller_type);
1743 return 0;
1744}
1745
1746static int
1747operator_clear(PyObject *module)
1748{
1749 _operator_state *state = get_operator_state(module);
1750 Py_CLEAR(state->attrgetter_type);
1751 Py_CLEAR(state->itemgetter_type);
1752 Py_CLEAR(state->methodcaller_type);
1753 return 0;
1754}
1755
1756static void
1757operator_free(void *module)
1758{
1759 operator_clear((PyObject *)module);
1760}
Martin v. Löwis1a214512008-06-11 05:26:20 +00001761
1762static struct PyModuleDef operatormodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 PyModuleDef_HEAD_INIT,
Dong-hee Na31967fd2020-08-26 17:22:27 +00001764 .m_name = "_operator",
1765 .m_doc = operator_doc,
1766 .m_size = sizeof(_operator_state),
1767 .m_methods = operator_methods,
1768 .m_slots = operator_slots,
1769 .m_traverse = operator_traverse,
1770 .m_clear = operator_clear,
1771 .m_free = operator_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +00001772};
Guido van Rossum037b9401996-07-30 16:55:54 +00001773
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001774PyMODINIT_FUNC
Antoine Pitroua85017f2013-04-20 19:21:44 +02001775PyInit__operator(void)
Guido van Rossum037b9401996-07-30 16:55:54 +00001776{
Paulo Henrique Silvaf3d5ac42020-03-24 23:18:47 -03001777 return PyModuleDef_Init(&operatormodule);
Guido van Rossum037b9401996-07-30 16:55:54 +00001778}