Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/cpython
Path: blob/main/Modules/_operator.c
12 views
1
#include "Python.h"
2
#include "pycore_moduleobject.h" // _PyModule_GetState()
3
#include "structmember.h" // PyMemberDef
4
#include "pycore_runtime.h" // _Py_ID()
5
#include "clinic/_operator.c.h"
6
7
typedef struct {
8
PyObject *itemgetter_type;
9
PyObject *attrgetter_type;
10
PyObject *methodcaller_type;
11
} _operator_state;
12
13
static inline _operator_state*
14
get_operator_state(PyObject *module)
15
{
16
void *state = _PyModule_GetState(module);
17
assert(state != NULL);
18
return (_operator_state *)state;
19
}
20
21
/*[clinic input]
22
module _operator
23
[clinic start generated code]*/
24
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=672ecf48487521e7]*/
25
26
PyDoc_STRVAR(operator_doc,
27
"Operator interface.\n\
28
\n\
29
This module exports a set of functions implemented in C corresponding\n\
30
to the intrinsic operators of Python. For example, operator.add(x, y)\n\
31
is equivalent to the expression x+y. The function names are those\n\
32
used for special methods; variants without leading and trailing\n\
33
'__' are also provided for convenience.");
34
35
36
/*[clinic input]
37
_operator.truth -> bool
38
39
a: object
40
/
41
42
Return True if a is true, False otherwise.
43
[clinic start generated code]*/
44
45
static int
46
_operator_truth_impl(PyObject *module, PyObject *a)
47
/*[clinic end generated code: output=eaf87767234fa5d7 input=bc74a4cd90235875]*/
48
{
49
return PyObject_IsTrue(a);
50
}
51
52
/*[clinic input]
53
_operator.add
54
55
a: object
56
b: object
57
/
58
59
Same as a + b.
60
[clinic start generated code]*/
61
62
static PyObject *
63
_operator_add_impl(PyObject *module, PyObject *a, PyObject *b)
64
/*[clinic end generated code: output=8292984204f45164 input=5efe3bff856ac215]*/
65
{
66
return PyNumber_Add(a, b);
67
}
68
69
/*[clinic input]
70
_operator.sub = _operator.add
71
72
Same as a - b.
73
[clinic start generated code]*/
74
75
static PyObject *
76
_operator_sub_impl(PyObject *module, PyObject *a, PyObject *b)
77
/*[clinic end generated code: output=4adfc3b888c1ee2e input=6494c6b100b8e795]*/
78
{
79
return PyNumber_Subtract(a, b);
80
}
81
82
/*[clinic input]
83
_operator.mul = _operator.add
84
85
Same as a * b.
86
[clinic start generated code]*/
87
88
static PyObject *
89
_operator_mul_impl(PyObject *module, PyObject *a, PyObject *b)
90
/*[clinic end generated code: output=d24d66f55a01944c input=2368615b4358b70d]*/
91
{
92
return PyNumber_Multiply(a, b);
93
}
94
95
/*[clinic input]
96
_operator.matmul = _operator.add
97
98
Same as a @ b.
99
[clinic start generated code]*/
100
101
static PyObject *
102
_operator_matmul_impl(PyObject *module, PyObject *a, PyObject *b)
103
/*[clinic end generated code: output=a20d917eb35d0101 input=9ab304e37fb42dd4]*/
104
{
105
return PyNumber_MatrixMultiply(a, b);
106
}
107
108
/*[clinic input]
109
_operator.floordiv = _operator.add
110
111
Same as a // b.
112
[clinic start generated code]*/
113
114
static PyObject *
115
_operator_floordiv_impl(PyObject *module, PyObject *a, PyObject *b)
116
/*[clinic end generated code: output=df26b71a60589f99 input=bb2e88ba446c612c]*/
117
{
118
return PyNumber_FloorDivide(a, b);
119
}
120
121
/*[clinic input]
122
_operator.truediv = _operator.add
123
124
Same as a / b.
125
[clinic start generated code]*/
126
127
static PyObject *
128
_operator_truediv_impl(PyObject *module, PyObject *a, PyObject *b)
129
/*[clinic end generated code: output=0e6a959944d77719 input=ecbb947673f4eb1f]*/
130
{
131
return PyNumber_TrueDivide(a, b);
132
}
133
134
/*[clinic input]
135
_operator.mod = _operator.add
136
137
Same as a % b.
138
[clinic start generated code]*/
139
140
static PyObject *
141
_operator_mod_impl(PyObject *module, PyObject *a, PyObject *b)
142
/*[clinic end generated code: output=9519822f0bbec166 input=102e19b422342ac1]*/
143
{
144
return PyNumber_Remainder(a, b);
145
}
146
147
/*[clinic input]
148
_operator.neg
149
150
a: object
151
/
152
153
Same as -a.
154
[clinic start generated code]*/
155
156
static PyObject *
157
_operator_neg(PyObject *module, PyObject *a)
158
/*[clinic end generated code: output=36e08ecfc6a1c08c input=84f09bdcf27c96ec]*/
159
{
160
return PyNumber_Negative(a);
161
}
162
163
/*[clinic input]
164
_operator.pos = _operator.neg
165
166
Same as +a.
167
[clinic start generated code]*/
168
169
static PyObject *
170
_operator_pos(PyObject *module, PyObject *a)
171
/*[clinic end generated code: output=dad7a126221dd091 input=b6445b63fddb8772]*/
172
{
173
return PyNumber_Positive(a);
174
}
175
176
/*[clinic input]
177
_operator.abs = _operator.neg
178
179
Same as abs(a).
180
[clinic start generated code]*/
181
182
static PyObject *
183
_operator_abs(PyObject *module, PyObject *a)
184
/*[clinic end generated code: output=1389a93ba053ea3e input=341d07ba86f58039]*/
185
{
186
return PyNumber_Absolute(a);
187
}
188
189
/*[clinic input]
190
_operator.inv = _operator.neg
191
192
Same as ~a.
193
[clinic start generated code]*/
194
195
static PyObject *
196
_operator_inv(PyObject *module, PyObject *a)
197
/*[clinic end generated code: output=a56875ba075ee06d input=b01a4677739f6eb2]*/
198
{
199
return PyNumber_Invert(a);
200
}
201
202
/*[clinic input]
203
_operator.invert = _operator.neg
204
205
Same as ~a.
206
[clinic start generated code]*/
207
208
static PyObject *
209
_operator_invert(PyObject *module, PyObject *a)
210
/*[clinic end generated code: output=406b5aa030545fcc input=7f2d607176672e55]*/
211
{
212
return PyNumber_Invert(a);
213
}
214
215
/*[clinic input]
216
_operator.lshift = _operator.add
217
218
Same as a << b.
219
[clinic start generated code]*/
220
221
static PyObject *
222
_operator_lshift_impl(PyObject *module, PyObject *a, PyObject *b)
223
/*[clinic end generated code: output=37f7e52c41435bd8 input=746e8a160cbbc9eb]*/
224
{
225
return PyNumber_Lshift(a, b);
226
}
227
228
/*[clinic input]
229
_operator.rshift = _operator.add
230
231
Same as a >> b.
232
[clinic start generated code]*/
233
234
static PyObject *
235
_operator_rshift_impl(PyObject *module, PyObject *a, PyObject *b)
236
/*[clinic end generated code: output=4593c7ef30ec2ee3 input=d2c85bb5a64504c2]*/
237
{
238
return PyNumber_Rshift(a, b);
239
}
240
241
/*[clinic input]
242
_operator.not_ = _operator.truth
243
244
Same as not a.
245
[clinic start generated code]*/
246
247
static int
248
_operator_not__impl(PyObject *module, PyObject *a)
249
/*[clinic end generated code: output=743f9c24a09759ef input=854156d50804d9b8]*/
250
{
251
return PyObject_Not(a);
252
}
253
254
/*[clinic input]
255
_operator.and_ = _operator.add
256
257
Same as a & b.
258
[clinic start generated code]*/
259
260
static PyObject *
261
_operator_and__impl(PyObject *module, PyObject *a, PyObject *b)
262
/*[clinic end generated code: output=93c4fe88f7b76d9e input=4f3057c90ec4c99f]*/
263
{
264
return PyNumber_And(a, b);
265
}
266
267
/*[clinic input]
268
_operator.xor = _operator.add
269
270
Same as a ^ b.
271
[clinic start generated code]*/
272
273
static PyObject *
274
_operator_xor_impl(PyObject *module, PyObject *a, PyObject *b)
275
/*[clinic end generated code: output=b24cd8b79fde0004 input=3c5cfa7253d808dd]*/
276
{
277
return PyNumber_Xor(a, b);
278
}
279
280
/*[clinic input]
281
_operator.or_ = _operator.add
282
283
Same as a | b.
284
[clinic start generated code]*/
285
286
static PyObject *
287
_operator_or__impl(PyObject *module, PyObject *a, PyObject *b)
288
/*[clinic end generated code: output=58024867b8d90461 input=b40c6c44f7c79c09]*/
289
{
290
return PyNumber_Or(a, b);
291
}
292
293
/*[clinic input]
294
_operator.iadd = _operator.add
295
296
Same as a += b.
297
[clinic start generated code]*/
298
299
static PyObject *
300
_operator_iadd_impl(PyObject *module, PyObject *a, PyObject *b)
301
/*[clinic end generated code: output=07dc627832526eb5 input=d22a91c07ac69227]*/
302
{
303
return PyNumber_InPlaceAdd(a, b);
304
}
305
306
/*[clinic input]
307
_operator.isub = _operator.add
308
309
Same as a -= b.
310
[clinic start generated code]*/
311
312
static PyObject *
313
_operator_isub_impl(PyObject *module, PyObject *a, PyObject *b)
314
/*[clinic end generated code: output=4513467d23b5e0b1 input=4591b00d0a0ccafd]*/
315
{
316
return PyNumber_InPlaceSubtract(a, b);
317
}
318
319
/*[clinic input]
320
_operator.imul = _operator.add
321
322
Same as a *= b.
323
[clinic start generated code]*/
324
325
static PyObject *
326
_operator_imul_impl(PyObject *module, PyObject *a, PyObject *b)
327
/*[clinic end generated code: output=5e87dacd19a71eab input=0e01fb8631e1b76f]*/
328
{
329
return PyNumber_InPlaceMultiply(a, b);
330
}
331
332
/*[clinic input]
333
_operator.imatmul = _operator.add
334
335
Same as a @= b.
336
[clinic start generated code]*/
337
338
static PyObject *
339
_operator_imatmul_impl(PyObject *module, PyObject *a, PyObject *b)
340
/*[clinic end generated code: output=d603cbdf716ce519 input=bb614026372cd542]*/
341
{
342
return PyNumber_InPlaceMatrixMultiply(a, b);
343
}
344
345
/*[clinic input]
346
_operator.ifloordiv = _operator.add
347
348
Same as a //= b.
349
[clinic start generated code]*/
350
351
static PyObject *
352
_operator_ifloordiv_impl(PyObject *module, PyObject *a, PyObject *b)
353
/*[clinic end generated code: output=535336048c681794 input=9df3b5021cff4ca1]*/
354
{
355
return PyNumber_InPlaceFloorDivide(a, b);
356
}
357
358
/*[clinic input]
359
_operator.itruediv = _operator.add
360
361
Same as a /= b.
362
[clinic start generated code]*/
363
364
static PyObject *
365
_operator_itruediv_impl(PyObject *module, PyObject *a, PyObject *b)
366
/*[clinic end generated code: output=28017fbd3563952f input=9a1ee01608f5f590]*/
367
{
368
return PyNumber_InPlaceTrueDivide(a, b);
369
}
370
371
/*[clinic input]
372
_operator.imod = _operator.add
373
374
Same as a %= b.
375
[clinic start generated code]*/
376
377
static PyObject *
378
_operator_imod_impl(PyObject *module, PyObject *a, PyObject *b)
379
/*[clinic end generated code: output=f7c540ae0fc70904 input=d0c384a3ce38e1dd]*/
380
{
381
return PyNumber_InPlaceRemainder(a, b);
382
}
383
384
/*[clinic input]
385
_operator.ilshift = _operator.add
386
387
Same as a <<= b.
388
[clinic start generated code]*/
389
390
static PyObject *
391
_operator_ilshift_impl(PyObject *module, PyObject *a, PyObject *b)
392
/*[clinic end generated code: output=e73a8fee1ac18749 input=e21b6b310f54572e]*/
393
{
394
return PyNumber_InPlaceLshift(a, b);
395
}
396
397
/*[clinic input]
398
_operator.irshift = _operator.add
399
400
Same as a >>= b.
401
[clinic start generated code]*/
402
403
static PyObject *
404
_operator_irshift_impl(PyObject *module, PyObject *a, PyObject *b)
405
/*[clinic end generated code: output=97f2af6b5ff2ed81 input=6778dbd0f6e1ec16]*/
406
{
407
return PyNumber_InPlaceRshift(a, b);
408
}
409
410
/*[clinic input]
411
_operator.iand = _operator.add
412
413
Same as a &= b.
414
[clinic start generated code]*/
415
416
static PyObject *
417
_operator_iand_impl(PyObject *module, PyObject *a, PyObject *b)
418
/*[clinic end generated code: output=4599e9d40cbf7d00 input=71dfd8e70c156a7b]*/
419
{
420
return PyNumber_InPlaceAnd(a, b);
421
}
422
423
/*[clinic input]
424
_operator.ixor = _operator.add
425
426
Same as a ^= b.
427
[clinic start generated code]*/
428
429
static PyObject *
430
_operator_ixor_impl(PyObject *module, PyObject *a, PyObject *b)
431
/*[clinic end generated code: output=5ff881766872be03 input=695c32bec0604d86]*/
432
{
433
return PyNumber_InPlaceXor(a, b);
434
}
435
436
/*[clinic input]
437
_operator.ior = _operator.add
438
439
Same as a |= b.
440
[clinic start generated code]*/
441
442
static PyObject *
443
_operator_ior_impl(PyObject *module, PyObject *a, PyObject *b)
444
/*[clinic end generated code: output=48aac319445bf759 input=8f01d03eda9920cf]*/
445
{
446
return PyNumber_InPlaceOr(a, b);
447
}
448
449
/*[clinic input]
450
_operator.concat = _operator.add
451
452
Same as a + b, for a and b sequences.
453
[clinic start generated code]*/
454
455
static PyObject *
456
_operator_concat_impl(PyObject *module, PyObject *a, PyObject *b)
457
/*[clinic end generated code: output=80028390942c5f11 input=8544ccd5341a3658]*/
458
{
459
return PySequence_Concat(a, b);
460
}
461
462
/*[clinic input]
463
_operator.iconcat = _operator.add
464
465
Same as a += b, for a and b sequences.
466
[clinic start generated code]*/
467
468
static PyObject *
469
_operator_iconcat_impl(PyObject *module, PyObject *a, PyObject *b)
470
/*[clinic end generated code: output=3ea0a162ebb2e26d input=8f5fe5722fcd837e]*/
471
{
472
return PySequence_InPlaceConcat(a, b);
473
}
474
475
/*[clinic input]
476
_operator.contains -> bool
477
478
a: object
479
b: object
480
/
481
482
Same as b in a (note reversed operands).
483
[clinic start generated code]*/
484
485
static int
486
_operator_contains_impl(PyObject *module, PyObject *a, PyObject *b)
487
/*[clinic end generated code: output=413b4dbe82b6ffc1 input=9122a69b505fde13]*/
488
{
489
return PySequence_Contains(a, b);
490
}
491
492
/*[clinic input]
493
_operator.indexOf -> Py_ssize_t
494
495
a: object
496
b: object
497
/
498
499
Return the first index of b in a.
500
[clinic start generated code]*/
501
502
static Py_ssize_t
503
_operator_indexOf_impl(PyObject *module, PyObject *a, PyObject *b)
504
/*[clinic end generated code: output=c6226d8e0fb60fa6 input=8be2e43b6a6fffe3]*/
505
{
506
return PySequence_Index(a, b);
507
}
508
509
/*[clinic input]
510
_operator.countOf = _operator.indexOf
511
512
Return the number of items in a which are, or which equal, b.
513
[clinic start generated code]*/
514
515
static Py_ssize_t
516
_operator_countOf_impl(PyObject *module, PyObject *a, PyObject *b)
517
/*[clinic end generated code: output=9e1623197daf3382 input=93ea57f170f3f0bb]*/
518
{
519
return PySequence_Count(a, b);
520
}
521
522
/*[clinic input]
523
_operator.getitem
524
525
a: object
526
b: object
527
/
528
529
Same as a[b].
530
[clinic start generated code]*/
531
532
static PyObject *
533
_operator_getitem_impl(PyObject *module, PyObject *a, PyObject *b)
534
/*[clinic end generated code: output=6c8d8101a676e594 input=6682797320e48845]*/
535
{
536
return PyObject_GetItem(a, b);
537
}
538
539
/*[clinic input]
540
_operator.setitem
541
542
a: object
543
b: object
544
c: object
545
/
546
547
Same as a[b] = c.
548
[clinic start generated code]*/
549
550
static PyObject *
551
_operator_setitem_impl(PyObject *module, PyObject *a, PyObject *b,
552
PyObject *c)
553
/*[clinic end generated code: output=1324f9061ae99e25 input=ceaf453c4d3a58df]*/
554
{
555
if (-1 == PyObject_SetItem(a, b, c))
556
return NULL;
557
Py_RETURN_NONE;
558
}
559
560
/*[clinic input]
561
_operator.delitem = _operator.getitem
562
563
Same as del a[b].
564
[clinic start generated code]*/
565
566
static PyObject *
567
_operator_delitem_impl(PyObject *module, PyObject *a, PyObject *b)
568
/*[clinic end generated code: output=db18f61506295799 input=991bec56a0d3ec7f]*/
569
{
570
if (-1 == PyObject_DelItem(a, b))
571
return NULL;
572
Py_RETURN_NONE;
573
}
574
575
/*[clinic input]
576
_operator.eq
577
578
a: object
579
b: object
580
/
581
582
Same as a == b.
583
[clinic start generated code]*/
584
585
static PyObject *
586
_operator_eq_impl(PyObject *module, PyObject *a, PyObject *b)
587
/*[clinic end generated code: output=8d7d46ed4135677c input=586fca687a95a83f]*/
588
{
589
return PyObject_RichCompare(a, b, Py_EQ);
590
}
591
592
/*[clinic input]
593
_operator.ne = _operator.eq
594
595
Same as a != b.
596
[clinic start generated code]*/
597
598
static PyObject *
599
_operator_ne_impl(PyObject *module, PyObject *a, PyObject *b)
600
/*[clinic end generated code: output=c99bd0c3a4c01297 input=5d88f23d35e9abac]*/
601
{
602
return PyObject_RichCompare(a, b, Py_NE);
603
}
604
605
/*[clinic input]
606
_operator.lt = _operator.eq
607
608
Same as a < b.
609
[clinic start generated code]*/
610
611
static PyObject *
612
_operator_lt_impl(PyObject *module, PyObject *a, PyObject *b)
613
/*[clinic end generated code: output=082d7c45c440e535 input=34a59ad6d39d3a2b]*/
614
{
615
return PyObject_RichCompare(a, b, Py_LT);
616
}
617
618
/*[clinic input]
619
_operator.le = _operator.eq
620
621
Same as a <= b.
622
[clinic start generated code]*/
623
624
static PyObject *
625
_operator_le_impl(PyObject *module, PyObject *a, PyObject *b)
626
/*[clinic end generated code: output=00970a2923d0ae17 input=b812a7860a0bef44]*/
627
{
628
return PyObject_RichCompare(a, b, Py_LE);
629
}
630
631
/*[clinic input]
632
_operator.gt = _operator.eq
633
634
Same as a > b.
635
[clinic start generated code]*/
636
637
static PyObject *
638
_operator_gt_impl(PyObject *module, PyObject *a, PyObject *b)
639
/*[clinic end generated code: output=8d373349ecf25641 input=9bdb45b995ada35b]*/
640
{
641
return PyObject_RichCompare(a, b, Py_GT);
642
}
643
644
/*[clinic input]
645
_operator.ge = _operator.eq
646
647
Same as a >= b.
648
[clinic start generated code]*/
649
650
static PyObject *
651
_operator_ge_impl(PyObject *module, PyObject *a, PyObject *b)
652
/*[clinic end generated code: output=7ce3882256d4b137 input=cf1dc4a5ca9c35f5]*/
653
{
654
return PyObject_RichCompare(a, b, Py_GE);
655
}
656
657
/*[clinic input]
658
_operator.pow = _operator.add
659
660
Same as a ** b.
661
[clinic start generated code]*/
662
663
static PyObject *
664
_operator_pow_impl(PyObject *module, PyObject *a, PyObject *b)
665
/*[clinic end generated code: output=09e668ad50036120 input=690b40f097ab1637]*/
666
{
667
return PyNumber_Power(a, b, Py_None);
668
}
669
670
/*[clinic input]
671
_operator.ipow = _operator.add
672
673
Same as a **= b.
674
[clinic start generated code]*/
675
676
static PyObject *
677
_operator_ipow_impl(PyObject *module, PyObject *a, PyObject *b)
678
/*[clinic end generated code: output=7189ff4d4367c808 input=f00623899d07499a]*/
679
{
680
return PyNumber_InPlacePower(a, b, Py_None);
681
}
682
683
/*[clinic input]
684
_operator.index
685
686
a: object
687
/
688
689
Same as a.__index__()
690
[clinic start generated code]*/
691
692
static PyObject *
693
_operator_index(PyObject *module, PyObject *a)
694
/*[clinic end generated code: output=d972b0764ac305fc input=6f54d50ea64a579c]*/
695
{
696
return PyNumber_Index(a);
697
}
698
699
/*[clinic input]
700
_operator.is_ = _operator.add
701
702
Same as a is b.
703
[clinic start generated code]*/
704
705
static PyObject *
706
_operator_is__impl(PyObject *module, PyObject *a, PyObject *b)
707
/*[clinic end generated code: output=bcd47a402e482e1d input=5fa9b97df03c427f]*/
708
{
709
PyObject *result = Py_Is(a, b) ? Py_True : Py_False;
710
return Py_NewRef(result);
711
}
712
713
/*[clinic input]
714
_operator.is_not = _operator.add
715
716
Same as a is not b.
717
[clinic start generated code]*/
718
719
static PyObject *
720
_operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b)
721
/*[clinic end generated code: output=491a1f2f81f6c7f9 input=5a93f7e1a93535f1]*/
722
{
723
PyObject *result;
724
result = (a != b) ? Py_True : Py_False;
725
return Py_NewRef(result);
726
}
727
728
/* compare_digest **********************************************************/
729
730
/*
731
* timing safe compare
732
*
733
* Returns 1 if the strings are equal.
734
* In case of len(a) != len(b) the function tries to keep the timing
735
* dependent on the length of b. CPU cache locality may still alter timing
736
* a bit.
737
*/
738
static int
739
_tscmp(const unsigned char *a, const unsigned char *b,
740
Py_ssize_t len_a, Py_ssize_t len_b)
741
{
742
/* The volatile type declarations make sure that the compiler has no
743
* chance to optimize and fold the code in any way that may change
744
* the timing.
745
*/
746
volatile Py_ssize_t length;
747
volatile const unsigned char *left;
748
volatile const unsigned char *right;
749
Py_ssize_t i;
750
volatile unsigned char result;
751
752
/* loop count depends on length of b */
753
length = len_b;
754
left = NULL;
755
right = b;
756
757
/* don't use else here to keep the amount of CPU instructions constant,
758
* volatile forces re-evaluation
759
* */
760
if (len_a == length) {
761
left = *((volatile const unsigned char**)&a);
762
result = 0;
763
}
764
if (len_a != length) {
765
left = b;
766
result = 1;
767
}
768
769
for (i=0; i < length; i++) {
770
result |= *left++ ^ *right++;
771
}
772
773
return (result == 0);
774
}
775
776
/*[clinic input]
777
_operator.length_hint -> Py_ssize_t
778
779
obj: object
780
default: Py_ssize_t = 0
781
/
782
783
Return an estimate of the number of items in obj.
784
785
This is useful for presizing containers when building from an iterable.
786
787
If the object supports len(), the result will be exact.
788
Otherwise, it may over- or under-estimate by an arbitrary amount.
789
The result will be an integer >= 0.
790
[clinic start generated code]*/
791
792
static Py_ssize_t
793
_operator_length_hint_impl(PyObject *module, PyObject *obj,
794
Py_ssize_t default_value)
795
/*[clinic end generated code: output=01d469edc1d612ad input=65ed29f04401e96a]*/
796
{
797
return PyObject_LengthHint(obj, default_value);
798
}
799
800
/* NOTE: Keep in sync with _hashopenssl.c implementation. */
801
802
/*[clinic input]
803
_operator._compare_digest = _operator.eq
804
805
Return 'a == b'.
806
807
This function uses an approach designed to prevent
808
timing analysis, making it appropriate for cryptography.
809
810
a and b must both be of the same type: either str (ASCII only),
811
or any bytes-like object.
812
813
Note: If a and b are of different lengths, or if an error occurs,
814
a timing attack could theoretically reveal information about the
815
types and lengths of a and b--but not their values.
816
[clinic start generated code]*/
817
818
static PyObject *
819
_operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b)
820
/*[clinic end generated code: output=11d452bdd3a23cbc input=9ac7e2c4e30bc356]*/
821
{
822
int rc;
823
824
/* ASCII unicode string */
825
if(PyUnicode_Check(a) && PyUnicode_Check(b)) {
826
if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) {
827
PyErr_SetString(PyExc_TypeError,
828
"comparing strings with non-ASCII characters is "
829
"not supported");
830
return NULL;
831
}
832
833
rc = _tscmp(PyUnicode_DATA(a),
834
PyUnicode_DATA(b),
835
PyUnicode_GET_LENGTH(a),
836
PyUnicode_GET_LENGTH(b));
837
}
838
/* fallback to buffer interface for bytes, bytearray and other */
839
else {
840
Py_buffer view_a;
841
Py_buffer view_b;
842
843
if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) {
844
PyErr_Format(PyExc_TypeError,
845
"unsupported operand types(s) or combination of types: "
846
"'%.100s' and '%.100s'",
847
Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
848
return NULL;
849
}
850
851
if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) {
852
return NULL;
853
}
854
if (view_a.ndim > 1) {
855
PyErr_SetString(PyExc_BufferError,
856
"Buffer must be single dimension");
857
PyBuffer_Release(&view_a);
858
return NULL;
859
}
860
861
if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) {
862
PyBuffer_Release(&view_a);
863
return NULL;
864
}
865
if (view_b.ndim > 1) {
866
PyErr_SetString(PyExc_BufferError,
867
"Buffer must be single dimension");
868
PyBuffer_Release(&view_a);
869
PyBuffer_Release(&view_b);
870
return NULL;
871
}
872
873
rc = _tscmp((const unsigned char*)view_a.buf,
874
(const unsigned char*)view_b.buf,
875
view_a.len,
876
view_b.len);
877
878
PyBuffer_Release(&view_a);
879
PyBuffer_Release(&view_b);
880
}
881
882
return PyBool_FromLong(rc);
883
}
884
885
PyDoc_STRVAR(_operator_call__doc__,
886
"call($module, obj, /, *args, **kwargs)\n"
887
"--\n"
888
"\n"
889
"Same as obj(*args, **kwargs).");
890
891
#define _OPERATOR_CALL_METHODDEF \
892
{"call", _PyCFunction_CAST(_operator_call), METH_FASTCALL | METH_KEYWORDS, _operator_call__doc__},
893
894
static PyObject *
895
_operator_call(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
896
{
897
if (!_PyArg_CheckPositional("call", nargs, 1, PY_SSIZE_T_MAX)) {
898
return NULL;
899
}
900
return PyObject_Vectorcall(
901
args[0],
902
&args[1], (PyVectorcall_NARGS(nargs) - 1) | PY_VECTORCALL_ARGUMENTS_OFFSET,
903
kwnames);
904
}
905
906
/* operator methods **********************************************************/
907
908
static struct PyMethodDef operator_methods[] = {
909
910
_OPERATOR_TRUTH_METHODDEF
911
_OPERATOR_CONTAINS_METHODDEF
912
_OPERATOR_INDEXOF_METHODDEF
913
_OPERATOR_COUNTOF_METHODDEF
914
_OPERATOR_IS__METHODDEF
915
_OPERATOR_IS_NOT_METHODDEF
916
_OPERATOR_INDEX_METHODDEF
917
_OPERATOR_ADD_METHODDEF
918
_OPERATOR_SUB_METHODDEF
919
_OPERATOR_MUL_METHODDEF
920
_OPERATOR_MATMUL_METHODDEF
921
_OPERATOR_FLOORDIV_METHODDEF
922
_OPERATOR_TRUEDIV_METHODDEF
923
_OPERATOR_MOD_METHODDEF
924
_OPERATOR_NEG_METHODDEF
925
_OPERATOR_POS_METHODDEF
926
_OPERATOR_ABS_METHODDEF
927
_OPERATOR_INV_METHODDEF
928
_OPERATOR_INVERT_METHODDEF
929
_OPERATOR_LSHIFT_METHODDEF
930
_OPERATOR_RSHIFT_METHODDEF
931
_OPERATOR_NOT__METHODDEF
932
_OPERATOR_AND__METHODDEF
933
_OPERATOR_XOR_METHODDEF
934
_OPERATOR_OR__METHODDEF
935
_OPERATOR_IADD_METHODDEF
936
_OPERATOR_ISUB_METHODDEF
937
_OPERATOR_IMUL_METHODDEF
938
_OPERATOR_IMATMUL_METHODDEF
939
_OPERATOR_IFLOORDIV_METHODDEF
940
_OPERATOR_ITRUEDIV_METHODDEF
941
_OPERATOR_IMOD_METHODDEF
942
_OPERATOR_ILSHIFT_METHODDEF
943
_OPERATOR_IRSHIFT_METHODDEF
944
_OPERATOR_IAND_METHODDEF
945
_OPERATOR_IXOR_METHODDEF
946
_OPERATOR_IOR_METHODDEF
947
_OPERATOR_CONCAT_METHODDEF
948
_OPERATOR_ICONCAT_METHODDEF
949
_OPERATOR_GETITEM_METHODDEF
950
_OPERATOR_SETITEM_METHODDEF
951
_OPERATOR_DELITEM_METHODDEF
952
_OPERATOR_POW_METHODDEF
953
_OPERATOR_IPOW_METHODDEF
954
_OPERATOR_EQ_METHODDEF
955
_OPERATOR_NE_METHODDEF
956
_OPERATOR_LT_METHODDEF
957
_OPERATOR_LE_METHODDEF
958
_OPERATOR_GT_METHODDEF
959
_OPERATOR_GE_METHODDEF
960
_OPERATOR__COMPARE_DIGEST_METHODDEF
961
_OPERATOR_LENGTH_HINT_METHODDEF
962
_OPERATOR_CALL_METHODDEF
963
{NULL, NULL} /* sentinel */
964
965
};
966
967
/* itemgetter object **********************************************************/
968
969
typedef struct {
970
PyObject_HEAD
971
Py_ssize_t nitems;
972
PyObject *item;
973
Py_ssize_t index; // -1 unless *item* is a single non-negative integer index
974
vectorcallfunc vectorcall;
975
} itemgetterobject;
976
977
// Forward declarations
978
static PyObject *
979
itemgetter_vectorcall(PyObject *, PyObject *const *, size_t, PyObject *);
980
static PyObject *
981
itemgetter_call_impl(itemgetterobject *, PyObject *);
982
983
/* AC 3.5: treats first argument as an iterable, otherwise uses *args */
984
static PyObject *
985
itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
986
{
987
itemgetterobject *ig;
988
PyObject *item;
989
Py_ssize_t nitems;
990
Py_ssize_t index;
991
992
if (!_PyArg_NoKeywords("itemgetter", kwds))
993
return NULL;
994
995
nitems = PyTuple_GET_SIZE(args);
996
if (nitems <= 1) {
997
if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item))
998
return NULL;
999
} else {
1000
item = args;
1001
}
1002
_operator_state *state = _PyType_GetModuleState(type);
1003
/* create itemgetterobject structure */
1004
ig = PyObject_GC_New(itemgetterobject, (PyTypeObject *) state->itemgetter_type);
1005
if (ig == NULL) {
1006
return NULL;
1007
}
1008
1009
ig->item = Py_NewRef(item);
1010
ig->nitems = nitems;
1011
ig->index = -1;
1012
if (PyLong_CheckExact(item)) {
1013
index = PyLong_AsSsize_t(item);
1014
if (index < 0) {
1015
/* If we get here, then either the index conversion failed
1016
* due to being out of range, or the index was a negative
1017
* integer. Either way, we clear any possible exception
1018
* and fall back to the slow path, where ig->index is -1.
1019
*/
1020
PyErr_Clear();
1021
}
1022
else {
1023
ig->index = index;
1024
}
1025
}
1026
1027
ig->vectorcall = (vectorcallfunc)itemgetter_vectorcall;
1028
PyObject_GC_Track(ig);
1029
return (PyObject *)ig;
1030
}
1031
1032
static int
1033
itemgetter_clear(itemgetterobject *ig)
1034
{
1035
Py_CLEAR(ig->item);
1036
return 0;
1037
}
1038
1039
static void
1040
itemgetter_dealloc(itemgetterobject *ig)
1041
{
1042
PyTypeObject *tp = Py_TYPE(ig);
1043
PyObject_GC_UnTrack(ig);
1044
(void)itemgetter_clear(ig);
1045
tp->tp_free(ig);
1046
Py_DECREF(tp);
1047
}
1048
1049
static int
1050
itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
1051
{
1052
Py_VISIT(Py_TYPE(ig));
1053
Py_VISIT(ig->item);
1054
return 0;
1055
}
1056
1057
static PyObject *
1058
itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
1059
{
1060
assert(PyTuple_CheckExact(args));
1061
if (!_PyArg_NoKeywords("itemgetter", kw))
1062
return NULL;
1063
if (!_PyArg_CheckPositional("itemgetter", PyTuple_GET_SIZE(args), 1, 1))
1064
return NULL;
1065
return itemgetter_call_impl(ig, PyTuple_GET_ITEM(args, 0));
1066
}
1067
1068
static PyObject *
1069
itemgetter_vectorcall(PyObject *ig, PyObject *const *args,
1070
size_t nargsf, PyObject *kwnames)
1071
{
1072
if (!_PyArg_NoKwnames("itemgetter", kwnames)) {
1073
return NULL;
1074
}
1075
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1076
if (!_PyArg_CheckPositional("itemgetter", nargs, 1, 1)) {
1077
return NULL;
1078
}
1079
return itemgetter_call_impl((itemgetterobject *)ig, args[0]);
1080
}
1081
1082
static PyObject *
1083
itemgetter_call_impl(itemgetterobject *ig, PyObject *obj)
1084
{
1085
PyObject *result;
1086
Py_ssize_t i, nitems=ig->nitems;
1087
if (nitems == 1) {
1088
if (ig->index >= 0
1089
&& PyTuple_CheckExact(obj)
1090
&& ig->index < PyTuple_GET_SIZE(obj))
1091
{
1092
result = PyTuple_GET_ITEM(obj, ig->index);
1093
return Py_NewRef(result);
1094
}
1095
return PyObject_GetItem(obj, ig->item);
1096
}
1097
1098
assert(PyTuple_Check(ig->item));
1099
assert(PyTuple_GET_SIZE(ig->item) == nitems);
1100
1101
result = PyTuple_New(nitems);
1102
if (result == NULL)
1103
return NULL;
1104
1105
for (i=0 ; i < nitems ; i++) {
1106
PyObject *item, *val;
1107
item = PyTuple_GET_ITEM(ig->item, i);
1108
val = PyObject_GetItem(obj, item);
1109
if (val == NULL) {
1110
Py_DECREF(result);
1111
return NULL;
1112
}
1113
PyTuple_SET_ITEM(result, i, val);
1114
}
1115
return result;
1116
}
1117
1118
static PyObject *
1119
itemgetter_repr(itemgetterobject *ig)
1120
{
1121
PyObject *repr;
1122
const char *reprfmt;
1123
1124
int status = Py_ReprEnter((PyObject *)ig);
1125
if (status != 0) {
1126
if (status < 0)
1127
return NULL;
1128
return PyUnicode_FromFormat("%s(...)", Py_TYPE(ig)->tp_name);
1129
}
1130
1131
reprfmt = ig->nitems == 1 ? "%s(%R)" : "%s%R";
1132
repr = PyUnicode_FromFormat(reprfmt, Py_TYPE(ig)->tp_name, ig->item);
1133
Py_ReprLeave((PyObject *)ig);
1134
return repr;
1135
}
1136
1137
static PyObject *
1138
itemgetter_reduce(itemgetterobject *ig, PyObject *Py_UNUSED(ignored))
1139
{
1140
if (ig->nitems == 1)
1141
return Py_BuildValue("O(O)", Py_TYPE(ig), ig->item);
1142
return PyTuple_Pack(2, Py_TYPE(ig), ig->item);
1143
}
1144
1145
PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1146
1147
static PyMethodDef itemgetter_methods[] = {
1148
{"__reduce__", (PyCFunction)itemgetter_reduce, METH_NOARGS,
1149
reduce_doc},
1150
{NULL}
1151
};
1152
1153
static PyMemberDef itemgetter_members[] = {
1154
{"__vectorcalloffset__", T_PYSSIZET, offsetof(itemgetterobject, vectorcall), READONLY},
1155
{NULL} /* Sentinel */
1156
};
1157
1158
PyDoc_STRVAR(itemgetter_doc,
1159
"itemgetter(item, /, *items)\n--\n\n\
1160
Return a callable object that fetches the given item(s) from its operand.\n\
1161
After f = itemgetter(2), the call f(r) returns r[2].\n\
1162
After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])");
1163
1164
static PyType_Slot itemgetter_type_slots[] = {
1165
{Py_tp_doc, (void *)itemgetter_doc},
1166
{Py_tp_dealloc, itemgetter_dealloc},
1167
{Py_tp_call, itemgetter_call},
1168
{Py_tp_traverse, itemgetter_traverse},
1169
{Py_tp_clear, itemgetter_clear},
1170
{Py_tp_methods, itemgetter_methods},
1171
{Py_tp_members, itemgetter_members},
1172
{Py_tp_new, itemgetter_new},
1173
{Py_tp_getattro, PyObject_GenericGetAttr},
1174
{Py_tp_repr, itemgetter_repr},
1175
{0, 0}
1176
};
1177
1178
static PyType_Spec itemgetter_type_spec = {
1179
.name = "operator.itemgetter",
1180
.basicsize = sizeof(itemgetterobject),
1181
.itemsize = 0,
1182
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1183
Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_VECTORCALL),
1184
.slots = itemgetter_type_slots,
1185
};
1186
1187
/* attrgetter object **********************************************************/
1188
1189
typedef struct {
1190
PyObject_HEAD
1191
Py_ssize_t nattrs;
1192
PyObject *attr;
1193
vectorcallfunc vectorcall;
1194
} attrgetterobject;
1195
1196
// Forward declarations
1197
static PyObject *
1198
attrgetter_vectorcall(PyObject *, PyObject *const *, size_t, PyObject *);
1199
static PyObject *
1200
attrgetter_call_impl(attrgetterobject *, PyObject *);
1201
1202
/* AC 3.5: treats first argument as an iterable, otherwise uses *args */
1203
static PyObject *
1204
attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1205
{
1206
attrgetterobject *ag;
1207
PyObject *attr;
1208
Py_ssize_t nattrs, idx, char_idx;
1209
1210
if (!_PyArg_NoKeywords("attrgetter", kwds))
1211
return NULL;
1212
1213
nattrs = PyTuple_GET_SIZE(args);
1214
if (nattrs <= 1) {
1215
if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
1216
return NULL;
1217
}
1218
1219
attr = PyTuple_New(nattrs);
1220
if (attr == NULL)
1221
return NULL;
1222
1223
/* prepare attr while checking args */
1224
for (idx = 0; idx < nattrs; ++idx) {
1225
PyObject *item = PyTuple_GET_ITEM(args, idx);
1226
int dot_count;
1227
1228
if (!PyUnicode_Check(item)) {
1229
PyErr_SetString(PyExc_TypeError,
1230
"attribute name must be a string");
1231
Py_DECREF(attr);
1232
return NULL;
1233
}
1234
Py_ssize_t item_len = PyUnicode_GET_LENGTH(item);
1235
int kind = PyUnicode_KIND(item);
1236
const void *data = PyUnicode_DATA(item);
1237
1238
/* check whether the string is dotted */
1239
dot_count = 0;
1240
for (char_idx = 0; char_idx < item_len; ++char_idx) {
1241
if (PyUnicode_READ(kind, data, char_idx) == '.')
1242
++dot_count;
1243
}
1244
1245
if (dot_count == 0) {
1246
Py_INCREF(item);
1247
PyUnicode_InternInPlace(&item);
1248
PyTuple_SET_ITEM(attr, idx, item);
1249
} else { /* make it a tuple of non-dotted attrnames */
1250
PyObject *attr_chain = PyTuple_New(dot_count + 1);
1251
PyObject *attr_chain_item;
1252
Py_ssize_t unibuff_from = 0;
1253
Py_ssize_t unibuff_till = 0;
1254
Py_ssize_t attr_chain_idx = 0;
1255
1256
if (attr_chain == NULL) {
1257
Py_DECREF(attr);
1258
return NULL;
1259
}
1260
1261
for (; dot_count > 0; --dot_count) {
1262
while (PyUnicode_READ(kind, data, unibuff_till) != '.') {
1263
++unibuff_till;
1264
}
1265
attr_chain_item = PyUnicode_Substring(item,
1266
unibuff_from,
1267
unibuff_till);
1268
if (attr_chain_item == NULL) {
1269
Py_DECREF(attr_chain);
1270
Py_DECREF(attr);
1271
return NULL;
1272
}
1273
PyUnicode_InternInPlace(&attr_chain_item);
1274
PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
1275
++attr_chain_idx;
1276
unibuff_till = unibuff_from = unibuff_till + 1;
1277
}
1278
1279
/* now add the last dotless name */
1280
attr_chain_item = PyUnicode_Substring(item,
1281
unibuff_from, item_len);
1282
if (attr_chain_item == NULL) {
1283
Py_DECREF(attr_chain);
1284
Py_DECREF(attr);
1285
return NULL;
1286
}
1287
PyUnicode_InternInPlace(&attr_chain_item);
1288
PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
1289
1290
PyTuple_SET_ITEM(attr, idx, attr_chain);
1291
}
1292
}
1293
1294
_operator_state *state = _PyType_GetModuleState(type);
1295
/* create attrgetterobject structure */
1296
ag = PyObject_GC_New(attrgetterobject, (PyTypeObject *)state->attrgetter_type);
1297
if (ag == NULL) {
1298
Py_DECREF(attr);
1299
return NULL;
1300
}
1301
1302
ag->attr = attr;
1303
ag->nattrs = nattrs;
1304
ag->vectorcall = (vectorcallfunc)attrgetter_vectorcall;
1305
1306
PyObject_GC_Track(ag);
1307
return (PyObject *)ag;
1308
}
1309
1310
static int
1311
attrgetter_clear(attrgetterobject *ag)
1312
{
1313
Py_CLEAR(ag->attr);
1314
return 0;
1315
}
1316
1317
static void
1318
attrgetter_dealloc(attrgetterobject *ag)
1319
{
1320
PyTypeObject *tp = Py_TYPE(ag);
1321
PyObject_GC_UnTrack(ag);
1322
(void)attrgetter_clear(ag);
1323
tp->tp_free(ag);
1324
Py_DECREF(tp);
1325
}
1326
1327
static int
1328
attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
1329
{
1330
Py_VISIT(ag->attr);
1331
Py_VISIT(Py_TYPE(ag));
1332
return 0;
1333
}
1334
1335
static PyObject *
1336
dotted_getattr(PyObject *obj, PyObject *attr)
1337
{
1338
PyObject *newobj;
1339
1340
/* attr is either a tuple or instance of str.
1341
Ensured by the setup code of attrgetter_new */
1342
if (PyTuple_CheckExact(attr)) { /* chained getattr */
1343
Py_ssize_t name_idx = 0, name_count;
1344
PyObject *attr_name;
1345
1346
name_count = PyTuple_GET_SIZE(attr);
1347
Py_INCREF(obj);
1348
for (name_idx = 0; name_idx < name_count; ++name_idx) {
1349
attr_name = PyTuple_GET_ITEM(attr, name_idx);
1350
newobj = PyObject_GetAttr(obj, attr_name);
1351
Py_DECREF(obj);
1352
if (newobj == NULL) {
1353
return NULL;
1354
}
1355
/* here */
1356
obj = newobj;
1357
}
1358
} else { /* single getattr */
1359
newobj = PyObject_GetAttr(obj, attr);
1360
if (newobj == NULL)
1361
return NULL;
1362
obj = newobj;
1363
}
1364
1365
return obj;
1366
}
1367
1368
static PyObject *
1369
attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
1370
{
1371
if (!_PyArg_NoKeywords("attrgetter", kw))
1372
return NULL;
1373
if (!_PyArg_CheckPositional("attrgetter", PyTuple_GET_SIZE(args), 1, 1))
1374
return NULL;
1375
return attrgetter_call_impl(ag, PyTuple_GET_ITEM(args, 0));
1376
}
1377
1378
static PyObject *
1379
attrgetter_vectorcall(PyObject *ag, PyObject *const *args, size_t nargsf, PyObject *kwnames)
1380
{
1381
if (!_PyArg_NoKwnames("attrgetter", kwnames)) {
1382
return NULL;
1383
}
1384
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1385
if (!_PyArg_CheckPositional("attrgetter", nargs, 1, 1)) {
1386
return NULL;
1387
}
1388
return attrgetter_call_impl((attrgetterobject *)ag, args[0]);
1389
}
1390
1391
static PyObject *
1392
attrgetter_call_impl(attrgetterobject *ag, PyObject *obj)
1393
{
1394
PyObject *result;
1395
Py_ssize_t i, nattrs=ag->nattrs;
1396
1397
if (ag->nattrs == 1) {
1398
/* ag->attr is always a tuple */
1399
return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0));
1400
}
1401
1402
assert(PyTuple_Check(ag->attr));
1403
assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
1404
1405
result = PyTuple_New(nattrs);
1406
if (result == NULL)
1407
return NULL;
1408
1409
for (i=0 ; i < nattrs ; i++) {
1410
PyObject *attr, *val;
1411
attr = PyTuple_GET_ITEM(ag->attr, i);
1412
val = dotted_getattr(obj, attr);
1413
if (val == NULL) {
1414
Py_DECREF(result);
1415
return NULL;
1416
}
1417
PyTuple_SET_ITEM(result, i, val);
1418
}
1419
return result;
1420
}
1421
1422
static PyObject *
1423
dotjoinattr(PyObject *attr, PyObject **attrsep)
1424
{
1425
if (PyTuple_CheckExact(attr)) {
1426
if (*attrsep == NULL) {
1427
*attrsep = PyUnicode_FromString(".");
1428
if (*attrsep == NULL)
1429
return NULL;
1430
}
1431
return PyUnicode_Join(*attrsep, attr);
1432
} else {
1433
return Py_NewRef(attr);
1434
}
1435
}
1436
1437
static PyObject *
1438
attrgetter_args(attrgetterobject *ag)
1439
{
1440
Py_ssize_t i;
1441
PyObject *attrsep = NULL;
1442
PyObject *attrstrings = PyTuple_New(ag->nattrs);
1443
if (attrstrings == NULL)
1444
return NULL;
1445
1446
for (i = 0; i < ag->nattrs; ++i) {
1447
PyObject *attr = PyTuple_GET_ITEM(ag->attr, i);
1448
PyObject *attrstr = dotjoinattr(attr, &attrsep);
1449
if (attrstr == NULL) {
1450
Py_XDECREF(attrsep);
1451
Py_DECREF(attrstrings);
1452
return NULL;
1453
}
1454
PyTuple_SET_ITEM(attrstrings, i, attrstr);
1455
}
1456
Py_XDECREF(attrsep);
1457
return attrstrings;
1458
}
1459
1460
static PyObject *
1461
attrgetter_repr(attrgetterobject *ag)
1462
{
1463
PyObject *repr = NULL;
1464
int status = Py_ReprEnter((PyObject *)ag);
1465
if (status != 0) {
1466
if (status < 0)
1467
return NULL;
1468
return PyUnicode_FromFormat("%s(...)", Py_TYPE(ag)->tp_name);
1469
}
1470
1471
if (ag->nattrs == 1) {
1472
PyObject *attrsep = NULL;
1473
PyObject *attr = dotjoinattr(PyTuple_GET_ITEM(ag->attr, 0), &attrsep);
1474
if (attr != NULL) {
1475
repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(ag)->tp_name, attr);
1476
Py_DECREF(attr);
1477
}
1478
Py_XDECREF(attrsep);
1479
}
1480
else {
1481
PyObject *attrstrings = attrgetter_args(ag);
1482
if (attrstrings != NULL) {
1483
repr = PyUnicode_FromFormat("%s%R",
1484
Py_TYPE(ag)->tp_name, attrstrings);
1485
Py_DECREF(attrstrings);
1486
}
1487
}
1488
Py_ReprLeave((PyObject *)ag);
1489
return repr;
1490
}
1491
1492
static PyObject *
1493
attrgetter_reduce(attrgetterobject *ag, PyObject *Py_UNUSED(ignored))
1494
{
1495
PyObject *attrstrings = attrgetter_args(ag);
1496
if (attrstrings == NULL)
1497
return NULL;
1498
1499
return Py_BuildValue("ON", Py_TYPE(ag), attrstrings);
1500
}
1501
1502
static PyMethodDef attrgetter_methods[] = {
1503
{"__reduce__", (PyCFunction)attrgetter_reduce, METH_NOARGS,
1504
reduce_doc},
1505
{NULL}
1506
};
1507
1508
static PyMemberDef attrgetter_members[] = {
1509
{"__vectorcalloffset__", T_PYSSIZET, offsetof(attrgetterobject, vectorcall), READONLY},
1510
{NULL} /* Sentinel*/
1511
};
1512
1513
PyDoc_STRVAR(attrgetter_doc,
1514
"attrgetter(attr, /, *attrs)\n--\n\n\
1515
Return a callable object that fetches the given attribute(s) from its operand.\n\
1516
After f = attrgetter('name'), the call f(r) returns r.name.\n\
1517
After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\
1518
After h = attrgetter('name.first', 'name.last'), the call h(r) returns\n\
1519
(r.name.first, r.name.last).");
1520
1521
static PyType_Slot attrgetter_type_slots[] = {
1522
{Py_tp_doc, (void *)attrgetter_doc},
1523
{Py_tp_dealloc, attrgetter_dealloc},
1524
{Py_tp_call, attrgetter_call},
1525
{Py_tp_traverse, attrgetter_traverse},
1526
{Py_tp_clear, attrgetter_clear},
1527
{Py_tp_methods, attrgetter_methods},
1528
{Py_tp_members, attrgetter_members},
1529
{Py_tp_new, attrgetter_new},
1530
{Py_tp_getattro, PyObject_GenericGetAttr},
1531
{Py_tp_repr, attrgetter_repr},
1532
{0, 0}
1533
};
1534
1535
static PyType_Spec attrgetter_type_spec = {
1536
.name = "operator.attrgetter",
1537
.basicsize = sizeof(attrgetterobject),
1538
.itemsize = 0,
1539
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1540
Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_VECTORCALL),
1541
.slots = attrgetter_type_slots,
1542
};
1543
1544
1545
/* methodcaller object **********************************************************/
1546
1547
typedef struct {
1548
PyObject_HEAD
1549
PyObject *name;
1550
PyObject *args;
1551
PyObject *kwds;
1552
} methodcallerobject;
1553
1554
/* AC 3.5: variable number of arguments, not currently support by AC */
1555
static PyObject *
1556
methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1557
{
1558
methodcallerobject *mc;
1559
PyObject *name;
1560
1561
if (PyTuple_GET_SIZE(args) < 1) {
1562
PyErr_SetString(PyExc_TypeError, "methodcaller needs at least "
1563
"one argument, the method name");
1564
return NULL;
1565
}
1566
1567
name = PyTuple_GET_ITEM(args, 0);
1568
if (!PyUnicode_Check(name)) {
1569
PyErr_SetString(PyExc_TypeError,
1570
"method name must be a string");
1571
return NULL;
1572
}
1573
1574
_operator_state *state = _PyType_GetModuleState(type);
1575
/* create methodcallerobject structure */
1576
mc = PyObject_GC_New(methodcallerobject, (PyTypeObject *)state->methodcaller_type);
1577
if (mc == NULL) {
1578
return NULL;
1579
}
1580
1581
name = PyTuple_GET_ITEM(args, 0);
1582
Py_INCREF(name);
1583
PyUnicode_InternInPlace(&name);
1584
mc->name = name;
1585
1586
mc->kwds = Py_XNewRef(kwds);
1587
1588
mc->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
1589
if (mc->args == NULL) {
1590
Py_DECREF(mc);
1591
return NULL;
1592
}
1593
1594
PyObject_GC_Track(mc);
1595
return (PyObject *)mc;
1596
}
1597
1598
static int
1599
methodcaller_clear(methodcallerobject *mc)
1600
{
1601
Py_CLEAR(mc->name);
1602
Py_CLEAR(mc->args);
1603
Py_CLEAR(mc->kwds);
1604
return 0;
1605
}
1606
1607
static void
1608
methodcaller_dealloc(methodcallerobject *mc)
1609
{
1610
PyTypeObject *tp = Py_TYPE(mc);
1611
PyObject_GC_UnTrack(mc);
1612
(void)methodcaller_clear(mc);
1613
tp->tp_free(mc);
1614
Py_DECREF(tp);
1615
}
1616
1617
static int
1618
methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
1619
{
1620
Py_VISIT(mc->name);
1621
Py_VISIT(mc->args);
1622
Py_VISIT(mc->kwds);
1623
Py_VISIT(Py_TYPE(mc));
1624
return 0;
1625
}
1626
1627
static PyObject *
1628
methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw)
1629
{
1630
PyObject *method, *obj, *result;
1631
1632
if (!_PyArg_NoKeywords("methodcaller", kw))
1633
return NULL;
1634
if (!_PyArg_CheckPositional("methodcaller", PyTuple_GET_SIZE(args), 1, 1))
1635
return NULL;
1636
obj = PyTuple_GET_ITEM(args, 0);
1637
method = PyObject_GetAttr(obj, mc->name);
1638
if (method == NULL)
1639
return NULL;
1640
result = PyObject_Call(method, mc->args, mc->kwds);
1641
Py_DECREF(method);
1642
return result;
1643
}
1644
1645
static PyObject *
1646
methodcaller_repr(methodcallerobject *mc)
1647
{
1648
PyObject *argreprs, *repr = NULL, *sep, *joinedargreprs;
1649
Py_ssize_t numtotalargs, numposargs, numkwdargs, i;
1650
int status = Py_ReprEnter((PyObject *)mc);
1651
if (status != 0) {
1652
if (status < 0)
1653
return NULL;
1654
return PyUnicode_FromFormat("%s(...)", Py_TYPE(mc)->tp_name);
1655
}
1656
1657
numkwdargs = mc->kwds != NULL ? PyDict_GET_SIZE(mc->kwds) : 0;
1658
numposargs = PyTuple_GET_SIZE(mc->args);
1659
numtotalargs = numposargs + numkwdargs;
1660
1661
if (numtotalargs == 0) {
1662
repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(mc)->tp_name, mc->name);
1663
Py_ReprLeave((PyObject *)mc);
1664
return repr;
1665
}
1666
1667
argreprs = PyTuple_New(numtotalargs);
1668
if (argreprs == NULL) {
1669
Py_ReprLeave((PyObject *)mc);
1670
return NULL;
1671
}
1672
1673
for (i = 0; i < numposargs; ++i) {
1674
PyObject *onerepr = PyObject_Repr(PyTuple_GET_ITEM(mc->args, i));
1675
if (onerepr == NULL)
1676
goto done;
1677
PyTuple_SET_ITEM(argreprs, i, onerepr);
1678
}
1679
1680
if (numkwdargs != 0) {
1681
PyObject *key, *value;
1682
Py_ssize_t pos = 0;
1683
while (PyDict_Next(mc->kwds, &pos, &key, &value)) {
1684
PyObject *onerepr = PyUnicode_FromFormat("%U=%R", key, value);
1685
if (onerepr == NULL)
1686
goto done;
1687
if (i >= numtotalargs) {
1688
i = -1;
1689
Py_DECREF(onerepr);
1690
break;
1691
}
1692
PyTuple_SET_ITEM(argreprs, i, onerepr);
1693
++i;
1694
}
1695
if (i != numtotalargs) {
1696
PyErr_SetString(PyExc_RuntimeError,
1697
"keywords dict changed size during iteration");
1698
goto done;
1699
}
1700
}
1701
1702
sep = PyUnicode_FromString(", ");
1703
if (sep == NULL)
1704
goto done;
1705
1706
joinedargreprs = PyUnicode_Join(sep, argreprs);
1707
Py_DECREF(sep);
1708
if (joinedargreprs == NULL)
1709
goto done;
1710
1711
repr = PyUnicode_FromFormat("%s(%R, %U)", Py_TYPE(mc)->tp_name,
1712
mc->name, joinedargreprs);
1713
Py_DECREF(joinedargreprs);
1714
1715
done:
1716
Py_DECREF(argreprs);
1717
Py_ReprLeave((PyObject *)mc);
1718
return repr;
1719
}
1720
1721
static PyObject *
1722
methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored))
1723
{
1724
PyObject *newargs;
1725
if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) {
1726
Py_ssize_t i;
1727
Py_ssize_t callargcount = PyTuple_GET_SIZE(mc->args);
1728
newargs = PyTuple_New(1 + callargcount);
1729
if (newargs == NULL)
1730
return NULL;
1731
PyTuple_SET_ITEM(newargs, 0, Py_NewRef(mc->name));
1732
for (i = 0; i < callargcount; ++i) {
1733
PyObject *arg = PyTuple_GET_ITEM(mc->args, i);
1734
PyTuple_SET_ITEM(newargs, i + 1, Py_NewRef(arg));
1735
}
1736
return Py_BuildValue("ON", Py_TYPE(mc), newargs);
1737
}
1738
else {
1739
PyObject *partial;
1740
PyObject *constructor;
1741
PyObject *newargs[2];
1742
1743
partial = _PyImport_GetModuleAttrString("functools", "partial");
1744
if (!partial)
1745
return NULL;
1746
1747
newargs[0] = (PyObject *)Py_TYPE(mc);
1748
newargs[1] = mc->name;
1749
constructor = PyObject_VectorcallDict(partial, newargs, 2, mc->kwds);
1750
1751
Py_DECREF(partial);
1752
return Py_BuildValue("NO", constructor, mc->args);
1753
}
1754
}
1755
1756
static PyMethodDef methodcaller_methods[] = {
1757
{"__reduce__", (PyCFunction)methodcaller_reduce, METH_NOARGS,
1758
reduce_doc},
1759
{NULL}
1760
};
1761
PyDoc_STRVAR(methodcaller_doc,
1762
"methodcaller(name, /, *args, **kwargs)\n--\n\n\
1763
Return a callable object that calls the given method on its operand.\n\
1764
After f = methodcaller('name'), the call f(r) returns r.name().\n\
1765
After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\
1766
r.name('date', foo=1).");
1767
1768
static PyType_Slot methodcaller_type_slots[] = {
1769
{Py_tp_doc, (void *)methodcaller_doc},
1770
{Py_tp_dealloc, methodcaller_dealloc},
1771
{Py_tp_call, methodcaller_call},
1772
{Py_tp_traverse, methodcaller_traverse},
1773
{Py_tp_clear, methodcaller_clear},
1774
{Py_tp_methods, methodcaller_methods},
1775
{Py_tp_new, methodcaller_new},
1776
{Py_tp_getattro, PyObject_GenericGetAttr},
1777
{Py_tp_repr, methodcaller_repr},
1778
{0, 0}
1779
};
1780
1781
static PyType_Spec methodcaller_type_spec = {
1782
.name = "operator.methodcaller",
1783
.basicsize = sizeof(methodcallerobject),
1784
.itemsize = 0,
1785
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1786
Py_TPFLAGS_IMMUTABLETYPE),
1787
.slots = methodcaller_type_slots,
1788
};
1789
1790
static int
1791
operator_exec(PyObject *module)
1792
{
1793
_operator_state *state = get_operator_state(module);
1794
state->attrgetter_type = PyType_FromModuleAndSpec(module, &attrgetter_type_spec, NULL);
1795
if (state->attrgetter_type == NULL) {
1796
return -1;
1797
}
1798
if (PyModule_AddType(module, (PyTypeObject *)state->attrgetter_type) < 0) {
1799
return -1;
1800
}
1801
1802
state->itemgetter_type = PyType_FromModuleAndSpec(module, &itemgetter_type_spec, NULL);
1803
if (state->itemgetter_type == NULL) {
1804
return -1;
1805
}
1806
if (PyModule_AddType(module, (PyTypeObject *)state->itemgetter_type) < 0) {
1807
return -1;
1808
}
1809
1810
state->methodcaller_type = PyType_FromModuleAndSpec(module, &methodcaller_type_spec, NULL);
1811
if (state->methodcaller_type == NULL) {
1812
return -1;
1813
}
1814
if (PyModule_AddType(module, (PyTypeObject *)state->methodcaller_type) < 0) {
1815
return -1;
1816
}
1817
1818
return 0;
1819
}
1820
1821
1822
static struct PyModuleDef_Slot operator_slots[] = {
1823
{Py_mod_exec, operator_exec},
1824
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
1825
{0, NULL}
1826
};
1827
1828
static int
1829
operator_traverse(PyObject *module, visitproc visit, void *arg)
1830
{
1831
_operator_state *state = get_operator_state(module);
1832
Py_VISIT(state->attrgetter_type);
1833
Py_VISIT(state->itemgetter_type);
1834
Py_VISIT(state->methodcaller_type);
1835
return 0;
1836
}
1837
1838
static int
1839
operator_clear(PyObject *module)
1840
{
1841
_operator_state *state = get_operator_state(module);
1842
Py_CLEAR(state->attrgetter_type);
1843
Py_CLEAR(state->itemgetter_type);
1844
Py_CLEAR(state->methodcaller_type);
1845
return 0;
1846
}
1847
1848
static void
1849
operator_free(void *module)
1850
{
1851
operator_clear((PyObject *)module);
1852
}
1853
1854
static struct PyModuleDef operatormodule = {
1855
PyModuleDef_HEAD_INIT,
1856
.m_name = "_operator",
1857
.m_doc = operator_doc,
1858
.m_size = sizeof(_operator_state),
1859
.m_methods = operator_methods,
1860
.m_slots = operator_slots,
1861
.m_traverse = operator_traverse,
1862
.m_clear = operator_clear,
1863
.m_free = operator_free,
1864
};
1865
1866
PyMODINIT_FUNC
1867
PyInit__operator(void)
1868
{
1869
return PyModuleDef_Init(&operatormodule);
1870
}
1871
1872