blob: 8a54829e5bbcc836e51f416b94c946b8a46286ee [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
6/*[clinic input]
7module _operator
8[clinic start generated code]*/
9/*[clinic end generated code: output=da39a3ee5e6b4b0d input=672ecf48487521e7]*/
10
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000011PyDoc_STRVAR(operator_doc,
12"Operator interface.\n\
Guido van Rossum037b9401996-07-30 16:55:54 +000013\n\
14This module exports a set of functions implemented in C corresponding\n\
15to the intrinsic operators of Python. For example, operator.add(x, y)\n\
16is equivalent to the expression x+y. The function names are those\n\
Benjamin Petersona0dfa822009-11-13 02:25:08 +000017used for special methods; variants without leading and trailing\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000018'__' are also provided for convenience.");
Guido van Rossum037b9401996-07-30 16:55:54 +000019
Guido van Rossum037b9401996-07-30 16:55:54 +000020
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020021/*[clinic input]
22_operator.truth -> bool
Guido van Rossum037b9401996-07-30 16:55:54 +000023
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020024 a: object
25 /
Guido van Rossum037b9401996-07-30 16:55:54 +000026
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020027Return True if a is true, False otherwise.
28[clinic start generated code]*/
Guido van Rossum037b9401996-07-30 16:55:54 +000029
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020030static int
31_operator_truth_impl(PyObject *module, PyObject *a)
32/*[clinic end generated code: output=eaf87767234fa5d7 input=bc74a4cd90235875]*/
Raymond Hettinger5959c552002-08-19 03:19:09 +000033{
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020034 return PyObject_IsTrue(a);
Raymond Hettinger5959c552002-08-19 03:19:09 +000035}
36
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020037/*[clinic input]
38_operator.add
39
40 a: object
41 b: object
42 /
43
44Same as a + b.
45[clinic start generated code]*/
Armin Rigof5bd3b42005-12-29 16:50:42 +000046
Guido van Rossum38fff8c2006-03-07 18:50:55 +000047static PyObject *
Serhiy Storchakab813a0e2017-01-19 17:44:13 +020048_operator_add_impl(PyObject *module, PyObject *a, PyObject *b)
49/*[clinic end generated code: output=8292984204f45164 input=5efe3bff856ac215]*/
50{
51 return PyNumber_Add(a, b);
52}
53
54/*[clinic input]
55_operator.sub = _operator.add
56
57Same as a - b.
58[clinic start generated code]*/
59
60static PyObject *
61_operator_sub_impl(PyObject *module, PyObject *a, PyObject *b)
62/*[clinic end generated code: output=4adfc3b888c1ee2e input=6494c6b100b8e795]*/
63{
64 return PyNumber_Subtract(a, b);
65}
66
67/*[clinic input]
68_operator.mul = _operator.add
69
70Same as a * b.
71[clinic start generated code]*/
72
73static PyObject *
74_operator_mul_impl(PyObject *module, PyObject *a, PyObject *b)
75/*[clinic end generated code: output=d24d66f55a01944c input=2368615b4358b70d]*/
76{
77 return PyNumber_Multiply(a, b);
78}
79
80/*[clinic input]
81_operator.matmul = _operator.add
82
83Same as a @ b.
84[clinic start generated code]*/
85
86static PyObject *
87_operator_matmul_impl(PyObject *module, PyObject *a, PyObject *b)
88/*[clinic end generated code: output=a20d917eb35d0101 input=9ab304e37fb42dd4]*/
89{
90 return PyNumber_MatrixMultiply(a, b);
91}
92
93/*[clinic input]
94_operator.floordiv = _operator.add
95
96Same as a // b.
97[clinic start generated code]*/
98
99static PyObject *
100_operator_floordiv_impl(PyObject *module, PyObject *a, PyObject *b)
101/*[clinic end generated code: output=df26b71a60589f99 input=bb2e88ba446c612c]*/
102{
103 return PyNumber_FloorDivide(a, b);
104}
105
106/*[clinic input]
107_operator.truediv = _operator.add
108
109Same as a / b.
110[clinic start generated code]*/
111
112static PyObject *
113_operator_truediv_impl(PyObject *module, PyObject *a, PyObject *b)
114/*[clinic end generated code: output=0e6a959944d77719 input=ecbb947673f4eb1f]*/
115{
116 return PyNumber_TrueDivide(a, b);
117}
118
119/*[clinic input]
120_operator.mod = _operator.add
121
122Same as a % b.
123[clinic start generated code]*/
124
125static PyObject *
126_operator_mod_impl(PyObject *module, PyObject *a, PyObject *b)
127/*[clinic end generated code: output=9519822f0bbec166 input=102e19b422342ac1]*/
128{
129 return PyNumber_Remainder(a, b);
130}
131
132/*[clinic input]
133_operator.neg
134
135 a: object
136 /
137
138Same as -a.
139[clinic start generated code]*/
140
141static PyObject *
142_operator_neg(PyObject *module, PyObject *a)
143/*[clinic end generated code: output=36e08ecfc6a1c08c input=84f09bdcf27c96ec]*/
144{
145 return PyNumber_Negative(a);
146}
147
148/*[clinic input]
149_operator.pos = _operator.neg
150
151Same as +a.
152[clinic start generated code]*/
153
154static PyObject *
155_operator_pos(PyObject *module, PyObject *a)
156/*[clinic end generated code: output=dad7a126221dd091 input=b6445b63fddb8772]*/
157{
158 return PyNumber_Positive(a);
159}
160
161/*[clinic input]
162_operator.abs = _operator.neg
163
164Same as abs(a).
165[clinic start generated code]*/
166
167static PyObject *
168_operator_abs(PyObject *module, PyObject *a)
169/*[clinic end generated code: output=1389a93ba053ea3e input=341d07ba86f58039]*/
170{
171 return PyNumber_Absolute(a);
172}
173
174/*[clinic input]
175_operator.inv = _operator.neg
176
177Same as ~a.
178[clinic start generated code]*/
179
180static PyObject *
181_operator_inv(PyObject *module, PyObject *a)
182/*[clinic end generated code: output=a56875ba075ee06d input=b01a4677739f6eb2]*/
183{
184 return PyNumber_Invert(a);
185}
186
187/*[clinic input]
188_operator.invert = _operator.neg
189
190Same as ~a.
191[clinic start generated code]*/
192
193static PyObject *
194_operator_invert(PyObject *module, PyObject *a)
195/*[clinic end generated code: output=406b5aa030545fcc input=7f2d607176672e55]*/
196{
197 return PyNumber_Invert(a);
198}
199
200/*[clinic input]
201_operator.lshift = _operator.add
202
203Same as a << b.
204[clinic start generated code]*/
205
206static PyObject *
207_operator_lshift_impl(PyObject *module, PyObject *a, PyObject *b)
208/*[clinic end generated code: output=37f7e52c41435bd8 input=746e8a160cbbc9eb]*/
209{
210 return PyNumber_Lshift(a, b);
211}
212
213/*[clinic input]
214_operator.rshift = _operator.add
215
216Same as a >> b.
217[clinic start generated code]*/
218
219static PyObject *
220_operator_rshift_impl(PyObject *module, PyObject *a, PyObject *b)
221/*[clinic end generated code: output=4593c7ef30ec2ee3 input=d2c85bb5a64504c2]*/
222{
223 return PyNumber_Rshift(a, b);
224}
225
226/*[clinic input]
227_operator.not_ = _operator.truth
228
229Same as not a.
230[clinic start generated code]*/
231
232static int
233_operator_not__impl(PyObject *module, PyObject *a)
234/*[clinic end generated code: output=743f9c24a09759ef input=854156d50804d9b8]*/
235{
236 return PyObject_Not(a);
237}
238
239/*[clinic input]
240_operator.and_ = _operator.add
241
242Same as a & b.
243[clinic start generated code]*/
244
245static PyObject *
246_operator_and__impl(PyObject *module, PyObject *a, PyObject *b)
247/*[clinic end generated code: output=93c4fe88f7b76d9e input=4f3057c90ec4c99f]*/
248{
249 return PyNumber_And(a, b);
250}
251
252/*[clinic input]
253_operator.xor = _operator.add
254
255Same as a ^ b.
256[clinic start generated code]*/
257
258static PyObject *
259_operator_xor_impl(PyObject *module, PyObject *a, PyObject *b)
260/*[clinic end generated code: output=b24cd8b79fde0004 input=3c5cfa7253d808dd]*/
261{
262 return PyNumber_Xor(a, b);
263}
264
265/*[clinic input]
266_operator.or_ = _operator.add
267
268Same as a | b.
269[clinic start generated code]*/
270
271static PyObject *
272_operator_or__impl(PyObject *module, PyObject *a, PyObject *b)
273/*[clinic end generated code: output=58024867b8d90461 input=b40c6c44f7c79c09]*/
274{
275 return PyNumber_Or(a, b);
276}
277
278/*[clinic input]
279_operator.iadd = _operator.add
280
281Same as a += b.
282[clinic start generated code]*/
283
284static PyObject *
285_operator_iadd_impl(PyObject *module, PyObject *a, PyObject *b)
286/*[clinic end generated code: output=07dc627832526eb5 input=d22a91c07ac69227]*/
287{
288 return PyNumber_InPlaceAdd(a, b);
289}
290
291/*[clinic input]
292_operator.isub = _operator.add
293
294Same as a -= b.
295[clinic start generated code]*/
296
297static PyObject *
298_operator_isub_impl(PyObject *module, PyObject *a, PyObject *b)
299/*[clinic end generated code: output=4513467d23b5e0b1 input=4591b00d0a0ccafd]*/
300{
301 return PyNumber_InPlaceSubtract(a, b);
302}
303
304/*[clinic input]
305_operator.imul = _operator.add
306
307Same as a *= b.
308[clinic start generated code]*/
309
310static PyObject *
311_operator_imul_impl(PyObject *module, PyObject *a, PyObject *b)
312/*[clinic end generated code: output=5e87dacd19a71eab input=0e01fb8631e1b76f]*/
313{
314 return PyNumber_InPlaceMultiply(a, b);
315}
316
317/*[clinic input]
318_operator.imatmul = _operator.add
319
320Same as a @= b.
321[clinic start generated code]*/
322
323static PyObject *
324_operator_imatmul_impl(PyObject *module, PyObject *a, PyObject *b)
325/*[clinic end generated code: output=d603cbdf716ce519 input=bb614026372cd542]*/
326{
327 return PyNumber_InPlaceMatrixMultiply(a, b);
328}
329
330/*[clinic input]
331_operator.ifloordiv = _operator.add
332
333Same as a //= b.
334[clinic start generated code]*/
335
336static PyObject *
337_operator_ifloordiv_impl(PyObject *module, PyObject *a, PyObject *b)
338/*[clinic end generated code: output=535336048c681794 input=9df3b5021cff4ca1]*/
339{
340 return PyNumber_InPlaceFloorDivide(a, b);
341}
342
343/*[clinic input]
344_operator.itruediv = _operator.add
345
346Same as a /= b.
347[clinic start generated code]*/
348
349static PyObject *
350_operator_itruediv_impl(PyObject *module, PyObject *a, PyObject *b)
351/*[clinic end generated code: output=28017fbd3563952f input=9a1ee01608f5f590]*/
352{
353 return PyNumber_InPlaceTrueDivide(a, b);
354}
355
356/*[clinic input]
357_operator.imod = _operator.add
358
359Same as a %= b.
360[clinic start generated code]*/
361
362static PyObject *
363_operator_imod_impl(PyObject *module, PyObject *a, PyObject *b)
364/*[clinic end generated code: output=f7c540ae0fc70904 input=d0c384a3ce38e1dd]*/
365{
366 return PyNumber_InPlaceRemainder(a, b);
367}
368
369/*[clinic input]
370_operator.ilshift = _operator.add
371
372Same as a <<= b.
373[clinic start generated code]*/
374
375static PyObject *
376_operator_ilshift_impl(PyObject *module, PyObject *a, PyObject *b)
377/*[clinic end generated code: output=e73a8fee1ac18749 input=e21b6b310f54572e]*/
378{
379 return PyNumber_InPlaceLshift(a, b);
380}
381
382/*[clinic input]
383_operator.irshift = _operator.add
384
385Same as a >>= b.
386[clinic start generated code]*/
387
388static PyObject *
389_operator_irshift_impl(PyObject *module, PyObject *a, PyObject *b)
390/*[clinic end generated code: output=97f2af6b5ff2ed81 input=6778dbd0f6e1ec16]*/
391{
392 return PyNumber_InPlaceRshift(a, b);
393}
394
395/*[clinic input]
396_operator.iand = _operator.add
397
398Same as a &= b.
399[clinic start generated code]*/
400
401static PyObject *
402_operator_iand_impl(PyObject *module, PyObject *a, PyObject *b)
403/*[clinic end generated code: output=4599e9d40cbf7d00 input=71dfd8e70c156a7b]*/
404{
405 return PyNumber_InPlaceAnd(a, b);
406}
407
408/*[clinic input]
409_operator.ixor = _operator.add
410
411Same as a ^= b.
412[clinic start generated code]*/
413
414static PyObject *
415_operator_ixor_impl(PyObject *module, PyObject *a, PyObject *b)
416/*[clinic end generated code: output=5ff881766872be03 input=695c32bec0604d86]*/
417{
418 return PyNumber_InPlaceXor(a, b);
419}
420
421/*[clinic input]
422_operator.ior = _operator.add
423
424Same as a |= b.
425[clinic start generated code]*/
426
427static PyObject *
428_operator_ior_impl(PyObject *module, PyObject *a, PyObject *b)
429/*[clinic end generated code: output=48aac319445bf759 input=8f01d03eda9920cf]*/
430{
431 return PyNumber_InPlaceOr(a, b);
432}
433
434/*[clinic input]
435_operator.concat = _operator.add
436
437Same as a + b, for a and b sequences.
438[clinic start generated code]*/
439
440static PyObject *
441_operator_concat_impl(PyObject *module, PyObject *a, PyObject *b)
442/*[clinic end generated code: output=80028390942c5f11 input=8544ccd5341a3658]*/
443{
444 return PySequence_Concat(a, b);
445}
446
447/*[clinic input]
448_operator.iconcat = _operator.add
449
450Same as a += b, for a and b sequences.
451[clinic start generated code]*/
452
453static PyObject *
454_operator_iconcat_impl(PyObject *module, PyObject *a, PyObject *b)
455/*[clinic end generated code: output=3ea0a162ebb2e26d input=8f5fe5722fcd837e]*/
456{
457 return PySequence_InPlaceConcat(a, b);
458}
459
460/*[clinic input]
461_operator.contains -> bool
462
463 a: object
464 b: object
465 /
466
467Same as b in a (note reversed operands).
468[clinic start generated code]*/
469
470static int
471_operator_contains_impl(PyObject *module, PyObject *a, PyObject *b)
472/*[clinic end generated code: output=413b4dbe82b6ffc1 input=9122a69b505fde13]*/
473{
474 return PySequence_Contains(a, b);
475}
476
477/*[clinic input]
478_operator.indexOf -> Py_ssize_t
479
480 a: object
481 b: object
482 /
483
484Return the first index of b in a.
485[clinic start generated code]*/
486
487static Py_ssize_t
488_operator_indexOf_impl(PyObject *module, PyObject *a, PyObject *b)
489/*[clinic end generated code: output=c6226d8e0fb60fa6 input=8be2e43b6a6fffe3]*/
490{
491 return PySequence_Index(a, b);
492}
493
494/*[clinic input]
495_operator.countOf = _operator.indexOf
496
497Return the number of times b occurs in a.
498[clinic start generated code]*/
499
500static Py_ssize_t
501_operator_countOf_impl(PyObject *module, PyObject *a, PyObject *b)
502/*[clinic end generated code: output=9e1623197daf3382 input=0c3a2656add252db]*/
503{
504 return PySequence_Count(a, b);
505}
506
507/*[clinic input]
508_operator.getitem
509
510 a: object
511 b: object
512 /
513
514Same as a[b].
515[clinic start generated code]*/
516
517static PyObject *
518_operator_getitem_impl(PyObject *module, PyObject *a, PyObject *b)
519/*[clinic end generated code: output=6c8d8101a676e594 input=6682797320e48845]*/
520{
521 return PyObject_GetItem(a, b);
522}
523
524/*[clinic input]
525_operator.setitem
526
527 a: object
528 b: object
529 c: object
530 /
531
532Same as a[b] = c.
533[clinic start generated code]*/
534
535static PyObject *
536_operator_setitem_impl(PyObject *module, PyObject *a, PyObject *b,
537 PyObject *c)
538/*[clinic end generated code: output=1324f9061ae99e25 input=ceaf453c4d3a58df]*/
539{
540 if (-1 == PyObject_SetItem(a, b, c))
541 return NULL;
542 Py_RETURN_NONE;
543}
544
545/*[clinic input]
546_operator.delitem = _operator.getitem
547
548Same as del a[b].
549[clinic start generated code]*/
550
551static PyObject *
552_operator_delitem_impl(PyObject *module, PyObject *a, PyObject *b)
553/*[clinic end generated code: output=db18f61506295799 input=991bec56a0d3ec7f]*/
554{
555 if (-1 == PyObject_DelItem(a, b))
556 return NULL;
557 Py_RETURN_NONE;
558}
559
560/*[clinic input]
561_operator.eq
562
563 a: object
564 b: object
565 /
566
567Same as a == b.
568[clinic start generated code]*/
569
570static PyObject *
571_operator_eq_impl(PyObject *module, PyObject *a, PyObject *b)
572/*[clinic end generated code: output=8d7d46ed4135677c input=586fca687a95a83f]*/
573{
574 return PyObject_RichCompare(a, b, Py_EQ);
575}
576
577/*[clinic input]
578_operator.ne = _operator.eq
579
580Same as a != b.
581[clinic start generated code]*/
582
583static PyObject *
584_operator_ne_impl(PyObject *module, PyObject *a, PyObject *b)
585/*[clinic end generated code: output=c99bd0c3a4c01297 input=5d88f23d35e9abac]*/
586{
587 return PyObject_RichCompare(a, b, Py_NE);
588}
589
590/*[clinic input]
591_operator.lt = _operator.eq
592
593Same as a < b.
594[clinic start generated code]*/
595
596static PyObject *
597_operator_lt_impl(PyObject *module, PyObject *a, PyObject *b)
598/*[clinic end generated code: output=082d7c45c440e535 input=34a59ad6d39d3a2b]*/
599{
600 return PyObject_RichCompare(a, b, Py_LT);
601}
602
603/*[clinic input]
604_operator.le = _operator.eq
605
606Same as a <= b.
607[clinic start generated code]*/
608
609static PyObject *
610_operator_le_impl(PyObject *module, PyObject *a, PyObject *b)
611/*[clinic end generated code: output=00970a2923d0ae17 input=b812a7860a0bef44]*/
612{
613 return PyObject_RichCompare(a, b, Py_LE);
614}
615
616/*[clinic input]
617_operator.gt = _operator.eq
618
619Same as a > b.
620[clinic start generated code]*/
621
622static PyObject *
623_operator_gt_impl(PyObject *module, PyObject *a, PyObject *b)
624/*[clinic end generated code: output=8d373349ecf25641 input=9bdb45b995ada35b]*/
625{
626 return PyObject_RichCompare(a, b, Py_GT);
627}
628
629/*[clinic input]
630_operator.ge = _operator.eq
631
632Same as a >= b.
633[clinic start generated code]*/
634
635static PyObject *
636_operator_ge_impl(PyObject *module, PyObject *a, PyObject *b)
637/*[clinic end generated code: output=7ce3882256d4b137 input=cf1dc4a5ca9c35f5]*/
638{
639 return PyObject_RichCompare(a, b, Py_GE);
640}
641
642/*[clinic input]
643_operator.pow = _operator.add
644
645Same as a ** b.
646[clinic start generated code]*/
647
648static PyObject *
649_operator_pow_impl(PyObject *module, PyObject *a, PyObject *b)
650/*[clinic end generated code: output=09e668ad50036120 input=690b40f097ab1637]*/
651{
652 return PyNumber_Power(a, b, Py_None);
653}
654
655/*[clinic input]
656_operator.ipow = _operator.add
657
658Same as a **= b.
659[clinic start generated code]*/
660
661static PyObject *
662_operator_ipow_impl(PyObject *module, PyObject *a, PyObject *b)
663/*[clinic end generated code: output=7189ff4d4367c808 input=f00623899d07499a]*/
664{
665 return PyNumber_InPlacePower(a, b, Py_None);
666}
667
668/*[clinic input]
669_operator.index
670
671 a: object
672 /
673
674Same as a.__index__()
675[clinic start generated code]*/
676
677static PyObject *
678_operator_index(PyObject *module, PyObject *a)
679/*[clinic end generated code: output=d972b0764ac305fc input=6f54d50ea64a579c]*/
Guido van Rossum38fff8c2006-03-07 18:50:55 +0000680{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 return PyNumber_Index(a);
Guido van Rossum38fff8c2006-03-07 18:50:55 +0000682}
683
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200684/*[clinic input]
685_operator.is_ = _operator.add
686
687Same as a is b.
688[clinic start generated code]*/
689
690static PyObject *
691_operator_is__impl(PyObject *module, PyObject *a, PyObject *b)
692/*[clinic end generated code: output=bcd47a402e482e1d input=5fa9b97df03c427f]*/
Raymond Hettinger9543b342003-01-18 23:22:20 +0000693{
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200694 PyObject *result;
695 result = (a == b) ? Py_True : Py_False;
696 Py_INCREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 return result;
Raymond Hettinger9543b342003-01-18 23:22:20 +0000698}
699
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200700/*[clinic input]
701_operator.is_not = _operator.add
702
703Same as a is not b.
704[clinic start generated code]*/
705
706static PyObject *
707_operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b)
708/*[clinic end generated code: output=491a1f2f81f6c7f9 input=5a93f7e1a93535f1]*/
Raymond Hettinger9543b342003-01-18 23:22:20 +0000709{
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200710 PyObject *result;
711 result = (a != b) ? Py_True : Py_False;
712 Py_INCREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000713 return result;
Raymond Hettinger9543b342003-01-18 23:22:20 +0000714}
715
Christian Heimes6cea6552012-06-24 13:48:32 +0200716/* compare_digest **********************************************************/
717
718/*
719 * timing safe compare
720 *
721 * Returns 1 of the strings are equal.
722 * In case of len(a) != len(b) the function tries to keep the timing
723 * dependent on the length of b. CPU cache locally may still alter timing
724 * a bit.
725 */
726static int
727_tscmp(const unsigned char *a, const unsigned char *b,
728 Py_ssize_t len_a, Py_ssize_t len_b)
729{
730 /* The volatile type declarations make sure that the compiler has no
731 * chance to optimize and fold the code in any way that may change
732 * the timing.
733 */
734 volatile Py_ssize_t length;
735 volatile const unsigned char *left;
736 volatile const unsigned char *right;
737 Py_ssize_t i;
738 unsigned char result;
739
740 /* loop count depends on length of b */
741 length = len_b;
742 left = NULL;
743 right = b;
744
745 /* don't use else here to keep the amount of CPU instructions constant,
746 * volatile forces re-evaluation
747 * */
748 if (len_a == length) {
749 left = *((volatile const unsigned char**)&a);
750 result = 0;
751 }
752 if (len_a != length) {
753 left = b;
754 result = 1;
755 }
756
757 for (i=0; i < length; i++) {
758 result |= *left++ ^ *right++;
759 }
760
761 return (result == 0);
762}
763
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200764/*[clinic input]
765_operator.length_hint -> Py_ssize_t
Armin Ronacheraa9a79d2012-10-06 14:03:24 +0200766
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200767 obj: object
768 default: Py_ssize_t = 0
769 /
770
771Return an estimate of the number of items in obj.
772
773This is useful for presizing containers when building from an iterable.
774
775If the object supports len(), the result will be exact.
776Otherwise, it may over- or under-estimate by an arbitrary amount.
777The result will be an integer >= 0.
778[clinic start generated code]*/
779
780static Py_ssize_t
781_operator_length_hint_impl(PyObject *module, PyObject *obj,
782 Py_ssize_t default_value)
783/*[clinic end generated code: output=01d469edc1d612ad input=65ed29f04401e96a]*/
Armin Ronacheraa9a79d2012-10-06 14:03:24 +0200784{
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200785 return PyObject_LengthHint(obj, default_value);
Armin Ronacheraa9a79d2012-10-06 14:03:24 +0200786}
787
Christian Heimesdb5aed92020-05-27 21:50:06 +0200788/* NOTE: Keep in sync with _hashopenssl.c implementation. */
789
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200790/*[clinic input]
791_operator._compare_digest = _operator.eq
Armin Ronacheraa9a79d2012-10-06 14:03:24 +0200792
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200793Return 'a == b'.
Christian Heimes6cea6552012-06-24 13:48:32 +0200794
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200795This function uses an approach designed to prevent
796timing analysis, making it appropriate for cryptography.
797
798a and b must both be of the same type: either str (ASCII only),
799or any bytes-like object.
800
801Note: If a and b are of different lengths, or if an error occurs,
802a timing attack could theoretically reveal information about the
803types and lengths of a and b--but not their values.
804[clinic start generated code]*/
805
806static PyObject *
807_operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b)
808/*[clinic end generated code: output=11d452bdd3a23cbc input=9ac7e2c4e30bc356]*/
Christian Heimes6cea6552012-06-24 13:48:32 +0200809{
Christian Heimes6cea6552012-06-24 13:48:32 +0200810 int rc;
Christian Heimes6cea6552012-06-24 13:48:32 +0200811
Christian Heimes6cea6552012-06-24 13:48:32 +0200812 /* ASCII unicode string */
813 if(PyUnicode_Check(a) && PyUnicode_Check(b)) {
814 if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) {
815 return NULL;
816 }
817 if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) {
818 PyErr_SetString(PyExc_TypeError,
819 "comparing strings with non-ASCII characters is "
820 "not supported");
821 return NULL;
822 }
823
824 rc = _tscmp(PyUnicode_DATA(a),
825 PyUnicode_DATA(b),
826 PyUnicode_GET_LENGTH(a),
827 PyUnicode_GET_LENGTH(b));
828 }
829 /* fallback to buffer interface for bytes, bytesarray and other */
830 else {
831 Py_buffer view_a;
832 Py_buffer view_b;
833
Benjamin Peterson23a192d2014-05-11 16:17:02 -0700834 if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) {
Christian Heimes6cea6552012-06-24 13:48:32 +0200835 PyErr_Format(PyExc_TypeError,
836 "unsupported operand types(s) or combination of types: "
837 "'%.100s' and '%.100s'",
838 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
839 return NULL;
840 }
841
842 if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) {
843 return NULL;
844 }
845 if (view_a.ndim > 1) {
846 PyErr_SetString(PyExc_BufferError,
847 "Buffer must be single dimension");
848 PyBuffer_Release(&view_a);
849 return NULL;
850 }
851
852 if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) {
853 PyBuffer_Release(&view_a);
854 return NULL;
855 }
856 if (view_b.ndim > 1) {
857 PyErr_SetString(PyExc_BufferError,
858 "Buffer must be single dimension");
859 PyBuffer_Release(&view_a);
860 PyBuffer_Release(&view_b);
861 return NULL;
862 }
863
864 rc = _tscmp((const unsigned char*)view_a.buf,
865 (const unsigned char*)view_b.buf,
866 view_a.len,
867 view_b.len);
868
869 PyBuffer_Release(&view_a);
870 PyBuffer_Release(&view_b);
871 }
872
Georg Brandl93b7d7e2012-06-24 13:54:51 +0200873 return PyBool_FromLong(rc);
Christian Heimes6cea6552012-06-24 13:48:32 +0200874}
875
876/* operator methods **********************************************************/
877
Guido van Rossum037b9401996-07-30 16:55:54 +0000878static struct PyMethodDef operator_methods[] = {
Guido van Rossum037b9401996-07-30 16:55:54 +0000879
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200880 _OPERATOR_TRUTH_METHODDEF
881 _OPERATOR_CONTAINS_METHODDEF
882 _OPERATOR_INDEXOF_METHODDEF
883 _OPERATOR_COUNTOF_METHODDEF
884 _OPERATOR_IS__METHODDEF
885 _OPERATOR_IS_NOT_METHODDEF
886 _OPERATOR_INDEX_METHODDEF
887 _OPERATOR_ADD_METHODDEF
888 _OPERATOR_SUB_METHODDEF
889 _OPERATOR_MUL_METHODDEF
890 _OPERATOR_MATMUL_METHODDEF
891 _OPERATOR_FLOORDIV_METHODDEF
892 _OPERATOR_TRUEDIV_METHODDEF
893 _OPERATOR_MOD_METHODDEF
894 _OPERATOR_NEG_METHODDEF
895 _OPERATOR_POS_METHODDEF
896 _OPERATOR_ABS_METHODDEF
897 _OPERATOR_INV_METHODDEF
898 _OPERATOR_INVERT_METHODDEF
899 _OPERATOR_LSHIFT_METHODDEF
900 _OPERATOR_RSHIFT_METHODDEF
901 _OPERATOR_NOT__METHODDEF
902 _OPERATOR_AND__METHODDEF
903 _OPERATOR_XOR_METHODDEF
904 _OPERATOR_OR__METHODDEF
905 _OPERATOR_IADD_METHODDEF
906 _OPERATOR_ISUB_METHODDEF
907 _OPERATOR_IMUL_METHODDEF
908 _OPERATOR_IMATMUL_METHODDEF
909 _OPERATOR_IFLOORDIV_METHODDEF
910 _OPERATOR_ITRUEDIV_METHODDEF
911 _OPERATOR_IMOD_METHODDEF
912 _OPERATOR_ILSHIFT_METHODDEF
913 _OPERATOR_IRSHIFT_METHODDEF
914 _OPERATOR_IAND_METHODDEF
915 _OPERATOR_IXOR_METHODDEF
916 _OPERATOR_IOR_METHODDEF
917 _OPERATOR_CONCAT_METHODDEF
918 _OPERATOR_ICONCAT_METHODDEF
919 _OPERATOR_GETITEM_METHODDEF
920 _OPERATOR_SETITEM_METHODDEF
921 _OPERATOR_DELITEM_METHODDEF
922 _OPERATOR_POW_METHODDEF
923 _OPERATOR_IPOW_METHODDEF
924 _OPERATOR_EQ_METHODDEF
925 _OPERATOR_NE_METHODDEF
926 _OPERATOR_LT_METHODDEF
927 _OPERATOR_LE_METHODDEF
928 _OPERATOR_GT_METHODDEF
929 _OPERATOR_GE_METHODDEF
930 _OPERATOR__COMPARE_DIGEST_METHODDEF
931 _OPERATOR_LENGTH_HINT_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 {NULL, NULL} /* sentinel */
Guido van Rossum037b9401996-07-30 16:55:54 +0000933
Guido van Rossum037b9401996-07-30 16:55:54 +0000934};
935
Raymond Hettinger166958b2003-12-01 13:18:39 +0000936/* itemgetter object **********************************************************/
Guido van Rossum037b9401996-07-30 16:55:54 +0000937
Raymond Hettinger166958b2003-12-01 13:18:39 +0000938typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000939 PyObject_HEAD
940 Py_ssize_t nitems;
941 PyObject *item;
Raymond Hettinger2d53bed2019-01-07 09:38:41 -0700942 Py_ssize_t index; // -1 unless *item* is a single non-negative integer index
Raymond Hettinger166958b2003-12-01 13:18:39 +0000943} itemgetterobject;
944
945static PyTypeObject itemgetter_type;
946
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200947/* AC 3.5: treats first argument as an iterable, otherwise uses *args */
Raymond Hettinger166958b2003-12-01 13:18:39 +0000948static PyObject *
949itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 itemgetterobject *ig;
952 PyObject *item;
953 Py_ssize_t nitems;
Raymond Hettinger2d53bed2019-01-07 09:38:41 -0700954 Py_ssize_t index;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000955
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +0300956 if (!_PyArg_NoKeywords("itemgetter", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +0000958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 nitems = PyTuple_GET_SIZE(args);
960 if (nitems <= 1) {
961 if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item))
962 return NULL;
963 } else
964 item = args;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 /* create itemgetterobject structure */
967 ig = PyObject_GC_New(itemgetterobject, &itemgetter_type);
968 if (ig == NULL)
969 return NULL;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 Py_INCREF(item);
972 ig->item = item;
973 ig->nitems = nitems;
Raymond Hettinger2d53bed2019-01-07 09:38:41 -0700974 ig->index = -1;
975 if (PyLong_CheckExact(item)) {
976 index = PyLong_AsSsize_t(item);
977 if (index < 0) {
978 /* If we get here, then either the index conversion failed
979 * due to being out of range, or the index was a negative
980 * integer. Either way, we clear any possible exception
981 * and fall back to the slow path, where ig->index is -1.
982 */
983 PyErr_Clear();
984 }
985 else {
986 ig->index = index;
987 }
988 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989
990 PyObject_GC_Track(ig);
991 return (PyObject *)ig;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000992}
993
994static void
995itemgetter_dealloc(itemgetterobject *ig)
996{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000997 PyObject_GC_UnTrack(ig);
998 Py_XDECREF(ig->item);
999 PyObject_GC_Del(ig);
Raymond Hettinger166958b2003-12-01 13:18:39 +00001000}
1001
1002static int
1003itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
1004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 Py_VISIT(ig->item);
1006 return 0;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001007}
1008
1009static PyObject *
1010itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
1011{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 PyObject *obj, *result;
1013 Py_ssize_t i, nitems=ig->nitems;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001014
Raymond Hettinger2d53bed2019-01-07 09:38:41 -07001015 assert(PyTuple_CheckExact(args));
Serhiy Storchaka79342662019-01-12 08:25:41 +02001016 if (!_PyArg_NoKeywords("itemgetter", kw))
1017 return NULL;
1018 if (!_PyArg_CheckPositional("itemgetter", PyTuple_GET_SIZE(args), 1, 1))
1019 return NULL;
1020
1021 obj = PyTuple_GET_ITEM(args, 0);
Raymond Hettinger2d53bed2019-01-07 09:38:41 -07001022 if (nitems == 1) {
1023 if (ig->index >= 0
1024 && PyTuple_CheckExact(obj)
1025 && ig->index < PyTuple_GET_SIZE(obj))
1026 {
1027 result = PyTuple_GET_ITEM(obj, ig->index);
1028 Py_INCREF(result);
1029 return result;
1030 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 return PyObject_GetItem(obj, ig->item);
Raymond Hettinger2d53bed2019-01-07 09:38:41 -07001032 }
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 assert(PyTuple_Check(ig->item));
1035 assert(PyTuple_GET_SIZE(ig->item) == nitems);
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001036
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037 result = PyTuple_New(nitems);
1038 if (result == NULL)
1039 return NULL;
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 for (i=0 ; i < nitems ; i++) {
1042 PyObject *item, *val;
1043 item = PyTuple_GET_ITEM(ig->item, i);
1044 val = PyObject_GetItem(obj, item);
1045 if (val == NULL) {
1046 Py_DECREF(result);
1047 return NULL;
1048 }
1049 PyTuple_SET_ITEM(result, i, val);
1050 }
1051 return result;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001052}
1053
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001054static PyObject *
1055itemgetter_repr(itemgetterobject *ig)
1056{
1057 PyObject *repr;
1058 const char *reprfmt;
1059
1060 int status = Py_ReprEnter((PyObject *)ig);
1061 if (status != 0) {
1062 if (status < 0)
1063 return NULL;
1064 return PyUnicode_FromFormat("%s(...)", Py_TYPE(ig)->tp_name);
1065 }
1066
1067 reprfmt = ig->nitems == 1 ? "%s(%R)" : "%s%R";
1068 repr = PyUnicode_FromFormat(reprfmt, Py_TYPE(ig)->tp_name, ig->item);
1069 Py_ReprLeave((PyObject *)ig);
1070 return repr;
1071}
1072
1073static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301074itemgetter_reduce(itemgetterobject *ig, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001075{
1076 if (ig->nitems == 1)
1077 return Py_BuildValue("O(O)", Py_TYPE(ig), ig->item);
1078 return PyTuple_Pack(2, Py_TYPE(ig), ig->item);
1079}
1080
1081PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1082
1083static PyMethodDef itemgetter_methods[] = {
1084 {"__reduce__", (PyCFunction)itemgetter_reduce, METH_NOARGS,
1085 reduce_doc},
1086 {NULL}
1087};
1088
Raymond Hettinger166958b2003-12-01 13:18:39 +00001089PyDoc_STRVAR(itemgetter_doc,
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001090"itemgetter(item, ...) --> itemgetter object\n\
Raymond Hettinger166958b2003-12-01 13:18:39 +00001091\n\
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001092Return a callable object that fetches the given item(s) from its operand.\n\
Ezio Melottibabc8222013-05-08 10:53:11 +03001093After f = itemgetter(2), the call f(r) returns r[2].\n\
1094After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])");
Raymond Hettinger166958b2003-12-01 13:18:39 +00001095
1096static PyTypeObject itemgetter_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001097 PyVarObject_HEAD_INIT(NULL, 0)
1098 "operator.itemgetter", /* tp_name */
1099 sizeof(itemgetterobject), /* tp_basicsize */
1100 0, /* tp_itemsize */
1101 /* methods */
1102 (destructor)itemgetter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001103 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 0, /* tp_getattr */
1105 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001106 0, /* tp_as_async */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001107 (reprfunc)itemgetter_repr, /* tp_repr */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001108 0, /* tp_as_number */
1109 0, /* tp_as_sequence */
1110 0, /* tp_as_mapping */
1111 0, /* tp_hash */
1112 (ternaryfunc)itemgetter_call, /* tp_call */
1113 0, /* tp_str */
1114 PyObject_GenericGetAttr, /* tp_getattro */
1115 0, /* tp_setattro */
1116 0, /* tp_as_buffer */
1117 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1118 itemgetter_doc, /* tp_doc */
1119 (traverseproc)itemgetter_traverse, /* tp_traverse */
1120 0, /* tp_clear */
1121 0, /* tp_richcompare */
1122 0, /* tp_weaklistoffset */
1123 0, /* tp_iter */
1124 0, /* tp_iternext */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001125 itemgetter_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 0, /* tp_members */
1127 0, /* tp_getset */
1128 0, /* tp_base */
1129 0, /* tp_dict */
1130 0, /* tp_descr_get */
1131 0, /* tp_descr_set */
1132 0, /* tp_dictoffset */
1133 0, /* tp_init */
1134 0, /* tp_alloc */
1135 itemgetter_new, /* tp_new */
1136 0, /* tp_free */
Raymond Hettinger166958b2003-12-01 13:18:39 +00001137};
1138
1139
1140/* attrgetter object **********************************************************/
1141
1142typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 PyObject_HEAD
1144 Py_ssize_t nattrs;
1145 PyObject *attr;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001146} attrgetterobject;
1147
1148static PyTypeObject attrgetter_type;
1149
Serhiy Storchakab813a0e2017-01-19 17:44:13 +02001150/* AC 3.5: treats first argument as an iterable, otherwise uses *args */
Raymond Hettinger166958b2003-12-01 13:18:39 +00001151static PyObject *
1152attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1153{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 attrgetterobject *ag;
1155 PyObject *attr;
Antoine Pitroue9745712010-10-31 15:26:04 +00001156 Py_ssize_t nattrs, idx, char_idx;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001157
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001158 if (!_PyArg_NoKeywords("attrgetter", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 nattrs = PyTuple_GET_SIZE(args);
1162 if (nattrs <= 1) {
1163 if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
1164 return NULL;
Antoine Pitroue9745712010-10-31 15:26:04 +00001165 }
1166
1167 attr = PyTuple_New(nattrs);
1168 if (attr == NULL)
1169 return NULL;
1170
1171 /* prepare attr while checking args */
1172 for (idx = 0; idx < nattrs; ++idx) {
1173 PyObject *item = PyTuple_GET_ITEM(args, idx);
1174 Py_ssize_t item_len;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +03001175 const void *data;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001176 unsigned int kind;
Antoine Pitroue9745712010-10-31 15:26:04 +00001177 int dot_count;
1178
1179 if (!PyUnicode_Check(item)) {
1180 PyErr_SetString(PyExc_TypeError,
1181 "attribute name must be a string");
1182 Py_DECREF(attr);
1183 return NULL;
1184 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001185 if (PyUnicode_READY(item)) {
1186 Py_DECREF(attr);
1187 return NULL;
1188 }
1189 item_len = PyUnicode_GET_LENGTH(item);
1190 kind = PyUnicode_KIND(item);
1191 data = PyUnicode_DATA(item);
Antoine Pitroue9745712010-10-31 15:26:04 +00001192
1193 /* check whethere the string is dotted */
1194 dot_count = 0;
1195 for (char_idx = 0; char_idx < item_len; ++char_idx) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001196 if (PyUnicode_READ(kind, data, char_idx) == '.')
Antoine Pitroue9745712010-10-31 15:26:04 +00001197 ++dot_count;
1198 }
1199
1200 if (dot_count == 0) {
1201 Py_INCREF(item);
1202 PyUnicode_InternInPlace(&item);
1203 PyTuple_SET_ITEM(attr, idx, item);
1204 } else { /* make it a tuple of non-dotted attrnames */
1205 PyObject *attr_chain = PyTuple_New(dot_count + 1);
1206 PyObject *attr_chain_item;
Antoine Pitrou87298c42010-10-31 21:03:01 +00001207 Py_ssize_t unibuff_from = 0;
1208 Py_ssize_t unibuff_till = 0;
1209 Py_ssize_t attr_chain_idx = 0;
Antoine Pitroue9745712010-10-31 15:26:04 +00001210
1211 if (attr_chain == NULL) {
1212 Py_DECREF(attr);
1213 return NULL;
1214 }
1215
Antoine Pitroue9745712010-10-31 15:26:04 +00001216 for (; dot_count > 0; --dot_count) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001217 while (PyUnicode_READ(kind, data, unibuff_till) != '.') {
Antoine Pitroue9745712010-10-31 15:26:04 +00001218 ++unibuff_till;
1219 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001220 attr_chain_item = PyUnicode_Substring(item,
1221 unibuff_from,
1222 unibuff_till);
Antoine Pitroue9745712010-10-31 15:26:04 +00001223 if (attr_chain_item == NULL) {
1224 Py_DECREF(attr_chain);
1225 Py_DECREF(attr);
1226 return NULL;
1227 }
1228 PyUnicode_InternInPlace(&attr_chain_item);
1229 PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
1230 ++attr_chain_idx;
1231 unibuff_till = unibuff_from = unibuff_till + 1;
1232 }
1233
1234 /* now add the last dotless name */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001235 attr_chain_item = PyUnicode_Substring(item,
1236 unibuff_from, item_len);
Antoine Pitroue9745712010-10-31 15:26:04 +00001237 if (attr_chain_item == NULL) {
1238 Py_DECREF(attr_chain);
1239 Py_DECREF(attr);
1240 return NULL;
1241 }
1242 PyUnicode_InternInPlace(&attr_chain_item);
1243 PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
1244
1245 PyTuple_SET_ITEM(attr, idx, attr_chain);
1246 }
1247 }
Raymond Hettinger166958b2003-12-01 13:18:39 +00001248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 /* create attrgetterobject structure */
1250 ag = PyObject_GC_New(attrgetterobject, &attrgetter_type);
Antoine Pitroue9745712010-10-31 15:26:04 +00001251 if (ag == NULL) {
1252 Py_DECREF(attr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 return NULL;
Antoine Pitroue9745712010-10-31 15:26:04 +00001254 }
Raymond Hettinger166958b2003-12-01 13:18:39 +00001255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 ag->attr = attr;
1257 ag->nattrs = nattrs;
1258
1259 PyObject_GC_Track(ag);
1260 return (PyObject *)ag;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001261}
1262
1263static void
1264attrgetter_dealloc(attrgetterobject *ag)
1265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 PyObject_GC_UnTrack(ag);
1267 Py_XDECREF(ag->attr);
1268 PyObject_GC_Del(ag);
Raymond Hettinger166958b2003-12-01 13:18:39 +00001269}
1270
1271static int
1272attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
1273{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 Py_VISIT(ag->attr);
1275 return 0;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001276}
1277
1278static PyObject *
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001279dotted_getattr(PyObject *obj, PyObject *attr)
1280{
Antoine Pitroue9745712010-10-31 15:26:04 +00001281 PyObject *newobj;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001282
Antoine Pitroue9745712010-10-31 15:26:04 +00001283 /* attr is either a tuple or instance of str.
1284 Ensured by the setup code of attrgetter_new */
1285 if (PyTuple_CheckExact(attr)) { /* chained getattr */
1286 Py_ssize_t name_idx = 0, name_count;
1287 PyObject *attr_name;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001288
Antoine Pitroue9745712010-10-31 15:26:04 +00001289 name_count = PyTuple_GET_SIZE(attr);
1290 Py_INCREF(obj);
1291 for (name_idx = 0; name_idx < name_count; ++name_idx) {
1292 attr_name = PyTuple_GET_ITEM(attr, name_idx);
1293 newobj = PyObject_GetAttr(obj, attr_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 Py_DECREF(obj);
Antoine Pitroue9745712010-10-31 15:26:04 +00001295 if (newobj == NULL) {
1296 return NULL;
1297 }
1298 /* here */
1299 obj = newobj;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 }
Antoine Pitroue9745712010-10-31 15:26:04 +00001301 } else { /* single getattr */
1302 newobj = PyObject_GetAttr(obj, attr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 if (newobj == NULL)
1304 return NULL;
1305 obj = newobj;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 }
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 return obj;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001309}
1310
1311static PyObject *
Raymond Hettinger166958b2003-12-01 13:18:39 +00001312attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
1313{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 PyObject *obj, *result;
1315 Py_ssize_t i, nattrs=ag->nattrs;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001316
Serhiy Storchaka68a001d2017-02-06 10:41:46 +02001317 if (!_PyArg_NoKeywords("attrgetter", kw))
Serhiy Storchakac2a2a752016-04-23 10:51:39 +03001318 return NULL;
Serhiy Storchaka79342662019-01-12 08:25:41 +02001319 if (!_PyArg_CheckPositional("attrgetter", PyTuple_GET_SIZE(args), 1, 1))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 return NULL;
Serhiy Storchaka79342662019-01-12 08:25:41 +02001321 obj = PyTuple_GET_ITEM(args, 0);
Antoine Pitroue9745712010-10-31 15:26:04 +00001322 if (ag->nattrs == 1) /* ag->attr is always a tuple */
1323 return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0));
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 assert(PyTuple_Check(ag->attr));
1326 assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 result = PyTuple_New(nattrs);
1329 if (result == NULL)
1330 return NULL;
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 for (i=0 ; i < nattrs ; i++) {
1333 PyObject *attr, *val;
1334 attr = PyTuple_GET_ITEM(ag->attr, i);
1335 val = dotted_getattr(obj, attr);
1336 if (val == NULL) {
1337 Py_DECREF(result);
1338 return NULL;
1339 }
1340 PyTuple_SET_ITEM(result, i, val);
1341 }
1342 return result;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001343}
1344
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001345static PyObject *
1346dotjoinattr(PyObject *attr, PyObject **attrsep)
1347{
1348 if (PyTuple_CheckExact(attr)) {
1349 if (*attrsep == NULL) {
1350 *attrsep = PyUnicode_FromString(".");
1351 if (*attrsep == NULL)
1352 return NULL;
1353 }
1354 return PyUnicode_Join(*attrsep, attr);
1355 } else {
1356 Py_INCREF(attr);
1357 return attr;
1358 }
1359}
1360
1361static PyObject *
1362attrgetter_args(attrgetterobject *ag)
1363{
1364 Py_ssize_t i;
1365 PyObject *attrsep = NULL;
1366 PyObject *attrstrings = PyTuple_New(ag->nattrs);
1367 if (attrstrings == NULL)
1368 return NULL;
1369
1370 for (i = 0; i < ag->nattrs; ++i) {
1371 PyObject *attr = PyTuple_GET_ITEM(ag->attr, i);
1372 PyObject *attrstr = dotjoinattr(attr, &attrsep);
1373 if (attrstr == NULL) {
1374 Py_XDECREF(attrsep);
1375 Py_DECREF(attrstrings);
1376 return NULL;
1377 }
1378 PyTuple_SET_ITEM(attrstrings, i, attrstr);
1379 }
1380 Py_XDECREF(attrsep);
1381 return attrstrings;
1382}
1383
1384static PyObject *
1385attrgetter_repr(attrgetterobject *ag)
1386{
1387 PyObject *repr = NULL;
1388 int status = Py_ReprEnter((PyObject *)ag);
1389 if (status != 0) {
1390 if (status < 0)
1391 return NULL;
1392 return PyUnicode_FromFormat("%s(...)", Py_TYPE(ag)->tp_name);
1393 }
1394
1395 if (ag->nattrs == 1) {
1396 PyObject *attrsep = NULL;
1397 PyObject *attr = dotjoinattr(PyTuple_GET_ITEM(ag->attr, 0), &attrsep);
Serhiy Storchaka548de2b2015-05-21 14:19:20 +03001398 if (attr != NULL) {
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001399 repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(ag)->tp_name, attr);
Serhiy Storchaka548de2b2015-05-21 14:19:20 +03001400 Py_DECREF(attr);
1401 }
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001402 Py_XDECREF(attrsep);
1403 }
1404 else {
1405 PyObject *attrstrings = attrgetter_args(ag);
1406 if (attrstrings != NULL) {
1407 repr = PyUnicode_FromFormat("%s%R",
1408 Py_TYPE(ag)->tp_name, attrstrings);
1409 Py_DECREF(attrstrings);
1410 }
1411 }
1412 Py_ReprLeave((PyObject *)ag);
1413 return repr;
1414}
1415
1416static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301417attrgetter_reduce(attrgetterobject *ag, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001418{
1419 PyObject *attrstrings = attrgetter_args(ag);
1420 if (attrstrings == NULL)
1421 return NULL;
1422
1423 return Py_BuildValue("ON", Py_TYPE(ag), attrstrings);
1424}
1425
1426static PyMethodDef attrgetter_methods[] = {
1427 {"__reduce__", (PyCFunction)attrgetter_reduce, METH_NOARGS,
1428 reduce_doc},
1429 {NULL}
1430};
1431
Raymond Hettinger166958b2003-12-01 13:18:39 +00001432PyDoc_STRVAR(attrgetter_doc,
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001433"attrgetter(attr, ...) --> attrgetter object\n\
Raymond Hettinger166958b2003-12-01 13:18:39 +00001434\n\
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001435Return a callable object that fetches the given attribute(s) from its operand.\n\
Ezio Melottibabc8222013-05-08 10:53:11 +03001436After f = attrgetter('name'), the call f(r) returns r.name.\n\
1437After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\
1438After h = attrgetter('name.first', 'name.last'), the call h(r) returns\n\
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001439(r.name.first, r.name.last).");
Raymond Hettinger166958b2003-12-01 13:18:39 +00001440
1441static PyTypeObject attrgetter_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 PyVarObject_HEAD_INIT(NULL, 0)
1443 "operator.attrgetter", /* tp_name */
1444 sizeof(attrgetterobject), /* tp_basicsize */
1445 0, /* tp_itemsize */
1446 /* methods */
1447 (destructor)attrgetter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001448 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001449 0, /* tp_getattr */
1450 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001451 0, /* tp_as_async */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001452 (reprfunc)attrgetter_repr, /* tp_repr */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 0, /* tp_as_number */
1454 0, /* tp_as_sequence */
1455 0, /* tp_as_mapping */
1456 0, /* tp_hash */
1457 (ternaryfunc)attrgetter_call, /* tp_call */
1458 0, /* tp_str */
1459 PyObject_GenericGetAttr, /* tp_getattro */
1460 0, /* tp_setattro */
1461 0, /* tp_as_buffer */
1462 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1463 attrgetter_doc, /* tp_doc */
1464 (traverseproc)attrgetter_traverse, /* tp_traverse */
1465 0, /* tp_clear */
1466 0, /* tp_richcompare */
1467 0, /* tp_weaklistoffset */
1468 0, /* tp_iter */
1469 0, /* tp_iternext */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001470 attrgetter_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 0, /* tp_members */
1472 0, /* tp_getset */
1473 0, /* tp_base */
1474 0, /* tp_dict */
1475 0, /* tp_descr_get */
1476 0, /* tp_descr_set */
1477 0, /* tp_dictoffset */
1478 0, /* tp_init */
1479 0, /* tp_alloc */
1480 attrgetter_new, /* tp_new */
1481 0, /* tp_free */
Raymond Hettinger166958b2003-12-01 13:18:39 +00001482};
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001483
1484
1485/* methodcaller object **********************************************************/
1486
1487typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 PyObject_HEAD
1489 PyObject *name;
1490 PyObject *args;
1491 PyObject *kwds;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001492} methodcallerobject;
1493
1494static PyTypeObject methodcaller_type;
1495
Serhiy Storchakab813a0e2017-01-19 17:44:13 +02001496/* AC 3.5: variable number of arguments, not currently support by AC */
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001497static PyObject *
1498methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1499{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 methodcallerobject *mc;
Benjamin Peterson1f0e7c92016-08-16 23:35:35 -07001501 PyObject *name;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 if (PyTuple_GET_SIZE(args) < 1) {
1504 PyErr_SetString(PyExc_TypeError, "methodcaller needs at least "
1505 "one argument, the method name");
1506 return NULL;
1507 }
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001508
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001509 name = PyTuple_GET_ITEM(args, 0);
1510 if (!PyUnicode_Check(name)) {
1511 PyErr_SetString(PyExc_TypeError,
1512 "method name must be a string");
1513 return NULL;
1514 }
1515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 /* create methodcallerobject structure */
1517 mc = PyObject_GC_New(methodcallerobject, &methodcaller_type);
1518 if (mc == NULL)
1519 return NULL;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 name = PyTuple_GET_ITEM(args, 0);
1522 Py_INCREF(name);
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001523 PyUnicode_InternInPlace(&name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 mc->name = name;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001525
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001526 Py_XINCREF(kwds);
1527 mc->kwds = kwds;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001528
Benjamin Peterson1f0e7c92016-08-16 23:35:35 -07001529 mc->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
1530 if (mc->args == NULL) {
1531 Py_DECREF(mc);
1532 return NULL;
1533 }
1534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 PyObject_GC_Track(mc);
1536 return (PyObject *)mc;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001537}
1538
1539static void
1540methodcaller_dealloc(methodcallerobject *mc)
1541{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 PyObject_GC_UnTrack(mc);
1543 Py_XDECREF(mc->name);
1544 Py_XDECREF(mc->args);
1545 Py_XDECREF(mc->kwds);
1546 PyObject_GC_Del(mc);
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001547}
1548
1549static int
1550methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
1551{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 Py_VISIT(mc->args);
1553 Py_VISIT(mc->kwds);
1554 return 0;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001555}
1556
1557static PyObject *
1558methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw)
1559{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 PyObject *method, *obj, *result;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001561
Serhiy Storchaka68a001d2017-02-06 10:41:46 +02001562 if (!_PyArg_NoKeywords("methodcaller", kw))
Serhiy Storchakac2a2a752016-04-23 10:51:39 +03001563 return NULL;
Serhiy Storchaka79342662019-01-12 08:25:41 +02001564 if (!_PyArg_CheckPositional("methodcaller", PyTuple_GET_SIZE(args), 1, 1))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 return NULL;
Serhiy Storchaka79342662019-01-12 08:25:41 +02001566 obj = PyTuple_GET_ITEM(args, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 method = PyObject_GetAttr(obj, mc->name);
1568 if (method == NULL)
1569 return NULL;
1570 result = PyObject_Call(method, mc->args, mc->kwds);
1571 Py_DECREF(method);
1572 return result;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001573}
1574
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001575static PyObject *
1576methodcaller_repr(methodcallerobject *mc)
1577{
1578 PyObject *argreprs, *repr = NULL, *sep, *joinedargreprs;
1579 Py_ssize_t numtotalargs, numposargs, numkwdargs, i;
1580 int status = Py_ReprEnter((PyObject *)mc);
1581 if (status != 0) {
1582 if (status < 0)
1583 return NULL;
1584 return PyUnicode_FromFormat("%s(...)", Py_TYPE(mc)->tp_name);
1585 }
1586
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02001587 numkwdargs = mc->kwds != NULL ? PyDict_GET_SIZE(mc->kwds) : 0;
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001588 numposargs = PyTuple_GET_SIZE(mc->args);
1589 numtotalargs = numposargs + numkwdargs;
1590
1591 if (numtotalargs == 0) {
1592 repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(mc)->tp_name, mc->name);
1593 Py_ReprLeave((PyObject *)mc);
1594 return repr;
1595 }
1596
1597 argreprs = PyTuple_New(numtotalargs);
1598 if (argreprs == NULL) {
1599 Py_ReprLeave((PyObject *)mc);
1600 return NULL;
1601 }
1602
1603 for (i = 0; i < numposargs; ++i) {
1604 PyObject *onerepr = PyObject_Repr(PyTuple_GET_ITEM(mc->args, i));
1605 if (onerepr == NULL)
1606 goto done;
1607 PyTuple_SET_ITEM(argreprs, i, onerepr);
1608 }
1609
1610 if (numkwdargs != 0) {
1611 PyObject *key, *value;
1612 Py_ssize_t pos = 0;
1613 while (PyDict_Next(mc->kwds, &pos, &key, &value)) {
1614 PyObject *onerepr = PyUnicode_FromFormat("%U=%R", key, value);
1615 if (onerepr == NULL)
1616 goto done;
1617 if (i >= numtotalargs) {
1618 i = -1;
Zackery Spytz5b83ef72018-11-23 12:26:46 -07001619 Py_DECREF(onerepr);
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001620 break;
1621 }
1622 PyTuple_SET_ITEM(argreprs, i, onerepr);
1623 ++i;
1624 }
1625 if (i != numtotalargs) {
1626 PyErr_SetString(PyExc_RuntimeError,
1627 "keywords dict changed size during iteration");
1628 goto done;
1629 }
1630 }
1631
1632 sep = PyUnicode_FromString(", ");
1633 if (sep == NULL)
1634 goto done;
1635
1636 joinedargreprs = PyUnicode_Join(sep, argreprs);
1637 Py_DECREF(sep);
1638 if (joinedargreprs == NULL)
1639 goto done;
1640
1641 repr = PyUnicode_FromFormat("%s(%R, %U)", Py_TYPE(mc)->tp_name,
1642 mc->name, joinedargreprs);
1643 Py_DECREF(joinedargreprs);
1644
1645done:
1646 Py_DECREF(argreprs);
1647 Py_ReprLeave((PyObject *)mc);
1648 return repr;
1649}
1650
1651static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301652methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001653{
1654 PyObject *newargs;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02001655 if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) {
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001656 Py_ssize_t i;
1657 Py_ssize_t callargcount = PyTuple_GET_SIZE(mc->args);
1658 newargs = PyTuple_New(1 + callargcount);
1659 if (newargs == NULL)
1660 return NULL;
1661 Py_INCREF(mc->name);
1662 PyTuple_SET_ITEM(newargs, 0, mc->name);
1663 for (i = 0; i < callargcount; ++i) {
1664 PyObject *arg = PyTuple_GET_ITEM(mc->args, i);
1665 Py_INCREF(arg);
1666 PyTuple_SET_ITEM(newargs, i + 1, arg);
1667 }
1668 return Py_BuildValue("ON", Py_TYPE(mc), newargs);
1669 }
1670 else {
1671 PyObject *functools;
1672 PyObject *partial;
1673 PyObject *constructor;
Victor Stinner7e7823a2016-08-23 00:23:23 +02001674 PyObject *newargs[2];
1675
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001676 _Py_IDENTIFIER(partial);
1677 functools = PyImport_ImportModule("functools");
1678 if (!functools)
1679 return NULL;
1680 partial = _PyObject_GetAttrId(functools, &PyId_partial);
1681 Py_DECREF(functools);
1682 if (!partial)
1683 return NULL;
Victor Stinner7e7823a2016-08-23 00:23:23 +02001684
1685 newargs[0] = (PyObject *)Py_TYPE(mc);
1686 newargs[1] = mc->name;
Petr Viktorinffd97532020-02-11 17:46:57 +01001687 constructor = PyObject_VectorcallDict(partial, newargs, 2, mc->kwds);
Victor Stinner7e7823a2016-08-23 00:23:23 +02001688
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001689 Py_DECREF(partial);
1690 return Py_BuildValue("NO", constructor, mc->args);
1691 }
1692}
1693
1694static PyMethodDef methodcaller_methods[] = {
1695 {"__reduce__", (PyCFunction)methodcaller_reduce, METH_NOARGS,
1696 reduce_doc},
1697 {NULL}
1698};
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001699PyDoc_STRVAR(methodcaller_doc,
1700"methodcaller(name, ...) --> methodcaller object\n\
1701\n\
1702Return a callable object that calls the given method on its operand.\n\
Antoine Pitroua85017f2013-04-20 19:21:44 +02001703After f = methodcaller('name'), the call f(r) returns r.name().\n\
1704After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001705r.name('date', foo=1).");
1706
1707static PyTypeObject methodcaller_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001708 PyVarObject_HEAD_INIT(NULL, 0)
1709 "operator.methodcaller", /* tp_name */
1710 sizeof(methodcallerobject), /* tp_basicsize */
1711 0, /* tp_itemsize */
1712 /* methods */
1713 (destructor)methodcaller_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001714 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001715 0, /* tp_getattr */
1716 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001717 0, /* tp_as_async */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001718 (reprfunc)methodcaller_repr, /* tp_repr */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001719 0, /* tp_as_number */
1720 0, /* tp_as_sequence */
1721 0, /* tp_as_mapping */
1722 0, /* tp_hash */
1723 (ternaryfunc)methodcaller_call, /* tp_call */
1724 0, /* tp_str */
1725 PyObject_GenericGetAttr, /* tp_getattro */
1726 0, /* tp_setattro */
1727 0, /* tp_as_buffer */
1728 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1729 methodcaller_doc, /* tp_doc */
1730 (traverseproc)methodcaller_traverse, /* tp_traverse */
1731 0, /* tp_clear */
1732 0, /* tp_richcompare */
1733 0, /* tp_weaklistoffset */
1734 0, /* tp_iter */
1735 0, /* tp_iternext */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001736 methodcaller_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001737 0, /* tp_members */
1738 0, /* tp_getset */
1739 0, /* tp_base */
1740 0, /* tp_dict */
1741 0, /* tp_descr_get */
1742 0, /* tp_descr_set */
1743 0, /* tp_dictoffset */
1744 0, /* tp_init */
1745 0, /* tp_alloc */
1746 methodcaller_new, /* tp_new */
1747 0, /* tp_free */
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001748};
1749
1750
Paulo Henrique Silvaf3d5ac42020-03-24 23:18:47 -03001751static int
1752operator_exec(PyObject *module)
1753{
1754 PyTypeObject *types[] = {
1755 &itemgetter_type,
1756 &attrgetter_type,
1757 &methodcaller_type
1758 };
1759
1760 for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) {
1761 if (PyModule_AddType(module, types[i]) < 0) {
1762 return -1;
1763 }
1764 }
1765
1766 return 0;
1767}
1768
1769
1770static struct PyModuleDef_Slot operator_slots[] = {
1771 {Py_mod_exec, operator_exec},
1772 {0, NULL}
1773};
Martin v. Löwis1a214512008-06-11 05:26:20 +00001774
1775
1776static struct PyModuleDef operatormodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 PyModuleDef_HEAD_INIT,
Antoine Pitroua85017f2013-04-20 19:21:44 +02001778 "_operator",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 operator_doc,
Paulo Henrique Silvaf3d5ac42020-03-24 23:18:47 -03001780 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 operator_methods,
Paulo Henrique Silvaf3d5ac42020-03-24 23:18:47 -03001782 operator_slots,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 NULL,
1784 NULL,
1785 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001786};
Guido van Rossum037b9401996-07-30 16:55:54 +00001787
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001788PyMODINIT_FUNC
Antoine Pitroua85017f2013-04-20 19:21:44 +02001789PyInit__operator(void)
Guido van Rossum037b9401996-07-30 16:55:54 +00001790{
Paulo Henrique Silvaf3d5ac42020-03-24 23:18:47 -03001791 return PyModuleDef_Init(&operatormodule);
Guido van Rossum037b9401996-07-30 16:55:54 +00001792}