LCOV - code coverage report
Current view: | top level - Modules - _operator.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 83 | 578 | 14.4 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 14 | 88 | 15.9 %
|  |  | Branches: | 36 | 320 | 11.2 %

               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                 :        104 : get_operator_state(PyObject *module)
          15                 :            : {
          16                 :        104 :     void *state = _PyModule_GetState(module);
          17                 :            :     assert(state != NULL);
          18                 :        104 :     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                 :          0 : _operator_truth_impl(PyObject *module, PyObject *a)
          47                 :            : /*[clinic end generated code: output=eaf87767234fa5d7 input=bc74a4cd90235875]*/
          48                 :            : {
          49                 :          0 :     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                 :          2 : _operator_add_impl(PyObject *module, PyObject *a, PyObject *b)
          64                 :            : /*[clinic end generated code: output=8292984204f45164 input=5efe3bff856ac215]*/
          65                 :            : {
          66                 :          2 :     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                 :          0 : _operator_sub_impl(PyObject *module, PyObject *a, PyObject *b)
          77                 :            : /*[clinic end generated code: output=4adfc3b888c1ee2e input=6494c6b100b8e795]*/
          78                 :            : {
          79                 :          0 :     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                 :          4 : _operator_mul_impl(PyObject *module, PyObject *a, PyObject *b)
          90                 :            : /*[clinic end generated code: output=d24d66f55a01944c input=2368615b4358b70d]*/
          91                 :            : {
          92                 :          4 :     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                 :          0 : _operator_matmul_impl(PyObject *module, PyObject *a, PyObject *b)
         103                 :            : /*[clinic end generated code: output=a20d917eb35d0101 input=9ab304e37fb42dd4]*/
         104                 :            : {
         105                 :          0 :     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                 :          0 : _operator_floordiv_impl(PyObject *module, PyObject *a, PyObject *b)
         116                 :            : /*[clinic end generated code: output=df26b71a60589f99 input=bb2e88ba446c612c]*/
         117                 :            : {
         118                 :          0 :     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                 :          0 : _operator_truediv_impl(PyObject *module, PyObject *a, PyObject *b)
         129                 :            : /*[clinic end generated code: output=0e6a959944d77719 input=ecbb947673f4eb1f]*/
         130                 :            : {
         131                 :          0 :     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                 :          0 : _operator_mod_impl(PyObject *module, PyObject *a, PyObject *b)
         142                 :            : /*[clinic end generated code: output=9519822f0bbec166 input=102e19b422342ac1]*/
         143                 :            : {
         144                 :          0 :     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                 :          0 : _operator_neg(PyObject *module, PyObject *a)
         158                 :            : /*[clinic end generated code: output=36e08ecfc6a1c08c input=84f09bdcf27c96ec]*/
         159                 :            : {
         160                 :          0 :     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                 :          0 : _operator_pos(PyObject *module, PyObject *a)
         171                 :            : /*[clinic end generated code: output=dad7a126221dd091 input=b6445b63fddb8772]*/
         172                 :            : {
         173                 :          0 :     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                 :          0 : _operator_abs(PyObject *module, PyObject *a)
         184                 :            : /*[clinic end generated code: output=1389a93ba053ea3e input=341d07ba86f58039]*/
         185                 :            : {
         186                 :          0 :     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                 :          0 : _operator_inv(PyObject *module, PyObject *a)
         197                 :            : /*[clinic end generated code: output=a56875ba075ee06d input=b01a4677739f6eb2]*/
         198                 :            : {
         199                 :          0 :     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                 :          0 : _operator_invert(PyObject *module, PyObject *a)
         210                 :            : /*[clinic end generated code: output=406b5aa030545fcc input=7f2d607176672e55]*/
         211                 :            : {
         212                 :          0 :     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                 :          0 : _operator_lshift_impl(PyObject *module, PyObject *a, PyObject *b)
         223                 :            : /*[clinic end generated code: output=37f7e52c41435bd8 input=746e8a160cbbc9eb]*/
         224                 :            : {
         225                 :          0 :     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                 :          0 : _operator_rshift_impl(PyObject *module, PyObject *a, PyObject *b)
         236                 :            : /*[clinic end generated code: output=4593c7ef30ec2ee3 input=d2c85bb5a64504c2]*/
         237                 :            : {
         238                 :          0 :     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                 :          0 : _operator_not__impl(PyObject *module, PyObject *a)
         249                 :            : /*[clinic end generated code: output=743f9c24a09759ef input=854156d50804d9b8]*/
         250                 :            : {
         251                 :          0 :     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                 :          0 : _operator_and__impl(PyObject *module, PyObject *a, PyObject *b)
         262                 :            : /*[clinic end generated code: output=93c4fe88f7b76d9e input=4f3057c90ec4c99f]*/
         263                 :            : {
         264                 :          0 :     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                 :          0 : _operator_xor_impl(PyObject *module, PyObject *a, PyObject *b)
         275                 :            : /*[clinic end generated code: output=b24cd8b79fde0004 input=3c5cfa7253d808dd]*/
         276                 :            : {
         277                 :          0 :     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                 :          0 : _operator_or__impl(PyObject *module, PyObject *a, PyObject *b)
         288                 :            : /*[clinic end generated code: output=58024867b8d90461 input=b40c6c44f7c79c09]*/
         289                 :            : {
         290                 :          0 :     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                 :          0 : _operator_iadd_impl(PyObject *module, PyObject *a, PyObject *b)
         301                 :            : /*[clinic end generated code: output=07dc627832526eb5 input=d22a91c07ac69227]*/
         302                 :            : {
         303                 :          0 :     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                 :          0 : _operator_isub_impl(PyObject *module, PyObject *a, PyObject *b)
         314                 :            : /*[clinic end generated code: output=4513467d23b5e0b1 input=4591b00d0a0ccafd]*/
         315                 :            : {
         316                 :          0 :     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                 :          0 : _operator_imul_impl(PyObject *module, PyObject *a, PyObject *b)
         327                 :            : /*[clinic end generated code: output=5e87dacd19a71eab input=0e01fb8631e1b76f]*/
         328                 :            : {
         329                 :          0 :     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                 :          0 : _operator_imatmul_impl(PyObject *module, PyObject *a, PyObject *b)
         340                 :            : /*[clinic end generated code: output=d603cbdf716ce519 input=bb614026372cd542]*/
         341                 :            : {
         342                 :          0 :     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                 :          0 : _operator_ifloordiv_impl(PyObject *module, PyObject *a, PyObject *b)
         353                 :            : /*[clinic end generated code: output=535336048c681794 input=9df3b5021cff4ca1]*/
         354                 :            : {
         355                 :          0 :     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                 :          0 : _operator_itruediv_impl(PyObject *module, PyObject *a, PyObject *b)
         366                 :            : /*[clinic end generated code: output=28017fbd3563952f input=9a1ee01608f5f590]*/
         367                 :            : {
         368                 :          0 :     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                 :          0 : _operator_imod_impl(PyObject *module, PyObject *a, PyObject *b)
         379                 :            : /*[clinic end generated code: output=f7c540ae0fc70904 input=d0c384a3ce38e1dd]*/
         380                 :            : {
         381                 :          0 :     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                 :          0 : _operator_ilshift_impl(PyObject *module, PyObject *a, PyObject *b)
         392                 :            : /*[clinic end generated code: output=e73a8fee1ac18749 input=e21b6b310f54572e]*/
         393                 :            : {
         394                 :          0 :     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                 :          0 : _operator_irshift_impl(PyObject *module, PyObject *a, PyObject *b)
         405                 :            : /*[clinic end generated code: output=97f2af6b5ff2ed81 input=6778dbd0f6e1ec16]*/
         406                 :            : {
         407                 :          0 :     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                 :          0 : _operator_iand_impl(PyObject *module, PyObject *a, PyObject *b)
         418                 :            : /*[clinic end generated code: output=4599e9d40cbf7d00 input=71dfd8e70c156a7b]*/
         419                 :            : {
         420                 :          0 :     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                 :          0 : _operator_ixor_impl(PyObject *module, PyObject *a, PyObject *b)
         431                 :            : /*[clinic end generated code: output=5ff881766872be03 input=695c32bec0604d86]*/
         432                 :            : {
         433                 :          0 :     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                 :          0 : _operator_ior_impl(PyObject *module, PyObject *a, PyObject *b)
         444                 :            : /*[clinic end generated code: output=48aac319445bf759 input=8f01d03eda9920cf]*/
         445                 :            : {
         446                 :          0 :     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                 :          0 : _operator_concat_impl(PyObject *module, PyObject *a, PyObject *b)
         457                 :            : /*[clinic end generated code: output=80028390942c5f11 input=8544ccd5341a3658]*/
         458                 :            : {
         459                 :          0 :     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                 :          0 : _operator_iconcat_impl(PyObject *module, PyObject *a, PyObject *b)
         470                 :            : /*[clinic end generated code: output=3ea0a162ebb2e26d input=8f5fe5722fcd837e]*/
         471                 :            : {
         472                 :          0 :     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                 :          0 : _operator_contains_impl(PyObject *module, PyObject *a, PyObject *b)
         487                 :            : /*[clinic end generated code: output=413b4dbe82b6ffc1 input=9122a69b505fde13]*/
         488                 :            : {
         489                 :          0 :     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                 :          0 : _operator_indexOf_impl(PyObject *module, PyObject *a, PyObject *b)
         504                 :            : /*[clinic end generated code: output=c6226d8e0fb60fa6 input=8be2e43b6a6fffe3]*/
         505                 :            : {
         506                 :          0 :     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                 :          0 : _operator_countOf_impl(PyObject *module, PyObject *a, PyObject *b)
         517                 :            : /*[clinic end generated code: output=9e1623197daf3382 input=93ea57f170f3f0bb]*/
         518                 :            : {
         519                 :          0 :     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                 :          0 : _operator_getitem_impl(PyObject *module, PyObject *a, PyObject *b)
         534                 :            : /*[clinic end generated code: output=6c8d8101a676e594 input=6682797320e48845]*/
         535                 :            : {
         536                 :          0 :     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                 :          0 : _operator_setitem_impl(PyObject *module, PyObject *a, PyObject *b,
         552                 :            :                        PyObject *c)
         553                 :            : /*[clinic end generated code: output=1324f9061ae99e25 input=ceaf453c4d3a58df]*/
         554                 :            : {
         555         [ #  # ]:          0 :     if (-1 == PyObject_SetItem(a, b, c))
         556                 :          0 :         return NULL;
         557                 :          0 :     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                 :          0 : _operator_delitem_impl(PyObject *module, PyObject *a, PyObject *b)
         568                 :            : /*[clinic end generated code: output=db18f61506295799 input=991bec56a0d3ec7f]*/
         569                 :            : {
         570         [ #  # ]:          0 :     if (-1 == PyObject_DelItem(a, b))
         571                 :          0 :         return NULL;
         572                 :          0 :     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                 :          0 : _operator_eq_impl(PyObject *module, PyObject *a, PyObject *b)
         587                 :            : /*[clinic end generated code: output=8d7d46ed4135677c input=586fca687a95a83f]*/
         588                 :            : {
         589                 :          0 :     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                 :          0 : _operator_ne_impl(PyObject *module, PyObject *a, PyObject *b)
         600                 :            : /*[clinic end generated code: output=c99bd0c3a4c01297 input=5d88f23d35e9abac]*/
         601                 :            : {
         602                 :          0 :     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                 :          0 : _operator_lt_impl(PyObject *module, PyObject *a, PyObject *b)
         613                 :            : /*[clinic end generated code: output=082d7c45c440e535 input=34a59ad6d39d3a2b]*/
         614                 :            : {
         615                 :          0 :     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                 :       9848 : _operator_le_impl(PyObject *module, PyObject *a, PyObject *b)
         626                 :            : /*[clinic end generated code: output=00970a2923d0ae17 input=b812a7860a0bef44]*/
         627                 :            : {
         628                 :       9848 :     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                 :          0 : _operator_gt_impl(PyObject *module, PyObject *a, PyObject *b)
         639                 :            : /*[clinic end generated code: output=8d373349ecf25641 input=9bdb45b995ada35b]*/
         640                 :            : {
         641                 :          0 :     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                 :          0 : _operator_ge_impl(PyObject *module, PyObject *a, PyObject *b)
         652                 :            : /*[clinic end generated code: output=7ce3882256d4b137 input=cf1dc4a5ca9c35f5]*/
         653                 :            : {
         654                 :          0 :     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                 :          0 : _operator_pow_impl(PyObject *module, PyObject *a, PyObject *b)
         665                 :            : /*[clinic end generated code: output=09e668ad50036120 input=690b40f097ab1637]*/
         666                 :            : {
         667                 :          0 :     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                 :          0 : _operator_ipow_impl(PyObject *module, PyObject *a, PyObject *b)
         678                 :            : /*[clinic end generated code: output=7189ff4d4367c808 input=f00623899d07499a]*/
         679                 :            : {
         680                 :          0 :     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                 :      10515 : _operator_index(PyObject *module, PyObject *a)
         694                 :            : /*[clinic end generated code: output=d972b0764ac305fc input=6f54d50ea64a579c]*/
         695                 :            : {
         696                 :      10515 :     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                 :          0 : _operator_is__impl(PyObject *module, PyObject *a, PyObject *b)
         707                 :            : /*[clinic end generated code: output=bcd47a402e482e1d input=5fa9b97df03c427f]*/
         708                 :            : {
         709         [ #  # ]:          0 :     PyObject *result = Py_Is(a, b) ? Py_True : Py_False;
         710                 :          0 :     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                 :          0 : _operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b)
         721                 :            : /*[clinic end generated code: output=491a1f2f81f6c7f9 input=5a93f7e1a93535f1]*/
         722                 :            : {
         723                 :            :     PyObject *result;
         724         [ #  # ]:          0 :     result = (a != b) ? Py_True : Py_False;
         725                 :          0 :     return Py_NewRef(result);
         726                 :            : }
         727                 :            :
         728                 :            : /* compare_digest **********************************************************/
         729                 :            :
         730                 :            : /*
         731                 :            :  * timing safe compare
         732                 :            :  *
         733                 :            :  * Returns 1 if the strings are equal.
         734                 :            :  * In case of len(a) != len(b) the function tries to keep the timing
         735                 :            :  * dependent on the length of b. CPU cache locality may still alter timing
         736                 :            :  * a bit.
         737                 :            :  */
         738                 :            : static int
         739                 :          0 : _tscmp(const unsigned char *a, const unsigned char *b,
         740                 :            :         Py_ssize_t len_a, Py_ssize_t len_b)
         741                 :            : {
         742                 :            :     /* The volatile type declarations make sure that the compiler has no
         743                 :            :      * chance to optimize and fold the code in any way that may change
         744                 :            :      * the timing.
         745                 :            :      */
         746                 :            :     volatile Py_ssize_t length;
         747                 :            :     volatile const unsigned char *left;
         748                 :            :     volatile const unsigned char *right;
         749                 :            :     Py_ssize_t i;
         750                 :            :     volatile unsigned char result;
         751                 :            :
         752                 :            :     /* loop count depends on length of b */
         753                 :          0 :     length = len_b;
         754                 :          0 :     left = NULL;
         755                 :          0 :     right = b;
         756                 :            :
         757                 :            :     /* don't use else here to keep the amount of CPU instructions constant,
         758                 :            :      * volatile forces re-evaluation
         759                 :            :      *  */
         760         [ #  # ]:          0 :     if (len_a == length) {
         761                 :          0 :         left = *((volatile const unsigned char**)&a);
         762                 :          0 :         result = 0;
         763                 :            :     }
         764         [ #  # ]:          0 :     if (len_a != length) {
         765                 :          0 :         left = b;
         766                 :          0 :         result = 1;
         767                 :            :     }
         768                 :            :
         769         [ #  # ]:          0 :     for (i=0; i < length; i++) {
         770                 :          0 :         result |= *left++ ^ *right++;
         771                 :            :     }
         772                 :            :
         773                 :          0 :     return (result == 0);
         774                 :            : }
         775                 :            :
         776                 :            : /*[clinic input]
         777                 :            : _operator.length_hint -> Py_ssize_t
         778                 :            :
         779                 :            :     obj: object
         780                 :            :     default: Py_ssize_t = 0
         781                 :            :     /
         782                 :            :
         783                 :            : Return an estimate of the number of items in obj.
         784                 :            :
         785                 :            : This is useful for presizing containers when building from an iterable.
         786                 :            :
         787                 :            : If the object supports len(), the result will be exact.
         788                 :            : Otherwise, it may over- or under-estimate by an arbitrary amount.
         789                 :            : The result will be an integer >= 0.
         790                 :            : [clinic start generated code]*/
         791                 :            :
         792                 :            : static Py_ssize_t
         793                 :          0 : _operator_length_hint_impl(PyObject *module, PyObject *obj,
         794                 :            :                            Py_ssize_t default_value)
         795                 :            : /*[clinic end generated code: output=01d469edc1d612ad input=65ed29f04401e96a]*/
         796                 :            : {
         797                 :          0 :     return PyObject_LengthHint(obj, default_value);
         798                 :            : }
         799                 :            :
         800                 :            : /* NOTE: Keep in sync with _hashopenssl.c implementation. */
         801                 :            :
         802                 :            : /*[clinic input]
         803                 :            : _operator._compare_digest = _operator.eq
         804                 :            :
         805                 :            : Return 'a == b'.
         806                 :            :
         807                 :            : This function uses an approach designed to prevent
         808                 :            : timing analysis, making it appropriate for cryptography.
         809                 :            :
         810                 :            : a and b must both be of the same type: either str (ASCII only),
         811                 :            : or any bytes-like object.
         812                 :            :
         813                 :            : Note: If a and b are of different lengths, or if an error occurs,
         814                 :            : a timing attack could theoretically reveal information about the
         815                 :            : types and lengths of a and b--but not their values.
         816                 :            : [clinic start generated code]*/
         817                 :            :
         818                 :            : static PyObject *
         819                 :          0 : _operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b)
         820                 :            : /*[clinic end generated code: output=11d452bdd3a23cbc input=9ac7e2c4e30bc356]*/
         821                 :            : {
         822                 :            :     int rc;
         823                 :            :
         824                 :            :     /* ASCII unicode string */
         825   [ #  #  #  # ]:          0 :     if(PyUnicode_Check(a) && PyUnicode_Check(b)) {
         826   [ #  #  #  # ]:          0 :         if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) {
         827                 :          0 :             return NULL;
         828                 :            :         }
         829   [ #  #  #  # ]:          0 :         if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) {
         830                 :          0 :             PyErr_SetString(PyExc_TypeError,
         831                 :            :                             "comparing strings with non-ASCII characters is "
         832                 :            :                             "not supported");
         833                 :          0 :             return NULL;
         834                 :            :         }
         835                 :            :
         836                 :          0 :         rc = _tscmp(PyUnicode_DATA(a),
         837                 :          0 :                     PyUnicode_DATA(b),
         838                 :            :                     PyUnicode_GET_LENGTH(a),
         839                 :            :                     PyUnicode_GET_LENGTH(b));
         840                 :            :     }
         841                 :            :     /* fallback to buffer interface for bytes, bytearray and other */
         842                 :            :     else {
         843                 :            :         Py_buffer view_a;
         844                 :            :         Py_buffer view_b;
         845                 :            :
         846   [ #  #  #  # ]:          0 :         if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) {
         847                 :          0 :             PyErr_Format(PyExc_TypeError,
         848                 :            :                          "unsupported operand types(s) or combination of types: "
         849                 :            :                          "'%.100s' and '%.100s'",
         850                 :          0 :                          Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
         851                 :          0 :             return NULL;
         852                 :            :         }
         853                 :            :
         854         [ #  # ]:          0 :         if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) {
         855                 :          0 :             return NULL;
         856                 :            :         }
         857         [ #  # ]:          0 :         if (view_a.ndim > 1) {
         858                 :          0 :             PyErr_SetString(PyExc_BufferError,
         859                 :            :                             "Buffer must be single dimension");
         860                 :          0 :             PyBuffer_Release(&view_a);
         861                 :          0 :             return NULL;
         862                 :            :         }
         863                 :            :
         864         [ #  # ]:          0 :         if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) {
         865                 :          0 :             PyBuffer_Release(&view_a);
         866                 :          0 :             return NULL;
         867                 :            :         }
         868         [ #  # ]:          0 :         if (view_b.ndim > 1) {
         869                 :          0 :             PyErr_SetString(PyExc_BufferError,
         870                 :            :                             "Buffer must be single dimension");
         871                 :          0 :             PyBuffer_Release(&view_a);
         872                 :          0 :             PyBuffer_Release(&view_b);
         873                 :          0 :             return NULL;
         874                 :            :         }
         875                 :            :
         876                 :          0 :         rc = _tscmp((const unsigned char*)view_a.buf,
         877                 :          0 :                     (const unsigned char*)view_b.buf,
         878                 :            :                     view_a.len,
         879                 :            :                     view_b.len);
         880                 :            :
         881                 :          0 :         PyBuffer_Release(&view_a);
         882                 :          0 :         PyBuffer_Release(&view_b);
         883                 :            :     }
         884                 :            :
         885                 :          0 :     return PyBool_FromLong(rc);
         886                 :            : }
         887                 :            :
         888                 :            : PyDoc_STRVAR(_operator_call__doc__,
         889                 :            : "call($module, obj, /, *args, **kwargs)\n"
         890                 :            : "--\n"
         891                 :            : "\n"
         892                 :            : "Same as obj(*args, **kwargs).");
         893                 :            :
         894                 :            : #define _OPERATOR_CALL_METHODDEF    \
         895                 :            :     {"call", _PyCFunction_CAST(_operator_call), METH_FASTCALL | METH_KEYWORDS, _operator_call__doc__},
         896                 :            :
         897                 :            : static PyObject *
         898                 :          0 : _operator_call(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
         899                 :            : {
         900         [ #  # ]:          0 :     if (!_PyArg_CheckPositional("call", nargs, 1, PY_SSIZE_T_MAX)) {
         901                 :          0 :         return NULL;
         902                 :            :     }
         903                 :          0 :     return PyObject_Vectorcall(
         904                 :            :             args[0],
         905                 :          0 :             &args[1], (PyVectorcall_NARGS(nargs) - 1) | PY_VECTORCALL_ARGUMENTS_OFFSET,
         906                 :            :             kwnames);
         907                 :            : }
         908                 :            :
         909                 :            : /* operator methods **********************************************************/
         910                 :            :
         911                 :            : static struct PyMethodDef operator_methods[] = {
         912                 :            :
         913                 :            :     _OPERATOR_TRUTH_METHODDEF
         914                 :            :     _OPERATOR_CONTAINS_METHODDEF
         915                 :            :     _OPERATOR_INDEXOF_METHODDEF
         916                 :            :     _OPERATOR_COUNTOF_METHODDEF
         917                 :            :     _OPERATOR_IS__METHODDEF
         918                 :            :     _OPERATOR_IS_NOT_METHODDEF
         919                 :            :     _OPERATOR_INDEX_METHODDEF
         920                 :            :     _OPERATOR_ADD_METHODDEF
         921                 :            :     _OPERATOR_SUB_METHODDEF
         922                 :            :     _OPERATOR_MUL_METHODDEF
         923                 :            :     _OPERATOR_MATMUL_METHODDEF
         924                 :            :     _OPERATOR_FLOORDIV_METHODDEF
         925                 :            :     _OPERATOR_TRUEDIV_METHODDEF
         926                 :            :     _OPERATOR_MOD_METHODDEF
         927                 :            :     _OPERATOR_NEG_METHODDEF
         928                 :            :     _OPERATOR_POS_METHODDEF
         929                 :            :     _OPERATOR_ABS_METHODDEF
         930                 :            :     _OPERATOR_INV_METHODDEF
         931                 :            :     _OPERATOR_INVERT_METHODDEF
         932                 :            :     _OPERATOR_LSHIFT_METHODDEF
         933                 :            :     _OPERATOR_RSHIFT_METHODDEF
         934                 :            :     _OPERATOR_NOT__METHODDEF
         935                 :            :     _OPERATOR_AND__METHODDEF
         936                 :            :     _OPERATOR_XOR_METHODDEF
         937                 :            :     _OPERATOR_OR__METHODDEF
         938                 :            :     _OPERATOR_IADD_METHODDEF
         939                 :            :     _OPERATOR_ISUB_METHODDEF
         940                 :            :     _OPERATOR_IMUL_METHODDEF
         941                 :            :     _OPERATOR_IMATMUL_METHODDEF
         942                 :            :     _OPERATOR_IFLOORDIV_METHODDEF
         943                 :            :     _OPERATOR_ITRUEDIV_METHODDEF
         944                 :            :     _OPERATOR_IMOD_METHODDEF
         945                 :            :     _OPERATOR_ILSHIFT_METHODDEF
         946                 :            :     _OPERATOR_IRSHIFT_METHODDEF
         947                 :            :     _OPERATOR_IAND_METHODDEF
         948                 :            :     _OPERATOR_IXOR_METHODDEF
         949                 :            :     _OPERATOR_IOR_METHODDEF
         950                 :            :     _OPERATOR_CONCAT_METHODDEF
         951                 :            :     _OPERATOR_ICONCAT_METHODDEF
         952                 :            :     _OPERATOR_GETITEM_METHODDEF
         953                 :            :     _OPERATOR_SETITEM_METHODDEF
         954                 :            :     _OPERATOR_DELITEM_METHODDEF
         955                 :            :     _OPERATOR_POW_METHODDEF
         956                 :            :     _OPERATOR_IPOW_METHODDEF
         957                 :            :     _OPERATOR_EQ_METHODDEF
         958                 :            :     _OPERATOR_NE_METHODDEF
         959                 :            :     _OPERATOR_LT_METHODDEF
         960                 :            :     _OPERATOR_LE_METHODDEF
         961                 :            :     _OPERATOR_GT_METHODDEF
         962                 :            :     _OPERATOR_GE_METHODDEF
         963                 :            :     _OPERATOR__COMPARE_DIGEST_METHODDEF
         964                 :            :     _OPERATOR_LENGTH_HINT_METHODDEF
         965                 :            :     _OPERATOR_CALL_METHODDEF
         966                 :            :     {NULL,              NULL}           /* sentinel */
         967                 :            :
         968                 :            : };
         969                 :            :
         970                 :            : /* itemgetter object **********************************************************/
         971                 :            :
         972                 :            : typedef struct {
         973                 :            :     PyObject_HEAD
         974                 :            :     Py_ssize_t nitems;
         975                 :            :     PyObject *item;
         976                 :            :     Py_ssize_t index; // -1 unless *item* is a single non-negative integer index
         977                 :            :     vectorcallfunc vectorcall;
         978                 :            : } itemgetterobject;
         979                 :            :
         980                 :            : // Forward declarations
         981                 :            : static PyObject *
         982                 :            : itemgetter_vectorcall(PyObject *, PyObject *const *, size_t, PyObject *);
         983                 :            : static PyObject *
         984                 :            : itemgetter_call_impl(itemgetterobject *, PyObject *);
         985                 :            :
         986                 :            : /* AC 3.5: treats first argument as an iterable, otherwise uses *args */
         987                 :            : static PyObject *
         988                 :          0 : itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         989                 :            : {
         990                 :            :     itemgetterobject *ig;
         991                 :            :     PyObject *item;
         992                 :            :     Py_ssize_t nitems;
         993                 :            :     Py_ssize_t index;
         994                 :            :
         995   [ #  #  #  # ]:          0 :     if (!_PyArg_NoKeywords("itemgetter", kwds))
         996                 :          0 :         return NULL;
         997                 :            :
         998                 :          0 :     nitems = PyTuple_GET_SIZE(args);
         999         [ #  # ]:          0 :     if (nitems <= 1) {
        1000         [ #  # ]:          0 :         if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item))
        1001                 :          0 :             return NULL;
        1002                 :            :     } else {
        1003                 :          0 :         item = args;
        1004                 :            :     }
        1005                 :          0 :     _operator_state *state = _PyType_GetModuleState(type);
        1006                 :            :     /* create itemgetterobject structure */
        1007                 :          0 :     ig = PyObject_GC_New(itemgetterobject, (PyTypeObject *) state->itemgetter_type);
        1008         [ #  # ]:          0 :     if (ig == NULL) {
        1009                 :          0 :         return NULL;
        1010                 :            :     }
        1011                 :            :
        1012                 :          0 :     ig->item = Py_NewRef(item);
        1013                 :          0 :     ig->nitems = nitems;
        1014                 :          0 :     ig->index = -1;
        1015         [ #  # ]:          0 :     if (PyLong_CheckExact(item)) {
        1016                 :          0 :         index = PyLong_AsSsize_t(item);
        1017         [ #  # ]:          0 :         if (index < 0) {
        1018                 :            :             /* If we get here, then either the index conversion failed
        1019                 :            :              * due to being out of range, or the index was a negative
        1020                 :            :              * integer.  Either way, we clear any possible exception
        1021                 :            :              * and fall back to the slow path, where ig->index is -1.
        1022                 :            :              */
        1023                 :          0 :             PyErr_Clear();
        1024                 :            :         }
        1025                 :            :         else {
        1026                 :          0 :             ig->index = index;
        1027                 :            :         }
        1028                 :            :     }
        1029                 :            :
        1030                 :          0 :     ig->vectorcall = (vectorcallfunc)itemgetter_vectorcall;
        1031                 :          0 :     PyObject_GC_Track(ig);
        1032                 :          0 :     return (PyObject *)ig;
        1033                 :            : }
        1034                 :            :
        1035                 :            : static int
        1036                 :          0 : itemgetter_clear(itemgetterobject *ig)
        1037                 :            : {
        1038         [ #  # ]:          0 :     Py_CLEAR(ig->item);
        1039                 :          0 :     return 0;
        1040                 :            : }
        1041                 :            :
        1042                 :            : static void
        1043                 :          0 : itemgetter_dealloc(itemgetterobject *ig)
        1044                 :            : {
        1045                 :          0 :     PyTypeObject *tp = Py_TYPE(ig);
        1046                 :          0 :     PyObject_GC_UnTrack(ig);
        1047                 :          0 :     (void)itemgetter_clear(ig);
        1048                 :          0 :     tp->tp_free(ig);
        1049                 :          0 :     Py_DECREF(tp);
        1050                 :          0 : }
        1051                 :            :
        1052                 :            : static int
        1053                 :          0 : itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
        1054                 :            : {
        1055   [ #  #  #  # ]:          0 :     Py_VISIT(Py_TYPE(ig));
        1056   [ #  #  #  # ]:          0 :     Py_VISIT(ig->item);
        1057                 :          0 :     return 0;
        1058                 :            : }
        1059                 :            :
        1060                 :            : static PyObject *
        1061                 :          0 : itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
        1062                 :            : {
        1063                 :            :     assert(PyTuple_CheckExact(args));
        1064   [ #  #  #  # ]:          0 :     if (!_PyArg_NoKeywords("itemgetter", kw))
        1065                 :          0 :         return NULL;
        1066   [ #  #  #  #  :          0 :     if (!_PyArg_CheckPositional("itemgetter", PyTuple_GET_SIZE(args), 1, 1))
                       #  # ]
        1067                 :          0 :         return NULL;
        1068                 :          0 :     return itemgetter_call_impl(ig, PyTuple_GET_ITEM(args, 0));
        1069                 :            : }
        1070                 :            :
        1071                 :            : static PyObject *
        1072                 :          0 : itemgetter_vectorcall(PyObject *ig, PyObject *const *args,
        1073                 :            :                       size_t nargsf, PyObject *kwnames)
        1074                 :            : {
        1075   [ #  #  #  # ]:          0 :     if (!_PyArg_NoKwnames("itemgetter", kwnames)) {
        1076                 :          0 :         return NULL;
        1077                 :            :     }
        1078                 :          0 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
        1079   [ #  #  #  #  :          0 :     if (!_PyArg_CheckPositional("itemgetter", nargs, 1, 1)) {
                       #  # ]
        1080                 :          0 :         return NULL;
        1081                 :            :     }
        1082                 :          0 :     return itemgetter_call_impl((itemgetterobject *)ig, args[0]);
        1083                 :            : }
        1084                 :            :
        1085                 :            : static PyObject *
        1086                 :          0 : itemgetter_call_impl(itemgetterobject *ig, PyObject *obj)
        1087                 :            : {
        1088                 :            :     PyObject *result;
        1089                 :          0 :     Py_ssize_t i, nitems=ig->nitems;
        1090         [ #  # ]:          0 :     if (nitems == 1) {
        1091         [ #  # ]:          0 :         if (ig->index >= 0
        1092         [ #  # ]:          0 :             && PyTuple_CheckExact(obj)
        1093         [ #  # ]:          0 :             && ig->index < PyTuple_GET_SIZE(obj))
        1094                 :            :         {
        1095                 :          0 :             result = PyTuple_GET_ITEM(obj, ig->index);
        1096                 :          0 :             return Py_NewRef(result);
        1097                 :            :         }
        1098                 :          0 :         return PyObject_GetItem(obj, ig->item);
        1099                 :            :     }
        1100                 :            :
        1101                 :            :     assert(PyTuple_Check(ig->item));
        1102                 :            :     assert(PyTuple_GET_SIZE(ig->item) == nitems);
        1103                 :            :
        1104                 :          0 :     result = PyTuple_New(nitems);
        1105         [ #  # ]:          0 :     if (result == NULL)
        1106                 :          0 :         return NULL;
        1107                 :            :
        1108         [ #  # ]:          0 :     for (i=0 ; i < nitems ; i++) {
        1109                 :            :         PyObject *item, *val;
        1110                 :          0 :         item = PyTuple_GET_ITEM(ig->item, i);
        1111                 :          0 :         val = PyObject_GetItem(obj, item);
        1112         [ #  # ]:          0 :         if (val == NULL) {
        1113                 :          0 :             Py_DECREF(result);
        1114                 :          0 :             return NULL;
        1115                 :            :         }
        1116                 :          0 :         PyTuple_SET_ITEM(result, i, val);
        1117                 :            :     }
        1118                 :          0 :     return result;
        1119                 :            : }
        1120                 :            :
        1121                 :            : static PyObject *
        1122                 :          0 : itemgetter_repr(itemgetterobject *ig)
        1123                 :            : {
        1124                 :            :     PyObject *repr;
        1125                 :            :     const char *reprfmt;
        1126                 :            :
        1127                 :          0 :     int status = Py_ReprEnter((PyObject *)ig);
        1128         [ #  # ]:          0 :     if (status != 0) {
        1129         [ #  # ]:          0 :         if (status < 0)
        1130                 :          0 :             return NULL;
        1131                 :          0 :         return PyUnicode_FromFormat("%s(...)", Py_TYPE(ig)->tp_name);
        1132                 :            :     }
        1133                 :            :
        1134         [ #  # ]:          0 :     reprfmt = ig->nitems == 1 ? "%s(%R)" : "%s%R";
        1135                 :          0 :     repr = PyUnicode_FromFormat(reprfmt, Py_TYPE(ig)->tp_name, ig->item);
        1136                 :          0 :     Py_ReprLeave((PyObject *)ig);
        1137                 :          0 :     return repr;
        1138                 :            : }
        1139                 :            :
        1140                 :            : static PyObject *
        1141                 :          0 : itemgetter_reduce(itemgetterobject *ig, PyObject *Py_UNUSED(ignored))
        1142                 :            : {
        1143         [ #  # ]:          0 :     if (ig->nitems == 1)
        1144                 :          0 :         return Py_BuildValue("O(O)", Py_TYPE(ig), ig->item);
        1145                 :          0 :     return PyTuple_Pack(2, Py_TYPE(ig), ig->item);
        1146                 :            : }
        1147                 :            :
        1148                 :            : PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
        1149                 :            :
        1150                 :            : static PyMethodDef itemgetter_methods[] = {
        1151                 :            :     {"__reduce__", (PyCFunction)itemgetter_reduce, METH_NOARGS,
        1152                 :            :      reduce_doc},
        1153                 :            :     {NULL}
        1154                 :            : };
        1155                 :            :
        1156                 :            : static PyMemberDef itemgetter_members[] = {
        1157                 :            :     {"__vectorcalloffset__", T_PYSSIZET, offsetof(itemgetterobject, vectorcall), READONLY},
        1158                 :            :     {NULL} /* Sentinel */
        1159                 :            : };
        1160                 :            :
        1161                 :            : PyDoc_STRVAR(itemgetter_doc,
        1162                 :            : "itemgetter(item, /, *items)\n--\n\n\
        1163                 :            : Return a callable object that fetches the given item(s) from its operand.\n\
        1164                 :            : After f = itemgetter(2), the call f(r) returns r[2].\n\
        1165                 :            : After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])");
        1166                 :            :
        1167                 :            : static PyType_Slot itemgetter_type_slots[] = {
        1168                 :            :     {Py_tp_doc, (void *)itemgetter_doc},
        1169                 :            :     {Py_tp_dealloc, itemgetter_dealloc},
        1170                 :            :     {Py_tp_call, itemgetter_call},
        1171                 :            :     {Py_tp_traverse, itemgetter_traverse},
        1172                 :            :     {Py_tp_clear, itemgetter_clear},
        1173                 :            :     {Py_tp_methods, itemgetter_methods},
        1174                 :            :     {Py_tp_members, itemgetter_members},
        1175                 :            :     {Py_tp_new, itemgetter_new},
        1176                 :            :     {Py_tp_getattro, PyObject_GenericGetAttr},
        1177                 :            :     {Py_tp_repr, itemgetter_repr},
        1178                 :            :     {0, 0}
        1179                 :            : };
        1180                 :            :
        1181                 :            : static PyType_Spec itemgetter_type_spec = {
        1182                 :            :     .name = "operator.itemgetter",
        1183                 :            :     .basicsize = sizeof(itemgetterobject),
        1184                 :            :     .itemsize = 0,
        1185                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        1186                 :            :               Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_VECTORCALL),
        1187                 :            :     .slots = itemgetter_type_slots,
        1188                 :            : };
        1189                 :            :
        1190                 :            : /* attrgetter object **********************************************************/
        1191                 :            :
        1192                 :            : typedef struct {
        1193                 :            :     PyObject_HEAD
        1194                 :            :     Py_ssize_t nattrs;
        1195                 :            :     PyObject *attr;
        1196                 :            :     vectorcallfunc vectorcall;
        1197                 :            : } attrgetterobject;
        1198                 :            :
        1199                 :            : // Forward declarations
        1200                 :            : static PyObject *
        1201                 :            : attrgetter_vectorcall(PyObject *, PyObject *const *, size_t, PyObject *);
        1202                 :            : static PyObject *
        1203                 :            : attrgetter_call_impl(attrgetterobject *, PyObject *);
        1204                 :            :
        1205                 :            : /* AC 3.5: treats first argument as an iterable, otherwise uses *args */
        1206                 :            : static PyObject *
        1207                 :          2 : attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        1208                 :            : {
        1209                 :            :     attrgetterobject *ag;
        1210                 :            :     PyObject *attr;
        1211                 :            :     Py_ssize_t nattrs, idx, char_idx;
        1212                 :            :
        1213   [ -  +  -  - ]:          2 :     if (!_PyArg_NoKeywords("attrgetter", kwds))
        1214                 :          0 :         return NULL;
        1215                 :            :
        1216                 :          2 :     nattrs = PyTuple_GET_SIZE(args);
        1217         [ +  - ]:          2 :     if (nattrs <= 1) {
        1218         [ -  + ]:          2 :         if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
        1219                 :          0 :             return NULL;
        1220                 :            :     }
        1221                 :            :
        1222                 :          2 :     attr = PyTuple_New(nattrs);
        1223         [ -  + ]:          2 :     if (attr == NULL)
        1224                 :          0 :         return NULL;
        1225                 :            :
        1226                 :            :     /* prepare attr while checking args */
        1227         [ +  + ]:          4 :     for (idx = 0; idx < nattrs; ++idx) {
        1228                 :          2 :         PyObject *item = PyTuple_GET_ITEM(args, idx);
        1229                 :            :         int dot_count;
        1230                 :            :
        1231         [ -  + ]:          2 :         if (!PyUnicode_Check(item)) {
        1232                 :          0 :             PyErr_SetString(PyExc_TypeError,
        1233                 :            :                             "attribute name must be a string");
        1234                 :          0 :             Py_DECREF(attr);
        1235                 :          0 :             return NULL;
        1236                 :            :         }
        1237         [ -  + ]:          2 :         if (PyUnicode_READY(item)) {
        1238                 :          0 :             Py_DECREF(attr);
        1239                 :          0 :             return NULL;
        1240                 :            :         }
        1241                 :          2 :         Py_ssize_t item_len = PyUnicode_GET_LENGTH(item);
        1242                 :          2 :         int kind = PyUnicode_KIND(item);
        1243                 :          2 :         const void *data = PyUnicode_DATA(item);
        1244                 :            :
        1245                 :            :         /* check whether the string is dotted */
        1246                 :          2 :         dot_count = 0;
        1247         [ +  + ]:         11 :         for (char_idx = 0; char_idx < item_len; ++char_idx) {
        1248         [ -  + ]:          9 :             if (PyUnicode_READ(kind, data, char_idx) == '.')
        1249                 :          0 :                 ++dot_count;
        1250                 :            :         }
        1251                 :            :
        1252         [ +  - ]:          2 :         if (dot_count == 0) {
        1253                 :          2 :             Py_INCREF(item);
        1254                 :          2 :             PyUnicode_InternInPlace(&item);
        1255                 :          2 :             PyTuple_SET_ITEM(attr, idx, item);
        1256                 :            :         } else { /* make it a tuple of non-dotted attrnames */
        1257                 :          0 :             PyObject *attr_chain = PyTuple_New(dot_count + 1);
        1258                 :            :             PyObject *attr_chain_item;
        1259                 :          0 :             Py_ssize_t unibuff_from = 0;
        1260                 :          0 :             Py_ssize_t unibuff_till = 0;
        1261                 :          0 :             Py_ssize_t attr_chain_idx = 0;
        1262                 :            :
        1263         [ #  # ]:          0 :             if (attr_chain == NULL) {
        1264                 :          0 :                 Py_DECREF(attr);
        1265                 :          0 :                 return NULL;
        1266                 :            :             }
        1267                 :            :
        1268         [ #  # ]:          0 :             for (; dot_count > 0; --dot_count) {
        1269         [ #  # ]:          0 :                 while (PyUnicode_READ(kind, data, unibuff_till) != '.') {
        1270                 :          0 :                     ++unibuff_till;
        1271                 :            :                 }
        1272                 :          0 :                 attr_chain_item = PyUnicode_Substring(item,
        1273                 :            :                                       unibuff_from,
        1274                 :            :                                       unibuff_till);
        1275         [ #  # ]:          0 :                 if (attr_chain_item == NULL) {
        1276                 :          0 :                     Py_DECREF(attr_chain);
        1277                 :          0 :                     Py_DECREF(attr);
        1278                 :          0 :                     return NULL;
        1279                 :            :                 }
        1280                 :          0 :                 PyUnicode_InternInPlace(&attr_chain_item);
        1281                 :          0 :                 PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
        1282                 :          0 :                 ++attr_chain_idx;
        1283                 :          0 :                 unibuff_till = unibuff_from = unibuff_till + 1;
        1284                 :            :             }
        1285                 :            :
        1286                 :            :             /* now add the last dotless name */
        1287                 :          0 :             attr_chain_item = PyUnicode_Substring(item,
        1288                 :            :                                                   unibuff_from, item_len);
        1289         [ #  # ]:          0 :             if (attr_chain_item == NULL) {
        1290                 :          0 :                 Py_DECREF(attr_chain);
        1291                 :          0 :                 Py_DECREF(attr);
        1292                 :          0 :                 return NULL;
        1293                 :            :             }
        1294                 :          0 :             PyUnicode_InternInPlace(&attr_chain_item);
        1295                 :          0 :             PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
        1296                 :            :
        1297                 :          0 :             PyTuple_SET_ITEM(attr, idx, attr_chain);
        1298                 :            :         }
        1299                 :            :     }
        1300                 :            :
        1301                 :          2 :     _operator_state *state = _PyType_GetModuleState(type);
        1302                 :            :     /* create attrgetterobject structure */
        1303                 :          2 :     ag = PyObject_GC_New(attrgetterobject, (PyTypeObject *)state->attrgetter_type);
        1304         [ -  + ]:          2 :     if (ag == NULL) {
        1305                 :          0 :         Py_DECREF(attr);
        1306                 :          0 :         return NULL;
        1307                 :            :     }
        1308                 :            :
        1309                 :          2 :     ag->attr = attr;
        1310                 :          2 :     ag->nattrs = nattrs;
        1311                 :          2 :     ag->vectorcall = (vectorcallfunc)attrgetter_vectorcall;
        1312                 :            :
        1313                 :          2 :     PyObject_GC_Track(ag);
        1314                 :          2 :     return (PyObject *)ag;
        1315                 :            : }
        1316                 :            :
        1317                 :            : static int
        1318                 :          2 : attrgetter_clear(attrgetterobject *ag)
        1319                 :            : {
        1320         [ +  - ]:          2 :     Py_CLEAR(ag->attr);
        1321                 :          2 :     return 0;
        1322                 :            : }
        1323                 :            :
        1324                 :            : static void
        1325                 :          2 : attrgetter_dealloc(attrgetterobject *ag)
        1326                 :            : {
        1327                 :          2 :     PyTypeObject *tp = Py_TYPE(ag);
        1328                 :          2 :     PyObject_GC_UnTrack(ag);
        1329                 :          2 :     (void)attrgetter_clear(ag);
        1330                 :          2 :     tp->tp_free(ag);
        1331                 :          2 :     Py_DECREF(tp);
        1332                 :          2 : }
        1333                 :            :
        1334                 :            : static int
        1335                 :         16 : attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
        1336                 :            : {
        1337   [ +  -  -  + ]:         16 :     Py_VISIT(ag->attr);
        1338   [ +  -  -  + ]:         16 :     Py_VISIT(Py_TYPE(ag));
        1339                 :         16 :     return 0;
        1340                 :            : }
        1341                 :            :
        1342                 :            : static PyObject *
        1343                 :          0 : dotted_getattr(PyObject *obj, PyObject *attr)
        1344                 :            : {
        1345                 :            :     PyObject *newobj;
        1346                 :            :
        1347                 :            :     /* attr is either a tuple or instance of str.
        1348                 :            :        Ensured by the setup code of attrgetter_new */
        1349         [ #  # ]:          0 :     if (PyTuple_CheckExact(attr)) { /* chained getattr */
        1350                 :          0 :         Py_ssize_t name_idx = 0, name_count;
        1351                 :            :         PyObject *attr_name;
        1352                 :            :
        1353                 :          0 :         name_count = PyTuple_GET_SIZE(attr);
        1354                 :          0 :         Py_INCREF(obj);
        1355         [ #  # ]:          0 :         for (name_idx = 0; name_idx < name_count; ++name_idx) {
        1356                 :          0 :             attr_name = PyTuple_GET_ITEM(attr, name_idx);
        1357                 :          0 :             newobj = PyObject_GetAttr(obj, attr_name);
        1358                 :          0 :             Py_DECREF(obj);
        1359         [ #  # ]:          0 :             if (newobj == NULL) {
        1360                 :          0 :                 return NULL;
        1361                 :            :             }
        1362                 :            :             /* here */
        1363                 :          0 :             obj = newobj;
        1364                 :            :         }
        1365                 :            :     } else { /* single getattr */
        1366                 :          0 :         newobj = PyObject_GetAttr(obj, attr);
        1367         [ #  # ]:          0 :         if (newobj == NULL)
        1368                 :          0 :             return NULL;
        1369                 :          0 :         obj = newobj;
        1370                 :            :     }
        1371                 :            :
        1372                 :          0 :     return obj;
        1373                 :            : }
        1374                 :            :
        1375                 :            : static PyObject *
        1376                 :          0 : attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
        1377                 :            : {
        1378   [ #  #  #  # ]:          0 :     if (!_PyArg_NoKeywords("attrgetter", kw))
        1379                 :          0 :         return NULL;
        1380   [ #  #  #  #  :          0 :     if (!_PyArg_CheckPositional("attrgetter", PyTuple_GET_SIZE(args), 1, 1))
                       #  # ]
        1381                 :          0 :         return NULL;
        1382                 :          0 :     return attrgetter_call_impl(ag, PyTuple_GET_ITEM(args, 0));
        1383                 :            : }
        1384                 :            :
        1385                 :            : static PyObject *
        1386                 :          0 : attrgetter_vectorcall(PyObject *ag, PyObject *const *args, size_t nargsf, PyObject *kwnames)
        1387                 :            : {
        1388   [ #  #  #  # ]:          0 :     if (!_PyArg_NoKwnames("attrgetter", kwnames)) {
        1389                 :          0 :         return NULL;
        1390                 :            :     }
        1391                 :          0 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
        1392   [ #  #  #  #  :          0 :     if (!_PyArg_CheckPositional("attrgetter", nargs, 1, 1)) {
                       #  # ]
        1393                 :          0 :         return NULL;
        1394                 :            :     }
        1395                 :          0 :     return attrgetter_call_impl((attrgetterobject *)ag, args[0]);
        1396                 :            : }
        1397                 :            :
        1398                 :            : static PyObject *
        1399                 :          0 : attrgetter_call_impl(attrgetterobject *ag, PyObject *obj)
        1400                 :            : {
        1401                 :            :     PyObject *result;
        1402                 :          0 :     Py_ssize_t i, nattrs=ag->nattrs;
        1403                 :            :
        1404         [ #  # ]:          0 :     if (ag->nattrs == 1) {
        1405                 :            :         /* ag->attr is always a tuple */
        1406                 :          0 :         return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0));
        1407                 :            :     }
        1408                 :            :
        1409                 :            :     assert(PyTuple_Check(ag->attr));
        1410                 :            :     assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
        1411                 :            :
        1412                 :          0 :     result = PyTuple_New(nattrs);
        1413         [ #  # ]:          0 :     if (result == NULL)
        1414                 :          0 :         return NULL;
        1415                 :            :
        1416         [ #  # ]:          0 :     for (i=0 ; i < nattrs ; i++) {
        1417                 :            :         PyObject *attr, *val;
        1418                 :          0 :         attr = PyTuple_GET_ITEM(ag->attr, i);
        1419                 :          0 :         val = dotted_getattr(obj, attr);
        1420         [ #  # ]:          0 :         if (val == NULL) {
        1421                 :          0 :             Py_DECREF(result);
        1422                 :          0 :             return NULL;
        1423                 :            :         }
        1424                 :          0 :         PyTuple_SET_ITEM(result, i, val);
        1425                 :            :     }
        1426                 :          0 :     return result;
        1427                 :            : }
        1428                 :            :
        1429                 :            : static PyObject *
        1430                 :          0 : dotjoinattr(PyObject *attr, PyObject **attrsep)
        1431                 :            : {
        1432         [ #  # ]:          0 :     if (PyTuple_CheckExact(attr)) {
        1433         [ #  # ]:          0 :         if (*attrsep == NULL) {
        1434                 :          0 :             *attrsep = PyUnicode_FromString(".");
        1435         [ #  # ]:          0 :             if (*attrsep == NULL)
        1436                 :          0 :                 return NULL;
        1437                 :            :         }
        1438                 :          0 :         return PyUnicode_Join(*attrsep, attr);
        1439                 :            :     } else {
        1440                 :          0 :         return Py_NewRef(attr);
        1441                 :            :     }
        1442                 :            : }
        1443                 :            :
        1444                 :            : static PyObject *
        1445                 :          0 : attrgetter_args(attrgetterobject *ag)
        1446                 :            : {
        1447                 :            :     Py_ssize_t i;
        1448                 :          0 :     PyObject *attrsep = NULL;
        1449                 :          0 :     PyObject *attrstrings = PyTuple_New(ag->nattrs);
        1450         [ #  # ]:          0 :     if (attrstrings == NULL)
        1451                 :          0 :         return NULL;
        1452                 :            :
        1453         [ #  # ]:          0 :     for (i = 0; i < ag->nattrs; ++i) {
        1454                 :          0 :         PyObject *attr = PyTuple_GET_ITEM(ag->attr, i);
        1455                 :          0 :         PyObject *attrstr = dotjoinattr(attr, &attrsep);
        1456         [ #  # ]:          0 :         if (attrstr == NULL) {
        1457                 :          0 :             Py_XDECREF(attrsep);
        1458                 :          0 :             Py_DECREF(attrstrings);
        1459                 :          0 :             return NULL;
        1460                 :            :         }
        1461                 :          0 :         PyTuple_SET_ITEM(attrstrings, i, attrstr);
        1462                 :            :     }
        1463                 :          0 :     Py_XDECREF(attrsep);
        1464                 :          0 :     return attrstrings;
        1465                 :            : }
        1466                 :            :
        1467                 :            : static PyObject *
        1468                 :          0 : attrgetter_repr(attrgetterobject *ag)
        1469                 :            : {
        1470                 :          0 :     PyObject *repr = NULL;
        1471                 :          0 :     int status = Py_ReprEnter((PyObject *)ag);
        1472         [ #  # ]:          0 :     if (status != 0) {
        1473         [ #  # ]:          0 :         if (status < 0)
        1474                 :          0 :             return NULL;
        1475                 :          0 :         return PyUnicode_FromFormat("%s(...)", Py_TYPE(ag)->tp_name);
        1476                 :            :     }
        1477                 :            :
        1478         [ #  # ]:          0 :     if (ag->nattrs == 1) {
        1479                 :          0 :         PyObject *attrsep = NULL;
        1480                 :          0 :         PyObject *attr = dotjoinattr(PyTuple_GET_ITEM(ag->attr, 0), &attrsep);
        1481         [ #  # ]:          0 :         if (attr != NULL) {
        1482                 :          0 :             repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(ag)->tp_name, attr);
        1483                 :          0 :             Py_DECREF(attr);
        1484                 :            :         }
        1485                 :          0 :         Py_XDECREF(attrsep);
        1486                 :            :     }
        1487                 :            :     else {
        1488                 :          0 :         PyObject *attrstrings = attrgetter_args(ag);
        1489         [ #  # ]:          0 :         if (attrstrings != NULL) {
        1490                 :          0 :             repr = PyUnicode_FromFormat("%s%R",
        1491                 :          0 :                                         Py_TYPE(ag)->tp_name, attrstrings);
        1492                 :          0 :             Py_DECREF(attrstrings);
        1493                 :            :         }
        1494                 :            :     }
        1495                 :          0 :     Py_ReprLeave((PyObject *)ag);
        1496                 :          0 :     return repr;
        1497                 :            : }
        1498                 :            :
        1499                 :            : static PyObject *
        1500                 :          0 : attrgetter_reduce(attrgetterobject *ag, PyObject *Py_UNUSED(ignored))
        1501                 :            : {
        1502                 :          0 :     PyObject *attrstrings = attrgetter_args(ag);
        1503         [ #  # ]:          0 :     if (attrstrings == NULL)
        1504                 :          0 :         return NULL;
        1505                 :            :
        1506                 :          0 :     return Py_BuildValue("ON", Py_TYPE(ag), attrstrings);
        1507                 :            : }
        1508                 :            :
        1509                 :            : static PyMethodDef attrgetter_methods[] = {
        1510                 :            :     {"__reduce__", (PyCFunction)attrgetter_reduce, METH_NOARGS,
        1511                 :            :      reduce_doc},
        1512                 :            :     {NULL}
        1513                 :            : };
        1514                 :            :
        1515                 :            : static PyMemberDef attrgetter_members[] = {
        1516                 :            :     {"__vectorcalloffset__", T_PYSSIZET, offsetof(attrgetterobject, vectorcall), READONLY},
        1517                 :            :     {NULL} /* Sentinel*/
        1518                 :            : };
        1519                 :            :
        1520                 :            : PyDoc_STRVAR(attrgetter_doc,
        1521                 :            : "attrgetter(attr, /, *attrs)\n--\n\n\
        1522                 :            : Return a callable object that fetches the given attribute(s) from its operand.\n\
        1523                 :            : After f = attrgetter('name'), the call f(r) returns r.name.\n\
        1524                 :            : After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\
        1525                 :            : After h = attrgetter('name.first', 'name.last'), the call h(r) returns\n\
        1526                 :            : (r.name.first, r.name.last).");
        1527                 :            :
        1528                 :            : static PyType_Slot attrgetter_type_slots[] = {
        1529                 :            :     {Py_tp_doc, (void *)attrgetter_doc},
        1530                 :            :     {Py_tp_dealloc, attrgetter_dealloc},
        1531                 :            :     {Py_tp_call, attrgetter_call},
        1532                 :            :     {Py_tp_traverse, attrgetter_traverse},
        1533                 :            :     {Py_tp_clear, attrgetter_clear},
        1534                 :            :     {Py_tp_methods, attrgetter_methods},
        1535                 :            :     {Py_tp_members, attrgetter_members},
        1536                 :            :     {Py_tp_new, attrgetter_new},
        1537                 :            :     {Py_tp_getattro, PyObject_GenericGetAttr},
        1538                 :            :     {Py_tp_repr, attrgetter_repr},
        1539                 :            :     {0, 0}
        1540                 :            : };
        1541                 :            :
        1542                 :            : static PyType_Spec attrgetter_type_spec = {
        1543                 :            :     .name = "operator.attrgetter",
        1544                 :            :     .basicsize = sizeof(attrgetterobject),
        1545                 :            :     .itemsize = 0,
        1546                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        1547                 :            :               Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_VECTORCALL),
        1548                 :            :     .slots = attrgetter_type_slots,
        1549                 :            : };
        1550                 :            :
        1551                 :            :
        1552                 :            : /* methodcaller object **********************************************************/
        1553                 :            :
        1554                 :            : typedef struct {
        1555                 :            :     PyObject_HEAD
        1556                 :            :     PyObject *name;
        1557                 :            :     PyObject *args;
        1558                 :            :     PyObject *kwds;
        1559                 :            : } methodcallerobject;
        1560                 :            :
        1561                 :            : /* AC 3.5: variable number of arguments, not currently support by AC */
        1562                 :            : static PyObject *
        1563                 :          0 : methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        1564                 :            : {
        1565                 :            :     methodcallerobject *mc;
        1566                 :            :     PyObject *name;
        1567                 :            :
        1568         [ #  # ]:          0 :     if (PyTuple_GET_SIZE(args) < 1) {
        1569                 :          0 :         PyErr_SetString(PyExc_TypeError, "methodcaller needs at least "
        1570                 :            :                         "one argument, the method name");
        1571                 :          0 :         return NULL;
        1572                 :            :     }
        1573                 :            :
        1574                 :          0 :     name = PyTuple_GET_ITEM(args, 0);
        1575         [ #  # ]:          0 :     if (!PyUnicode_Check(name)) {
        1576                 :          0 :         PyErr_SetString(PyExc_TypeError,
        1577                 :            :                         "method name must be a string");
        1578                 :          0 :         return NULL;
        1579                 :            :     }
        1580                 :            :
        1581                 :          0 :     _operator_state *state = _PyType_GetModuleState(type);
        1582                 :            :     /* create methodcallerobject structure */
        1583                 :          0 :     mc = PyObject_GC_New(methodcallerobject, (PyTypeObject *)state->methodcaller_type);
        1584         [ #  # ]:          0 :     if (mc == NULL) {
        1585                 :          0 :         return NULL;
        1586                 :            :     }
        1587                 :            :
        1588                 :          0 :     name = PyTuple_GET_ITEM(args, 0);
        1589                 :          0 :     Py_INCREF(name);
        1590                 :          0 :     PyUnicode_InternInPlace(&name);
        1591                 :          0 :     mc->name = name;
        1592                 :            :
        1593                 :          0 :     mc->kwds = Py_XNewRef(kwds);
        1594                 :            :
        1595                 :          0 :     mc->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
        1596         [ #  # ]:          0 :     if (mc->args == NULL) {
        1597                 :          0 :         Py_DECREF(mc);
        1598                 :          0 :         return NULL;
        1599                 :            :     }
        1600                 :            :
        1601                 :          0 :     PyObject_GC_Track(mc);
        1602                 :          0 :     return (PyObject *)mc;
        1603                 :            : }
        1604                 :            :
        1605                 :            : static int
        1606                 :          0 : methodcaller_clear(methodcallerobject *mc)
        1607                 :            : {
        1608         [ #  # ]:          0 :     Py_CLEAR(mc->name);
        1609         [ #  # ]:          0 :     Py_CLEAR(mc->args);
        1610         [ #  # ]:          0 :     Py_CLEAR(mc->kwds);
        1611                 :          0 :     return 0;
        1612                 :            : }
        1613                 :            :
        1614                 :            : static void
        1615                 :          0 : methodcaller_dealloc(methodcallerobject *mc)
        1616                 :            : {
        1617                 :          0 :     PyTypeObject *tp = Py_TYPE(mc);
        1618                 :          0 :     PyObject_GC_UnTrack(mc);
        1619                 :          0 :     (void)methodcaller_clear(mc);
        1620                 :          0 :     tp->tp_free(mc);
        1621                 :          0 :     Py_DECREF(tp);
        1622                 :          0 : }
        1623                 :            :
        1624                 :            : static int
        1625                 :          0 : methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
        1626                 :            : {
        1627   [ #  #  #  # ]:          0 :     Py_VISIT(mc->name);
        1628   [ #  #  #  # ]:          0 :     Py_VISIT(mc->args);
        1629   [ #  #  #  # ]:          0 :     Py_VISIT(mc->kwds);
        1630   [ #  #  #  # ]:          0 :     Py_VISIT(Py_TYPE(mc));
        1631                 :          0 :     return 0;
        1632                 :            : }
        1633                 :            :
        1634                 :            : static PyObject *
        1635                 :          0 : methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw)
        1636                 :            : {
        1637                 :            :     PyObject *method, *obj, *result;
        1638                 :            :
        1639   [ #  #  #  # ]:          0 :     if (!_PyArg_NoKeywords("methodcaller", kw))
        1640                 :          0 :         return NULL;
        1641   [ #  #  #  #  :          0 :     if (!_PyArg_CheckPositional("methodcaller", PyTuple_GET_SIZE(args), 1, 1))
                       #  # ]
        1642                 :          0 :         return NULL;
        1643                 :          0 :     obj = PyTuple_GET_ITEM(args, 0);
        1644                 :          0 :     method = PyObject_GetAttr(obj, mc->name);
        1645         [ #  # ]:          0 :     if (method == NULL)
        1646                 :          0 :         return NULL;
        1647                 :          0 :     result = PyObject_Call(method, mc->args, mc->kwds);
        1648                 :          0 :     Py_DECREF(method);
        1649                 :          0 :     return result;
        1650                 :            : }
        1651                 :            :
        1652                 :            : static PyObject *
        1653                 :          0 : methodcaller_repr(methodcallerobject *mc)
        1654                 :            : {
        1655                 :          0 :     PyObject *argreprs, *repr = NULL, *sep, *joinedargreprs;
        1656                 :            :     Py_ssize_t numtotalargs, numposargs, numkwdargs, i;
        1657                 :          0 :     int status = Py_ReprEnter((PyObject *)mc);
        1658         [ #  # ]:          0 :     if (status != 0) {
        1659         [ #  # ]:          0 :         if (status < 0)
        1660                 :          0 :             return NULL;
        1661                 :          0 :         return PyUnicode_FromFormat("%s(...)", Py_TYPE(mc)->tp_name);
        1662                 :            :     }
        1663                 :            :
        1664         [ #  # ]:          0 :     numkwdargs = mc->kwds != NULL ? PyDict_GET_SIZE(mc->kwds) : 0;
        1665                 :          0 :     numposargs = PyTuple_GET_SIZE(mc->args);
        1666                 :          0 :     numtotalargs = numposargs + numkwdargs;
        1667                 :            :
        1668         [ #  # ]:          0 :     if (numtotalargs == 0) {
        1669                 :          0 :         repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(mc)->tp_name, mc->name);
        1670                 :          0 :         Py_ReprLeave((PyObject *)mc);
        1671                 :          0 :         return repr;
        1672                 :            :     }
        1673                 :            :
        1674                 :          0 :     argreprs = PyTuple_New(numtotalargs);
        1675         [ #  # ]:          0 :     if (argreprs == NULL) {
        1676                 :          0 :         Py_ReprLeave((PyObject *)mc);
        1677                 :          0 :         return NULL;
        1678                 :            :     }
        1679                 :            :
        1680         [ #  # ]:          0 :     for (i = 0; i < numposargs; ++i) {
        1681                 :          0 :         PyObject *onerepr = PyObject_Repr(PyTuple_GET_ITEM(mc->args, i));
        1682         [ #  # ]:          0 :         if (onerepr == NULL)
        1683                 :          0 :             goto done;
        1684                 :          0 :         PyTuple_SET_ITEM(argreprs, i, onerepr);
        1685                 :            :     }
        1686                 :            :
        1687         [ #  # ]:          0 :     if (numkwdargs != 0) {
        1688                 :            :         PyObject *key, *value;
        1689                 :          0 :         Py_ssize_t pos = 0;
        1690         [ #  # ]:          0 :         while (PyDict_Next(mc->kwds, &pos, &key, &value)) {
        1691                 :          0 :             PyObject *onerepr = PyUnicode_FromFormat("%U=%R", key, value);
        1692         [ #  # ]:          0 :             if (onerepr == NULL)
        1693                 :          0 :                 goto done;
        1694         [ #  # ]:          0 :             if (i >= numtotalargs) {
        1695                 :          0 :                 i = -1;
        1696                 :          0 :                 Py_DECREF(onerepr);
        1697                 :          0 :                 break;
        1698                 :            :             }
        1699                 :          0 :             PyTuple_SET_ITEM(argreprs, i, onerepr);
        1700                 :          0 :             ++i;
        1701                 :            :         }
        1702         [ #  # ]:          0 :         if (i != numtotalargs) {
        1703                 :          0 :             PyErr_SetString(PyExc_RuntimeError,
        1704                 :            :                             "keywords dict changed size during iteration");
        1705                 :          0 :             goto done;
        1706                 :            :         }
        1707                 :            :     }
        1708                 :            :
        1709                 :          0 :     sep = PyUnicode_FromString(", ");
        1710         [ #  # ]:          0 :     if (sep == NULL)
        1711                 :          0 :         goto done;
        1712                 :            :
        1713                 :          0 :     joinedargreprs = PyUnicode_Join(sep, argreprs);
        1714                 :          0 :     Py_DECREF(sep);
        1715         [ #  # ]:          0 :     if (joinedargreprs == NULL)
        1716                 :          0 :         goto done;
        1717                 :            :
        1718                 :          0 :     repr = PyUnicode_FromFormat("%s(%R, %U)", Py_TYPE(mc)->tp_name,
        1719                 :            :                                 mc->name, joinedargreprs);
        1720                 :          0 :     Py_DECREF(joinedargreprs);
        1721                 :            :
        1722                 :          0 : done:
        1723                 :          0 :     Py_DECREF(argreprs);
        1724                 :          0 :     Py_ReprLeave((PyObject *)mc);
        1725                 :          0 :     return repr;
        1726                 :            : }
        1727                 :            :
        1728                 :            : static PyObject *
        1729                 :          0 : methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored))
        1730                 :            : {
        1731                 :            :     PyObject *newargs;
        1732   [ #  #  #  # ]:          0 :     if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) {
        1733                 :            :         Py_ssize_t i;
        1734                 :          0 :         Py_ssize_t callargcount = PyTuple_GET_SIZE(mc->args);
        1735                 :          0 :         newargs = PyTuple_New(1 + callargcount);
        1736         [ #  # ]:          0 :         if (newargs == NULL)
        1737                 :          0 :             return NULL;
        1738                 :          0 :         PyTuple_SET_ITEM(newargs, 0, Py_NewRef(mc->name));
        1739         [ #  # ]:          0 :         for (i = 0; i < callargcount; ++i) {
        1740                 :          0 :             PyObject *arg = PyTuple_GET_ITEM(mc->args, i);
        1741                 :          0 :             PyTuple_SET_ITEM(newargs, i + 1, Py_NewRef(arg));
        1742                 :            :         }
        1743                 :          0 :         return Py_BuildValue("ON", Py_TYPE(mc), newargs);
        1744                 :            :     }
        1745                 :            :     else {
        1746                 :            :         PyObject *partial;
        1747                 :            :         PyObject *constructor;
        1748                 :            :         PyObject *newargs[2];
        1749                 :            :
        1750                 :          0 :         partial = _PyImport_GetModuleAttrString("functools", "partial");
        1751         [ #  # ]:          0 :         if (!partial)
        1752                 :          0 :             return NULL;
        1753                 :            :
        1754                 :          0 :         newargs[0] = (PyObject *)Py_TYPE(mc);
        1755                 :          0 :         newargs[1] = mc->name;
        1756                 :          0 :         constructor = PyObject_VectorcallDict(partial, newargs, 2, mc->kwds);
        1757                 :            :
        1758                 :          0 :         Py_DECREF(partial);
        1759                 :          0 :         return Py_BuildValue("NO", constructor, mc->args);
        1760                 :            :     }
        1761                 :            : }
        1762                 :            :
        1763                 :            : static PyMethodDef methodcaller_methods[] = {
        1764                 :            :     {"__reduce__", (PyCFunction)methodcaller_reduce, METH_NOARGS,
        1765                 :            :      reduce_doc},
        1766                 :            :     {NULL}
        1767                 :            : };
        1768                 :            : PyDoc_STRVAR(methodcaller_doc,
        1769                 :            : "methodcaller(name, /, *args, **kwargs)\n--\n\n\
        1770                 :            : Return a callable object that calls the given method on its operand.\n\
        1771                 :            : After f = methodcaller('name'), the call f(r) returns r.name().\n\
        1772                 :            : After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\
        1773                 :            : r.name('date', foo=1).");
        1774                 :            :
        1775                 :            : static PyType_Slot methodcaller_type_slots[] = {
        1776                 :            :     {Py_tp_doc, (void *)methodcaller_doc},
        1777                 :            :     {Py_tp_dealloc, methodcaller_dealloc},
        1778                 :            :     {Py_tp_call, methodcaller_call},
        1779                 :            :     {Py_tp_traverse, methodcaller_traverse},
        1780                 :            :     {Py_tp_clear, methodcaller_clear},
        1781                 :            :     {Py_tp_methods, methodcaller_methods},
        1782                 :            :     {Py_tp_new, methodcaller_new},
        1783                 :            :     {Py_tp_getattro, PyObject_GenericGetAttr},
        1784                 :            :     {Py_tp_repr, methodcaller_repr},
        1785                 :            :     {0, 0}
        1786                 :            : };
        1787                 :            :
        1788                 :            : static PyType_Spec methodcaller_type_spec = {
        1789                 :            :     .name = "operator.methodcaller",
        1790                 :            :     .basicsize = sizeof(methodcallerobject),
        1791                 :            :     .itemsize = 0,
        1792                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        1793                 :            :               Py_TPFLAGS_IMMUTABLETYPE),
        1794                 :            :     .slots = methodcaller_type_slots,
        1795                 :            : };
        1796                 :            :
        1797                 :            : static int
        1798                 :          6 : operator_exec(PyObject *module)
        1799                 :            : {
        1800                 :          6 :     _operator_state *state = get_operator_state(module);
        1801                 :          6 :     state->attrgetter_type = PyType_FromModuleAndSpec(module, &attrgetter_type_spec, NULL);
        1802         [ -  + ]:          6 :     if (state->attrgetter_type == NULL) {
        1803                 :          0 :         return -1;
        1804                 :            :     }
        1805         [ -  + ]:          6 :     if (PyModule_AddType(module, (PyTypeObject *)state->attrgetter_type) < 0) {
        1806                 :          0 :         return -1;
        1807                 :            :     }
        1808                 :            :
        1809                 :          6 :     state->itemgetter_type = PyType_FromModuleAndSpec(module, &itemgetter_type_spec, NULL);
        1810         [ -  + ]:          6 :     if (state->itemgetter_type == NULL) {
        1811                 :          0 :         return -1;
        1812                 :            :     }
        1813         [ -  + ]:          6 :     if (PyModule_AddType(module, (PyTypeObject *)state->itemgetter_type) < 0) {
        1814                 :          0 :         return -1;
        1815                 :            :     }
        1816                 :            :
        1817                 :          6 :     state->methodcaller_type = PyType_FromModuleAndSpec(module, &methodcaller_type_spec, NULL);
        1818         [ -  + ]:          6 :     if (state->methodcaller_type == NULL) {
        1819                 :          0 :         return -1;
        1820                 :            :     }
        1821         [ -  + ]:          6 :     if (PyModule_AddType(module, (PyTypeObject *)state->methodcaller_type) < 0) {
        1822                 :          0 :         return -1;
        1823                 :            :     }
        1824                 :            :
        1825                 :          6 :     return 0;
        1826                 :            : }
        1827                 :            :
        1828                 :            :
        1829                 :            : static struct PyModuleDef_Slot operator_slots[] = {
        1830                 :            :     {Py_mod_exec, operator_exec},
        1831                 :            :     {0, NULL}
        1832                 :            : };
        1833                 :            :
        1834                 :            : static int
        1835                 :         86 : operator_traverse(PyObject *module, visitproc visit, void *arg)
        1836                 :            : {
        1837                 :         86 :     _operator_state *state = get_operator_state(module);
        1838   [ +  -  -  + ]:         86 :     Py_VISIT(state->attrgetter_type);
        1839   [ +  -  -  + ]:         86 :     Py_VISIT(state->itemgetter_type);
        1840   [ +  -  -  + ]:         86 :     Py_VISIT(state->methodcaller_type);
        1841                 :         86 :     return 0;
        1842                 :            : }
        1843                 :            :
        1844                 :            : static int
        1845                 :         12 : operator_clear(PyObject *module)
        1846                 :            : {
        1847                 :         12 :     _operator_state *state = get_operator_state(module);
        1848         [ +  + ]:         12 :     Py_CLEAR(state->attrgetter_type);
        1849         [ +  + ]:         12 :     Py_CLEAR(state->itemgetter_type);
        1850         [ +  + ]:         12 :     Py_CLEAR(state->methodcaller_type);
        1851                 :         12 :     return 0;
        1852                 :            : }
        1853                 :            :
        1854                 :            : static void
        1855                 :          6 : operator_free(void *module)
        1856                 :            : {
        1857                 :          6 :     operator_clear((PyObject *)module);
        1858                 :          6 : }
        1859                 :            :
        1860                 :            : static struct PyModuleDef operatormodule = {
        1861                 :            :     PyModuleDef_HEAD_INIT,
        1862                 :            :     .m_name = "_operator",
        1863                 :            :     .m_doc = operator_doc,
        1864                 :            :     .m_size = sizeof(_operator_state),
        1865                 :            :     .m_methods = operator_methods,
        1866                 :            :     .m_slots = operator_slots,
        1867                 :            :     .m_traverse = operator_traverse,
        1868                 :            :     .m_clear = operator_clear,
        1869                 :            :     .m_free = operator_free,
        1870                 :            : };
        1871                 :            :
        1872                 :            : PyMODINIT_FUNC
        1873                 :          6 : PyInit__operator(void)
        1874                 :            : {
        1875                 :          6 :     return PyModuleDef_Init(&operatormodule);
        1876                 :            : }

Generated by: LCOV version 1.14