1
2 #include "Python.h"
3
4 #include "clinic/_operator.c.h"
5
6 /*[clinic input]
7 module _operator
8 [clinic start generated code]*/
9 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=672ecf48487521e7]*/
10
11 PyDoc_STRVAR(operator_doc,
12 "Operator interface.\n\
13 \n\
14 This module exports a set of functions implemented in C corresponding\n\
15 to the intrinsic operators of Python. For example, operator.add(x, y)\n\
16 is equivalent to the expression x+y. The function names are those\n\
17 used for special methods; variants without leading and trailing\n\
18 '__' are also provided for convenience.");
19
20
21 /*[clinic input]
22 _operator.truth -> bool
23
24 a: object
25 /
26
27 Return True if a is true, False otherwise.
28 [clinic start generated code]*/
29
30 static int
_operator_truth_impl(PyObject * module,PyObject * a)31 _operator_truth_impl(PyObject *module, PyObject *a)
32 /*[clinic end generated code: output=eaf87767234fa5d7 input=bc74a4cd90235875]*/
33 {
34 return PyObject_IsTrue(a);
35 }
36
37 /*[clinic input]
38 _operator.add
39
40 a: object
41 b: object
42 /
43
44 Same as a + b.
45 [clinic start generated code]*/
46
47 static PyObject *
_operator_add_impl(PyObject * module,PyObject * a,PyObject * b)48 _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
57 Same as a - b.
58 [clinic start generated code]*/
59
60 static PyObject *
_operator_sub_impl(PyObject * module,PyObject * a,PyObject * b)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
70 Same as a * b.
71 [clinic start generated code]*/
72
73 static PyObject *
_operator_mul_impl(PyObject * module,PyObject * a,PyObject * b)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
83 Same as a @ b.
84 [clinic start generated code]*/
85
86 static PyObject *
_operator_matmul_impl(PyObject * module,PyObject * a,PyObject * b)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
96 Same as a // b.
97 [clinic start generated code]*/
98
99 static PyObject *
_operator_floordiv_impl(PyObject * module,PyObject * a,PyObject * b)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
109 Same as a / b.
110 [clinic start generated code]*/
111
112 static PyObject *
_operator_truediv_impl(PyObject * module,PyObject * a,PyObject * b)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
122 Same as a % b.
123 [clinic start generated code]*/
124
125 static PyObject *
_operator_mod_impl(PyObject * module,PyObject * a,PyObject * b)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
138 Same as -a.
139 [clinic start generated code]*/
140
141 static PyObject *
_operator_neg(PyObject * module,PyObject * a)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
151 Same as +a.
152 [clinic start generated code]*/
153
154 static PyObject *
_operator_pos(PyObject * module,PyObject * a)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
164 Same as abs(a).
165 [clinic start generated code]*/
166
167 static PyObject *
_operator_abs(PyObject * module,PyObject * a)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
177 Same as ~a.
178 [clinic start generated code]*/
179
180 static PyObject *
_operator_inv(PyObject * module,PyObject * a)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
190 Same as ~a.
191 [clinic start generated code]*/
192
193 static PyObject *
_operator_invert(PyObject * module,PyObject * a)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
203 Same as a << b.
204 [clinic start generated code]*/
205
206 static PyObject *
_operator_lshift_impl(PyObject * module,PyObject * a,PyObject * b)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
216 Same as a >> b.
217 [clinic start generated code]*/
218
219 static PyObject *
_operator_rshift_impl(PyObject * module,PyObject * a,PyObject * b)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
229 Same as not a.
230 [clinic start generated code]*/
231
232 static int
_operator_not__impl(PyObject * module,PyObject * a)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
242 Same as a & b.
243 [clinic start generated code]*/
244
245 static PyObject *
_operator_and__impl(PyObject * module,PyObject * a,PyObject * b)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
255 Same as a ^ b.
256 [clinic start generated code]*/
257
258 static PyObject *
_operator_xor_impl(PyObject * module,PyObject * a,PyObject * b)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
268 Same as a | b.
269 [clinic start generated code]*/
270
271 static PyObject *
_operator_or__impl(PyObject * module,PyObject * a,PyObject * b)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
281 Same as a += b.
282 [clinic start generated code]*/
283
284 static PyObject *
_operator_iadd_impl(PyObject * module,PyObject * a,PyObject * b)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
294 Same as a -= b.
295 [clinic start generated code]*/
296
297 static PyObject *
_operator_isub_impl(PyObject * module,PyObject * a,PyObject * b)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
307 Same as a *= b.
308 [clinic start generated code]*/
309
310 static PyObject *
_operator_imul_impl(PyObject * module,PyObject * a,PyObject * b)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
320 Same as a @= b.
321 [clinic start generated code]*/
322
323 static PyObject *
_operator_imatmul_impl(PyObject * module,PyObject * a,PyObject * b)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
333 Same as a //= b.
334 [clinic start generated code]*/
335
336 static PyObject *
_operator_ifloordiv_impl(PyObject * module,PyObject * a,PyObject * b)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
346 Same as a /= b.
347 [clinic start generated code]*/
348
349 static PyObject *
_operator_itruediv_impl(PyObject * module,PyObject * a,PyObject * b)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
359 Same as a %= b.
360 [clinic start generated code]*/
361
362 static PyObject *
_operator_imod_impl(PyObject * module,PyObject * a,PyObject * b)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
372 Same as a <<= b.
373 [clinic start generated code]*/
374
375 static PyObject *
_operator_ilshift_impl(PyObject * module,PyObject * a,PyObject * b)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
385 Same as a >>= b.
386 [clinic start generated code]*/
387
388 static PyObject *
_operator_irshift_impl(PyObject * module,PyObject * a,PyObject * b)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
398 Same as a &= b.
399 [clinic start generated code]*/
400
401 static PyObject *
_operator_iand_impl(PyObject * module,PyObject * a,PyObject * b)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
411 Same as a ^= b.
412 [clinic start generated code]*/
413
414 static PyObject *
_operator_ixor_impl(PyObject * module,PyObject * a,PyObject * b)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
424 Same as a |= b.
425 [clinic start generated code]*/
426
427 static PyObject *
_operator_ior_impl(PyObject * module,PyObject * a,PyObject * b)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
437 Same as a + b, for a and b sequences.
438 [clinic start generated code]*/
439
440 static PyObject *
_operator_concat_impl(PyObject * module,PyObject * a,PyObject * b)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
450 Same as a += b, for a and b sequences.
451 [clinic start generated code]*/
452
453 static PyObject *
_operator_iconcat_impl(PyObject * module,PyObject * a,PyObject * b)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
467 Same as b in a (note reversed operands).
468 [clinic start generated code]*/
469
470 static int
_operator_contains_impl(PyObject * module,PyObject * a,PyObject * b)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
484 Return the first index of b in a.
485 [clinic start generated code]*/
486
487 static Py_ssize_t
_operator_indexOf_impl(PyObject * module,PyObject * a,PyObject * b)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
497 Return the number of times b occurs in a.
498 [clinic start generated code]*/
499
500 static Py_ssize_t
_operator_countOf_impl(PyObject * module,PyObject * a,PyObject * b)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
514 Same as a[b].
515 [clinic start generated code]*/
516
517 static PyObject *
_operator_getitem_impl(PyObject * module,PyObject * a,PyObject * b)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
532 Same as a[b] = c.
533 [clinic start generated code]*/
534
535 static PyObject *
_operator_setitem_impl(PyObject * module,PyObject * a,PyObject * b,PyObject * c)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
548 Same as del a[b].
549 [clinic start generated code]*/
550
551 static PyObject *
_operator_delitem_impl(PyObject * module,PyObject * a,PyObject * b)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
567 Same as a == b.
568 [clinic start generated code]*/
569
570 static PyObject *
_operator_eq_impl(PyObject * module,PyObject * a,PyObject * b)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
580 Same as a != b.
581 [clinic start generated code]*/
582
583 static PyObject *
_operator_ne_impl(PyObject * module,PyObject * a,PyObject * b)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
593 Same as a < b.
594 [clinic start generated code]*/
595
596 static PyObject *
_operator_lt_impl(PyObject * module,PyObject * a,PyObject * b)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
606 Same as a <= b.
607 [clinic start generated code]*/
608
609 static PyObject *
_operator_le_impl(PyObject * module,PyObject * a,PyObject * b)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
619 Same as a > b.
620 [clinic start generated code]*/
621
622 static PyObject *
_operator_gt_impl(PyObject * module,PyObject * a,PyObject * b)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
632 Same as a >= b.
633 [clinic start generated code]*/
634
635 static PyObject *
_operator_ge_impl(PyObject * module,PyObject * a,PyObject * b)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
645 Same as a ** b.
646 [clinic start generated code]*/
647
648 static PyObject *
_operator_pow_impl(PyObject * module,PyObject * a,PyObject * b)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
658 Same as a **= b.
659 [clinic start generated code]*/
660
661 static PyObject *
_operator_ipow_impl(PyObject * module,PyObject * a,PyObject * b)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
674 Same as a.__index__()
675 [clinic start generated code]*/
676
677 static PyObject *
_operator_index(PyObject * module,PyObject * a)678 _operator_index(PyObject *module, PyObject *a)
679 /*[clinic end generated code: output=d972b0764ac305fc input=6f54d50ea64a579c]*/
680 {
681 return PyNumber_Index(a);
682 }
683
684 /*[clinic input]
685 _operator.is_ = _operator.add
686
687 Same as a is b.
688 [clinic start generated code]*/
689
690 static PyObject *
_operator_is__impl(PyObject * module,PyObject * a,PyObject * b)691 _operator_is__impl(PyObject *module, PyObject *a, PyObject *b)
692 /*[clinic end generated code: output=bcd47a402e482e1d input=5fa9b97df03c427f]*/
693 {
694 PyObject *result;
695 result = (a == b) ? Py_True : Py_False;
696 Py_INCREF(result);
697 return result;
698 }
699
700 /*[clinic input]
701 _operator.is_not = _operator.add
702
703 Same as a is not b.
704 [clinic start generated code]*/
705
706 static PyObject *
_operator_is_not_impl(PyObject * module,PyObject * a,PyObject * b)707 _operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b)
708 /*[clinic end generated code: output=491a1f2f81f6c7f9 input=5a93f7e1a93535f1]*/
709 {
710 PyObject *result;
711 result = (a != b) ? Py_True : Py_False;
712 Py_INCREF(result);
713 return result;
714 }
715
716 /* 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 */
726 static int
_tscmp(const unsigned char * a,const unsigned char * b,Py_ssize_t len_a,Py_ssize_t len_b)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 volatile 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
764 /*[clinic input]
765 _operator.length_hint -> Py_ssize_t
766
767 obj: object
768 default: Py_ssize_t = 0
769 /
770
771 Return an estimate of the number of items in obj.
772
773 This is useful for presizing containers when building from an iterable.
774
775 If the object supports len(), the result will be exact.
776 Otherwise, it may over- or under-estimate by an arbitrary amount.
777 The result will be an integer >= 0.
778 [clinic start generated code]*/
779
780 static Py_ssize_t
_operator_length_hint_impl(PyObject * module,PyObject * obj,Py_ssize_t default_value)781 _operator_length_hint_impl(PyObject *module, PyObject *obj,
782 Py_ssize_t default_value)
783 /*[clinic end generated code: output=01d469edc1d612ad input=65ed29f04401e96a]*/
784 {
785 return PyObject_LengthHint(obj, default_value);
786 }
787
788 /*[clinic input]
789 _operator._compare_digest = _operator.eq
790
791 Return 'a == b'.
792
793 This function uses an approach designed to prevent
794 timing analysis, making it appropriate for cryptography.
795
796 a and b must both be of the same type: either str (ASCII only),
797 or any bytes-like object.
798
799 Note: If a and b are of different lengths, or if an error occurs,
800 a timing attack could theoretically reveal information about the
801 types and lengths of a and b--but not their values.
802 [clinic start generated code]*/
803
804 static PyObject *
_operator__compare_digest_impl(PyObject * module,PyObject * a,PyObject * b)805 _operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b)
806 /*[clinic end generated code: output=11d452bdd3a23cbc input=9ac7e2c4e30bc356]*/
807 {
808 int rc;
809
810 /* 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
832 if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) {
833 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
871 return PyBool_FromLong(rc);
872 }
873
874 /* operator methods **********************************************************/
875
876 static struct PyMethodDef operator_methods[] = {
877
878 _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
930 {NULL, NULL} /* sentinel */
931
932 };
933
934 /* itemgetter object **********************************************************/
935
936 typedef struct {
937 PyObject_HEAD
938 Py_ssize_t nitems;
939 PyObject *item;
940 Py_ssize_t index; // -1 unless *item* is a single non-negative integer index
941 } itemgetterobject;
942
943 static PyTypeObject itemgetter_type;
944
945 /* AC 3.5: treats first argument as an iterable, otherwise uses *args */
946 static PyObject *
itemgetter_new(PyTypeObject * type,PyObject * args,PyObject * kwds)947 itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
948 {
949 itemgetterobject *ig;
950 PyObject *item;
951 Py_ssize_t nitems;
952 Py_ssize_t index;
953
954 if (!_PyArg_NoKeywords("itemgetter", kwds))
955 return NULL;
956
957 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;
963
964 /* create itemgetterobject structure */
965 ig = PyObject_GC_New(itemgetterobject, &itemgetter_type);
966 if (ig == NULL)
967 return NULL;
968
969 Py_INCREF(item);
970 ig->item = item;
971 ig->nitems = nitems;
972 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 }
987
988 PyObject_GC_Track(ig);
989 return (PyObject *)ig;
990 }
991
992 static void
itemgetter_dealloc(itemgetterobject * ig)993 itemgetter_dealloc(itemgetterobject *ig)
994 {
995 PyObject_GC_UnTrack(ig);
996 Py_XDECREF(ig->item);
997 PyObject_GC_Del(ig);
998 }
999
1000 static int
itemgetter_traverse(itemgetterobject * ig,visitproc visit,void * arg)1001 itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
1002 {
1003 Py_VISIT(ig->item);
1004 return 0;
1005 }
1006
1007 static PyObject *
itemgetter_call(itemgetterobject * ig,PyObject * args,PyObject * kw)1008 itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
1009 {
1010 PyObject *obj, *result;
1011 Py_ssize_t i, nitems=ig->nitems;
1012
1013 assert(PyTuple_CheckExact(args));
1014 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);
1020 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 }
1029 return PyObject_GetItem(obj, ig->item);
1030 }
1031
1032 assert(PyTuple_Check(ig->item));
1033 assert(PyTuple_GET_SIZE(ig->item) == nitems);
1034
1035 result = PyTuple_New(nitems);
1036 if (result == NULL)
1037 return NULL;
1038
1039 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;
1050 }
1051
1052 static PyObject *
itemgetter_repr(itemgetterobject * ig)1053 itemgetter_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
1071 static PyObject *
itemgetter_reduce(itemgetterobject * ig,PyObject * Py_UNUSED (ignored))1072 itemgetter_reduce(itemgetterobject *ig, PyObject *Py_UNUSED(ignored))
1073 {
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
1079 PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1080
1081 static PyMethodDef itemgetter_methods[] = {
1082 {"__reduce__", (PyCFunction)itemgetter_reduce, METH_NOARGS,
1083 reduce_doc},
1084 {NULL}
1085 };
1086
1087 PyDoc_STRVAR(itemgetter_doc,
1088 "itemgetter(item, ...) --> itemgetter object\n\
1089 \n\
1090 Return a callable object that fetches the given item(s) from its operand.\n\
1091 After f = itemgetter(2), the call f(r) returns r[2].\n\
1092 After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])");
1093
1094 static PyTypeObject itemgetter_type = {
1095 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_vectorcall_offset */
1102 0, /* tp_getattr */
1103 0, /* tp_setattr */
1104 0, /* tp_as_async */
1105 (reprfunc)itemgetter_repr, /* tp_repr */
1106 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 */
1123 itemgetter_methods, /* tp_methods */
1124 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 */
1135 };
1136
1137
1138 /* attrgetter object **********************************************************/
1139
1140 typedef struct {
1141 PyObject_HEAD
1142 Py_ssize_t nattrs;
1143 PyObject *attr;
1144 } attrgetterobject;
1145
1146 static PyTypeObject attrgetter_type;
1147
1148 /* AC 3.5: treats first argument as an iterable, otherwise uses *args */
1149 static PyObject *
attrgetter_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1150 attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1151 {
1152 attrgetterobject *ag;
1153 PyObject *attr;
1154 Py_ssize_t nattrs, idx, char_idx;
1155
1156 if (!_PyArg_NoKeywords("attrgetter", kwds))
1157 return NULL;
1158
1159 nattrs = PyTuple_GET_SIZE(args);
1160 if (nattrs <= 1) {
1161 if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
1162 return NULL;
1163 }
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;
1173 void *data;
1174 unsigned int kind;
1175 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 }
1183 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);
1190
1191 /* check whethere the string is dotted */
1192 dot_count = 0;
1193 for (char_idx = 0; char_idx < item_len; ++char_idx) {
1194 if (PyUnicode_READ(kind, data, char_idx) == '.')
1195 ++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;
1205 Py_ssize_t unibuff_from = 0;
1206 Py_ssize_t unibuff_till = 0;
1207 Py_ssize_t attr_chain_idx = 0;
1208
1209 if (attr_chain == NULL) {
1210 Py_DECREF(attr);
1211 return NULL;
1212 }
1213
1214 for (; dot_count > 0; --dot_count) {
1215 while (PyUnicode_READ(kind, data, unibuff_till) != '.') {
1216 ++unibuff_till;
1217 }
1218 attr_chain_item = PyUnicode_Substring(item,
1219 unibuff_from,
1220 unibuff_till);
1221 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 */
1233 attr_chain_item = PyUnicode_Substring(item,
1234 unibuff_from, item_len);
1235 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 }
1246
1247 /* create attrgetterobject structure */
1248 ag = PyObject_GC_New(attrgetterobject, &attrgetter_type);
1249 if (ag == NULL) {
1250 Py_DECREF(attr);
1251 return NULL;
1252 }
1253
1254 ag->attr = attr;
1255 ag->nattrs = nattrs;
1256
1257 PyObject_GC_Track(ag);
1258 return (PyObject *)ag;
1259 }
1260
1261 static void
attrgetter_dealloc(attrgetterobject * ag)1262 attrgetter_dealloc(attrgetterobject *ag)
1263 {
1264 PyObject_GC_UnTrack(ag);
1265 Py_XDECREF(ag->attr);
1266 PyObject_GC_Del(ag);
1267 }
1268
1269 static int
attrgetter_traverse(attrgetterobject * ag,visitproc visit,void * arg)1270 attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
1271 {
1272 Py_VISIT(ag->attr);
1273 return 0;
1274 }
1275
1276 static PyObject *
dotted_getattr(PyObject * obj,PyObject * attr)1277 dotted_getattr(PyObject *obj, PyObject *attr)
1278 {
1279 PyObject *newobj;
1280
1281 /* 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;
1286
1287 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);
1292 Py_DECREF(obj);
1293 if (newobj == NULL) {
1294 return NULL;
1295 }
1296 /* here */
1297 obj = newobj;
1298 }
1299 } else { /* single getattr */
1300 newobj = PyObject_GetAttr(obj, attr);
1301 if (newobj == NULL)
1302 return NULL;
1303 obj = newobj;
1304 }
1305
1306 return obj;
1307 }
1308
1309 static PyObject *
attrgetter_call(attrgetterobject * ag,PyObject * args,PyObject * kw)1310 attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
1311 {
1312 PyObject *obj, *result;
1313 Py_ssize_t i, nattrs=ag->nattrs;
1314
1315 if (!_PyArg_NoKeywords("attrgetter", kw))
1316 return NULL;
1317 if (!_PyArg_CheckPositional("attrgetter", PyTuple_GET_SIZE(args), 1, 1))
1318 return NULL;
1319 obj = PyTuple_GET_ITEM(args, 0);
1320 if (ag->nattrs == 1) /* ag->attr is always a tuple */
1321 return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0));
1322
1323 assert(PyTuple_Check(ag->attr));
1324 assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
1325
1326 result = PyTuple_New(nattrs);
1327 if (result == NULL)
1328 return NULL;
1329
1330 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;
1341 }
1342
1343 static PyObject *
dotjoinattr(PyObject * attr,PyObject ** attrsep)1344 dotjoinattr(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
1359 static PyObject *
attrgetter_args(attrgetterobject * ag)1360 attrgetter_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
1382 static PyObject *
attrgetter_repr(attrgetterobject * ag)1383 attrgetter_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);
1396 if (attr != NULL) {
1397 repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(ag)->tp_name, attr);
1398 Py_DECREF(attr);
1399 }
1400 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
1414 static PyObject *
attrgetter_reduce(attrgetterobject * ag,PyObject * Py_UNUSED (ignored))1415 attrgetter_reduce(attrgetterobject *ag, PyObject *Py_UNUSED(ignored))
1416 {
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
1424 static PyMethodDef attrgetter_methods[] = {
1425 {"__reduce__", (PyCFunction)attrgetter_reduce, METH_NOARGS,
1426 reduce_doc},
1427 {NULL}
1428 };
1429
1430 PyDoc_STRVAR(attrgetter_doc,
1431 "attrgetter(attr, ...) --> attrgetter object\n\
1432 \n\
1433 Return a callable object that fetches the given attribute(s) from its operand.\n\
1434 After f = attrgetter('name'), the call f(r) returns r.name.\n\
1435 After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\
1436 After h = attrgetter('name.first', 'name.last'), the call h(r) returns\n\
1437 (r.name.first, r.name.last).");
1438
1439 static PyTypeObject attrgetter_type = {
1440 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_vectorcall_offset */
1447 0, /* tp_getattr */
1448 0, /* tp_setattr */
1449 0, /* tp_as_async */
1450 (reprfunc)attrgetter_repr, /* tp_repr */
1451 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 */
1468 attrgetter_methods, /* tp_methods */
1469 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 */
1480 };
1481
1482
1483 /* methodcaller object **********************************************************/
1484
1485 typedef struct {
1486 PyObject_HEAD
1487 PyObject *name;
1488 PyObject *args;
1489 PyObject *kwds;
1490 } methodcallerobject;
1491
1492 static PyTypeObject methodcaller_type;
1493
1494 /* AC 3.5: variable number of arguments, not currently support by AC */
1495 static PyObject *
methodcaller_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1496 methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1497 {
1498 methodcallerobject *mc;
1499 PyObject *name;
1500
1501 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 }
1506
1507 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
1514 /* create methodcallerobject structure */
1515 mc = PyObject_GC_New(methodcallerobject, &methodcaller_type);
1516 if (mc == NULL)
1517 return NULL;
1518
1519 name = PyTuple_GET_ITEM(args, 0);
1520 Py_INCREF(name);
1521 PyUnicode_InternInPlace(&name);
1522 mc->name = name;
1523
1524 Py_XINCREF(kwds);
1525 mc->kwds = kwds;
1526
1527 mc->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
1528 if (mc->args == NULL) {
1529 Py_DECREF(mc);
1530 return NULL;
1531 }
1532
1533 PyObject_GC_Track(mc);
1534 return (PyObject *)mc;
1535 }
1536
1537 static void
methodcaller_dealloc(methodcallerobject * mc)1538 methodcaller_dealloc(methodcallerobject *mc)
1539 {
1540 PyObject_GC_UnTrack(mc);
1541 Py_XDECREF(mc->name);
1542 Py_XDECREF(mc->args);
1543 Py_XDECREF(mc->kwds);
1544 PyObject_GC_Del(mc);
1545 }
1546
1547 static int
methodcaller_traverse(methodcallerobject * mc,visitproc visit,void * arg)1548 methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
1549 {
1550 Py_VISIT(mc->args);
1551 Py_VISIT(mc->kwds);
1552 return 0;
1553 }
1554
1555 static PyObject *
methodcaller_call(methodcallerobject * mc,PyObject * args,PyObject * kw)1556 methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw)
1557 {
1558 PyObject *method, *obj, *result;
1559
1560 if (!_PyArg_NoKeywords("methodcaller", kw))
1561 return NULL;
1562 if (!_PyArg_CheckPositional("methodcaller", PyTuple_GET_SIZE(args), 1, 1))
1563 return NULL;
1564 obj = PyTuple_GET_ITEM(args, 0);
1565 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;
1571 }
1572
1573 static PyObject *
methodcaller_repr(methodcallerobject * mc)1574 methodcaller_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
1585 numkwdargs = mc->kwds != NULL ? PyDict_GET_SIZE(mc->kwds) : 0;
1586 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;
1617 Py_DECREF(onerepr);
1618 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
1643 done:
1644 Py_DECREF(argreprs);
1645 Py_ReprLeave((PyObject *)mc);
1646 return repr;
1647 }
1648
1649 static PyObject *
methodcaller_reduce(methodcallerobject * mc,PyObject * Py_UNUSED (ignored))1650 methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored))
1651 {
1652 PyObject *newargs;
1653 if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) {
1654 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;
1672 PyObject *newargs[2];
1673
1674 _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;
1682
1683 newargs[0] = (PyObject *)Py_TYPE(mc);
1684 newargs[1] = mc->name;
1685 constructor = _PyObject_FastCallDict(partial, newargs, 2, mc->kwds);
1686
1687 Py_DECREF(partial);
1688 return Py_BuildValue("NO", constructor, mc->args);
1689 }
1690 }
1691
1692 static PyMethodDef methodcaller_methods[] = {
1693 {"__reduce__", (PyCFunction)methodcaller_reduce, METH_NOARGS,
1694 reduce_doc},
1695 {NULL}
1696 };
1697 PyDoc_STRVAR(methodcaller_doc,
1698 "methodcaller(name, ...) --> methodcaller object\n\
1699 \n\
1700 Return a callable object that calls the given method on its operand.\n\
1701 After f = methodcaller('name'), the call f(r) returns r.name().\n\
1702 After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\
1703 r.name('date', foo=1).");
1704
1705 static PyTypeObject methodcaller_type = {
1706 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_vectorcall_offset */
1713 0, /* tp_getattr */
1714 0, /* tp_setattr */
1715 0, /* tp_as_async */
1716 (reprfunc)methodcaller_repr, /* tp_repr */
1717 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 */
1734 methodcaller_methods, /* tp_methods */
1735 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 */
1746 };
1747
1748
1749 /* Initialization function for the module (*must* be called PyInit__operator) */
1750
1751
1752 static struct PyModuleDef operatormodule = {
1753 PyModuleDef_HEAD_INIT,
1754 "_operator",
1755 operator_doc,
1756 -1,
1757 operator_methods,
1758 NULL,
1759 NULL,
1760 NULL,
1761 NULL
1762 };
1763
1764 PyMODINIT_FUNC
PyInit__operator(void)1765 PyInit__operator(void)
1766 {
1767 PyObject *m;
1768
1769 /* Create the module and add the functions */
1770 m = PyModule_Create(&operatormodule);
1771 if (m == NULL)
1772 return NULL;
1773
1774 if (PyType_Ready(&itemgetter_type) < 0)
1775 return NULL;
1776 Py_INCREF(&itemgetter_type);
1777 PyModule_AddObject(m, "itemgetter", (PyObject *)&itemgetter_type);
1778
1779 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;
1789 }
1790