1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882 |
- #include "Python.h"
- #include "pycore_moduleobject.h" // _PyModule_GetState()
- #include "structmember.h" // PyMemberDef
- #include "pycore_runtime.h" // _Py_ID()
- #include "pycore_pystate.h" // _PyInterpreterState_GET()
- #include "clinic/_operator.c.h"
- typedef struct {
- PyObject *itemgetter_type;
- PyObject *attrgetter_type;
- PyObject *methodcaller_type;
- } _operator_state;
- static inline _operator_state*
- get_operator_state(PyObject *module)
- {
- void *state = _PyModule_GetState(module);
- assert(state != NULL);
- return (_operator_state *)state;
- }
- /*[clinic input]
- module _operator
- [clinic start generated code]*/
- /*[clinic end generated code: output=da39a3ee5e6b4b0d input=672ecf48487521e7]*/
- PyDoc_STRVAR(operator_doc,
- "Operator interface.\n\
- \n\
- This module exports a set of functions implemented in C corresponding\n\
- to the intrinsic operators of Python. For example, operator.add(x, y)\n\
- is equivalent to the expression x+y. The function names are those\n\
- used for special methods; variants without leading and trailing\n\
- '__' are also provided for convenience.");
- /*[clinic input]
- _operator.truth -> bool
- a: object
- /
- Return True if a is true, False otherwise.
- [clinic start generated code]*/
- static int
- _operator_truth_impl(PyObject *module, PyObject *a)
- /*[clinic end generated code: output=eaf87767234fa5d7 input=bc74a4cd90235875]*/
- {
- return PyObject_IsTrue(a);
- }
- /*[clinic input]
- _operator.add
- a: object
- b: object
- /
- Same as a + b.
- [clinic start generated code]*/
- static PyObject *
- _operator_add_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=8292984204f45164 input=5efe3bff856ac215]*/
- {
- return PyNumber_Add(a, b);
- }
- /*[clinic input]
- _operator.sub = _operator.add
- Same as a - b.
- [clinic start generated code]*/
- static PyObject *
- _operator_sub_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=4adfc3b888c1ee2e input=6494c6b100b8e795]*/
- {
- return PyNumber_Subtract(a, b);
- }
- /*[clinic input]
- _operator.mul = _operator.add
- Same as a * b.
- [clinic start generated code]*/
- static PyObject *
- _operator_mul_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=d24d66f55a01944c input=2368615b4358b70d]*/
- {
- return PyNumber_Multiply(a, b);
- }
- /*[clinic input]
- _operator.matmul = _operator.add
- Same as a @ b.
- [clinic start generated code]*/
- static PyObject *
- _operator_matmul_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=a20d917eb35d0101 input=9ab304e37fb42dd4]*/
- {
- return PyNumber_MatrixMultiply(a, b);
- }
- /*[clinic input]
- _operator.floordiv = _operator.add
- Same as a // b.
- [clinic start generated code]*/
- static PyObject *
- _operator_floordiv_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=df26b71a60589f99 input=bb2e88ba446c612c]*/
- {
- return PyNumber_FloorDivide(a, b);
- }
- /*[clinic input]
- _operator.truediv = _operator.add
- Same as a / b.
- [clinic start generated code]*/
- static PyObject *
- _operator_truediv_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=0e6a959944d77719 input=ecbb947673f4eb1f]*/
- {
- return PyNumber_TrueDivide(a, b);
- }
- /*[clinic input]
- _operator.mod = _operator.add
- Same as a % b.
- [clinic start generated code]*/
- static PyObject *
- _operator_mod_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=9519822f0bbec166 input=102e19b422342ac1]*/
- {
- return PyNumber_Remainder(a, b);
- }
- /*[clinic input]
- _operator.neg
- a: object
- /
- Same as -a.
- [clinic start generated code]*/
- static PyObject *
- _operator_neg(PyObject *module, PyObject *a)
- /*[clinic end generated code: output=36e08ecfc6a1c08c input=84f09bdcf27c96ec]*/
- {
- return PyNumber_Negative(a);
- }
- /*[clinic input]
- _operator.pos = _operator.neg
- Same as +a.
- [clinic start generated code]*/
- static PyObject *
- _operator_pos(PyObject *module, PyObject *a)
- /*[clinic end generated code: output=dad7a126221dd091 input=b6445b63fddb8772]*/
- {
- return PyNumber_Positive(a);
- }
- /*[clinic input]
- _operator.abs = _operator.neg
- Same as abs(a).
- [clinic start generated code]*/
- static PyObject *
- _operator_abs(PyObject *module, PyObject *a)
- /*[clinic end generated code: output=1389a93ba053ea3e input=341d07ba86f58039]*/
- {
- return PyNumber_Absolute(a);
- }
- /*[clinic input]
- _operator.inv = _operator.neg
- Same as ~a.
- [clinic start generated code]*/
- static PyObject *
- _operator_inv(PyObject *module, PyObject *a)
- /*[clinic end generated code: output=a56875ba075ee06d input=b01a4677739f6eb2]*/
- {
- return PyNumber_Invert(a);
- }
- /*[clinic input]
- _operator.invert = _operator.neg
- Same as ~a.
- [clinic start generated code]*/
- static PyObject *
- _operator_invert(PyObject *module, PyObject *a)
- /*[clinic end generated code: output=406b5aa030545fcc input=7f2d607176672e55]*/
- {
- return PyNumber_Invert(a);
- }
- /*[clinic input]
- _operator.lshift = _operator.add
- Same as a << b.
- [clinic start generated code]*/
- static PyObject *
- _operator_lshift_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=37f7e52c41435bd8 input=746e8a160cbbc9eb]*/
- {
- return PyNumber_Lshift(a, b);
- }
- /*[clinic input]
- _operator.rshift = _operator.add
- Same as a >> b.
- [clinic start generated code]*/
- static PyObject *
- _operator_rshift_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=4593c7ef30ec2ee3 input=d2c85bb5a64504c2]*/
- {
- return PyNumber_Rshift(a, b);
- }
- /*[clinic input]
- _operator.not_ = _operator.truth
- Same as not a.
- [clinic start generated code]*/
- static int
- _operator_not__impl(PyObject *module, PyObject *a)
- /*[clinic end generated code: output=743f9c24a09759ef input=854156d50804d9b8]*/
- {
- return PyObject_Not(a);
- }
- /*[clinic input]
- _operator.and_ = _operator.add
- Same as a & b.
- [clinic start generated code]*/
- static PyObject *
- _operator_and__impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=93c4fe88f7b76d9e input=4f3057c90ec4c99f]*/
- {
- return PyNumber_And(a, b);
- }
- /*[clinic input]
- _operator.xor = _operator.add
- Same as a ^ b.
- [clinic start generated code]*/
- static PyObject *
- _operator_xor_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=b24cd8b79fde0004 input=3c5cfa7253d808dd]*/
- {
- return PyNumber_Xor(a, b);
- }
- /*[clinic input]
- _operator.or_ = _operator.add
- Same as a | b.
- [clinic start generated code]*/
- static PyObject *
- _operator_or__impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=58024867b8d90461 input=b40c6c44f7c79c09]*/
- {
- return PyNumber_Or(a, b);
- }
- /*[clinic input]
- _operator.iadd = _operator.add
- Same as a += b.
- [clinic start generated code]*/
- static PyObject *
- _operator_iadd_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=07dc627832526eb5 input=d22a91c07ac69227]*/
- {
- return PyNumber_InPlaceAdd(a, b);
- }
- /*[clinic input]
- _operator.isub = _operator.add
- Same as a -= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_isub_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=4513467d23b5e0b1 input=4591b00d0a0ccafd]*/
- {
- return PyNumber_InPlaceSubtract(a, b);
- }
- /*[clinic input]
- _operator.imul = _operator.add
- Same as a *= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_imul_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=5e87dacd19a71eab input=0e01fb8631e1b76f]*/
- {
- return PyNumber_InPlaceMultiply(a, b);
- }
- /*[clinic input]
- _operator.imatmul = _operator.add
- Same as a @= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_imatmul_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=d603cbdf716ce519 input=bb614026372cd542]*/
- {
- return PyNumber_InPlaceMatrixMultiply(a, b);
- }
- /*[clinic input]
- _operator.ifloordiv = _operator.add
- Same as a //= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_ifloordiv_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=535336048c681794 input=9df3b5021cff4ca1]*/
- {
- return PyNumber_InPlaceFloorDivide(a, b);
- }
- /*[clinic input]
- _operator.itruediv = _operator.add
- Same as a /= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_itruediv_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=28017fbd3563952f input=9a1ee01608f5f590]*/
- {
- return PyNumber_InPlaceTrueDivide(a, b);
- }
- /*[clinic input]
- _operator.imod = _operator.add
- Same as a %= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_imod_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=f7c540ae0fc70904 input=d0c384a3ce38e1dd]*/
- {
- return PyNumber_InPlaceRemainder(a, b);
- }
- /*[clinic input]
- _operator.ilshift = _operator.add
- Same as a <<= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_ilshift_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=e73a8fee1ac18749 input=e21b6b310f54572e]*/
- {
- return PyNumber_InPlaceLshift(a, b);
- }
- /*[clinic input]
- _operator.irshift = _operator.add
- Same as a >>= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_irshift_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=97f2af6b5ff2ed81 input=6778dbd0f6e1ec16]*/
- {
- return PyNumber_InPlaceRshift(a, b);
- }
- /*[clinic input]
- _operator.iand = _operator.add
- Same as a &= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_iand_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=4599e9d40cbf7d00 input=71dfd8e70c156a7b]*/
- {
- return PyNumber_InPlaceAnd(a, b);
- }
- /*[clinic input]
- _operator.ixor = _operator.add
- Same as a ^= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_ixor_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=5ff881766872be03 input=695c32bec0604d86]*/
- {
- return PyNumber_InPlaceXor(a, b);
- }
- /*[clinic input]
- _operator.ior = _operator.add
- Same as a |= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_ior_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=48aac319445bf759 input=8f01d03eda9920cf]*/
- {
- return PyNumber_InPlaceOr(a, b);
- }
- /*[clinic input]
- _operator.concat = _operator.add
- Same as a + b, for a and b sequences.
- [clinic start generated code]*/
- static PyObject *
- _operator_concat_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=80028390942c5f11 input=8544ccd5341a3658]*/
- {
- return PySequence_Concat(a, b);
- }
- /*[clinic input]
- _operator.iconcat = _operator.add
- Same as a += b, for a and b sequences.
- [clinic start generated code]*/
- static PyObject *
- _operator_iconcat_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=3ea0a162ebb2e26d input=8f5fe5722fcd837e]*/
- {
- return PySequence_InPlaceConcat(a, b);
- }
- /*[clinic input]
- _operator.contains -> bool
- a: object
- b: object
- /
- Same as b in a (note reversed operands).
- [clinic start generated code]*/
- static int
- _operator_contains_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=413b4dbe82b6ffc1 input=9122a69b505fde13]*/
- {
- return PySequence_Contains(a, b);
- }
- /*[clinic input]
- _operator.indexOf -> Py_ssize_t
- a: object
- b: object
- /
- Return the first index of b in a.
- [clinic start generated code]*/
- static Py_ssize_t
- _operator_indexOf_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=c6226d8e0fb60fa6 input=8be2e43b6a6fffe3]*/
- {
- return PySequence_Index(a, b);
- }
- /*[clinic input]
- _operator.countOf = _operator.indexOf
- Return the number of items in a which are, or which equal, b.
- [clinic start generated code]*/
- static Py_ssize_t
- _operator_countOf_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=9e1623197daf3382 input=93ea57f170f3f0bb]*/
- {
- return PySequence_Count(a, b);
- }
- /*[clinic input]
- _operator.getitem
- a: object
- b: object
- /
- Same as a[b].
- [clinic start generated code]*/
- static PyObject *
- _operator_getitem_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=6c8d8101a676e594 input=6682797320e48845]*/
- {
- return PyObject_GetItem(a, b);
- }
- /*[clinic input]
- _operator.setitem
- a: object
- b: object
- c: object
- /
- Same as a[b] = c.
- [clinic start generated code]*/
- static PyObject *
- _operator_setitem_impl(PyObject *module, PyObject *a, PyObject *b,
- PyObject *c)
- /*[clinic end generated code: output=1324f9061ae99e25 input=ceaf453c4d3a58df]*/
- {
- if (-1 == PyObject_SetItem(a, b, c))
- return NULL;
- Py_RETURN_NONE;
- }
- /*[clinic input]
- _operator.delitem = _operator.getitem
- Same as del a[b].
- [clinic start generated code]*/
- static PyObject *
- _operator_delitem_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=db18f61506295799 input=991bec56a0d3ec7f]*/
- {
- if (-1 == PyObject_DelItem(a, b))
- return NULL;
- Py_RETURN_NONE;
- }
- /*[clinic input]
- _operator.eq
- a: object
- b: object
- /
- Same as a == b.
- [clinic start generated code]*/
- static PyObject *
- _operator_eq_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=8d7d46ed4135677c input=586fca687a95a83f]*/
- {
- return PyObject_RichCompare(a, b, Py_EQ);
- }
- /*[clinic input]
- _operator.ne = _operator.eq
- Same as a != b.
- [clinic start generated code]*/
- static PyObject *
- _operator_ne_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=c99bd0c3a4c01297 input=5d88f23d35e9abac]*/
- {
- return PyObject_RichCompare(a, b, Py_NE);
- }
- /*[clinic input]
- _operator.lt = _operator.eq
- Same as a < b.
- [clinic start generated code]*/
- static PyObject *
- _operator_lt_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=082d7c45c440e535 input=34a59ad6d39d3a2b]*/
- {
- return PyObject_RichCompare(a, b, Py_LT);
- }
- /*[clinic input]
- _operator.le = _operator.eq
- Same as a <= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_le_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=00970a2923d0ae17 input=b812a7860a0bef44]*/
- {
- return PyObject_RichCompare(a, b, Py_LE);
- }
- /*[clinic input]
- _operator.gt = _operator.eq
- Same as a > b.
- [clinic start generated code]*/
- static PyObject *
- _operator_gt_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=8d373349ecf25641 input=9bdb45b995ada35b]*/
- {
- return PyObject_RichCompare(a, b, Py_GT);
- }
- /*[clinic input]
- _operator.ge = _operator.eq
- Same as a >= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_ge_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=7ce3882256d4b137 input=cf1dc4a5ca9c35f5]*/
- {
- return PyObject_RichCompare(a, b, Py_GE);
- }
- /*[clinic input]
- _operator.pow = _operator.add
- Same as a ** b.
- [clinic start generated code]*/
- static PyObject *
- _operator_pow_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=09e668ad50036120 input=690b40f097ab1637]*/
- {
- return PyNumber_Power(a, b, Py_None);
- }
- /*[clinic input]
- _operator.ipow = _operator.add
- Same as a **= b.
- [clinic start generated code]*/
- static PyObject *
- _operator_ipow_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=7189ff4d4367c808 input=f00623899d07499a]*/
- {
- return PyNumber_InPlacePower(a, b, Py_None);
- }
- /*[clinic input]
- _operator.index
- a: object
- /
- Same as a.__index__()
- [clinic start generated code]*/
- static PyObject *
- _operator_index(PyObject *module, PyObject *a)
- /*[clinic end generated code: output=d972b0764ac305fc input=6f54d50ea64a579c]*/
- {
- return PyNumber_Index(a);
- }
- /*[clinic input]
- _operator.is_ = _operator.add
- Same as a is b.
- [clinic start generated code]*/
- static PyObject *
- _operator_is__impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=bcd47a402e482e1d input=5fa9b97df03c427f]*/
- {
- PyObject *result = Py_Is(a, b) ? Py_True : Py_False;
- return Py_NewRef(result);
- }
- /*[clinic input]
- _operator.is_not = _operator.add
- Same as a is not b.
- [clinic start generated code]*/
- static PyObject *
- _operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=491a1f2f81f6c7f9 input=5a93f7e1a93535f1]*/
- {
- PyObject *result;
- result = (a != b) ? Py_True : Py_False;
- return Py_NewRef(result);
- }
- /* compare_digest **********************************************************/
- /*
- * timing safe compare
- *
- * Returns 1 if the strings are equal.
- * In case of len(a) != len(b) the function tries to keep the timing
- * dependent on the length of b. CPU cache locality may still alter timing
- * a bit.
- */
- static int
- _tscmp(const unsigned char *a, const unsigned char *b,
- Py_ssize_t len_a, Py_ssize_t len_b)
- {
- /* The volatile type declarations make sure that the compiler has no
- * chance to optimize and fold the code in any way that may change
- * the timing.
- */
- volatile Py_ssize_t length;
- volatile const unsigned char *left;
- volatile const unsigned char *right;
- Py_ssize_t i;
- volatile unsigned char result;
- /* loop count depends on length of b */
- length = len_b;
- left = NULL;
- right = b;
- /* don't use else here to keep the amount of CPU instructions constant,
- * volatile forces re-evaluation
- * */
- if (len_a == length) {
- left = *((volatile const unsigned char**)&a);
- result = 0;
- }
- if (len_a != length) {
- left = b;
- result = 1;
- }
- for (i=0; i < length; i++) {
- result |= *left++ ^ *right++;
- }
- return (result == 0);
- }
- /*[clinic input]
- _operator.length_hint -> Py_ssize_t
- obj: object
- default: Py_ssize_t = 0
- /
- Return an estimate of the number of items in obj.
- This is useful for presizing containers when building from an iterable.
- If the object supports len(), the result will be exact.
- Otherwise, it may over- or under-estimate by an arbitrary amount.
- The result will be an integer >= 0.
- [clinic start generated code]*/
- static Py_ssize_t
- _operator_length_hint_impl(PyObject *module, PyObject *obj,
- Py_ssize_t default_value)
- /*[clinic end generated code: output=01d469edc1d612ad input=65ed29f04401e96a]*/
- {
- return PyObject_LengthHint(obj, default_value);
- }
- /* NOTE: Keep in sync with _hashopenssl.c implementation. */
- /*[clinic input]
- _operator._compare_digest = _operator.eq
- Return 'a == b'.
- This function uses an approach designed to prevent
- timing analysis, making it appropriate for cryptography.
- a and b must both be of the same type: either str (ASCII only),
- or any bytes-like object.
- Note: If a and b are of different lengths, or if an error occurs,
- a timing attack could theoretically reveal information about the
- types and lengths of a and b--but not their values.
- [clinic start generated code]*/
- static PyObject *
- _operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b)
- /*[clinic end generated code: output=11d452bdd3a23cbc input=9ac7e2c4e30bc356]*/
- {
- int rc;
- /* ASCII unicode string */
- if(PyUnicode_Check(a) && PyUnicode_Check(b)) {
- if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) {
- return NULL;
- }
- if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) {
- PyErr_SetString(PyExc_TypeError,
- "comparing strings with non-ASCII characters is "
- "not supported");
- return NULL;
- }
- rc = _tscmp(PyUnicode_DATA(a),
- PyUnicode_DATA(b),
- PyUnicode_GET_LENGTH(a),
- PyUnicode_GET_LENGTH(b));
- }
- /* fallback to buffer interface for bytes, bytearray and other */
- else {
- Py_buffer view_a;
- Py_buffer view_b;
- if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) {
- PyErr_Format(PyExc_TypeError,
- "unsupported operand types(s) or combination of types: "
- "'%.100s' and '%.100s'",
- Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
- return NULL;
- }
- if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) {
- return NULL;
- }
- if (view_a.ndim > 1) {
- PyErr_SetString(PyExc_BufferError,
- "Buffer must be single dimension");
- PyBuffer_Release(&view_a);
- return NULL;
- }
- if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) {
- PyBuffer_Release(&view_a);
- return NULL;
- }
- if (view_b.ndim > 1) {
- PyErr_SetString(PyExc_BufferError,
- "Buffer must be single dimension");
- PyBuffer_Release(&view_a);
- PyBuffer_Release(&view_b);
- return NULL;
- }
- rc = _tscmp((const unsigned char*)view_a.buf,
- (const unsigned char*)view_b.buf,
- view_a.len,
- view_b.len);
- PyBuffer_Release(&view_a);
- PyBuffer_Release(&view_b);
- }
- return PyBool_FromLong(rc);
- }
- PyDoc_STRVAR(_operator_call__doc__,
- "call($module, obj, /, *args, **kwargs)\n"
- "--\n"
- "\n"
- "Same as obj(*args, **kwargs).");
- #define _OPERATOR_CALL_METHODDEF \
- {"call", _PyCFunction_CAST(_operator_call), METH_FASTCALL | METH_KEYWORDS, _operator_call__doc__},
- static PyObject *
- _operator_call(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
- {
- if (!_PyArg_CheckPositional("call", nargs, 1, PY_SSIZE_T_MAX)) {
- return NULL;
- }
- return PyObject_Vectorcall(
- args[0],
- &args[1], (PyVectorcall_NARGS(nargs) - 1) | PY_VECTORCALL_ARGUMENTS_OFFSET,
- kwnames);
- }
- /* operator methods **********************************************************/
- static struct PyMethodDef operator_methods[] = {
- _OPERATOR_TRUTH_METHODDEF
- _OPERATOR_CONTAINS_METHODDEF
- _OPERATOR_INDEXOF_METHODDEF
- _OPERATOR_COUNTOF_METHODDEF
- _OPERATOR_IS__METHODDEF
- _OPERATOR_IS_NOT_METHODDEF
- _OPERATOR_INDEX_METHODDEF
- _OPERATOR_ADD_METHODDEF
- _OPERATOR_SUB_METHODDEF
- _OPERATOR_MUL_METHODDEF
- _OPERATOR_MATMUL_METHODDEF
- _OPERATOR_FLOORDIV_METHODDEF
- _OPERATOR_TRUEDIV_METHODDEF
- _OPERATOR_MOD_METHODDEF
- _OPERATOR_NEG_METHODDEF
- _OPERATOR_POS_METHODDEF
- _OPERATOR_ABS_METHODDEF
- _OPERATOR_INV_METHODDEF
- _OPERATOR_INVERT_METHODDEF
- _OPERATOR_LSHIFT_METHODDEF
- _OPERATOR_RSHIFT_METHODDEF
- _OPERATOR_NOT__METHODDEF
- _OPERATOR_AND__METHODDEF
- _OPERATOR_XOR_METHODDEF
- _OPERATOR_OR__METHODDEF
- _OPERATOR_IADD_METHODDEF
- _OPERATOR_ISUB_METHODDEF
- _OPERATOR_IMUL_METHODDEF
- _OPERATOR_IMATMUL_METHODDEF
- _OPERATOR_IFLOORDIV_METHODDEF
- _OPERATOR_ITRUEDIV_METHODDEF
- _OPERATOR_IMOD_METHODDEF
- _OPERATOR_ILSHIFT_METHODDEF
- _OPERATOR_IRSHIFT_METHODDEF
- _OPERATOR_IAND_METHODDEF
- _OPERATOR_IXOR_METHODDEF
- _OPERATOR_IOR_METHODDEF
- _OPERATOR_CONCAT_METHODDEF
- _OPERATOR_ICONCAT_METHODDEF
- _OPERATOR_GETITEM_METHODDEF
- _OPERATOR_SETITEM_METHODDEF
- _OPERATOR_DELITEM_METHODDEF
- _OPERATOR_POW_METHODDEF
- _OPERATOR_IPOW_METHODDEF
- _OPERATOR_EQ_METHODDEF
- _OPERATOR_NE_METHODDEF
- _OPERATOR_LT_METHODDEF
- _OPERATOR_LE_METHODDEF
- _OPERATOR_GT_METHODDEF
- _OPERATOR_GE_METHODDEF
- _OPERATOR__COMPARE_DIGEST_METHODDEF
- _OPERATOR_LENGTH_HINT_METHODDEF
- _OPERATOR_CALL_METHODDEF
- {NULL, NULL} /* sentinel */
- };
- /* itemgetter object **********************************************************/
- typedef struct {
- PyObject_HEAD
- Py_ssize_t nitems;
- PyObject *item;
- Py_ssize_t index; // -1 unless *item* is a single non-negative integer index
- vectorcallfunc vectorcall;
- } itemgetterobject;
- // Forward declarations
- static PyObject *
- itemgetter_vectorcall(PyObject *, PyObject *const *, size_t, PyObject *);
- static PyObject *
- itemgetter_call_impl(itemgetterobject *, PyObject *);
- /* AC 3.5: treats first argument as an iterable, otherwise uses *args */
- static PyObject *
- itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
- itemgetterobject *ig;
- PyObject *item;
- Py_ssize_t nitems;
- Py_ssize_t index;
- if (!_PyArg_NoKeywords("itemgetter", kwds))
- return NULL;
- nitems = PyTuple_GET_SIZE(args);
- if (nitems <= 1) {
- if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item))
- return NULL;
- } else {
- item = args;
- }
- _operator_state *state = _PyType_GetModuleState(type);
- /* create itemgetterobject structure */
- ig = PyObject_GC_New(itemgetterobject, (PyTypeObject *) state->itemgetter_type);
- if (ig == NULL) {
- return NULL;
- }
- ig->item = Py_NewRef(item);
- ig->nitems = nitems;
- ig->index = -1;
- if (PyLong_CheckExact(item)) {
- index = PyLong_AsSsize_t(item);
- if (index < 0) {
- /* If we get here, then either the index conversion failed
- * due to being out of range, or the index was a negative
- * integer. Either way, we clear any possible exception
- * and fall back to the slow path, where ig->index is -1.
- */
- PyErr_Clear();
- }
- else {
- ig->index = index;
- }
- }
- ig->vectorcall = (vectorcallfunc)itemgetter_vectorcall;
- PyObject_GC_Track(ig);
- return (PyObject *)ig;
- }
- static int
- itemgetter_clear(itemgetterobject *ig)
- {
- Py_CLEAR(ig->item);
- return 0;
- }
- static void
- itemgetter_dealloc(itemgetterobject *ig)
- {
- PyTypeObject *tp = Py_TYPE(ig);
- PyObject_GC_UnTrack(ig);
- (void)itemgetter_clear(ig);
- tp->tp_free(ig);
- Py_DECREF(tp);
- }
- static int
- itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
- {
- Py_VISIT(Py_TYPE(ig));
- Py_VISIT(ig->item);
- return 0;
- }
- static PyObject *
- itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
- {
- assert(PyTuple_CheckExact(args));
- if (!_PyArg_NoKeywords("itemgetter", kw))
- return NULL;
- if (!_PyArg_CheckPositional("itemgetter", PyTuple_GET_SIZE(args), 1, 1))
- return NULL;
- return itemgetter_call_impl(ig, PyTuple_GET_ITEM(args, 0));
- }
- static PyObject *
- itemgetter_vectorcall(PyObject *ig, PyObject *const *args,
- size_t nargsf, PyObject *kwnames)
- {
- if (!_PyArg_NoKwnames("itemgetter", kwnames)) {
- return NULL;
- }
- Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
- if (!_PyArg_CheckPositional("itemgetter", nargs, 1, 1)) {
- return NULL;
- }
- return itemgetter_call_impl((itemgetterobject *)ig, args[0]);
- }
- static PyObject *
- itemgetter_call_impl(itemgetterobject *ig, PyObject *obj)
- {
- PyObject *result;
- Py_ssize_t i, nitems=ig->nitems;
- if (nitems == 1) {
- if (ig->index >= 0
- && PyTuple_CheckExact(obj)
- && ig->index < PyTuple_GET_SIZE(obj))
- {
- result = PyTuple_GET_ITEM(obj, ig->index);
- return Py_NewRef(result);
- }
- return PyObject_GetItem(obj, ig->item);
- }
- assert(PyTuple_Check(ig->item));
- assert(PyTuple_GET_SIZE(ig->item) == nitems);
- result = PyTuple_New(nitems);
- if (result == NULL)
- return NULL;
- for (i=0 ; i < nitems ; i++) {
- PyObject *item, *val;
- item = PyTuple_GET_ITEM(ig->item, i);
- val = PyObject_GetItem(obj, item);
- if (val == NULL) {
- Py_DECREF(result);
- return NULL;
- }
- PyTuple_SET_ITEM(result, i, val);
- }
- return result;
- }
- static PyObject *
- itemgetter_repr(itemgetterobject *ig)
- {
- PyObject *repr;
- const char *reprfmt;
- int status = Py_ReprEnter((PyObject *)ig);
- if (status != 0) {
- if (status < 0)
- return NULL;
- return PyUnicode_FromFormat("%s(...)", Py_TYPE(ig)->tp_name);
- }
- reprfmt = ig->nitems == 1 ? "%s(%R)" : "%s%R";
- repr = PyUnicode_FromFormat(reprfmt, Py_TYPE(ig)->tp_name, ig->item);
- Py_ReprLeave((PyObject *)ig);
- return repr;
- }
- static PyObject *
- itemgetter_reduce(itemgetterobject *ig, PyObject *Py_UNUSED(ignored))
- {
- if (ig->nitems == 1)
- return Py_BuildValue("O(O)", Py_TYPE(ig), ig->item);
- return PyTuple_Pack(2, Py_TYPE(ig), ig->item);
- }
- PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
- static PyMethodDef itemgetter_methods[] = {
- {"__reduce__", (PyCFunction)itemgetter_reduce, METH_NOARGS,
- reduce_doc},
- {NULL}
- };
- static PyMemberDef itemgetter_members[] = {
- {"__vectorcalloffset__", T_PYSSIZET, offsetof(itemgetterobject, vectorcall), READONLY},
- {NULL} /* Sentinel */
- };
- PyDoc_STRVAR(itemgetter_doc,
- "itemgetter(item, /, *items)\n--\n\n\
- Return a callable object that fetches the given item(s) from its operand.\n\
- After f = itemgetter(2), the call f(r) returns r[2].\n\
- After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])");
- static PyType_Slot itemgetter_type_slots[] = {
- {Py_tp_doc, (void *)itemgetter_doc},
- {Py_tp_dealloc, itemgetter_dealloc},
- {Py_tp_call, itemgetter_call},
- {Py_tp_traverse, itemgetter_traverse},
- {Py_tp_clear, itemgetter_clear},
- {Py_tp_methods, itemgetter_methods},
- {Py_tp_members, itemgetter_members},
- {Py_tp_new, itemgetter_new},
- {Py_tp_getattro, PyObject_GenericGetAttr},
- {Py_tp_repr, itemgetter_repr},
- {0, 0}
- };
- static PyType_Spec itemgetter_type_spec = {
- .name = "operator.itemgetter",
- .basicsize = sizeof(itemgetterobject),
- .itemsize = 0,
- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
- Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_VECTORCALL),
- .slots = itemgetter_type_slots,
- };
- /* attrgetter object **********************************************************/
- typedef struct {
- PyObject_HEAD
- Py_ssize_t nattrs;
- PyObject *attr;
- vectorcallfunc vectorcall;
- } attrgetterobject;
- // Forward declarations
- static PyObject *
- attrgetter_vectorcall(PyObject *, PyObject *const *, size_t, PyObject *);
- static PyObject *
- attrgetter_call_impl(attrgetterobject *, PyObject *);
- /* AC 3.5: treats first argument as an iterable, otherwise uses *args */
- static PyObject *
- attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
- attrgetterobject *ag;
- PyObject *attr;
- Py_ssize_t nattrs, idx, char_idx;
- if (!_PyArg_NoKeywords("attrgetter", kwds))
- return NULL;
- nattrs = PyTuple_GET_SIZE(args);
- if (nattrs <= 1) {
- if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
- return NULL;
- }
- attr = PyTuple_New(nattrs);
- if (attr == NULL)
- return NULL;
- /* prepare attr while checking args */
- PyInterpreterState *interp = _PyInterpreterState_GET();
- for (idx = 0; idx < nattrs; ++idx) {
- PyObject *item = PyTuple_GET_ITEM(args, idx);
- int dot_count;
- if (!PyUnicode_Check(item)) {
- PyErr_SetString(PyExc_TypeError,
- "attribute name must be a string");
- Py_DECREF(attr);
- return NULL;
- }
- if (PyUnicode_READY(item)) {
- Py_DECREF(attr);
- return NULL;
- }
- Py_ssize_t item_len = PyUnicode_GET_LENGTH(item);
- int kind = PyUnicode_KIND(item);
- const void *data = PyUnicode_DATA(item);
- /* check whether the string is dotted */
- dot_count = 0;
- for (char_idx = 0; char_idx < item_len; ++char_idx) {
- if (PyUnicode_READ(kind, data, char_idx) == '.')
- ++dot_count;
- }
- if (dot_count == 0) {
- Py_INCREF(item);
- _PyUnicode_InternMortal(interp, &item);
- PyTuple_SET_ITEM(attr, idx, item);
- } else { /* make it a tuple of non-dotted attrnames */
- PyObject *attr_chain = PyTuple_New(dot_count + 1);
- PyObject *attr_chain_item;
- Py_ssize_t unibuff_from = 0;
- Py_ssize_t unibuff_till = 0;
- Py_ssize_t attr_chain_idx = 0;
- if (attr_chain == NULL) {
- Py_DECREF(attr);
- return NULL;
- }
- for (; dot_count > 0; --dot_count) {
- while (PyUnicode_READ(kind, data, unibuff_till) != '.') {
- ++unibuff_till;
- }
- attr_chain_item = PyUnicode_Substring(item,
- unibuff_from,
- unibuff_till);
- if (attr_chain_item == NULL) {
- Py_DECREF(attr_chain);
- Py_DECREF(attr);
- return NULL;
- }
- _PyUnicode_InternMortal(interp, &attr_chain_item);
- PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
- ++attr_chain_idx;
- unibuff_till = unibuff_from = unibuff_till + 1;
- }
- /* now add the last dotless name */
- attr_chain_item = PyUnicode_Substring(item,
- unibuff_from, item_len);
- if (attr_chain_item == NULL) {
- Py_DECREF(attr_chain);
- Py_DECREF(attr);
- return NULL;
- }
- _PyUnicode_InternMortal(interp, &attr_chain_item);
- PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
- PyTuple_SET_ITEM(attr, idx, attr_chain);
- }
- }
- _operator_state *state = _PyType_GetModuleState(type);
- /* create attrgetterobject structure */
- ag = PyObject_GC_New(attrgetterobject, (PyTypeObject *)state->attrgetter_type);
- if (ag == NULL) {
- Py_DECREF(attr);
- return NULL;
- }
- ag->attr = attr;
- ag->nattrs = nattrs;
- ag->vectorcall = (vectorcallfunc)attrgetter_vectorcall;
- PyObject_GC_Track(ag);
- return (PyObject *)ag;
- }
- static int
- attrgetter_clear(attrgetterobject *ag)
- {
- Py_CLEAR(ag->attr);
- return 0;
- }
- static void
- attrgetter_dealloc(attrgetterobject *ag)
- {
- PyTypeObject *tp = Py_TYPE(ag);
- PyObject_GC_UnTrack(ag);
- (void)attrgetter_clear(ag);
- tp->tp_free(ag);
- Py_DECREF(tp);
- }
- static int
- attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
- {
- Py_VISIT(ag->attr);
- Py_VISIT(Py_TYPE(ag));
- return 0;
- }
- static PyObject *
- dotted_getattr(PyObject *obj, PyObject *attr)
- {
- PyObject *newobj;
- /* attr is either a tuple or instance of str.
- Ensured by the setup code of attrgetter_new */
- if (PyTuple_CheckExact(attr)) { /* chained getattr */
- Py_ssize_t name_idx = 0, name_count;
- PyObject *attr_name;
- name_count = PyTuple_GET_SIZE(attr);
- Py_INCREF(obj);
- for (name_idx = 0; name_idx < name_count; ++name_idx) {
- attr_name = PyTuple_GET_ITEM(attr, name_idx);
- newobj = PyObject_GetAttr(obj, attr_name);
- Py_DECREF(obj);
- if (newobj == NULL) {
- return NULL;
- }
- /* here */
- obj = newobj;
- }
- } else { /* single getattr */
- newobj = PyObject_GetAttr(obj, attr);
- if (newobj == NULL)
- return NULL;
- obj = newobj;
- }
- return obj;
- }
- static PyObject *
- attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
- {
- if (!_PyArg_NoKeywords("attrgetter", kw))
- return NULL;
- if (!_PyArg_CheckPositional("attrgetter", PyTuple_GET_SIZE(args), 1, 1))
- return NULL;
- return attrgetter_call_impl(ag, PyTuple_GET_ITEM(args, 0));
- }
- static PyObject *
- attrgetter_vectorcall(PyObject *ag, PyObject *const *args, size_t nargsf, PyObject *kwnames)
- {
- if (!_PyArg_NoKwnames("attrgetter", kwnames)) {
- return NULL;
- }
- Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
- if (!_PyArg_CheckPositional("attrgetter", nargs, 1, 1)) {
- return NULL;
- }
- return attrgetter_call_impl((attrgetterobject *)ag, args[0]);
- }
- static PyObject *
- attrgetter_call_impl(attrgetterobject *ag, PyObject *obj)
- {
- PyObject *result;
- Py_ssize_t i, nattrs=ag->nattrs;
- if (ag->nattrs == 1) {
- /* ag->attr is always a tuple */
- return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0));
- }
- assert(PyTuple_Check(ag->attr));
- assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
- result = PyTuple_New(nattrs);
- if (result == NULL)
- return NULL;
- for (i=0 ; i < nattrs ; i++) {
- PyObject *attr, *val;
- attr = PyTuple_GET_ITEM(ag->attr, i);
- val = dotted_getattr(obj, attr);
- if (val == NULL) {
- Py_DECREF(result);
- return NULL;
- }
- PyTuple_SET_ITEM(result, i, val);
- }
- return result;
- }
- static PyObject *
- dotjoinattr(PyObject *attr, PyObject **attrsep)
- {
- if (PyTuple_CheckExact(attr)) {
- if (*attrsep == NULL) {
- *attrsep = PyUnicode_FromString(".");
- if (*attrsep == NULL)
- return NULL;
- }
- return PyUnicode_Join(*attrsep, attr);
- } else {
- return Py_NewRef(attr);
- }
- }
- static PyObject *
- attrgetter_args(attrgetterobject *ag)
- {
- Py_ssize_t i;
- PyObject *attrsep = NULL;
- PyObject *attrstrings = PyTuple_New(ag->nattrs);
- if (attrstrings == NULL)
- return NULL;
- for (i = 0; i < ag->nattrs; ++i) {
- PyObject *attr = PyTuple_GET_ITEM(ag->attr, i);
- PyObject *attrstr = dotjoinattr(attr, &attrsep);
- if (attrstr == NULL) {
- Py_XDECREF(attrsep);
- Py_DECREF(attrstrings);
- return NULL;
- }
- PyTuple_SET_ITEM(attrstrings, i, attrstr);
- }
- Py_XDECREF(attrsep);
- return attrstrings;
- }
- static PyObject *
- attrgetter_repr(attrgetterobject *ag)
- {
- PyObject *repr = NULL;
- int status = Py_ReprEnter((PyObject *)ag);
- if (status != 0) {
- if (status < 0)
- return NULL;
- return PyUnicode_FromFormat("%s(...)", Py_TYPE(ag)->tp_name);
- }
- if (ag->nattrs == 1) {
- PyObject *attrsep = NULL;
- PyObject *attr = dotjoinattr(PyTuple_GET_ITEM(ag->attr, 0), &attrsep);
- if (attr != NULL) {
- repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(ag)->tp_name, attr);
- Py_DECREF(attr);
- }
- Py_XDECREF(attrsep);
- }
- else {
- PyObject *attrstrings = attrgetter_args(ag);
- if (attrstrings != NULL) {
- repr = PyUnicode_FromFormat("%s%R",
- Py_TYPE(ag)->tp_name, attrstrings);
- Py_DECREF(attrstrings);
- }
- }
- Py_ReprLeave((PyObject *)ag);
- return repr;
- }
- static PyObject *
- attrgetter_reduce(attrgetterobject *ag, PyObject *Py_UNUSED(ignored))
- {
- PyObject *attrstrings = attrgetter_args(ag);
- if (attrstrings == NULL)
- return NULL;
- return Py_BuildValue("ON", Py_TYPE(ag), attrstrings);
- }
- static PyMethodDef attrgetter_methods[] = {
- {"__reduce__", (PyCFunction)attrgetter_reduce, METH_NOARGS,
- reduce_doc},
- {NULL}
- };
- static PyMemberDef attrgetter_members[] = {
- {"__vectorcalloffset__", T_PYSSIZET, offsetof(attrgetterobject, vectorcall), READONLY},
- {NULL} /* Sentinel*/
- };
- PyDoc_STRVAR(attrgetter_doc,
- "attrgetter(attr, /, *attrs)\n--\n\n\
- Return a callable object that fetches the given attribute(s) from its operand.\n\
- After f = attrgetter('name'), the call f(r) returns r.name.\n\
- After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\
- After h = attrgetter('name.first', 'name.last'), the call h(r) returns\n\
- (r.name.first, r.name.last).");
- static PyType_Slot attrgetter_type_slots[] = {
- {Py_tp_doc, (void *)attrgetter_doc},
- {Py_tp_dealloc, attrgetter_dealloc},
- {Py_tp_call, attrgetter_call},
- {Py_tp_traverse, attrgetter_traverse},
- {Py_tp_clear, attrgetter_clear},
- {Py_tp_methods, attrgetter_methods},
- {Py_tp_members, attrgetter_members},
- {Py_tp_new, attrgetter_new},
- {Py_tp_getattro, PyObject_GenericGetAttr},
- {Py_tp_repr, attrgetter_repr},
- {0, 0}
- };
- static PyType_Spec attrgetter_type_spec = {
- .name = "operator.attrgetter",
- .basicsize = sizeof(attrgetterobject),
- .itemsize = 0,
- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
- Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_VECTORCALL),
- .slots = attrgetter_type_slots,
- };
- /* methodcaller object **********************************************************/
- typedef struct {
- PyObject_HEAD
- PyObject *name;
- PyObject *args;
- PyObject *kwds;
- } methodcallerobject;
- /* AC 3.5: variable number of arguments, not currently support by AC */
- static PyObject *
- methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
- methodcallerobject *mc;
- PyObject *name;
- if (PyTuple_GET_SIZE(args) < 1) {
- PyErr_SetString(PyExc_TypeError, "methodcaller needs at least "
- "one argument, the method name");
- return NULL;
- }
- name = PyTuple_GET_ITEM(args, 0);
- if (!PyUnicode_Check(name)) {
- PyErr_SetString(PyExc_TypeError,
- "method name must be a string");
- return NULL;
- }
- _operator_state *state = _PyType_GetModuleState(type);
- /* create methodcallerobject structure */
- mc = PyObject_GC_New(methodcallerobject, (PyTypeObject *)state->methodcaller_type);
- if (mc == NULL) {
- return NULL;
- }
- name = PyTuple_GET_ITEM(args, 0);
- Py_INCREF(name);
- PyInterpreterState *interp = _PyInterpreterState_GET();
- _PyUnicode_InternMortal(interp, &name);
- mc->name = name;
- mc->kwds = Py_XNewRef(kwds);
- mc->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
- if (mc->args == NULL) {
- Py_DECREF(mc);
- return NULL;
- }
- PyObject_GC_Track(mc);
- return (PyObject *)mc;
- }
- static int
- methodcaller_clear(methodcallerobject *mc)
- {
- Py_CLEAR(mc->name);
- Py_CLEAR(mc->args);
- Py_CLEAR(mc->kwds);
- return 0;
- }
- static void
- methodcaller_dealloc(methodcallerobject *mc)
- {
- PyTypeObject *tp = Py_TYPE(mc);
- PyObject_GC_UnTrack(mc);
- (void)methodcaller_clear(mc);
- tp->tp_free(mc);
- Py_DECREF(tp);
- }
- static int
- methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
- {
- Py_VISIT(mc->name);
- Py_VISIT(mc->args);
- Py_VISIT(mc->kwds);
- Py_VISIT(Py_TYPE(mc));
- return 0;
- }
- static PyObject *
- methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw)
- {
- PyObject *method, *obj, *result;
- if (!_PyArg_NoKeywords("methodcaller", kw))
- return NULL;
- if (!_PyArg_CheckPositional("methodcaller", PyTuple_GET_SIZE(args), 1, 1))
- return NULL;
- obj = PyTuple_GET_ITEM(args, 0);
- method = PyObject_GetAttr(obj, mc->name);
- if (method == NULL)
- return NULL;
- result = PyObject_Call(method, mc->args, mc->kwds);
- Py_DECREF(method);
- return result;
- }
- static PyObject *
- methodcaller_repr(methodcallerobject *mc)
- {
- PyObject *argreprs, *repr = NULL, *sep, *joinedargreprs;
- Py_ssize_t numtotalargs, numposargs, numkwdargs, i;
- int status = Py_ReprEnter((PyObject *)mc);
- if (status != 0) {
- if (status < 0)
- return NULL;
- return PyUnicode_FromFormat("%s(...)", Py_TYPE(mc)->tp_name);
- }
- numkwdargs = mc->kwds != NULL ? PyDict_GET_SIZE(mc->kwds) : 0;
- numposargs = PyTuple_GET_SIZE(mc->args);
- numtotalargs = numposargs + numkwdargs;
- if (numtotalargs == 0) {
- repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(mc)->tp_name, mc->name);
- Py_ReprLeave((PyObject *)mc);
- return repr;
- }
- argreprs = PyTuple_New(numtotalargs);
- if (argreprs == NULL) {
- Py_ReprLeave((PyObject *)mc);
- return NULL;
- }
- for (i = 0; i < numposargs; ++i) {
- PyObject *onerepr = PyObject_Repr(PyTuple_GET_ITEM(mc->args, i));
- if (onerepr == NULL)
- goto done;
- PyTuple_SET_ITEM(argreprs, i, onerepr);
- }
- if (numkwdargs != 0) {
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- while (PyDict_Next(mc->kwds, &pos, &key, &value)) {
- PyObject *onerepr = PyUnicode_FromFormat("%U=%R", key, value);
- if (onerepr == NULL)
- goto done;
- if (i >= numtotalargs) {
- i = -1;
- Py_DECREF(onerepr);
- break;
- }
- PyTuple_SET_ITEM(argreprs, i, onerepr);
- ++i;
- }
- if (i != numtotalargs) {
- PyErr_SetString(PyExc_RuntimeError,
- "keywords dict changed size during iteration");
- goto done;
- }
- }
- sep = PyUnicode_FromString(", ");
- if (sep == NULL)
- goto done;
- joinedargreprs = PyUnicode_Join(sep, argreprs);
- Py_DECREF(sep);
- if (joinedargreprs == NULL)
- goto done;
- repr = PyUnicode_FromFormat("%s(%R, %U)", Py_TYPE(mc)->tp_name,
- mc->name, joinedargreprs);
- Py_DECREF(joinedargreprs);
- done:
- Py_DECREF(argreprs);
- Py_ReprLeave((PyObject *)mc);
- return repr;
- }
- static PyObject *
- methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored))
- {
- PyObject *newargs;
- if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) {
- Py_ssize_t i;
- Py_ssize_t callargcount = PyTuple_GET_SIZE(mc->args);
- newargs = PyTuple_New(1 + callargcount);
- if (newargs == NULL)
- return NULL;
- PyTuple_SET_ITEM(newargs, 0, Py_NewRef(mc->name));
- for (i = 0; i < callargcount; ++i) {
- PyObject *arg = PyTuple_GET_ITEM(mc->args, i);
- PyTuple_SET_ITEM(newargs, i + 1, Py_NewRef(arg));
- }
- return Py_BuildValue("ON", Py_TYPE(mc), newargs);
- }
- else {
- PyObject *partial;
- PyObject *constructor;
- PyObject *newargs[2];
- partial = _PyImport_GetModuleAttrString("functools", "partial");
- if (!partial)
- return NULL;
- newargs[0] = (PyObject *)Py_TYPE(mc);
- newargs[1] = mc->name;
- constructor = PyObject_VectorcallDict(partial, newargs, 2, mc->kwds);
- Py_DECREF(partial);
- return Py_BuildValue("NO", constructor, mc->args);
- }
- }
- static PyMethodDef methodcaller_methods[] = {
- {"__reduce__", (PyCFunction)methodcaller_reduce, METH_NOARGS,
- reduce_doc},
- {NULL}
- };
- PyDoc_STRVAR(methodcaller_doc,
- "methodcaller(name, /, *args, **kwargs)\n--\n\n\
- Return a callable object that calls the given method on its operand.\n\
- After f = methodcaller('name'), the call f(r) returns r.name().\n\
- After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\
- r.name('date', foo=1).");
- static PyType_Slot methodcaller_type_slots[] = {
- {Py_tp_doc, (void *)methodcaller_doc},
- {Py_tp_dealloc, methodcaller_dealloc},
- {Py_tp_call, methodcaller_call},
- {Py_tp_traverse, methodcaller_traverse},
- {Py_tp_clear, methodcaller_clear},
- {Py_tp_methods, methodcaller_methods},
- {Py_tp_new, methodcaller_new},
- {Py_tp_getattro, PyObject_GenericGetAttr},
- {Py_tp_repr, methodcaller_repr},
- {0, 0}
- };
- static PyType_Spec methodcaller_type_spec = {
- .name = "operator.methodcaller",
- .basicsize = sizeof(methodcallerobject),
- .itemsize = 0,
- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
- Py_TPFLAGS_IMMUTABLETYPE),
- .slots = methodcaller_type_slots,
- };
- static int
- operator_exec(PyObject *module)
- {
- _operator_state *state = get_operator_state(module);
- state->attrgetter_type = PyType_FromModuleAndSpec(module, &attrgetter_type_spec, NULL);
- if (state->attrgetter_type == NULL) {
- return -1;
- }
- if (PyModule_AddType(module, (PyTypeObject *)state->attrgetter_type) < 0) {
- return -1;
- }
- state->itemgetter_type = PyType_FromModuleAndSpec(module, &itemgetter_type_spec, NULL);
- if (state->itemgetter_type == NULL) {
- return -1;
- }
- if (PyModule_AddType(module, (PyTypeObject *)state->itemgetter_type) < 0) {
- return -1;
- }
- state->methodcaller_type = PyType_FromModuleAndSpec(module, &methodcaller_type_spec, NULL);
- if (state->methodcaller_type == NULL) {
- return -1;
- }
- if (PyModule_AddType(module, (PyTypeObject *)state->methodcaller_type) < 0) {
- return -1;
- }
- return 0;
- }
- static struct PyModuleDef_Slot operator_slots[] = {
- {Py_mod_exec, operator_exec},
- {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
- {0, NULL}
- };
- static int
- operator_traverse(PyObject *module, visitproc visit, void *arg)
- {
- _operator_state *state = get_operator_state(module);
- Py_VISIT(state->attrgetter_type);
- Py_VISIT(state->itemgetter_type);
- Py_VISIT(state->methodcaller_type);
- return 0;
- }
- static int
- operator_clear(PyObject *module)
- {
- _operator_state *state = get_operator_state(module);
- Py_CLEAR(state->attrgetter_type);
- Py_CLEAR(state->itemgetter_type);
- Py_CLEAR(state->methodcaller_type);
- return 0;
- }
- static void
- operator_free(void *module)
- {
- operator_clear((PyObject *)module);
- }
- static struct PyModuleDef operatormodule = {
- PyModuleDef_HEAD_INIT,
- .m_name = "_operator",
- .m_doc = operator_doc,
- .m_size = sizeof(_operator_state),
- .m_methods = operator_methods,
- .m_slots = operator_slots,
- .m_traverse = operator_traverse,
- .m_clear = operator_clear,
- .m_free = operator_free,
- };
- PyMODINIT_FUNC
- PyInit__operator(void)
- {
- return PyModuleDef_Init(&operatormodule);
- }
|