LCOV - code coverage report
Current view: top level - Modules - _operator.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 508 585 86.8 %
Date: 2022-07-20 13:12:14 Functions: 86 88 97.7 %
Branches: 221 320 69.1 %

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

Generated by: LCOV version 1.14