mirror of
				https://github.com/python/cpython.git
				synced 2025-10-25 18:54:53 +00:00 
			
		
		
		
	GH-90699: use statically allocated interned strings in typeobject's slotdefs (GH-94706)
This commit is contained in:
		
							parent
							
								
									b65686c505
								
							
						
					
					
						commit
						4e4bfffe2d
					
				
					 5 changed files with 140 additions and 176 deletions
				
			
		|  | @ -11,7 +11,6 @@ extern "C" { | ||||||
| 
 | 
 | ||||||
| /* runtime lifecycle */ | /* runtime lifecycle */ | ||||||
| 
 | 
 | ||||||
| extern PyStatus _PyTypes_InitState(PyInterpreterState *); |  | ||||||
| extern PyStatus _PyTypes_InitTypes(PyInterpreterState *); | extern PyStatus _PyTypes_InitTypes(PyInterpreterState *); | ||||||
| extern void _PyTypes_FiniTypes(PyInterpreterState *); | extern void _PyTypes_FiniTypes(PyInterpreterState *); | ||||||
| extern void _PyTypes_Fini(PyInterpreterState *); | extern void _PyTypes_Fini(PyInterpreterState *); | ||||||
|  | @ -67,8 +66,6 @@ struct types_state { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| extern PyStatus _PyTypes_InitSlotDefs(void); |  | ||||||
| 
 |  | ||||||
| extern int _PyStaticType_InitBuiltin(PyTypeObject *type); | extern int _PyStaticType_InitBuiltin(PyTypeObject *type); | ||||||
| extern static_builtin_state * _PyStaticType_GetState(PyTypeObject *); | extern static_builtin_state * _PyStaticType_GetState(PyTypeObject *); | ||||||
| extern void _PyStaticType_ClearWeakRefs(PyTypeObject *type); | extern void _PyStaticType_ClearWeakRefs(PyTypeObject *type); | ||||||
|  |  | ||||||
|  | @ -14,7 +14,6 @@ | ||||||
| #include "pycore_pymem.h"         // _PyMem_IsPtrFreed() | #include "pycore_pymem.h"         // _PyMem_IsPtrFreed() | ||||||
| #include "pycore_pystate.h"       // _PyThreadState_GET() | #include "pycore_pystate.h"       // _PyThreadState_GET() | ||||||
| #include "pycore_symtable.h"      // PySTEntry_Type | #include "pycore_symtable.h"      // PySTEntry_Type | ||||||
| #include "pycore_typeobject.h"    // _PyTypes_InitSlotDefs() |  | ||||||
| #include "pycore_unionobject.h"   // _PyUnion_Type | #include "pycore_unionobject.h"   // _PyUnion_Type | ||||||
| #include "pycore_interpreteridobject.h"  // _PyInterpreterID_Type | #include "pycore_interpreteridobject.h"  // _PyInterpreterID_Type | ||||||
| 
 | 
 | ||||||
|  | @ -1835,23 +1834,6 @@ PyObject _Py_NotImplementedStruct = { | ||||||
|     1, &_PyNotImplemented_Type |     1, &_PyNotImplemented_Type | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| PyStatus |  | ||||||
| _PyTypes_InitState(PyInterpreterState *interp) |  | ||||||
| { |  | ||||||
|     if (!_Py_IsMainInterpreter(interp)) { |  | ||||||
|         return _PyStatus_OK(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     PyStatus status = _PyTypes_InitSlotDefs(); |  | ||||||
|     if (_PyStatus_EXCEPTION(status)) { |  | ||||||
|         return status; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return _PyStatus_OK(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| #ifdef MS_WINDOWS | #ifdef MS_WINDOWS | ||||||
| extern PyTypeObject PyHKEY_Type; | extern PyTypeObject PyHKEY_Type; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -56,9 +56,6 @@ typedef struct PySlot_Offset { | ||||||
| static PyObject * | static PyObject * | ||||||
| slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds); | slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds); | ||||||
| 
 | 
 | ||||||
| static void |  | ||||||
| clear_slotdefs(void); |  | ||||||
| 
 |  | ||||||
| static PyObject * | static PyObject * | ||||||
| lookup_maybe_method(PyObject *self, PyObject *attr, int *unbound); | lookup_maybe_method(PyObject *self, PyObject *attr, int *unbound); | ||||||
| 
 | 
 | ||||||
|  | @ -364,9 +361,6 @@ _PyTypes_Fini(PyInterpreterState *interp) | ||||||
| { | { | ||||||
|     struct type_cache *cache = &interp->types.type_cache; |     struct type_cache *cache = &interp->types.type_cache; | ||||||
|     type_cache_clear(cache, NULL); |     type_cache_clear(cache, NULL); | ||||||
|     if (_Py_IsMainInterpreter(interp)) { |  | ||||||
|         clear_slotdefs(); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     assert(interp->types.num_builtins_initialized == 0); |     assert(interp->types.num_builtins_initialized == 0); | ||||||
|     // All the static builtin types should have been finalized already.
 |     // All the static builtin types should have been finalized already.
 | ||||||
|  | @ -8451,8 +8445,7 @@ which incorporates the additional structures used for numbers, sequences and | ||||||
| mappings.  Note that multiple names may map to the same slot (e.g. __eq__, | mappings.  Note that multiple names may map to the same slot (e.g. __eq__, | ||||||
| __ne__ etc. all map to tp_richcompare) and one name may map to multiple slots | __ne__ etc. all map to tp_richcompare) and one name may map to multiple slots | ||||||
| (e.g. __str__ affects tp_str as well as tp_repr). The table is terminated with | (e.g. __str__ affects tp_str as well as tp_repr). The table is terminated with | ||||||
| an all-zero entry.  (This table is further initialized in | an all-zero entry. | ||||||
| _PyTypes_InitSlotDefs().) |  | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| typedef struct wrapperbase slotdef; | typedef struct wrapperbase slotdef; | ||||||
|  | @ -8470,14 +8463,14 @@ typedef struct wrapperbase slotdef; | ||||||
| #undef RBINSLOT | #undef RBINSLOT | ||||||
| 
 | 
 | ||||||
| #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ | #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ | ||||||
|     {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ |     {#NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ | ||||||
|      PyDoc_STR(DOC)} |      PyDoc_STR(DOC), .name_strobj = &_Py_ID(NAME)} | ||||||
| #define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \ | #define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \ | ||||||
|     {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ |     {#NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ | ||||||
|      PyDoc_STR(DOC), FLAGS} |      PyDoc_STR(DOC), FLAGS, .name_strobj = &_Py_ID(NAME) } | ||||||
| #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ | #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ | ||||||
|     {NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ |     {#NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ | ||||||
|      PyDoc_STR(DOC)} |      PyDoc_STR(DOC), .name_strobj = &_Py_ID(NAME) } | ||||||
| #define AMSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ | #define AMSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ | ||||||
|     ETSLOT(NAME, as_async.SLOT, FUNCTION, WRAPPER, DOC) |     ETSLOT(NAME, as_async.SLOT, FUNCTION, WRAPPER, DOC) | ||||||
| #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ | #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ | ||||||
|  | @ -8488,204 +8481,204 @@ typedef struct wrapperbase slotdef; | ||||||
|     ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC) |     ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC) | ||||||
| #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ | #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ | ||||||
|     ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ |     ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ | ||||||
|            NAME "($self, /)\n--\n\n" DOC) |            #NAME "($self, /)\n--\n\n" DOC) | ||||||
| #define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ | #define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ | ||||||
|     ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ |     ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ | ||||||
|            NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") |            #NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") | ||||||
| #define BINSLOT(NAME, SLOT, FUNCTION, DOC) \ | #define BINSLOT(NAME, SLOT, FUNCTION, DOC) \ | ||||||
|     ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ |     ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ | ||||||
|            NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") |            #NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") | ||||||
| #define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \ | #define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \ | ||||||
|     ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ |     ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ | ||||||
|            NAME "($self, value, /)\n--\n\nReturn value" DOC "self.") |            #NAME "($self, value, /)\n--\n\nReturn value" DOC "self.") | ||||||
| #define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ | #define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ | ||||||
|     ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ |     ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ | ||||||
|            NAME "($self, value, /)\n--\n\n" DOC) |            #NAME "($self, value, /)\n--\n\n" DOC) | ||||||
| #define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ | #define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ | ||||||
|     ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ |     ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ | ||||||
|            NAME "($self, value, /)\n--\n\n" DOC) |            #NAME "($self, value, /)\n--\n\n" DOC) | ||||||
| 
 | 
 | ||||||
| static slotdef slotdefs[] = { | static slotdef slotdefs[] = { | ||||||
|     TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), |     TPSLOT(__getattribute__, tp_getattr, NULL, NULL, ""), | ||||||
|     TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""), |     TPSLOT(__getattr__, tp_getattr, NULL, NULL, ""), | ||||||
|     TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), |     TPSLOT(__setattr__, tp_setattr, NULL, NULL, ""), | ||||||
|     TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), |     TPSLOT(__delattr__, tp_setattr, NULL, NULL, ""), | ||||||
|     TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, |     TPSLOT(__repr__, tp_repr, slot_tp_repr, wrap_unaryfunc, | ||||||
|            "__repr__($self, /)\n--\n\nReturn repr(self)."), |            "__repr__($self, /)\n--\n\nReturn repr(self)."), | ||||||
|     TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, |     TPSLOT(__hash__, tp_hash, slot_tp_hash, wrap_hashfunc, | ||||||
|            "__hash__($self, /)\n--\n\nReturn hash(self)."), |            "__hash__($self, /)\n--\n\nReturn hash(self)."), | ||||||
|     FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)(void(*)(void))wrap_call, |     FLSLOT(__call__, tp_call, slot_tp_call, (wrapperfunc)(void(*)(void))wrap_call, | ||||||
|            "__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function.", |            "__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function.", | ||||||
|            PyWrapperFlag_KEYWORDS), |            PyWrapperFlag_KEYWORDS), | ||||||
|     TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, |     TPSLOT(__str__, tp_str, slot_tp_str, wrap_unaryfunc, | ||||||
|            "__str__($self, /)\n--\n\nReturn str(self)."), |            "__str__($self, /)\n--\n\nReturn str(self)."), | ||||||
|     TPSLOT("__getattribute__", tp_getattro, _Py_slot_tp_getattr_hook, |     TPSLOT(__getattribute__, tp_getattro, _Py_slot_tp_getattr_hook, | ||||||
|            wrap_binaryfunc, |            wrap_binaryfunc, | ||||||
|            "__getattribute__($self, name, /)\n--\n\nReturn getattr(self, name)."), |            "__getattribute__($self, name, /)\n--\n\nReturn getattr(self, name)."), | ||||||
|     TPSLOT("__getattr__", tp_getattro, _Py_slot_tp_getattr_hook, NULL, ""), |     TPSLOT(__getattr__, tp_getattro, _Py_slot_tp_getattr_hook, NULL, ""), | ||||||
|     TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, |     TPSLOT(__setattr__, tp_setattro, slot_tp_setattro, wrap_setattr, | ||||||
|            "__setattr__($self, name, value, /)\n--\n\nImplement setattr(self, name, value)."), |            "__setattr__($self, name, value, /)\n--\n\nImplement setattr(self, name, value)."), | ||||||
|     TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr, |     TPSLOT(__delattr__, tp_setattro, slot_tp_setattro, wrap_delattr, | ||||||
|            "__delattr__($self, name, /)\n--\n\nImplement delattr(self, name)."), |            "__delattr__($self, name, /)\n--\n\nImplement delattr(self, name)."), | ||||||
|     TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt, |     TPSLOT(__lt__, tp_richcompare, slot_tp_richcompare, richcmp_lt, | ||||||
|            "__lt__($self, value, /)\n--\n\nReturn self<value."), |            "__lt__($self, value, /)\n--\n\nReturn self<value."), | ||||||
|     TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le, |     TPSLOT(__le__, tp_richcompare, slot_tp_richcompare, richcmp_le, | ||||||
|            "__le__($self, value, /)\n--\n\nReturn self<=value."), |            "__le__($self, value, /)\n--\n\nReturn self<=value."), | ||||||
|     TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq, |     TPSLOT(__eq__, tp_richcompare, slot_tp_richcompare, richcmp_eq, | ||||||
|            "__eq__($self, value, /)\n--\n\nReturn self==value."), |            "__eq__($self, value, /)\n--\n\nReturn self==value."), | ||||||
|     TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne, |     TPSLOT(__ne__, tp_richcompare, slot_tp_richcompare, richcmp_ne, | ||||||
|            "__ne__($self, value, /)\n--\n\nReturn self!=value."), |            "__ne__($self, value, /)\n--\n\nReturn self!=value."), | ||||||
|     TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt, |     TPSLOT(__gt__, tp_richcompare, slot_tp_richcompare, richcmp_gt, | ||||||
|            "__gt__($self, value, /)\n--\n\nReturn self>value."), |            "__gt__($self, value, /)\n--\n\nReturn self>value."), | ||||||
|     TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge, |     TPSLOT(__ge__, tp_richcompare, slot_tp_richcompare, richcmp_ge, | ||||||
|            "__ge__($self, value, /)\n--\n\nReturn self>=value."), |            "__ge__($self, value, /)\n--\n\nReturn self>=value."), | ||||||
|     TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc, |     TPSLOT(__iter__, tp_iter, slot_tp_iter, wrap_unaryfunc, | ||||||
|            "__iter__($self, /)\n--\n\nImplement iter(self)."), |            "__iter__($self, /)\n--\n\nImplement iter(self)."), | ||||||
|     TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next, |     TPSLOT(__next__, tp_iternext, slot_tp_iternext, wrap_next, | ||||||
|            "__next__($self, /)\n--\n\nImplement next(self)."), |            "__next__($self, /)\n--\n\nImplement next(self)."), | ||||||
|     TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get, |     TPSLOT(__get__, tp_descr_get, slot_tp_descr_get, wrap_descr_get, | ||||||
|            "__get__($self, instance, owner=None, /)\n--\n\nReturn an attribute of instance, which is of type owner."), |            "__get__($self, instance, owner=None, /)\n--\n\nReturn an attribute of instance, which is of type owner."), | ||||||
|     TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, |     TPSLOT(__set__, tp_descr_set, slot_tp_descr_set, wrap_descr_set, | ||||||
|            "__set__($self, instance, value, /)\n--\n\nSet an attribute of instance to value."), |            "__set__($self, instance, value, /)\n--\n\nSet an attribute of instance to value."), | ||||||
|     TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set, |     TPSLOT(__delete__, tp_descr_set, slot_tp_descr_set, | ||||||
|            wrap_descr_delete, |            wrap_descr_delete, | ||||||
|            "__delete__($self, instance, /)\n--\n\nDelete an attribute of instance."), |            "__delete__($self, instance, /)\n--\n\nDelete an attribute of instance."), | ||||||
|     FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)(void(*)(void))wrap_init, |     FLSLOT(__init__, tp_init, slot_tp_init, (wrapperfunc)(void(*)(void))wrap_init, | ||||||
|            "__init__($self, /, *args, **kwargs)\n--\n\n" |            "__init__($self, /, *args, **kwargs)\n--\n\n" | ||||||
|            "Initialize self.  See help(type(self)) for accurate signature.", |            "Initialize self.  See help(type(self)) for accurate signature.", | ||||||
|            PyWrapperFlag_KEYWORDS), |            PyWrapperFlag_KEYWORDS), | ||||||
|     TPSLOT("__new__", tp_new, slot_tp_new, NULL, |     TPSLOT(__new__, tp_new, slot_tp_new, NULL, | ||||||
|            "__new__(type, /, *args, **kwargs)\n--\n\n" |            "__new__(type, /, *args, **kwargs)\n--\n\n" | ||||||
|            "Create and return new object.  See help(type) for accurate signature."), |            "Create and return new object.  See help(type) for accurate signature."), | ||||||
|     TPSLOT("__del__", tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""), |     TPSLOT(__del__, tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""), | ||||||
| 
 | 
 | ||||||
