Coverage Report

Created: 2025-07-11 06:59

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