blob: d291ec1f920ed175c09f511a28a990ec86f2c672 [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
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200788/*[clinic input]
789_operator._compare_digest = _operator.eq
Armin Ronacheraa9a79d2012-10-06 14:03:24 +0200790
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200791Return 'a == b'.
Christian Heimes6cea6552012-06-24 13:48:32 +0200792
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200793This function uses an approach designed to prevent
794timing analysis, making it appropriate for cryptography.
795
796a and b must both be of the same type: either str (ASCII only),
797or any bytes-like object.
798
799Note: If a and b are of different lengths, or if an error occurs,
800a timing attack could theoretically reveal information about the
801types and lengths of a and b--but not their values.
802[clinic start generated code]*/
803
804static PyObject *
805_operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b)
806/*[clinic end generated code: output=11d452bdd3a23cbc input=9ac7e2c4e30bc356]*/
Christian Heimes6cea6552012-06-24 13:48:32 +0200807{
Christian Heimes6cea6552012-06-24 13:48:32 +0200808 int rc;
Christian Heimes6cea6552012-06-24 13:48:32 +0200809
Christian Heimes6cea6552012-06-24 13:48:32 +0200810 /* ASCII unicode string */
811 if(PyUnicode_Check(a) && PyUnicode_Check(b)) {
812 if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) {
813 return NULL;
814 }
815 if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) {
816 PyErr_SetString(PyExc_TypeError,
817 "comparing strings with non-ASCII characters is "
818 "not supported");
819 return NULL;
820 }
821
822 rc = _tscmp(PyUnicode_DATA(a),
823 PyUnicode_DATA(b),
824 PyUnicode_GET_LENGTH(a),
825 PyUnicode_GET_LENGTH(b));
826 }
827 /* fallback to buffer interface for bytes, bytesarray and other */
828 else {
829 Py_buffer view_a;
830 Py_buffer view_b;
831
Benjamin Peterson23a192d2014-05-11 16:17:02 -0700832 if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) {
Christian Heimes6cea6552012-06-24 13:48:32 +0200833 PyErr_Format(PyExc_TypeError,
834 "unsupported operand types(s) or combination of types: "
835 "'%.100s' and '%.100s'",
836 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
837 return NULL;
838 }
839
840 if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) {
841 return NULL;
842 }
843 if (view_a.ndim > 1) {
844 PyErr_SetString(PyExc_BufferError,
845 "Buffer must be single dimension");
846 PyBuffer_Release(&view_a);
847 return NULL;
848 }
849
850 if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) {
851 PyBuffer_Release(&view_a);
852 return NULL;
853 }
854 if (view_b.ndim > 1) {
855 PyErr_SetString(PyExc_BufferError,
856 "Buffer must be single dimension");
857 PyBuffer_Release(&view_a);
858 PyBuffer_Release(&view_b);
859 return NULL;
860 }
861
862 rc = _tscmp((const unsigned char*)view_a.buf,
863 (const unsigned char*)view_b.buf,
864 view_a.len,
865 view_b.len);
866
867 PyBuffer_Release(&view_a);
868 PyBuffer_Release(&view_b);
869 }
870
Georg Brandl93b7d7e2012-06-24 13:54:51 +0200871 return PyBool_FromLong(rc);
Christian Heimes6cea6552012-06-24 13:48:32 +0200872}
873
874/* operator methods **********************************************************/
875
Guido van Rossum037b9401996-07-30 16:55:54 +0000876static struct PyMethodDef operator_methods[] = {
Guido van Rossum037b9401996-07-30 16:55:54 +0000877
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200878 _OPERATOR_TRUTH_METHODDEF
879 _OPERATOR_CONTAINS_METHODDEF
880 _OPERATOR_INDEXOF_METHODDEF
881 _OPERATOR_COUNTOF_METHODDEF
882 _OPERATOR_IS__METHODDEF
883 _OPERATOR_IS_NOT_METHODDEF
884 _OPERATOR_INDEX_METHODDEF
885 _OPERATOR_ADD_METHODDEF
886 _OPERATOR_SUB_METHODDEF
887 _OPERATOR_MUL_METHODDEF
888 _OPERATOR_MATMUL_METHODDEF
889 _OPERATOR_FLOORDIV_METHODDEF
890 _OPERATOR_TRUEDIV_METHODDEF
891 _OPERATOR_MOD_METHODDEF
892 _OPERATOR_NEG_METHODDEF
893 _OPERATOR_POS_METHODDEF
894 _OPERATOR_ABS_METHODDEF
895 _OPERATOR_INV_METHODDEF
896 _OPERATOR_INVERT_METHODDEF
897 _OPERATOR_LSHIFT_METHODDEF
898 _OPERATOR_RSHIFT_METHODDEF
899 _OPERATOR_NOT__METHODDEF
900 _OPERATOR_AND__METHODDEF
901 _OPERATOR_XOR_METHODDEF
902 _OPERATOR_OR__METHODDEF
903 _OPERATOR_IADD_METHODDEF
904 _OPERATOR_ISUB_METHODDEF
905 _OPERATOR_IMUL_METHODDEF
906 _OPERATOR_IMATMUL_METHODDEF
907 _OPERATOR_IFLOORDIV_METHODDEF
908 _OPERATOR_ITRUEDIV_METHODDEF
909 _OPERATOR_IMOD_METHODDEF
910 _OPERATOR_ILSHIFT_METHODDEF
911 _OPERATOR_IRSHIFT_METHODDEF
912 _OPERATOR_IAND_METHODDEF
913 _OPERATOR_IXOR_METHODDEF
914 _OPERATOR_IOR_METHODDEF
915 _OPERATOR_CONCAT_METHODDEF
916 _OPERATOR_ICONCAT_METHODDEF
917 _OPERATOR_GETITEM_METHODDEF
918 _OPERATOR_SETITEM_METHODDEF
919 _OPERATOR_DELITEM_METHODDEF
920 _OPERATOR_POW_METHODDEF
921 _OPERATOR_IPOW_METHODDEF
922 _OPERATOR_EQ_METHODDEF
923 _OPERATOR_NE_METHODDEF
924 _OPERATOR_LT_METHODDEF
925 _OPERATOR_LE_METHODDEF
926 _OPERATOR_GT_METHODDEF
927 _OPERATOR_GE_METHODDEF
928 _OPERATOR__COMPARE_DIGEST_METHODDEF
929 _OPERATOR_LENGTH_HINT_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 {NULL, NULL} /* sentinel */
Guido van Rossum037b9401996-07-30 16:55:54 +0000931
Guido van Rossum037b9401996-07-30 16:55:54 +0000932};
933
Raymond Hettinger166958b2003-12-01 13:18:39 +0000934/* itemgetter object **********************************************************/
Guido van Rossum037b9401996-07-30 16:55:54 +0000935
Raymond Hettinger166958b2003-12-01 13:18:39 +0000936typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 PyObject_HEAD
938 Py_ssize_t nitems;
939 PyObject *item;
Raymond Hettinger2d53bed2019-01-07 09:38:41 -0700940 Py_ssize_t index; // -1 unless *item* is a single non-negative integer index
Raymond Hettinger166958b2003-12-01 13:18:39 +0000941} itemgetterobject;
942
943static PyTypeObject itemgetter_type;
944
Serhiy Storchakab813a0e2017-01-19 17:44:13 +0200945/* AC 3.5: treats first argument as an iterable, otherwise uses *args */
Raymond Hettinger166958b2003-12-01 13:18:39 +0000946static PyObject *
947itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 itemgetterobject *ig;
950 PyObject *item;
951 Py_ssize_t nitems;
Raymond Hettinger2d53bed2019-01-07 09:38:41 -0700952 Py_ssize_t index;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000953
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +0300954 if (!_PyArg_NoKeywords("itemgetter", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +0000956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 nitems = PyTuple_GET_SIZE(args);
958 if (nitems <= 1) {
959 if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item))
960 return NULL;
961 } else
962 item = args;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000963
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 /* create itemgetterobject structure */
965 ig = PyObject_GC_New(itemgetterobject, &itemgetter_type);
966 if (ig == NULL)
967 return NULL;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 Py_INCREF(item);
970 ig->item = item;
971 ig->nitems = nitems;
Raymond Hettinger2d53bed2019-01-07 09:38:41 -0700972 ig->index = -1;
973 if (PyLong_CheckExact(item)) {
974 index = PyLong_AsSsize_t(item);
975 if (index < 0) {
976 /* If we get here, then either the index conversion failed
977 * due to being out of range, or the index was a negative
978 * integer. Either way, we clear any possible exception
979 * and fall back to the slow path, where ig->index is -1.
980 */
981 PyErr_Clear();
982 }
983 else {
984 ig->index = index;
985 }
986 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987
988 PyObject_GC_Track(ig);
989 return (PyObject *)ig;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000990}
991
992static void
993itemgetter_dealloc(itemgetterobject *ig)
994{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 PyObject_GC_UnTrack(ig);
996 Py_XDECREF(ig->item);
997 PyObject_GC_Del(ig);
Raymond Hettinger166958b2003-12-01 13:18:39 +0000998}
999
1000static int
1001itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
1002{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 Py_VISIT(ig->item);
1004 return 0;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001005}
1006
1007static PyObject *
1008itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
1009{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 PyObject *obj, *result;
1011 Py_ssize_t i, nitems=ig->nitems;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001012
Raymond Hettinger2d53bed2019-01-07 09:38:41 -07001013 assert(PyTuple_CheckExact(args));
Serhiy Storchaka79342662019-01-12 08:25:41 +02001014 if (!_PyArg_NoKeywords("itemgetter", kw))
1015 return NULL;
1016 if (!_PyArg_CheckPositional("itemgetter", PyTuple_GET_SIZE(args), 1, 1))
1017 return NULL;
1018
1019 obj = PyTuple_GET_ITEM(args, 0);
Raymond Hettinger2d53bed2019-01-07 09:38:41 -07001020 if (nitems == 1) {
1021 if (ig->index >= 0
1022 && PyTuple_CheckExact(obj)
1023 && ig->index < PyTuple_GET_SIZE(obj))
1024 {
1025 result = PyTuple_GET_ITEM(obj, ig->index);
1026 Py_INCREF(result);
1027 return result;
1028 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 return PyObject_GetItem(obj, ig->item);
Raymond Hettinger2d53bed2019-01-07 09:38:41 -07001030 }
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 assert(PyTuple_Check(ig->item));
1033 assert(PyTuple_GET_SIZE(ig->item) == nitems);
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 result = PyTuple_New(nitems);
1036 if (result == NULL)
1037 return NULL;
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 for (i=0 ; i < nitems ; i++) {
1040 PyObject *item, *val;
1041 item = PyTuple_GET_ITEM(ig->item, i);
1042 val = PyObject_GetItem(obj, item);
1043 if (val == NULL) {
1044 Py_DECREF(result);
1045 return NULL;
1046 }
1047 PyTuple_SET_ITEM(result, i, val);
1048 }
1049 return result;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001050}
1051
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001052static PyObject *
1053itemgetter_repr(itemgetterobject *ig)
1054{
1055 PyObject *repr;
1056 const char *reprfmt;
1057
1058 int status = Py_ReprEnter((PyObject *)ig);
1059 if (status != 0) {
1060 if (status < 0)
1061 return NULL;
1062 return PyUnicode_FromFormat("%s(...)", Py_TYPE(ig)->tp_name);
1063 }
1064
1065 reprfmt = ig->nitems == 1 ? "%s(%R)" : "%s%R";
1066 repr = PyUnicode_FromFormat(reprfmt, Py_TYPE(ig)->tp_name, ig->item);
1067 Py_ReprLeave((PyObject *)ig);
1068 return repr;
1069}
1070
1071static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301072itemgetter_reduce(itemgetterobject *ig, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001073{
1074 if (ig->nitems == 1)
1075 return Py_BuildValue("O(O)", Py_TYPE(ig), ig->item);
1076 return PyTuple_Pack(2, Py_TYPE(ig), ig->item);
1077}
1078
1079PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1080
1081static PyMethodDef itemgetter_methods[] = {
1082 {"__reduce__", (PyCFunction)itemgetter_reduce, METH_NOARGS,
1083 reduce_doc},
1084 {NULL}
1085};
1086
Raymond Hettinger166958b2003-12-01 13:18:39 +00001087PyDoc_STRVAR(itemgetter_doc,
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001088"itemgetter(item, ...) --> itemgetter object\n\
Raymond Hettinger166958b2003-12-01 13:18:39 +00001089\n\
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001090Return a callable object that fetches the given item(s) from its operand.\n\
Ezio Melottibabc8222013-05-08 10:53:11 +03001091After f = itemgetter(2), the call f(r) returns r[2].\n\
1092After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])");
Raymond Hettinger166958b2003-12-01 13:18:39 +00001093
1094static PyTypeObject itemgetter_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 PyVarObject_HEAD_INIT(NULL, 0)
1096 "operator.itemgetter", /* tp_name */
1097 sizeof(itemgetterobject), /* tp_basicsize */
1098 0, /* tp_itemsize */
1099 /* methods */
1100 (destructor)itemgetter_dealloc, /* tp_dealloc */
1101 0, /* tp_print */
1102 0, /* tp_getattr */
1103 0, /* tp_setattr */
1104 0, /* tp_reserved */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001105 (reprfunc)itemgetter_repr, /* tp_repr */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001106 0, /* tp_as_number */
1107 0, /* tp_as_sequence */
1108 0, /* tp_as_mapping */
1109 0, /* tp_hash */
1110 (ternaryfunc)itemgetter_call, /* tp_call */
1111 0, /* tp_str */
1112 PyObject_GenericGetAttr, /* tp_getattro */
1113 0, /* tp_setattro */
1114 0, /* tp_as_buffer */
1115 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1116 itemgetter_doc, /* tp_doc */
1117 (traverseproc)itemgetter_traverse, /* tp_traverse */
1118 0, /* tp_clear */
1119 0, /* tp_richcompare */
1120 0, /* tp_weaklistoffset */
1121 0, /* tp_iter */
1122 0, /* tp_iternext */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001123 itemgetter_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 0, /* tp_members */
1125 0, /* tp_getset */
1126 0, /* tp_base */
1127 0, /* tp_dict */
1128 0, /* tp_descr_get */
1129 0, /* tp_descr_set */
1130 0, /* tp_dictoffset */
1131 0, /* tp_init */
1132 0, /* tp_alloc */
1133 itemgetter_new, /* tp_new */
1134 0, /* tp_free */
Raymond Hettinger166958b2003-12-01 13:18:39 +00001135};
1136
1137
1138/* attrgetter object **********************************************************/
1139
1140typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 PyObject_HEAD
1142 Py_ssize_t nattrs;
1143 PyObject *attr;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001144} attrgetterobject;
1145
1146static PyTypeObject attrgetter_type;
1147
Serhiy Storchakab813a0e2017-01-19 17:44:13 +02001148/* AC 3.5: treats first argument as an iterable, otherwise uses *args */
Raymond Hettinger166958b2003-12-01 13:18:39 +00001149static PyObject *
1150attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 attrgetterobject *ag;
1153 PyObject *attr;
Antoine Pitroue9745712010-10-31 15:26:04 +00001154 Py_ssize_t nattrs, idx, char_idx;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001155
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001156 if (!_PyArg_NoKeywords("attrgetter", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 nattrs = PyTuple_GET_SIZE(args);
1160 if (nattrs <= 1) {
1161 if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
1162 return NULL;
Antoine Pitroue9745712010-10-31 15:26:04 +00001163 }
1164
1165 attr = PyTuple_New(nattrs);
1166 if (attr == NULL)
1167 return NULL;
1168
1169 /* prepare attr while checking args */
1170 for (idx = 0; idx < nattrs; ++idx) {
1171 PyObject *item = PyTuple_GET_ITEM(args, idx);
1172 Py_ssize_t item_len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001173 void *data;
1174 unsigned int kind;
Antoine Pitroue9745712010-10-31 15:26:04 +00001175 int dot_count;
1176
1177 if (!PyUnicode_Check(item)) {
1178 PyErr_SetString(PyExc_TypeError,
1179 "attribute name must be a string");
1180 Py_DECREF(attr);
1181 return NULL;
1182 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001183 if (PyUnicode_READY(item)) {
1184 Py_DECREF(attr);
1185 return NULL;
1186 }
1187 item_len = PyUnicode_GET_LENGTH(item);
1188 kind = PyUnicode_KIND(item);
1189 data = PyUnicode_DATA(item);
Antoine Pitroue9745712010-10-31 15:26:04 +00001190
1191 /* check whethere the string is dotted */
1192 dot_count = 0;
1193 for (char_idx = 0; char_idx < item_len; ++char_idx) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001194 if (PyUnicode_READ(kind, data, char_idx) == '.')
Antoine Pitroue9745712010-10-31 15:26:04 +00001195 ++dot_count;
1196 }
1197
1198 if (dot_count == 0) {
1199 Py_INCREF(item);
1200 PyUnicode_InternInPlace(&item);
1201 PyTuple_SET_ITEM(attr, idx, item);
1202 } else { /* make it a tuple of non-dotted attrnames */
1203 PyObject *attr_chain = PyTuple_New(dot_count + 1);
1204 PyObject *attr_chain_item;
Antoine Pitrou87298c42010-10-31 21:03:01 +00001205 Py_ssize_t unibuff_from = 0;
1206 Py_ssize_t unibuff_till = 0;
1207 Py_ssize_t attr_chain_idx = 0;
Antoine Pitroue9745712010-10-31 15:26:04 +00001208
1209 if (attr_chain == NULL) {
1210 Py_DECREF(attr);
1211 return NULL;
1212 }
1213
Antoine Pitroue9745712010-10-31 15:26:04 +00001214 for (; dot_count > 0; --dot_count) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001215 while (PyUnicode_READ(kind, data, unibuff_till) != '.') {
Antoine Pitroue9745712010-10-31 15:26:04 +00001216 ++unibuff_till;
1217 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001218 attr_chain_item = PyUnicode_Substring(item,
1219 unibuff_from,
1220 unibuff_till);
Antoine Pitroue9745712010-10-31 15:26:04 +00001221 if (attr_chain_item == NULL) {
1222 Py_DECREF(attr_chain);
1223 Py_DECREF(attr);
1224 return NULL;
1225 }
1226 PyUnicode_InternInPlace(&attr_chain_item);
1227 PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
1228 ++attr_chain_idx;
1229 unibuff_till = unibuff_from = unibuff_till + 1;
1230 }
1231
1232 /* now add the last dotless name */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001233 attr_chain_item = PyUnicode_Substring(item,
1234 unibuff_from, item_len);
Antoine Pitroue9745712010-10-31 15:26:04 +00001235 if (attr_chain_item == NULL) {
1236 Py_DECREF(attr_chain);
1237 Py_DECREF(attr);
1238 return NULL;
1239 }
1240 PyUnicode_InternInPlace(&attr_chain_item);
1241 PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
1242
1243 PyTuple_SET_ITEM(attr, idx, attr_chain);
1244 }
1245 }
Raymond Hettinger166958b2003-12-01 13:18:39 +00001246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 /* create attrgetterobject structure */
1248 ag = PyObject_GC_New(attrgetterobject, &attrgetter_type);
Antoine Pitroue9745712010-10-31 15:26:04 +00001249 if (ag == NULL) {
1250 Py_DECREF(attr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 return NULL;
Antoine Pitroue9745712010-10-31 15:26:04 +00001252 }
Raymond Hettinger166958b2003-12-01 13:18:39 +00001253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 ag->attr = attr;
1255 ag->nattrs = nattrs;
1256
1257 PyObject_GC_Track(ag);
1258 return (PyObject *)ag;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001259}
1260
1261static void
1262attrgetter_dealloc(attrgetterobject *ag)
1263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 PyObject_GC_UnTrack(ag);
1265 Py_XDECREF(ag->attr);
1266 PyObject_GC_Del(ag);
Raymond Hettinger166958b2003-12-01 13:18:39 +00001267}
1268
1269static int
1270attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
1271{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 Py_VISIT(ag->attr);
1273 return 0;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001274}
1275
1276static PyObject *
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001277dotted_getattr(PyObject *obj, PyObject *attr)
1278{
Antoine Pitroue9745712010-10-31 15:26:04 +00001279 PyObject *newobj;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001280
Antoine Pitroue9745712010-10-31 15:26:04 +00001281 /* attr is either a tuple or instance of str.
1282 Ensured by the setup code of attrgetter_new */
1283 if (PyTuple_CheckExact(attr)) { /* chained getattr */
1284 Py_ssize_t name_idx = 0, name_count;
1285 PyObject *attr_name;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001286
Antoine Pitroue9745712010-10-31 15:26:04 +00001287 name_count = PyTuple_GET_SIZE(attr);
1288 Py_INCREF(obj);
1289 for (name_idx = 0; name_idx < name_count; ++name_idx) {
1290 attr_name = PyTuple_GET_ITEM(attr, name_idx);
1291 newobj = PyObject_GetAttr(obj, attr_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 Py_DECREF(obj);
Antoine Pitroue9745712010-10-31 15:26:04 +00001293 if (newobj == NULL) {
1294 return NULL;
1295 }
1296 /* here */
1297 obj = newobj;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 }
Antoine Pitroue9745712010-10-31 15:26:04 +00001299 } else { /* single getattr */
1300 newobj = PyObject_GetAttr(obj, attr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 if (newobj == NULL)
1302 return NULL;
1303 obj = newobj;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 }
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 return obj;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001307}
1308
1309static PyObject *
Raymond Hettinger166958b2003-12-01 13:18:39 +00001310attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
1311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 PyObject *obj, *result;
1313 Py_ssize_t i, nattrs=ag->nattrs;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001314
Serhiy Storchaka68a001d2017-02-06 10:41:46 +02001315 if (!_PyArg_NoKeywords("attrgetter", kw))
Serhiy Storchakac2a2a752016-04-23 10:51:39 +03001316 return NULL;
Serhiy Storchaka79342662019-01-12 08:25:41 +02001317 if (!_PyArg_CheckPositional("attrgetter", PyTuple_GET_SIZE(args), 1, 1))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 return NULL;
Serhiy Storchaka79342662019-01-12 08:25:41 +02001319 obj = PyTuple_GET_ITEM(args, 0);
Antoine Pitroue9745712010-10-31 15:26:04 +00001320 if (ag->nattrs == 1) /* ag->attr is always a tuple */
1321 return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0));
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 assert(PyTuple_Check(ag->attr));
1324 assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 result = PyTuple_New(nattrs);
1327 if (result == NULL)
1328 return NULL;
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 for (i=0 ; i < nattrs ; i++) {
1331 PyObject *attr, *val;
1332 attr = PyTuple_GET_ITEM(ag->attr, i);
1333 val = dotted_getattr(obj, attr);
1334 if (val == NULL) {
1335 Py_DECREF(result);
1336 return NULL;
1337 }
1338 PyTuple_SET_ITEM(result, i, val);
1339 }
1340 return result;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001341}
1342
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001343static PyObject *
1344dotjoinattr(PyObject *attr, PyObject **attrsep)
1345{
1346 if (PyTuple_CheckExact(attr)) {
1347 if (*attrsep == NULL) {
1348 *attrsep = PyUnicode_FromString(".");
1349 if (*attrsep == NULL)
1350 return NULL;
1351 }
1352 return PyUnicode_Join(*attrsep, attr);
1353 } else {
1354 Py_INCREF(attr);
1355 return attr;
1356 }
1357}
1358
1359static PyObject *
1360attrgetter_args(attrgetterobject *ag)
1361{
1362 Py_ssize_t i;
1363 PyObject *attrsep = NULL;
1364 PyObject *attrstrings = PyTuple_New(ag->nattrs);
1365 if (attrstrings == NULL)
1366 return NULL;
1367
1368 for (i = 0; i < ag->nattrs; ++i) {
1369 PyObject *attr = PyTuple_GET_ITEM(ag->attr, i);
1370 PyObject *attrstr = dotjoinattr(attr, &attrsep);
1371 if (attrstr == NULL) {
1372 Py_XDECREF(attrsep);
1373 Py_DECREF(attrstrings);
1374 return NULL;
1375 }
1376 PyTuple_SET_ITEM(attrstrings, i, attrstr);
1377 }
1378 Py_XDECREF(attrsep);
1379 return attrstrings;
1380}
1381
1382static PyObject *
1383attrgetter_repr(attrgetterobject *ag)
1384{
1385 PyObject *repr = NULL;
1386 int status = Py_ReprEnter((PyObject *)ag);
1387 if (status != 0) {
1388 if (status < 0)
1389 return NULL;
1390 return PyUnicode_FromFormat("%s(...)", Py_TYPE(ag)->tp_name);
1391 }
1392
1393 if (ag->nattrs == 1) {
1394 PyObject *attrsep = NULL;
1395 PyObject *attr = dotjoinattr(PyTuple_GET_ITEM(ag->attr, 0), &attrsep);
Serhiy Storchaka548de2b2015-05-21 14:19:20 +03001396 if (attr != NULL) {
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001397 repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(ag)->tp_name, attr);
Serhiy Storchaka548de2b2015-05-21 14:19:20 +03001398 Py_DECREF(attr);
1399 }
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001400 Py_XDECREF(attrsep);
1401 }
1402 else {
1403 PyObject *attrstrings = attrgetter_args(ag);
1404 if (attrstrings != NULL) {
1405 repr = PyUnicode_FromFormat("%s%R",
1406 Py_TYPE(ag)->tp_name, attrstrings);
1407 Py_DECREF(attrstrings);
1408 }
1409 }
1410 Py_ReprLeave((PyObject *)ag);
1411 return repr;
1412}
1413
1414static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301415attrgetter_reduce(attrgetterobject *ag, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001416{
1417 PyObject *attrstrings = attrgetter_args(ag);
1418 if (attrstrings == NULL)
1419 return NULL;
1420
1421 return Py_BuildValue("ON", Py_TYPE(ag), attrstrings);
1422}
1423
1424static PyMethodDef attrgetter_methods[] = {
1425 {"__reduce__", (PyCFunction)attrgetter_reduce, METH_NOARGS,
1426 reduce_doc},
1427 {NULL}
1428};
1429
Raymond Hettinger166958b2003-12-01 13:18:39 +00001430PyDoc_STRVAR(attrgetter_doc,
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001431"attrgetter(attr, ...) --> attrgetter object\n\
Raymond Hettinger166958b2003-12-01 13:18:39 +00001432\n\
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001433Return a callable object that fetches the given attribute(s) from its operand.\n\
Ezio Melottibabc8222013-05-08 10:53:11 +03001434After f = attrgetter('name'), the call f(r) returns r.name.\n\
1435After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\
1436After h = attrgetter('name.first', 'name.last'), the call h(r) returns\n\
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001437(r.name.first, r.name.last).");
Raymond Hettinger166958b2003-12-01 13:18:39 +00001438
1439static PyTypeObject attrgetter_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 PyVarObject_HEAD_INIT(NULL, 0)
1441 "operator.attrgetter", /* tp_name */
1442 sizeof(attrgetterobject), /* tp_basicsize */
1443 0, /* tp_itemsize */
1444 /* methods */
1445 (destructor)attrgetter_dealloc, /* tp_dealloc */
1446 0, /* tp_print */
1447 0, /* tp_getattr */
1448 0, /* tp_setattr */
1449 0, /* tp_reserved */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001450 (reprfunc)attrgetter_repr, /* tp_repr */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 0, /* tp_as_number */
1452 0, /* tp_as_sequence */
1453 0, /* tp_as_mapping */
1454 0, /* tp_hash */
1455 (ternaryfunc)attrgetter_call, /* tp_call */
1456 0, /* tp_str */
1457 PyObject_GenericGetAttr, /* tp_getattro */
1458 0, /* tp_setattro */
1459 0, /* tp_as_buffer */
1460 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1461 attrgetter_doc, /* tp_doc */
1462 (traverseproc)attrgetter_traverse, /* tp_traverse */
1463 0, /* tp_clear */
1464 0, /* tp_richcompare */
1465 0, /* tp_weaklistoffset */
1466 0, /* tp_iter */
1467 0, /* tp_iternext */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001468 attrgetter_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 0, /* tp_members */
1470 0, /* tp_getset */
1471 0, /* tp_base */
1472 0, /* tp_dict */
1473 0, /* tp_descr_get */
1474 0, /* tp_descr_set */
1475 0, /* tp_dictoffset */
1476 0, /* tp_init */
1477 0, /* tp_alloc */
1478 attrgetter_new, /* tp_new */
1479 0, /* tp_free */
Raymond Hettinger166958b2003-12-01 13:18:39 +00001480};
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001481
1482
1483/* methodcaller object **********************************************************/
1484
1485typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 PyObject_HEAD
1487 PyObject *name;
1488 PyObject *args;
1489 PyObject *kwds;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001490} methodcallerobject;
1491
1492static PyTypeObject methodcaller_type;
1493
Serhiy Storchakab813a0e2017-01-19 17:44:13 +02001494/* AC 3.5: variable number of arguments, not currently support by AC */
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001495static PyObject *
1496methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 methodcallerobject *mc;
Benjamin Peterson1f0e7c92016-08-16 23:35:35 -07001499 PyObject *name;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 if (PyTuple_GET_SIZE(args) < 1) {
1502 PyErr_SetString(PyExc_TypeError, "methodcaller needs at least "
1503 "one argument, the method name");
1504 return NULL;
1505 }
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001506
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001507 name = PyTuple_GET_ITEM(args, 0);
1508 if (!PyUnicode_Check(name)) {
1509 PyErr_SetString(PyExc_TypeError,
1510 "method name must be a string");
1511 return NULL;
1512 }
1513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 /* create methodcallerobject structure */
1515 mc = PyObject_GC_New(methodcallerobject, &methodcaller_type);
1516 if (mc == NULL)
1517 return NULL;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 name = PyTuple_GET_ITEM(args, 0);
1520 Py_INCREF(name);
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001521 PyUnicode_InternInPlace(&name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 mc->name = name;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 Py_XINCREF(kwds);
1525 mc->kwds = kwds;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001526
Benjamin Peterson1f0e7c92016-08-16 23:35:35 -07001527 mc->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
1528 if (mc->args == NULL) {
1529 Py_DECREF(mc);
1530 return NULL;
1531 }
1532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 PyObject_GC_Track(mc);
1534 return (PyObject *)mc;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001535}
1536
1537static void
1538methodcaller_dealloc(methodcallerobject *mc)
1539{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 PyObject_GC_UnTrack(mc);
1541 Py_XDECREF(mc->name);
1542 Py_XDECREF(mc->args);
1543 Py_XDECREF(mc->kwds);
1544 PyObject_GC_Del(mc);
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001545}
1546
1547static int
1548methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
1549{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550 Py_VISIT(mc->args);
1551 Py_VISIT(mc->kwds);
1552 return 0;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001553}
1554
1555static PyObject *
1556methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw)
1557{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 PyObject *method, *obj, *result;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001559
Serhiy Storchaka68a001d2017-02-06 10:41:46 +02001560 if (!_PyArg_NoKeywords("methodcaller", kw))
Serhiy Storchakac2a2a752016-04-23 10:51:39 +03001561 return NULL;
Serhiy Storchaka79342662019-01-12 08:25:41 +02001562 if (!_PyArg_CheckPositional("methodcaller", PyTuple_GET_SIZE(args), 1, 1))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 return NULL;
Serhiy Storchaka79342662019-01-12 08:25:41 +02001564 obj = PyTuple_GET_ITEM(args, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 method = PyObject_GetAttr(obj, mc->name);
1566 if (method == NULL)
1567 return NULL;
1568 result = PyObject_Call(method, mc->args, mc->kwds);
1569 Py_DECREF(method);
1570 return result;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001571}
1572
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001573static PyObject *
1574methodcaller_repr(methodcallerobject *mc)
1575{
1576 PyObject *argreprs, *repr = NULL, *sep, *joinedargreprs;
1577 Py_ssize_t numtotalargs, numposargs, numkwdargs, i;
1578 int status = Py_ReprEnter((PyObject *)mc);
1579 if (status != 0) {
1580 if (status < 0)
1581 return NULL;
1582 return PyUnicode_FromFormat("%s(...)", Py_TYPE(mc)->tp_name);
1583 }
1584
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02001585 numkwdargs = mc->kwds != NULL ? PyDict_GET_SIZE(mc->kwds) : 0;
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001586 numposargs = PyTuple_GET_SIZE(mc->args);
1587 numtotalargs = numposargs + numkwdargs;
1588
1589 if (numtotalargs == 0) {
1590 repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(mc)->tp_name, mc->name);
1591 Py_ReprLeave((PyObject *)mc);
1592 return repr;
1593 }
1594
1595 argreprs = PyTuple_New(numtotalargs);
1596 if (argreprs == NULL) {
1597 Py_ReprLeave((PyObject *)mc);
1598 return NULL;
1599 }
1600
1601 for (i = 0; i < numposargs; ++i) {
1602 PyObject *onerepr = PyObject_Repr(PyTuple_GET_ITEM(mc->args, i));
1603 if (onerepr == NULL)
1604 goto done;
1605 PyTuple_SET_ITEM(argreprs, i, onerepr);
1606 }
1607
1608 if (numkwdargs != 0) {
1609 PyObject *key, *value;
1610 Py_ssize_t pos = 0;
1611 while (PyDict_Next(mc->kwds, &pos, &key, &value)) {
1612 PyObject *onerepr = PyUnicode_FromFormat("%U=%R", key, value);
1613 if (onerepr == NULL)
1614 goto done;
1615 if (i >= numtotalargs) {
1616 i = -1;
Zackery Spytz5b83ef72018-11-23 12:26:46 -07001617 Py_DECREF(onerepr);
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001618 break;
1619 }
1620 PyTuple_SET_ITEM(argreprs, i, onerepr);
1621 ++i;
1622 }
1623 if (i != numtotalargs) {
1624 PyErr_SetString(PyExc_RuntimeError,
1625 "keywords dict changed size during iteration");
1626 goto done;
1627 }
1628 }
1629
1630 sep = PyUnicode_FromString(", ");
1631 if (sep == NULL)
1632 goto done;
1633
1634 joinedargreprs = PyUnicode_Join(sep, argreprs);
1635 Py_DECREF(sep);
1636 if (joinedargreprs == NULL)
1637 goto done;
1638
1639 repr = PyUnicode_FromFormat("%s(%R, %U)", Py_TYPE(mc)->tp_name,
1640 mc->name, joinedargreprs);
1641 Py_DECREF(joinedargreprs);
1642
1643done:
1644 Py_DECREF(argreprs);
1645 Py_ReprLeave((PyObject *)mc);
1646 return repr;
1647}
1648
1649static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301650methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001651{
1652 PyObject *newargs;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02001653 if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) {
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001654 Py_ssize_t i;
1655 Py_ssize_t callargcount = PyTuple_GET_SIZE(mc->args);
1656 newargs = PyTuple_New(1 + callargcount);
1657 if (newargs == NULL)
1658 return NULL;
1659 Py_INCREF(mc->name);
1660 PyTuple_SET_ITEM(newargs, 0, mc->name);
1661 for (i = 0; i < callargcount; ++i) {
1662 PyObject *arg = PyTuple_GET_ITEM(mc->args, i);
1663 Py_INCREF(arg);
1664 PyTuple_SET_ITEM(newargs, i + 1, arg);
1665 }
1666 return Py_BuildValue("ON", Py_TYPE(mc), newargs);
1667 }
1668 else {
1669 PyObject *functools;
1670 PyObject *partial;
1671 PyObject *constructor;
Victor Stinner7e7823a2016-08-23 00:23:23 +02001672 PyObject *newargs[2];
1673
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001674 _Py_IDENTIFIER(partial);
1675 functools = PyImport_ImportModule("functools");
1676 if (!functools)
1677 return NULL;
1678 partial = _PyObject_GetAttrId(functools, &PyId_partial);
1679 Py_DECREF(functools);
1680 if (!partial)
1681 return NULL;
Victor Stinner7e7823a2016-08-23 00:23:23 +02001682
1683 newargs[0] = (PyObject *)Py_TYPE(mc);
1684 newargs[1] = mc->name;
1685 constructor = _PyObject_FastCallDict(partial, newargs, 2, mc->kwds);
1686
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001687 Py_DECREF(partial);
1688 return Py_BuildValue("NO", constructor, mc->args);
1689 }
1690}
1691
1692static PyMethodDef methodcaller_methods[] = {
1693 {"__reduce__", (PyCFunction)methodcaller_reduce, METH_NOARGS,
1694 reduce_doc},
1695 {NULL}
1696};
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001697PyDoc_STRVAR(methodcaller_doc,
1698"methodcaller(name, ...) --> methodcaller object\n\
1699\n\
1700Return a callable object that calls the given method on its operand.\n\
Antoine Pitroua85017f2013-04-20 19:21:44 +02001701After f = methodcaller('name'), the call f(r) returns r.name().\n\
1702After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001703r.name('date', foo=1).");
1704
1705static PyTypeObject methodcaller_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001706 PyVarObject_HEAD_INIT(NULL, 0)
1707 "operator.methodcaller", /* tp_name */
1708 sizeof(methodcallerobject), /* tp_basicsize */
1709 0, /* tp_itemsize */
1710 /* methods */
1711 (destructor)methodcaller_dealloc, /* tp_dealloc */
1712 0, /* tp_print */
1713 0, /* tp_getattr */
1714 0, /* tp_setattr */
1715 0, /* tp_reserved */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001716 (reprfunc)methodcaller_repr, /* tp_repr */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 0, /* tp_as_number */
1718 0, /* tp_as_sequence */
1719 0, /* tp_as_mapping */
1720 0, /* tp_hash */
1721 (ternaryfunc)methodcaller_call, /* tp_call */
1722 0, /* tp_str */
1723 PyObject_GenericGetAttr, /* tp_getattro */
1724 0, /* tp_setattro */
1725 0, /* tp_as_buffer */
1726 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1727 methodcaller_doc, /* tp_doc */
1728 (traverseproc)methodcaller_traverse, /* tp_traverse */
1729 0, /* tp_clear */
1730 0, /* tp_richcompare */
1731 0, /* tp_weaklistoffset */
1732 0, /* tp_iter */
1733 0, /* tp_iternext */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001734 methodcaller_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 0, /* tp_members */
1736 0, /* tp_getset */
1737 0, /* tp_base */
1738 0, /* tp_dict */
1739 0, /* tp_descr_get */
1740 0, /* tp_descr_set */
1741 0, /* tp_dictoffset */
1742 0, /* tp_init */
1743 0, /* tp_alloc */
1744 methodcaller_new, /* tp_new */
1745 0, /* tp_free */
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001746};
1747
1748
Antoine Pitroua85017f2013-04-20 19:21:44 +02001749/* Initialization function for the module (*must* be called PyInit__operator) */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001750
1751
1752static struct PyModuleDef operatormodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001753 PyModuleDef_HEAD_INIT,
Antoine Pitroua85017f2013-04-20 19:21:44 +02001754 "_operator",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001755 operator_doc,
1756 -1,
1757 operator_methods,
1758 NULL,
1759 NULL,
1760 NULL,
1761 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001762};
Guido van Rossum037b9401996-07-30 16:55:54 +00001763
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001764PyMODINIT_FUNC
Antoine Pitroua85017f2013-04-20 19:21:44 +02001765PyInit__operator(void)
Guido van Rossum037b9401996-07-30 16:55:54 +00001766{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001767 PyObject *m;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 /* Create the module and add the functions */
1770 m = PyModule_Create(&operatormodule);
1771 if (m == NULL)
1772 return NULL;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 if (PyType_Ready(&itemgetter_type) < 0)
1775 return NULL;
1776 Py_INCREF(&itemgetter_type);
1777 PyModule_AddObject(m, "itemgetter", (PyObject *)&itemgetter_type);
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 if (PyType_Ready(&attrgetter_type) < 0)
1780 return NULL;
1781 Py_INCREF(&attrgetter_type);
1782 PyModule_AddObject(m, "attrgetter", (PyObject *)&attrgetter_type);
1783
1784 if (PyType_Ready(&methodcaller_type) < 0)
1785 return NULL;
1786 Py_INCREF(&methodcaller_type);
1787 PyModule_AddObject(m, "methodcaller", (PyObject *)&methodcaller_type);
1788 return m;
Guido van Rossum037b9401996-07-30 16:55:54 +00001789}