|     AMSLOT("__await__", am_await, slot_am_await, wrap_unaryfunc, |     AMSLOT(__await__, am_await, slot_am_await, wrap_unaryfunc, | ||||||
|            "__await__($self, /)\n--\n\nReturn an iterator to be used in await expression."), |            "__await__($self, /)\n--\n\nReturn an iterator to be used in await expression."), | ||||||
|     AMSLOT("__aiter__", am_aiter, slot_am_aiter, wrap_unaryfunc, |     AMSLOT(__aiter__, am_aiter, slot_am_aiter, wrap_unaryfunc, | ||||||
|            "__aiter__($self, /)\n--\n\nReturn an awaitable, that resolves in asynchronous iterator."), |            "__aiter__($self, /)\n--\n\nReturn an awaitable, that resolves in asynchronous iterator."), | ||||||
|     AMSLOT("__anext__", am_anext, slot_am_anext, wrap_unaryfunc, |     AMSLOT(__anext__, am_anext, slot_am_anext, wrap_unaryfunc, | ||||||
|            "__anext__($self, /)\n--\n\nReturn a value or raise StopAsyncIteration."), |            "__anext__($self, /)\n--\n\nReturn a value or raise StopAsyncIteration."), | ||||||
| 
 | 
 | ||||||
|     BINSLOT("__add__", nb_add, slot_nb_add, |     BINSLOT(__add__, nb_add, slot_nb_add, | ||||||
|            "+"), |            "+"), | ||||||
|     RBINSLOT("__radd__", nb_add, slot_nb_add, |     RBINSLOT(__radd__, nb_add, slot_nb_add, | ||||||
|            "+"), |            "+"), | ||||||
|     BINSLOT("__sub__", nb_subtract, slot_nb_subtract, |     BINSLOT(__sub__, nb_subtract, slot_nb_subtract, | ||||||
|            "-"), |            "-"), | ||||||
|     RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract, |     RBINSLOT(__rsub__, nb_subtract, slot_nb_subtract, | ||||||
|            "-"), |            "-"), | ||||||
|     BINSLOT("__mul__", nb_multiply, slot_nb_multiply, |     BINSLOT(__mul__, nb_multiply, slot_nb_multiply, | ||||||
|            "*"), |            "*"), | ||||||
|     RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply, |     RBINSLOT(__rmul__, nb_multiply, slot_nb_multiply, | ||||||
|            "*"), |            "*"), | ||||||
|     BINSLOT("__mod__", nb_remainder, slot_nb_remainder, |     BINSLOT(__mod__, nb_remainder, slot_nb_remainder, | ||||||
|            "%"), |            "%"), | ||||||
|     RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder, |     RBINSLOT(__rmod__, nb_remainder, slot_nb_remainder, | ||||||
|            "%"), |            "%"), | ||||||
|     BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod, |     BINSLOTNOTINFIX(__divmod__, nb_divmod, slot_nb_divmod, | ||||||
|            "Return divmod(self, value)."), |            "Return divmod(self, value)."), | ||||||
|     RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod, |     RBINSLOTNOTINFIX(__rdivmod__, nb_divmod, slot_nb_divmod, | ||||||
|            "Return divmod(value, self)."), |            "Return divmod(value, self)."), | ||||||
|     NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc, |     NBSLOT(__pow__, nb_power, slot_nb_power, wrap_ternaryfunc, | ||||||
|            "__pow__($self, value, mod=None, /)\n--\n\nReturn pow(self, value, mod)."), |            "__pow__($self, value, mod=None, /)\n--\n\nReturn pow(self, value, mod)."), | ||||||
|     NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r, |     NBSLOT(__rpow__, nb_power, slot_nb_power, wrap_ternaryfunc_r, | ||||||
|            "__rpow__($self, value, mod=None, /)\n--\n\nReturn pow(value, self, mod)."), |            "__rpow__($self, value, mod=None, /)\n--\n\nReturn pow(value, self, mod)."), | ||||||
|     UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"), |     UNSLOT(__neg__, nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"), | ||||||
|     UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"), |     UNSLOT(__pos__, nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"), | ||||||
|     UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc, |     UNSLOT(__abs__, nb_absolute, slot_nb_absolute, wrap_unaryfunc, | ||||||
|            "abs(self)"), |            "abs(self)"), | ||||||
|     UNSLOT("__bool__", nb_bool, slot_nb_bool, wrap_inquirypred, |     UNSLOT(__bool__, nb_bool, slot_nb_bool, wrap_inquirypred, | ||||||
|            "True if self else False"), |            "True if self else False"), | ||||||
|     UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~self"), |     UNSLOT(__invert__, nb_invert, slot_nb_invert, wrap_unaryfunc, "~self"), | ||||||
|     BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"), |     BINSLOT(__lshift__, nb_lshift, slot_nb_lshift, "<<"), | ||||||
|     RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"), |     RBINSLOT(__rlshift__, nb_lshift, slot_nb_lshift, "<<"), | ||||||
|     BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"), |     BINSLOT(__rshift__, nb_rshift, slot_nb_rshift, ">>"), | ||||||
|     RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift, ">>"), |     RBINSLOT(__rrshift__, nb_rshift, slot_nb_rshift, ">>"), | ||||||
|     BINSLOT("__and__", nb_and, slot_nb_and, "&"), |     BINSLOT(__and__, nb_and, slot_nb_and, "&"), | ||||||
|     RBINSLOT("__rand__", nb_and, slot_nb_and, "&"), |     RBINSLOT(__rand__, nb_and, slot_nb_and, "&"), | ||||||
|     BINSLOT("__xor__", nb_xor, slot_nb_xor, "^"), |     BINSLOT(__xor__, nb_xor, slot_nb_xor, "^"), | ||||||
|     RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"), |     RBINSLOT(__rxor__, nb_xor, slot_nb_xor, "^"), | ||||||
|     BINSLOT("__or__", nb_or, slot_nb_or, "|"), |     BINSLOT(__or__, nb_or, slot_nb_or, "|"), | ||||||
|     RBINSLOT("__ror__", nb_or, slot_nb_or, "|"), |     RBINSLOT(__ror__, nb_or, slot_nb_or, "|"), | ||||||
|     UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, |     UNSLOT(__int__, nb_int, slot_nb_int, wrap_unaryfunc, | ||||||
|            "int(self)"), |            "int(self)"), | ||||||
|     UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, |     UNSLOT(__float__, nb_float, slot_nb_float, wrap_unaryfunc, | ||||||
|            "float(self)"), |            "float(self)"), | ||||||
|     IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, |     IBSLOT(__iadd__, nb_inplace_add, slot_nb_inplace_add, | ||||||
|            wrap_binaryfunc, "+="), |            wrap_binaryfunc, "+="), | ||||||
|     IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, |     IBSLOT(__isub__, nb_inplace_subtract, slot_nb_inplace_subtract, | ||||||
|            wrap_binaryfunc, "-="), |            wrap_binaryfunc, "-="), | ||||||
|     IBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply, |     IBSLOT(__imul__, nb_inplace_multiply, slot_nb_inplace_multiply, | ||||||
|            wrap_binaryfunc, "*="), |            wrap_binaryfunc, "*="), | ||||||
|     IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder, |     IBSLOT(__imod__, nb_inplace_remainder, slot_nb_inplace_remainder, | ||||||
|            wrap_binaryfunc, "%="), |            wrap_binaryfunc, "%="), | ||||||
|     IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power, |     IBSLOT(__ipow__, nb_inplace_power, slot_nb_inplace_power, | ||||||
|            wrap_ternaryfunc, "**="), |            wrap_ternaryfunc, "**="), | ||||||
|     IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift, |     IBSLOT(__ilshift__, nb_inplace_lshift, slot_nb_inplace_lshift, | ||||||
|            wrap_binaryfunc, "<<="), |            wrap_binaryfunc, "<<="), | ||||||
|     IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift, |     IBSLOT(__irshift__, nb_inplace_rshift, slot_nb_inplace_rshift, | ||||||
|            wrap_binaryfunc, ">>="), |            wrap_binaryfunc, ">>="), | ||||||
|     IBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and, |     IBSLOT(__iand__, nb_inplace_and, slot_nb_inplace_and, | ||||||
|            wrap_binaryfunc, "&="), |            wrap_binaryfunc, "&="), | ||||||
|     IBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor, |     IBSLOT(__ixor__, nb_inplace_xor, slot_nb_inplace_xor, | ||||||
|            wrap_binaryfunc, "^="), |            wrap_binaryfunc, "^="), | ||||||
|     IBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or, |     IBSLOT(__ior__, nb_inplace_or, slot_nb_inplace_or, | ||||||
|            wrap_binaryfunc, "|="), |            wrap_binaryfunc, "|="), | ||||||
|     BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), |     BINSLOT(__floordiv__, nb_floor_divide, slot_nb_floor_divide, "//"), | ||||||
|     RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), |     RBINSLOT(__rfloordiv__, nb_floor_divide, slot_nb_floor_divide, "//"), | ||||||
|     BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide, "/"), |     BINSLOT(__truediv__, nb_true_divide, slot_nb_true_divide, "/"), | ||||||
|     RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide, "/"), |     RBINSLOT(__rtruediv__, nb_true_divide, slot_nb_true_divide, "/"), | ||||||
|     IBSLOT("__ifloordiv__", nb_inplace_floor_divide, |     IBSLOT(__ifloordiv__, nb_inplace_floor_divide, | ||||||
|            slot_nb_inplace_floor_divide, wrap_binaryfunc, "//="), |            slot_nb_inplace_floor_divide, wrap_binaryfunc, "//="), | ||||||
|     IBSLOT("__itruediv__", nb_inplace_true_divide, |     IBSLOT(__itruediv__, nb_inplace_true_divide, | ||||||
|            slot_nb_inplace_true_divide, wrap_binaryfunc, "/="), |            slot_nb_inplace_true_divide, wrap_binaryfunc, "/="), | ||||||
|     NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, |     NBSLOT(__index__, nb_index, slot_nb_index, wrap_unaryfunc, | ||||||
|            "__index__($self, /)\n--\n\n" |            "__index__($self, /)\n--\n\n" | ||||||
|            "Return self converted to an integer, if self is suitable " |            "Return self converted to an integer, if self is suitable " | ||||||
|            "for use as an index into a list."), |            "for use as an index into a list."), | ||||||
|     BINSLOT("__matmul__", nb_matrix_multiply, slot_nb_matrix_multiply, |     BINSLOT(__matmul__, nb_matrix_multiply, slot_nb_matrix_multiply, | ||||||
|             "@"), |             "@"), | ||||||
|     RBINSLOT("__rmatmul__", nb_matrix_multiply, slot_nb_matrix_multiply, |     RBINSLOT(__rmatmul__, nb_matrix_multiply, slot_nb_matrix_multiply, | ||||||
|              "@"), |              "@"), | ||||||
|     IBSLOT("__imatmul__", nb_inplace_matrix_multiply, slot_nb_inplace_matrix_multiply, |     IBSLOT(__imatmul__, nb_inplace_matrix_multiply, slot_nb_inplace_matrix_multiply, | ||||||
|            wrap_binaryfunc, "@="), |            wrap_binaryfunc, "@="), | ||||||
|     MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc, |     MPSLOT(__len__, mp_length, slot_mp_length, wrap_lenfunc, | ||||||
|            "__len__($self, /)\n--\n\nReturn len(self)."), |            "__len__($self, /)\n--\n\nReturn len(self)."), | ||||||
|     MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, |     MPSLOT(__getitem__, mp_subscript, slot_mp_subscript, | ||||||
|            wrap_binaryfunc, |            wrap_binaryfunc, | ||||||
|            "__getitem__($self, key, /)\n--\n\nReturn self[key]."), |            "__getitem__($self, key, /)\n--\n\nReturn self[key]."), | ||||||
|     MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, |     MPSLOT(__setitem__, mp_ass_subscript, slot_mp_ass_subscript, | ||||||
|            wrap_objobjargproc, |            wrap_objobjargproc, | ||||||
|            "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), |            "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), | ||||||
|     MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript, |     MPSLOT(__delitem__, mp_ass_subscript, slot_mp_ass_subscript, | ||||||
|            wrap_delitem, |            wrap_delitem, | ||||||
|            "__delitem__($self, key, /)\n--\n\nDelete self[key]."), |            "__delitem__($self, key, /)\n--\n\nDelete self[key]."), | ||||||
| 
 | 
 | ||||||
