blob: d6c6a18d81b449c7538b735cde9aaba9cf002daa [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));
1014 if (kw == NULL && PyTuple_GET_SIZE(args) == 1) {
1015 obj = PyTuple_GET_ITEM(args, 0);
1016 }
1017 else {
1018 if (!_PyArg_NoKeywords("itemgetter", kw))
1019 return NULL;
1020 if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &obj))
1021 return NULL;
1022 }
1023 if (nitems == 1) {
1024 if (ig->index >= 0
1025 && PyTuple_CheckExact(obj)
1026 && ig->index < PyTuple_GET_SIZE(obj))
1027 {
1028 result = PyTuple_GET_ITEM(obj, ig->index);
1029 Py_INCREF(result);
1030 return result;
1031 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 return PyObject_GetItem(obj, ig->item);
Raymond Hettinger2d53bed2019-01-07 09:38:41 -07001033 }
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 assert(PyTuple_Check(ig->item));
1036 assert(PyTuple_GET_SIZE(ig->item) == nitems);
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 result = PyTuple_New(nitems);
1039 if (result == NULL)
1040 return NULL;
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 for (i=0 ; i < nitems ; i++) {
1043 PyObject *item, *val;
1044 item = PyTuple_GET_ITEM(ig->item, i);
1045 val = PyObject_GetItem(obj, item);
1046 if (val == NULL) {
1047 Py_DECREF(result);
1048 return NULL;
1049 }
1050 PyTuple_SET_ITEM(result, i, val);
1051 }
1052 return result;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001053}
1054
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001055static PyObject *
1056itemgetter_repr(itemgetterobject *ig)
1057{
1058 PyObject *repr;
1059 const char *reprfmt;
1060
1061 int status = Py_ReprEnter((PyObject *)ig);
1062 if (status != 0) {
1063 if (status < 0)
1064 return NULL;
1065 return PyUnicode_FromFormat("%s(...)", Py_TYPE(ig)->tp_name);
1066 }
1067
1068 reprfmt = ig->nitems == 1 ? "%s(%R)" : "%s%R";
1069 repr = PyUnicode_FromFormat(reprfmt, Py_TYPE(ig)->tp_name, ig->item);
1070 Py_ReprLeave((PyObject *)ig);
1071 return repr;
1072}
1073
1074static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301075itemgetter_reduce(itemgetterobject *ig, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001076{
1077 if (ig->nitems == 1)
1078 return Py_BuildValue("O(O)", Py_TYPE(ig), ig->item);
1079 return PyTuple_Pack(2, Py_TYPE(ig), ig->item);
1080}
1081
1082PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1083
1084static PyMethodDef itemgetter_methods[] = {
1085 {"__reduce__", (PyCFunction)itemgetter_reduce, METH_NOARGS,
1086 reduce_doc},
1087 {NULL}
1088};
1089
Raymond Hettinger166958b2003-12-01 13:18:39 +00001090PyDoc_STRVAR(itemgetter_doc,
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001091"itemgetter(item, ...) --> itemgetter object\n\
Raymond Hettinger166958b2003-12-01 13:18:39 +00001092\n\
Raymond Hettinger984f9bb2005-03-09 16:38:48 +00001093Return a callable object that fetches the given item(s) from its operand.\n\
Ezio Melottibabc8222013-05-08 10:53:11 +03001094After f = itemgetter(2), the call f(r) returns r[2].\n\
1095After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])");
Raymond Hettinger166958b2003-12-01 13:18:39 +00001096
1097static PyTypeObject itemgetter_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 PyVarObject_HEAD_INIT(NULL, 0)
1099 "operator.itemgetter", /* tp_name */
1100 sizeof(itemgetterobject), /* tp_basicsize */
1101 0, /* tp_itemsize */
1102 /* methods */
1103 (destructor)itemgetter_dealloc, /* tp_dealloc */
1104 0, /* tp_print */
1105 0, /* tp_getattr */
1106 0, /* tp_setattr */
1107 0, /* tp_reserved */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001108 (reprfunc)itemgetter_repr, /* tp_repr */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 0, /* tp_as_number */
1110 0, /* tp_as_sequence */
1111 0, /* tp_as_mapping */
1112 0, /* tp_hash */
1113 (ternaryfunc)itemgetter_call, /* tp_call */
1114 0, /* tp_str */
1115 PyObject_GenericGetAttr, /* tp_getattro */
1116 0, /* tp_setattro */
1117 0, /* tp_as_buffer */
1118 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1119 itemgetter_doc, /* tp_doc */
1120 (traverseproc)itemgetter_traverse, /* tp_traverse */
1121 0, /* tp_clear */
1122 0, /* tp_richcompare */
1123 0, /* tp_weaklistoffset */
1124 0, /* tp_iter */
1125 0, /* tp_iternext */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001126 itemgetter_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 0, /* tp_members */
1128 0, /* tp_getset */
1129 0, /* tp_base */
1130 0, /* tp_dict */
1131 0, /* tp_descr_get */
1132 0, /* tp_descr_set */
1133 0, /* tp_dictoffset */
1134 0, /* tp_init */
1135 0, /* tp_alloc */
1136 itemgetter_new, /* tp_new */
1137 0, /* tp_free */
Raymond Hettinger166958b2003-12-01 13:18:39 +00001138};
1139
1140
1141/* attrgetter object **********************************************************/
1142
1143typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 PyObject_HEAD
1145 Py_ssize_t nattrs;
1146 PyObject *attr;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001147} attrgetterobject;
1148
1149static PyTypeObject attrgetter_type;
1150
Serhiy Storchakab813a0e2017-01-19 17:44:13 +02001151/* AC 3.5: treats first argument as an iterable, otherwise uses *args */
Raymond Hettinger166958b2003-12-01 13:18:39 +00001152static PyObject *
1153attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1154{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 attrgetterobject *ag;
1156 PyObject *attr;
Antoine Pitroue9745712010-10-31 15:26:04 +00001157 Py_ssize_t nattrs, idx, char_idx;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001158
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001159 if (!_PyArg_NoKeywords("attrgetter", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 nattrs = PyTuple_GET_SIZE(args);
1163 if (nattrs <= 1) {
1164 if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
1165 return NULL;
Antoine Pitroue9745712010-10-31 15:26:04 +00001166 }
1167
1168 attr = PyTuple_New(nattrs);
1169 if (attr == NULL)
1170 return NULL;
1171
1172 /* prepare attr while checking args */
1173 for (idx = 0; idx < nattrs; ++idx) {
1174 PyObject *item = PyTuple_GET_ITEM(args, idx);
1175 Py_ssize_t item_len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001176 void *data;
1177 unsigned int kind;
Antoine Pitroue9745712010-10-31 15:26:04 +00001178 int dot_count;
1179
1180 if (!PyUnicode_Check(item)) {
1181 PyErr_SetString(PyExc_TypeError,
1182 "attribute name must be a string");
1183 Py_DECREF(attr);
1184 return NULL;
1185 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001186 if (PyUnicode_READY(item)) {
1187 Py_DECREF(attr);
1188 return NULL;
1189 }
1190 item_len = PyUnicode_GET_LENGTH(item);
1191 kind = PyUnicode_KIND(item);
1192 data = PyUnicode_DATA(item);
Antoine Pitroue9745712010-10-31 15:26:04 +00001193
1194 /* check whethere the string is dotted */
1195 dot_count = 0;
1196 for (char_idx = 0; char_idx < item_len; ++char_idx) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001197 if (PyUnicode_READ(kind, data, char_idx) == '.')
Antoine Pitroue9745712010-10-31 15:26:04 +00001198 ++dot_count;
1199 }
1200
1201 if (dot_count == 0) {
1202 Py_INCREF(item);
1203 PyUnicode_InternInPlace(&item);
1204 PyTuple_SET_ITEM(attr, idx, item);
1205 } else { /* make it a tuple of non-dotted attrnames */
1206 PyObject *attr_chain = PyTuple_New(dot_count + 1);
1207 PyObject *attr_chain_item;
Antoine Pitrou87298c42010-10-31 21:03:01 +00001208 Py_ssize_t unibuff_from = 0;
1209 Py_ssize_t unibuff_till = 0;
1210 Py_ssize_t attr_chain_idx = 0;
Antoine Pitroue9745712010-10-31 15:26:04 +00001211
1212 if (attr_chain == NULL) {
1213 Py_DECREF(attr);
1214 return NULL;
1215 }
1216
Antoine Pitroue9745712010-10-31 15:26:04 +00001217 for (; dot_count > 0; --dot_count) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001218 while (PyUnicode_READ(kind, data, unibuff_till) != '.') {
Antoine Pitroue9745712010-10-31 15:26:04 +00001219 ++unibuff_till;
1220 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001221 attr_chain_item = PyUnicode_Substring(item,
1222 unibuff_from,
1223 unibuff_till);
Antoine Pitroue9745712010-10-31 15:26:04 +00001224 if (attr_chain_item == NULL) {
1225 Py_DECREF(attr_chain);
1226 Py_DECREF(attr);
1227 return NULL;
1228 }
1229 PyUnicode_InternInPlace(&attr_chain_item);
1230 PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
1231 ++attr_chain_idx;
1232 unibuff_till = unibuff_from = unibuff_till + 1;
1233 }
1234
1235 /* now add the last dotless name */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001236 attr_chain_item = PyUnicode_Substring(item,
1237 unibuff_from, item_len);
Antoine Pitroue9745712010-10-31 15:26:04 +00001238 if (attr_chain_item == NULL) {
1239 Py_DECREF(attr_chain);
1240 Py_DECREF(attr);
1241 return NULL;
1242 }
1243 PyUnicode_InternInPlace(&attr_chain_item);
1244 PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
1245
1246 PyTuple_SET_ITEM(attr, idx, attr_chain);
1247 }
1248 }
Raymond Hettinger166958b2003-12-01 13:18:39 +00001249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 /* create attrgetterobject structure */
1251 ag = PyObject_GC_New(attrgetterobject, &attrgetter_type);
Antoine Pitroue9745712010-10-31 15:26:04 +00001252 if (ag == NULL) {
1253 Py_DECREF(attr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 return NULL;
Antoine Pitroue9745712010-10-31 15:26:04 +00001255 }
Raymond Hettinger166958b2003-12-01 13:18:39 +00001256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 ag->attr = attr;
1258 ag->nattrs = nattrs;
1259
1260 PyObject_GC_Track(ag);
1261 return (PyObject *)ag;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001262}
1263
1264static void
1265attrgetter_dealloc(attrgetterobject *ag)
1266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 PyObject_GC_UnTrack(ag);
1268 Py_XDECREF(ag->attr);
1269 PyObject_GC_Del(ag);
Raymond Hettinger166958b2003-12-01 13:18:39 +00001270}
1271
1272static int
1273attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
1274{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 Py_VISIT(ag->attr);
1276 return 0;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001277}
1278
1279static PyObject *
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001280dotted_getattr(PyObject *obj, PyObject *attr)
1281{
Antoine Pitroue9745712010-10-31 15:26:04 +00001282 PyObject *newobj;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001283
Antoine Pitroue9745712010-10-31 15:26:04 +00001284 /* attr is either a tuple or instance of str.
1285 Ensured by the setup code of attrgetter_new */
1286 if (PyTuple_CheckExact(attr)) { /* chained getattr */
1287 Py_ssize_t name_idx = 0, name_count;
1288 PyObject *attr_name;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001289
Antoine Pitroue9745712010-10-31 15:26:04 +00001290 name_count = PyTuple_GET_SIZE(attr);
1291 Py_INCREF(obj);
1292 for (name_idx = 0; name_idx < name_count; ++name_idx) {
1293 attr_name = PyTuple_GET_ITEM(attr, name_idx);
1294 newobj = PyObject_GetAttr(obj, attr_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 Py_DECREF(obj);
Antoine Pitroue9745712010-10-31 15:26:04 +00001296 if (newobj == NULL) {
1297 return NULL;
1298 }
1299 /* here */
1300 obj = newobj;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 }
Antoine Pitroue9745712010-10-31 15:26:04 +00001302 } else { /* single getattr */
1303 newobj = PyObject_GetAttr(obj, attr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 if (newobj == NULL)
1305 return NULL;
1306 obj = newobj;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 }
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 return obj;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001310}
1311
1312static PyObject *
Raymond Hettinger166958b2003-12-01 13:18:39 +00001313attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
1314{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 PyObject *obj, *result;
1316 Py_ssize_t i, nattrs=ag->nattrs;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001317
Serhiy Storchaka68a001d2017-02-06 10:41:46 +02001318 if (!_PyArg_NoKeywords("attrgetter", kw))
Serhiy Storchakac2a2a752016-04-23 10:51:39 +03001319 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &obj))
1321 return NULL;
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 */
1448 0, /* tp_print */
1449 0, /* tp_getattr */
1450 0, /* tp_setattr */
1451 0, /* tp_reserved */
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;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001564 if (!PyArg_UnpackTuple(args, "methodcaller", 1, 1, &obj))
1565 return NULL;
1566 method = PyObject_GetAttr(obj, mc->name);
1567 if (method == NULL)
1568 return NULL;
1569 result = PyObject_Call(method, mc->args, mc->kwds);
1570 Py_DECREF(method);
1571 return result;
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001572}
1573
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001574static PyObject *
1575methodcaller_repr(methodcallerobject *mc)
1576{
1577 PyObject *argreprs, *repr = NULL, *sep, *joinedargreprs;
1578 Py_ssize_t numtotalargs, numposargs, numkwdargs, i;
1579 int status = Py_ReprEnter((PyObject *)mc);
1580 if (status != 0) {
1581 if (status < 0)
1582 return NULL;
1583 return PyUnicode_FromFormat("%s(...)", Py_TYPE(mc)->tp_name);
1584 }
1585
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02001586 numkwdargs = mc->kwds != NULL ? PyDict_GET_SIZE(mc->kwds) : 0;
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001587 numposargs = PyTuple_GET_SIZE(mc->args);
1588 numtotalargs = numposargs + numkwdargs;
1589
1590 if (numtotalargs == 0) {
1591 repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(mc)->tp_name, mc->name);
1592 Py_ReprLeave((PyObject *)mc);
1593 return repr;
1594 }
1595
1596 argreprs = PyTuple_New(numtotalargs);
1597 if (argreprs == NULL) {
1598 Py_ReprLeave((PyObject *)mc);
1599 return NULL;
1600 }
1601
1602 for (i = 0; i < numposargs; ++i) {
1603 PyObject *onerepr = PyObject_Repr(PyTuple_GET_ITEM(mc->args, i));
1604 if (onerepr == NULL)
1605 goto done;
1606 PyTuple_SET_ITEM(argreprs, i, onerepr);
1607 }
1608
1609 if (numkwdargs != 0) {
1610 PyObject *key, *value;
1611 Py_ssize_t pos = 0;
1612 while (PyDict_Next(mc->kwds, &pos, &key, &value)) {
1613 PyObject *onerepr = PyUnicode_FromFormat("%U=%R", key, value);
1614 if (onerepr == NULL)
1615 goto done;
1616 if (i >= numtotalargs) {
1617 i = -1;
Zackery Spytz5b83ef72018-11-23 12:26:46 -07001618 Py_DECREF(onerepr);
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001619 break;
1620 }
1621 PyTuple_SET_ITEM(argreprs, i, onerepr);
1622 ++i;
1623 }
1624 if (i != numtotalargs) {
1625 PyErr_SetString(PyExc_RuntimeError,
1626 "keywords dict changed size during iteration");
1627 goto done;
1628 }
1629 }
1630
1631 sep = PyUnicode_FromString(", ");
1632 if (sep == NULL)
1633 goto done;
1634
1635 joinedargreprs = PyUnicode_Join(sep, argreprs);
1636 Py_DECREF(sep);
1637 if (joinedargreprs == NULL)
1638 goto done;
1639
1640 repr = PyUnicode_FromFormat("%s(%R, %U)", Py_TYPE(mc)->tp_name,
1641 mc->name, joinedargreprs);
1642 Py_DECREF(joinedargreprs);
1643
1644done:
1645 Py_DECREF(argreprs);
1646 Py_ReprLeave((PyObject *)mc);
1647 return repr;
1648}
1649
1650static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301651methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001652{
1653 PyObject *newargs;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02001654 if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) {
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001655 Py_ssize_t i;
1656 Py_ssize_t callargcount = PyTuple_GET_SIZE(mc->args);
1657 newargs = PyTuple_New(1 + callargcount);
1658 if (newargs == NULL)
1659 return NULL;
1660 Py_INCREF(mc->name);
1661 PyTuple_SET_ITEM(newargs, 0, mc->name);
1662 for (i = 0; i < callargcount; ++i) {
1663 PyObject *arg = PyTuple_GET_ITEM(mc->args, i);
1664 Py_INCREF(arg);
1665 PyTuple_SET_ITEM(newargs, i + 1, arg);
1666 }
1667 return Py_BuildValue("ON", Py_TYPE(mc), newargs);
1668 }
1669 else {
1670 PyObject *functools;
1671 PyObject *partial;
1672 PyObject *constructor;
Victor Stinner7e7823a2016-08-23 00:23:23 +02001673 PyObject *newargs[2];
1674
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001675 _Py_IDENTIFIER(partial);
1676 functools = PyImport_ImportModule("functools");
1677 if (!functools)
1678 return NULL;
1679 partial = _PyObject_GetAttrId(functools, &PyId_partial);
1680 Py_DECREF(functools);
1681 if (!partial)
1682 return NULL;
Victor Stinner7e7823a2016-08-23 00:23:23 +02001683
1684 newargs[0] = (PyObject *)Py_TYPE(mc);
1685 newargs[1] = mc->name;
1686 constructor = _PyObject_FastCallDict(partial, newargs, 2, mc->kwds);
1687
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001688 Py_DECREF(partial);
1689 return Py_BuildValue("NO", constructor, mc->args);
1690 }
1691}
1692
1693static PyMethodDef methodcaller_methods[] = {
1694 {"__reduce__", (PyCFunction)methodcaller_reduce, METH_NOARGS,
1695 reduce_doc},
1696 {NULL}
1697};
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001698PyDoc_STRVAR(methodcaller_doc,
1699"methodcaller(name, ...) --> methodcaller object\n\
1700\n\
1701Return a callable object that calls the given method on its operand.\n\
Antoine Pitroua85017f2013-04-20 19:21:44 +02001702After f = methodcaller('name'), the call f(r) returns r.name().\n\
1703After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001704r.name('date', foo=1).");
1705
1706static PyTypeObject methodcaller_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001707 PyVarObject_HEAD_INIT(NULL, 0)
1708 "operator.methodcaller", /* tp_name */
1709 sizeof(methodcallerobject), /* tp_basicsize */
1710 0, /* tp_itemsize */
1711 /* methods */
1712 (destructor)methodcaller_dealloc, /* tp_dealloc */
1713 0, /* tp_print */
1714 0, /* tp_getattr */
1715 0, /* tp_setattr */
1716 0, /* tp_reserved */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001717 (reprfunc)methodcaller_repr, /* tp_repr */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001718 0, /* tp_as_number */
1719 0, /* tp_as_sequence */
1720 0, /* tp_as_mapping */
1721 0, /* tp_hash */
1722 (ternaryfunc)methodcaller_call, /* tp_call */
1723 0, /* tp_str */
1724 PyObject_GenericGetAttr, /* tp_getattro */
1725 0, /* tp_setattro */
1726 0, /* tp_as_buffer */
1727 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1728 methodcaller_doc, /* tp_doc */
1729 (traverseproc)methodcaller_traverse, /* tp_traverse */
1730 0, /* tp_clear */
1731 0, /* tp_richcompare */
1732 0, /* tp_weaklistoffset */
1733 0, /* tp_iter */
1734 0, /* tp_iternext */
Serhiy Storchaka35ac5f82015-05-20 18:29:18 +03001735 methodcaller_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 0, /* tp_members */
1737 0, /* tp_getset */
1738 0, /* tp_base */
1739 0, /* tp_dict */
1740 0, /* tp_descr_get */
1741 0, /* tp_descr_set */
1742 0, /* tp_dictoffset */
1743 0, /* tp_init */
1744 0, /* tp_alloc */
1745 methodcaller_new, /* tp_new */
1746 0, /* tp_free */
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001747};
1748
1749
Antoine Pitroua85017f2013-04-20 19:21:44 +02001750/* Initialization function for the module (*must* be called PyInit__operator) */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001751
1752
1753static struct PyModuleDef operatormodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 PyModuleDef_HEAD_INIT,
Antoine Pitroua85017f2013-04-20 19:21:44 +02001755 "_operator",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 operator_doc,
1757 -1,
1758 operator_methods,
1759 NULL,
1760 NULL,
1761 NULL,
1762 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001763};
Guido van Rossum037b9401996-07-30 16:55:54 +00001764
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001765PyMODINIT_FUNC
Antoine Pitroua85017f2013-04-20 19:21:44 +02001766PyInit__operator(void)
Guido van Rossum037b9401996-07-30 16:55:54 +00001767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 PyObject *m;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001769
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 /* Create the module and add the functions */
1771 m = PyModule_Create(&operatormodule);
1772 if (m == NULL)
1773 return NULL;
Raymond Hettinger166958b2003-12-01 13:18:39 +00001774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 if (PyType_Ready(&itemgetter_type) < 0)
1776 return NULL;
1777 Py_INCREF(&itemgetter_type);
1778 PyModule_AddObject(m, "itemgetter", (PyObject *)&itemgetter_type);
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 if (PyType_Ready(&attrgetter_type) < 0)
1781 return NULL;
1782 Py_INCREF(&attrgetter_type);
1783 PyModule_AddObject(m, "attrgetter", (PyObject *)&attrgetter_type);
1784
1785 if (PyType_Ready(&methodcaller_type) < 0)
1786 return NULL;
1787 Py_INCREF(&methodcaller_type);
1788 PyModule_AddObject(m, "methodcaller", (PyObject *)&methodcaller_type);
1789 return m;
Guido van Rossum037b9401996-07-30 16:55:54 +00001790}