Coverage Report

Created: 2025-07-04 06:49

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