|     SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, |     SQSLOT(__len__, sq_length, slot_sq_length, wrap_lenfunc, | ||||||
|            "__len__($self, /)\n--\n\nReturn len(self)."), |            "__len__($self, /)\n--\n\nReturn len(self)."), | ||||||
|     /* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL.
 |     /* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL.
 | ||||||
|        The logic in abstract.c always falls back to nb_add/nb_multiply in |        The logic in abstract.c always falls back to nb_add/nb_multiply in | ||||||
|        this case.  Defining both the nb_* and the sq_* slots to call the |        this case.  Defining both the nb_* and the sq_* slots to call the | ||||||
|        user-defined methods has unexpected side-effects, as shown by |        user-defined methods has unexpected side-effects, as shown by | ||||||
|        test_descr.notimplemented() */ |        test_descr.notimplemented() */ | ||||||
|     SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, |     SQSLOT(__add__, sq_concat, NULL, wrap_binaryfunc, | ||||||
|            "__add__($self, value, /)\n--\n\nReturn self+value."), |            "__add__($self, value, /)\n--\n\nReturn self+value."), | ||||||
|     SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc, |     SQSLOT(__mul__, sq_repeat, NULL, wrap_indexargfunc, | ||||||
|            "__mul__($self, value, /)\n--\n\nReturn self*value."), |            "__mul__($self, value, /)\n--\n\nReturn self*value."), | ||||||
|     SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc, |     SQSLOT(__rmul__, sq_repeat, NULL, wrap_indexargfunc, | ||||||
|            "__rmul__($self, value, /)\n--\n\nReturn value*self."), |            "__rmul__($self, value, /)\n--\n\nReturn value*self."), | ||||||
|     SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, |     SQSLOT(__getitem__, sq_item, slot_sq_item, wrap_sq_item, | ||||||
|            "__getitem__($self, key, /)\n--\n\nReturn self[key]."), |            "__getitem__($self, key, /)\n--\n\nReturn self[key]."), | ||||||
|     SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, |     SQSLOT(__setitem__, sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, | ||||||
|            "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), |            "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), | ||||||
|     SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, |     SQSLOT(__delitem__, sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, | ||||||
|            "__delitem__($self, key, /)\n--\n\nDelete self[key]."), |            "__delitem__($self, key, /)\n--\n\nDelete self[key]."), | ||||||
|     SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc, |     SQSLOT(__contains__, sq_contains, slot_sq_contains, wrap_objobjproc, | ||||||
|            "__contains__($self, key, /)\n--\n\nReturn key in self."), |            "__contains__($self, key, /)\n--\n\nReturn key in self."), | ||||||
|     SQSLOT("__iadd__", sq_inplace_concat, NULL, |     SQSLOT(__iadd__, sq_inplace_concat, NULL, | ||||||
|            wrap_binaryfunc, |            wrap_binaryfunc, | ||||||
|            "__iadd__($self, value, /)\n--\n\nImplement self+=value."), |            "__iadd__($self, value, /)\n--\n\nImplement self+=value."), | ||||||
|     SQSLOT("__imul__", sq_inplace_repeat, NULL, |     SQSLOT(__imul__, sq_inplace_repeat, NULL, | ||||||
|            wrap_indexargfunc, |            wrap_indexargfunc, | ||||||
|            "__imul__($self, value, /)\n--\n\nImplement self*=value."), |            "__imul__($self, value, /)\n--\n\nImplement self*=value."), | ||||||
| 
 | 
 | ||||||
|  | @ -8953,38 +8946,6 @@ update_slots_callback(PyTypeObject *type, void *data) | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int slotdefs_initialized = 0; |  | ||||||
| /* Initialize the slotdefs table by adding interned string objects for the
 |  | ||||||
|    names. */ |  | ||||||
| PyStatus |  | ||||||
| _PyTypes_InitSlotDefs(void) |  | ||||||
| { |  | ||||||
|     if (slotdefs_initialized) { |  | ||||||
|         return _PyStatus_OK(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     for (slotdef *p = slotdefs; p->name; p++) { |  | ||||||
|         /* Slots must be ordered by their offset in the PyHeapTypeObject. */ |  | ||||||
|         assert(!p[1].name || p->offset <= p[1].offset); |  | ||||||
|         /* bpo-40521: Interned strings are shared by all subinterpreters */ |  | ||||||
|         p->name_strobj = PyUnicode_InternFromString(p->name); |  | ||||||
|         if (!p->name_strobj || !PyUnicode_CHECK_INTERNED(p->name_strobj)) { |  | ||||||
|             return _PyStatus_NO_MEMORY(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     slotdefs_initialized = 1; |  | ||||||
|     return _PyStatus_OK(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Undo _PyTypes_InitSlotDefs(), releasing the interned strings. */ |  | ||||||
| static void clear_slotdefs(void) |  | ||||||
| { |  | ||||||
|     for (slotdef *p = slotdefs; p->name; p++) { |  | ||||||
|         Py_CLEAR(p->name_strobj); |  | ||||||
|     } |  | ||||||
|     slotdefs_initialized = 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Update the slots after assignment to a class (type) attribute. */ | /* Update the slots after assignment to a class (type) attribute. */ | ||||||
| static int | static int | ||||||
| update_slot(PyTypeObject *type, PyObject *name) | update_slot(PyTypeObject *type, PyObject *name) | ||||||
|  | @ -8997,10 +8958,10 @@ update_slot(PyTypeObject *type, PyObject *name) | ||||||
|     assert(PyUnicode_CheckExact(name)); |     assert(PyUnicode_CheckExact(name)); | ||||||
|     assert(PyUnicode_CHECK_INTERNED(name)); |     assert(PyUnicode_CHECK_INTERNED(name)); | ||||||
| 
 | 
 | ||||||
|     assert(slotdefs_initialized); |  | ||||||
|     pp = ptrs; |     pp = ptrs; | ||||||
|     for (p = slotdefs; p->name; p++) { |     for (p = slotdefs; p->name; p++) { | ||||||
|         assert(PyUnicode_CheckExact(p->name_strobj)); |         assert(PyUnicode_CheckExact(p->name_strobj)); | ||||||
|  |         assert(PyUnicode_CHECK_INTERNED(p->name_strobj)); | ||||||
|         assert(PyUnicode_CheckExact(name)); |         assert(PyUnicode_CheckExact(name)); | ||||||
|         /* bpo-40521: Using interned strings. */ |         /* bpo-40521: Using interned strings. */ | ||||||
|         if (p->name_strobj == name) { |         if (p->name_strobj == name) { | ||||||
|  | @ -9028,7 +8989,6 @@ static void | ||||||
| fixup_slot_dispatchers(PyTypeObject *type) | fixup_slot_dispatchers(PyTypeObject *type) | ||||||
| { | { | ||||||
|     assert(!PyErr_Occurred()); |     assert(!PyErr_Occurred()); | ||||||
|     assert(slotdefs_initialized); |  | ||||||
|     for (slotdef *p = slotdefs; p->name; ) { |     for (slotdef *p = slotdefs; p->name; ) { | ||||||
|         p = update_one_slot(type, p); |         p = update_one_slot(type, p); | ||||||
|     } |     } | ||||||
|  | @ -9042,7 +9002,6 @@ update_all_slots(PyTypeObject* type) | ||||||
|     /* Clear the VALID_VERSION flag of 'type' and all its subclasses. */ |     /* Clear the VALID_VERSION flag of 'type' and all its subclasses. */ | ||||||
|     PyType_Modified(type); |     PyType_Modified(type); | ||||||
| 
 | 
 | ||||||
|     assert(slotdefs_initialized); |  | ||||||
|     for (p = slotdefs; p->name; p++) { |     for (p = slotdefs; p->name; p++) { | ||||||
|         /* update_slot returns int but can't actually fail */ |         /* update_slot returns int but can't actually fail */ | ||||||
|         update_slot(type, p->name_strobj); |         update_slot(type, p->name_strobj); | ||||||
|  | @ -9213,7 +9172,6 @@ add_operators(PyTypeObject *type) | ||||||
|     PyObject *descr; |     PyObject *descr; | ||||||
|     void **ptr; |     void **ptr; | ||||||
| 
 | 
 | ||||||
|     assert(slotdefs_initialized); |  | ||||||
|     for (p = slotdefs; p->name; p++) { |     for (p = slotdefs; p->name; p++) { | ||||||
|         if (p->wrapper == NULL) |         if (p->wrapper == NULL) | ||||||
|             continue; |             continue; | ||||||
|  |  | ||||||
|  | @ -695,11 +695,6 @@ pycore_init_types(PyInterpreterState *interp) | ||||||
| { | { | ||||||
|     PyStatus status; |     PyStatus status; | ||||||
| 
 | 
 | ||||||
|     status = _PyTypes_InitState(interp); |  | ||||||
|     if (_PyStatus_EXCEPTION(status)) { |  | ||||||
|         return status; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     status = _PyTypes_InitTypes(interp); |     status = _PyTypes_InitTypes(interp); | ||||||
|     if (_PyStatus_EXCEPTION(status)) { |     if (_PyStatus_EXCEPTION(status)) { | ||||||
|         return status; |         return status; | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
|     'DUNDER',  # Objects/typeobject.c |     'DUNDER',  # Objects/typeobject.c | ||||||
|     'RDUNDER',  # Objects/typeobject.c |     'RDUNDER',  # Objects/typeobject.c | ||||||
|     'SPECIAL',  # Objects/weakrefobject.c |     'SPECIAL',  # Objects/weakrefobject.c | ||||||
|  |     'NAME',  # Objects/typeobject.c | ||||||
| } | } | ||||||
| IDENTIFIERS = [ | IDENTIFIERS = [ | ||||||
|     # from ADD() Python/_warnings.c |     # from ADD() Python/_warnings.c | ||||||
|  | @ -42,11 +43,27 @@ | ||||||
|     # from SLOT* in Objects/typeobject.c |     # from SLOT* in Objects/typeobject.c | ||||||
|     '__abs__', |     '__abs__', | ||||||
|     '__add__', |     '__add__', | ||||||
|  |     '__aiter__', | ||||||
|     '__and__', |     '__and__', | ||||||
|     '__divmod__', |     '__anext__', | ||||||
|  |     '__await__', | ||||||
|  |     '__bool__', | ||||||
|  |     '__call__', | ||||||
|  |     '__contains__', | ||||||
|  |     '__del__', | ||||||
|  |     '__delattr__', | ||||||
|  |     '__delete__', | ||||||
|  |     '__delitem__', | ||||||
|  |     '__eq__', | ||||||
|     '__float__', |     '__float__', | ||||||
|     '__floordiv__', |     '__floordiv__', | ||||||
|  |     '__ge__', | ||||||
|  |     '__get__', | ||||||
|  |     '__getattr__', | ||||||
|  |     '__getattribute__', | ||||||
|     '__getitem__', |     '__getitem__', | ||||||
|  |     '__gt__', | ||||||
|  |     '__hash__', | ||||||
|     '__iadd__', |     '__iadd__', | ||||||
|     '__iand__', |     '__iand__', | ||||||
|     '__ifloordiv__', |     '__ifloordiv__', | ||||||
|  | @ -54,24 +71,34 @@ | ||||||
|     '__imatmul__', |     '__imatmul__', | ||||||
|     '__imod__', |     '__imod__', | ||||||
|     '__imul__', |     '__imul__', | ||||||
|  |     '__index__', | ||||||
|  |     '__init__', | ||||||
|     '__int__', |     '__int__', | ||||||
|     '__invert__', |     '__invert__', | ||||||
|     '__ior__', |     '__ior__', | ||||||
|  |     '__ipow__', | ||||||
|     '__irshift__', |     '__irshift__', | ||||||
|     '__isub__', |     '__isub__', | ||||||
|  |     '__iter__', | ||||||
|     '__itruediv__', |     '__itruediv__', | ||||||
|     '__ixor__', |     '__ixor__', | ||||||
|  |     '__le__', | ||||||
|  |     '__len__', | ||||||
|     '__lshift__', |     '__lshift__', | ||||||
|  |     '__lt__', | ||||||
|     '__matmul__', |     '__matmul__', | ||||||
|     '__mod__', |     '__mod__', | ||||||
|     '__mul__', |     '__mul__', | ||||||
|  |     '__ne__', | ||||||
|     '__neg__', |     '__neg__', | ||||||
|  |     '__new__', | ||||||
|  |     '__next__', | ||||||
|     '__or__', |     '__or__', | ||||||
|     '__pos__', |     '__pos__', | ||||||
|     '__pow__', |     '__pow__', | ||||||
|     '__radd__', |     '__radd__', | ||||||
|     '__rand__', |     '__rand__', | ||||||
|     '__rdivmod__', |     '__repr__', | ||||||
|     '__rfloordiv__', |     '__rfloordiv__', | ||||||
|     '__rlshift__', |     '__rlshift__', | ||||||
|     '__rmatmul__', |     '__rmatmul__', | ||||||
|  | @ -84,10 +111,15 @@ | ||||||
|     '__rsub__', |     '__rsub__', | ||||||
|     '__rtruediv__', |     '__rtruediv__', | ||||||
|     '__rxor__', |     '__rxor__', | ||||||
|  |     '__set__', | ||||||
|  |     '__setattr__', | ||||||
|  |     '__setitem__', | ||||||
|     '__str__', |     '__str__', | ||||||
|     '__sub__', |     '__sub__', | ||||||
|     '__truediv__', |     '__truediv__', | ||||||
|     '__xor__', |     '__xor__', | ||||||
|  |     '__divmod__', | ||||||
|  |     '__rdivmod__', | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Kumar Aditya
						Kumar Aditya