diff --git a/Include/internal/pycore_abstract.h b/Include/internal/pycore_abstract.h index 67c6fa7c0c4ed5..81d1079c312820 100644 --- a/Include/internal/pycore_abstract.h +++ b/Include/internal/pycore_abstract.h @@ -12,8 +12,7 @@ extern "C" { static inline int _PyIndex_Check(PyObject *obj) { - PyNumberMethods *tp_as_number = Py_TYPE(obj)->tp_as_number; - return (tp_as_number != NULL && tp_as_number->nb_index != NULL); + return (Py_TYPE(obj)->tp_as_number->nb_index != NULL); } // Exported for external JIT support diff --git a/Include/internal/pycore_slots_generated.h b/Include/internal/pycore_slots_generated.h index 73a77070038cef..5d10e98918834b 100644 --- a/Include/internal/pycore_slots_generated.h +++ b/Include/internal/pycore_slots_generated.h @@ -153,130 +153,88 @@ _PySlot_type_getslot(PyTypeObject *tp, uint16_t slot_id) { switch (slot_id) { case Py_mp_subscript: - if (!(tp->tp_as_mapping)) return NULL; return (void*)tp->tp_as_mapping->mp_subscript; case Py_nb_absolute: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_absolute; case Py_nb_add: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_add; case Py_nb_and: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_and; case Py_nb_bool: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_bool; case Py_nb_divmod: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_divmod; case Py_nb_float: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_float; case Py_nb_floor_divide: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_floor_divide; case Py_nb_index: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_index; case Py_nb_inplace_add: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_inplace_add; case Py_nb_inplace_and: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_inplace_and; case Py_nb_inplace_floor_divide: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_inplace_floor_divide; case Py_nb_inplace_lshift: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_inplace_lshift; case Py_nb_inplace_multiply: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_inplace_multiply; case Py_nb_inplace_or: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_inplace_or; case Py_nb_inplace_power: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_inplace_power; case Py_nb_inplace_remainder: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_inplace_remainder; case Py_nb_inplace_rshift: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_inplace_rshift; case Py_nb_inplace_subtract: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_inplace_subtract; case Py_nb_inplace_true_divide: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_inplace_true_divide; case Py_nb_inplace_xor: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_inplace_xor; case Py_nb_int: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_int; case Py_nb_invert: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_invert; case Py_nb_lshift: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_lshift; case Py_nb_multiply: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_multiply; case Py_nb_negative: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_negative; case Py_nb_or: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_or; case Py_nb_positive: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_positive; case Py_nb_power: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_power; case Py_nb_remainder: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_remainder; case Py_nb_rshift: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_rshift; case Py_nb_subtract: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_subtract; case Py_nb_true_divide: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_true_divide; case Py_nb_xor: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_xor; case Py_sq_ass_item: - if (!(tp->tp_as_sequence)) return NULL; return (void*)tp->tp_as_sequence->sq_ass_item; case Py_sq_concat: - if (!(tp->tp_as_sequence)) return NULL; return (void*)tp->tp_as_sequence->sq_concat; case Py_sq_contains: - if (!(tp->tp_as_sequence)) return NULL; return (void*)tp->tp_as_sequence->sq_contains; case Py_sq_inplace_concat: - if (!(tp->tp_as_sequence)) return NULL; return (void*)tp->tp_as_sequence->sq_inplace_concat; case Py_sq_inplace_repeat: - if (!(tp->tp_as_sequence)) return NULL; return (void*)tp->tp_as_sequence->sq_inplace_repeat; case Py_sq_item: - if (!(tp->tp_as_sequence)) return NULL; return (void*)tp->tp_as_sequence->sq_item; case Py_sq_length: - if (!(tp->tp_as_sequence)) return NULL; return (void*)tp->tp_as_sequence->sq_length; case Py_sq_repeat: - if (!(tp->tp_as_sequence)) return NULL; return (void*)tp->tp_as_sequence->sq_repeat; case Py_tp_alloc: return (void*)tp->tp_alloc; @@ -335,24 +293,18 @@ _PySlot_type_getslot(PyTypeObject *tp, uint16_t slot_id) case Py_tp_free: return (void*)tp->tp_free; case Py_nb_matrix_multiply: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_matrix_multiply; case Py_nb_inplace_matrix_multiply: - if (!(tp->tp_as_number)) return NULL; return (void*)tp->tp_as_number->nb_inplace_matrix_multiply; case Py_am_await: - if (!(tp->tp_as_async)) return NULL; return (void*)tp->tp_as_async->am_await; case Py_am_aiter: - if (!(tp->tp_as_async)) return NULL; return (void*)tp->tp_as_async->am_aiter; case Py_am_anext: - if (!(tp->tp_as_async)) return NULL; return (void*)tp->tp_as_async->am_anext; case Py_tp_finalize: return (void*)tp->tp_finalize; case Py_am_send: - if (!(tp->tp_as_async)) return NULL; return (void*)tp->tp_as_async->am_send; case Py_tp_vectorcall: return (void*)tp->tp_vectorcall; @@ -360,16 +312,12 @@ _PySlot_type_getslot(PyTypeObject *tp, uint16_t slot_id) if (!(tp->tp_flags & Py_TPFLAGS_HEAPTYPE)) return NULL; return (void*)((PyHeapTypeObject*)tp)->ht_token; case Py_bf_getbuffer: - if (!(tp->tp_as_buffer)) return NULL; return (void*)tp->tp_as_buffer->bf_getbuffer; case Py_bf_releasebuffer: - if (!(tp->tp_as_buffer)) return NULL; return (void*)tp->tp_as_buffer->bf_releasebuffer; case Py_mp_ass_subscript: - if (!(tp->tp_as_mapping)) return NULL; return (void*)tp->tp_as_mapping->mp_ass_subscript; case Py_mp_length: - if (!(tp->tp_as_mapping)) return NULL; return (void*)tp->tp_as_mapping->mp_length; } _PySlot_err_bad_slot("PyType_GetSlot", slot_id); diff --git a/Modules/_bisectmodule.c b/Modules/_bisectmodule.c index a953f8bfa11aea..1cf11ea55c2109 100644 --- a/Modules/_bisectmodule.c +++ b/Modules/_bisectmodule.c @@ -35,11 +35,11 @@ get_sq_item(PyObject *s) // The parts of PySequence_GetItem that we only need to do once PyTypeObject *tp = Py_TYPE(s); PySequenceMethods *m = tp->tp_as_sequence; - if (m && m->sq_item) { + if (m->sq_item) { return m->sq_item; } const char *msg; - if (tp->tp_as_mapping && tp->tp_as_mapping->mp_subscript) { + if (tp->tp_as_mapping->mp_subscript) { msg = "%.200s is not a sequence"; } else { diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index 7a75e80298fcd8..e407069f6048fd 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -661,11 +661,6 @@ { nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!Py_TYPE(o)->tp_as_mapping) { - UPDATE_MISS_STATS(BINARY_OP); - assert(_PyOpcode_Deopt[opcode] == (BINARY_OP)); - JUMP_TO_PREDICTED(BINARY_OP); - } if (Py_TYPE(o)->tp_as_mapping->mp_subscript != _PyDict_Subscript) { UPDATE_MISS_STATS(BINARY_OP); assert(_PyOpcode_Deopt[opcode] == (BINARY_OP)); @@ -6708,13 +6703,10 @@ _PyStackRef obj; _PyStackRef iter; obj = stack_pointer[-1]; - unaryfunc getter = NULL; PyObject *obj_o = PyStackRef_AsPyObjectBorrow(obj); PyObject *iter_o; PyTypeObject *type = Py_TYPE(obj_o); - if (type->tp_as_async != NULL) { - getter = type->tp_as_async->am_aiter; - } + unaryfunc getter = type->tp_as_async->am_aiter; if (getter == NULL) { _PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_StackPointerValidate(frame); @@ -6744,8 +6736,7 @@ if (iter_o == NULL) { JUMP_TO_LABEL(error); } - if (Py_TYPE(iter_o)->tp_as_async == NULL || - Py_TYPE(iter_o)->tp_as_async->am_anext == NULL) { + if (Py_TYPE(iter_o)->tp_as_async->am_anext == NULL) { assert(stack_pointer == _PyFrame_GetStackPointer(frame)); _PyFrame_StackPointerValidate(frame); _PyErr_Format(tstate, PyExc_TypeError, @@ -12686,11 +12677,6 @@ { nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!Py_TYPE(o)->tp_as_mapping) { - UPDATE_MISS_STATS(STORE_SUBSCR); - assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR)); - JUMP_TO_PREDICTED(STORE_SUBSCR); - } if (Py_TYPE(o)->tp_as_mapping->mp_ass_subscript != _PyDict_StoreSubscript) { UPDATE_MISS_STATS(STORE_SUBSCR); assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR)); diff --git a/Objects/abstract.c b/Objects/abstract.c index 28f751965f36b9..1f4bdd1348dc03 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -62,7 +62,7 @@ PyObject_Size(PyObject *o) } PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (m && m->sq_length) { + if (m->sq_length) { Py_ssize_t len = m->sq_length(o); assert(_Py_CheckSlotResult(o, "__len__", len >= 0)); return len; @@ -81,8 +81,8 @@ PyObject_Length(PyObject *o) int _PyObject_HasLen(PyObject *o) { - return (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_length) || - (Py_TYPE(o)->tp_as_mapping && Py_TYPE(o)->tp_as_mapping->mp_length); + PyTypeObject *type = Py_TYPE(o); + return (type->tp_as_sequence->sq_length || type->tp_as_mapping->mp_length); } /* The length hint function returns a non-negative value from o.__len__() @@ -159,14 +159,14 @@ PyObject_GetItem(PyObject *o, PyObject *key) } PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping; - if (m && m->mp_subscript) { + if (m->mp_subscript) { PyObject *item = m->mp_subscript(o, key); assert(_Py_CheckSlotResult(o, "__getitem__", item != NULL)); return item; } PySequenceMethods *ms = Py_TYPE(o)->tp_as_sequence; - if (ms && ms->sq_item) { + if (ms->sq_item) { if (_PyIndex_Check(key)) { Py_ssize_t key_value; key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); @@ -241,25 +241,23 @@ PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value) } PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping; - if (m && m->mp_ass_subscript) { + if (m->mp_ass_subscript) { int res = m->mp_ass_subscript(o, key, value); assert(_Py_CheckSlotResult(o, "__setitem__", res >= 0)); return res; } - if (Py_TYPE(o)->tp_as_sequence) { - if (_PyIndex_Check(key)) { - Py_ssize_t key_value; - key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); - if (key_value == -1 && PyErr_Occurred()) - return -1; - return PySequence_SetItem(o, key_value, value); - } - else if (Py_TYPE(o)->tp_as_sequence->sq_ass_item) { - type_error("sequence index must be " - "integer, not '%.200s'", key); + if (_PyIndex_Check(key)) { + Py_ssize_t key_value; + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); + if (key_value == -1 && PyErr_Occurred()) return -1; - } + return PySequence_SetItem(o, key_value, value); + } + else if (Py_TYPE(o)->tp_as_sequence->sq_ass_item) { + type_error("sequence index must be " + "integer, not '%.200s'", key); + return -1; } type_error("'%.200s' object does not support item assignment", o); @@ -275,25 +273,23 @@ PyObject_DelItem(PyObject *o, PyObject *key) } PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping; - if (m && m->mp_ass_subscript) { + if (m->mp_ass_subscript) { int res = m->mp_ass_subscript(o, key, (PyObject*)NULL); assert(_Py_CheckSlotResult(o, "__delitem__", res >= 0)); return res; } - if (Py_TYPE(o)->tp_as_sequence) { - if (_PyIndex_Check(key)) { - Py_ssize_t key_value; - key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); - if (key_value == -1 && PyErr_Occurred()) - return -1; - return PySequence_DelItem(o, key_value); - } - else if (Py_TYPE(o)->tp_as_sequence->sq_ass_item) { - type_error("sequence index must be " - "integer, not '%.200s'", key); + if (_PyIndex_Check(key)) { + Py_ssize_t key_value; + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); + if (key_value == -1 && PyErr_Occurred()) return -1; - } + return PySequence_DelItem(o, key_value); + } + else if (Py_TYPE(o)->tp_as_sequence->sq_ass_item) { + type_error("sequence index must be " + "integer, not '%.200s'", key); + return -1; } type_error("'%.200s' object does not support item deletion", o); @@ -324,7 +320,7 @@ int PyObject_CheckBuffer(PyObject *obj) { PyBufferProcs *tp_as_buffer = Py_TYPE(obj)->tp_as_buffer; - return (tp_as_buffer != NULL && tp_as_buffer->bf_getbuffer != NULL); + return (tp_as_buffer->bf_getbuffer != NULL); } // Old buffer protocols (deprecated, abi only) @@ -343,8 +339,7 @@ PyObject_CheckReadBuffer(PyObject *obj) PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer; Py_buffer view; - if (pb == NULL || - pb->bf_getbuffer == NULL) + if (pb->bf_getbuffer == NULL) return 0; if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE) == -1) { PyErr_Clear(); @@ -419,8 +414,7 @@ PyObject_AsWriteBuffer(PyObject *obj, return -1; } pb = Py_TYPE(obj)->tp_as_buffer; - if (pb == NULL || - pb->bf_getbuffer == NULL || + if (pb->bf_getbuffer == NULL || ((*pb->bf_getbuffer)(obj, &view, PyBUF_WRITABLE) != 0)) { PyErr_SetString(PyExc_TypeError, "expected a writable bytes-like object"); @@ -446,7 +440,7 @@ PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) } PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer; - if (pb == NULL || pb->bf_getbuffer == NULL) { + if (pb->bf_getbuffer == NULL) { PyErr_Format(PyExc_TypeError, "a bytes-like object is required, not '%.100s'", Py_TYPE(obj)->tp_name); @@ -821,7 +815,7 @@ PyBuffer_Release(Py_buffer *view) if (obj == NULL) return; pb = Py_TYPE(obj)->tp_as_buffer; - if (pb && pb->bf_releasebuffer) { + if (pb->bf_releasebuffer) { pb->bf_releasebuffer(obj, view); } view->obj = NULL; @@ -915,7 +909,7 @@ PyNumber_Check(PyObject *o) if (o == NULL) return 0; PyNumberMethods *nb = Py_TYPE(o)->tp_as_number; - return nb && (nb->nb_index || nb->nb_int || nb->nb_float || PyComplex_Check(o)); + return (nb->nb_index || nb->nb_int || nb->nb_float || PyComplex_Check(o)); } /* Binary operators */ @@ -944,15 +938,10 @@ binary_op1(PyObject *v, PyObject *w, const int op_slot ) { binaryfunc slotv; - if (Py_TYPE(v)->tp_as_number != NULL) { - slotv = NB_BINOP(Py_TYPE(v)->tp_as_number, op_slot); - } - else { - slotv = NULL; - } + slotv = NB_BINOP(Py_TYPE(v)->tp_as_number, op_slot); binaryfunc slotw; - if (!Py_IS_TYPE(w, Py_TYPE(v)) && Py_TYPE(w)->tp_as_number != NULL) { + if (!Py_IS_TYPE(w, Py_TYPE(v))) { slotw = NB_BINOP(Py_TYPE(w)->tp_as_number, op_slot); if (slotw == slotv) { slotw = NULL; @@ -1037,16 +1026,10 @@ ternary_op(PyObject *v, PyNumberMethods *mv = Py_TYPE(v)->tp_as_number; PyNumberMethods *mw = Py_TYPE(w)->tp_as_number; - ternaryfunc slotv; - if (mv != NULL) { - slotv = NB_TERNOP(mv, op_slot); - } - else { - slotv = NULL; - } + ternaryfunc slotv = NB_TERNOP(mv, op_slot); ternaryfunc slotw; - if (!Py_IS_TYPE(w, Py_TYPE(v)) && mw != NULL) { + if (!Py_IS_TYPE(w, Py_TYPE(v))) { slotw = NB_TERNOP(mw, op_slot); if (slotw == slotv) { slotw = NULL; @@ -1083,19 +1066,17 @@ ternary_op(PyObject *v, } PyNumberMethods *mz = Py_TYPE(z)->tp_as_number; - if (mz != NULL) { - ternaryfunc slotz = NB_TERNOP(mz, op_slot); - if (slotz == slotv || slotz == slotw) { - slotz = NULL; - } - if (slotz) { - PyObject *x = slotz(v, w, z); - assert(_Py_CheckSlotResult(z, op_name, x != NULL)); - if (x != Py_NotImplemented) { - return x; - } - Py_DECREF(x); /* can't do it */ + ternaryfunc slotz = NB_TERNOP(mz, op_slot); + if (slotz == slotv || slotz == slotw) { + slotz = NULL; + } + if (slotz) { + PyObject *x = slotz(v, w, z); + assert(_Py_CheckSlotResult(z, op_name, x != NULL)); + if (x != Py_NotImplemented) { + return x; } + Py_DECREF(x); /* can't do it */ } if (z == Py_None) { @@ -1144,7 +1125,7 @@ PyNumber_Add(PyObject *v, PyObject *w) Py_DECREF(result); PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence; - if (m && m->sq_concat) { + if (m->sq_concat) { result = (*m->sq_concat)(v, w); assert(_Py_CheckSlotResult(v, "+", result != NULL)); return result; @@ -1180,10 +1161,10 @@ PyNumber_Multiply(PyObject *v, PyObject *w) PySequenceMethods *mv = Py_TYPE(v)->tp_as_sequence; PySequenceMethods *mw = Py_TYPE(w)->tp_as_sequence; Py_DECREF(result); - if (mv && mv->sq_repeat) { + if (mv->sq_repeat) { return sequence_repeat(mv->sq_repeat, v, w); } - else if (mw && mw->sq_repeat) { + else if (mw->sq_repeat) { return sequence_repeat(mw->sq_repeat, w, v); } result = binop_type_error(v, w, "*"); @@ -1232,17 +1213,16 @@ binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot ) { PyNumberMethods *mv = Py_TYPE(v)->tp_as_number; - if (mv != NULL) { - binaryfunc slot = NB_BINOP(mv, iop_slot); - if (slot) { - PyObject *x = (slot)(v, w); - assert(_Py_CheckSlotResult(v, op_name, x != NULL)); - if (x != Py_NotImplemented) { - return x; - } - Py_DECREF(x); + binaryfunc slot = NB_BINOP(mv, iop_slot); + if (slot) { + PyObject *x = (slot)(v, w); + assert(_Py_CheckSlotResult(v, op_name, x != NULL)); + if (x != Py_NotImplemented) { + return x; } + Py_DECREF(x); } + #ifdef NDEBUG return binary_op1(v, w, op_slot); #else @@ -1273,16 +1253,15 @@ ternary_iop(PyObject *v, PyObject *w, PyObject *z, const int iop_slot, const int const char *op_name) { PyNumberMethods *mv = Py_TYPE(v)->tp_as_number; - if (mv != NULL) { - ternaryfunc slot = NB_TERNOP(mv, iop_slot); - if (slot) { - PyObject *x = (slot)(v, w, z); - if (x != Py_NotImplemented) { - return x; - } - Py_DECREF(x); + ternaryfunc slot = NB_TERNOP(mv, iop_slot); + if (slot) { + PyObject *x = (slot)(v, w, z); + if (x != Py_NotImplemented) { + return x; } + Py_DECREF(x); } + return ternary_op(v, w, z, op_slot, op_name); } @@ -1311,15 +1290,13 @@ PyNumber_InPlaceAdd(PyObject *v, PyObject *w) if (result == Py_NotImplemented) { PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence; Py_DECREF(result); - if (m != NULL) { - binaryfunc func = m->sq_inplace_concat; - if (func == NULL) - func = m->sq_concat; - if (func != NULL) { - result = func(v, w); - assert(_Py_CheckSlotResult(v, "+=", result != NULL)); - return result; - } + binaryfunc func = m->sq_inplace_concat; + if (func == NULL) + func = m->sq_concat; + if (func != NULL) { + result = func(v, w); + assert(_Py_CheckSlotResult(v, "+=", result != NULL)); + return result; } result = binop_type_error(v, w, "+="); } @@ -1336,20 +1313,20 @@ PyNumber_InPlaceMultiply(PyObject *v, PyObject *w) PySequenceMethods *mv = Py_TYPE(v)->tp_as_sequence; PySequenceMethods *mw = Py_TYPE(w)->tp_as_sequence; Py_DECREF(result); - if (mv != NULL) { - f = mv->sq_inplace_repeat; - if (f == NULL) - f = mv->sq_repeat; - if (f != NULL) - return sequence_repeat(f, v, w); - } - else if (mw != NULL) { - /* Note that the right hand operand should not be - * mutated in this case so sq_inplace_repeat is not - * used. */ - if (mw->sq_repeat) - return sequence_repeat(mw->sq_repeat, w, v); - } + + f = mv->sq_inplace_repeat; + if (f == NULL) + f = mv->sq_repeat; + if (f != NULL) + return sequence_repeat(f, v, w); + + /* Note that the right hand operand should not be + * mutated in this case so sq_inplace_repeat is not + * used. */ + f = mw->sq_repeat; + if (f) + return sequence_repeat(f, w, v); + result = binop_type_error(v, w, "*="); } return result; @@ -1379,7 +1356,7 @@ _PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs) } \ \ PyNumberMethods *m = Py_TYPE(o)->tp_as_number; \ - if (m && m->op) { \ + if (m->op) { \ PyObject *res = (*m->op)(o); \ assert(_Py_CheckSlotResult(o, #meth_name, res != NULL)); \ return res; \ @@ -1530,7 +1507,7 @@ PyNumber_Long(PyObject *o) return Py_NewRef(o); } m = Py_TYPE(o)->tp_as_number; - if (m && m->nb_int) { /* This should include subclasses of int */ + if (m->nb_int) { /* This should include subclasses of int */ /* Convert using the nb_int slot, which should return something of exact type int. */ result = m->nb_int(o); @@ -1558,7 +1535,7 @@ PyNumber_Long(PyObject *o) Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); return result; } - if (m && m->nb_index) { + if (m->nb_index) { return PyNumber_Index(o); } @@ -1610,7 +1587,7 @@ PyNumber_Float(PyObject *o) } PyNumberMethods *m = Py_TYPE(o)->tp_as_number; - if (m && m->nb_float) { /* This should include subclasses of float */ + if (m->nb_float) { /* This should include subclasses of float */ PyObject *res = m->nb_float(o); assert(_Py_CheckSlotResult(o, "__float__", res != NULL)); if (!res || PyFloat_CheckExact(res)) { @@ -1637,7 +1614,7 @@ PyNumber_Float(PyObject *o) return PyFloat_FromDouble(val); } - if (m && m->nb_index) { + if (m->nb_index) { PyObject *res = _PyNumber_Index(o); if (!res) { return NULL; @@ -1682,8 +1659,7 @@ PySequence_Check(PyObject *s) { if (PyDict_Check(s)) return 0; - return Py_TYPE(s)->tp_as_sequence && - Py_TYPE(s)->tp_as_sequence->sq_item != NULL; + return (Py_TYPE(s)->tp_as_sequence->sq_item != NULL); } Py_ssize_t @@ -1695,13 +1671,13 @@ PySequence_Size(PyObject *s) } PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; - if (m && m->sq_length) { + if (m->sq_length) { Py_ssize_t len = m->sq_length(s); assert(_Py_CheckSlotResult(s, "__len__", len >= 0)); return len; } - if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_length) { + if (Py_TYPE(s)->tp_as_mapping->mp_length) { type_error("%.200s is not a sequence", s); return -1; } @@ -1725,7 +1701,7 @@ PySequence_Concat(PyObject *s, PyObject *o) } PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; - if (m && m->sq_concat) { + if (m->sq_concat) { PyObject *res = m->sq_concat(s, o); assert(_Py_CheckSlotResult(s, "+", res != NULL)); return res; @@ -1751,7 +1727,7 @@ PySequence_Repeat(PyObject *o, Py_ssize_t count) } PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (m && m->sq_repeat) { + if (m->sq_repeat) { PyObject *res = m->sq_repeat(o, count); assert(_Py_CheckSlotResult(o, "*", res != NULL)); return res; @@ -1782,12 +1758,12 @@ PySequence_InPlaceConcat(PyObject *s, PyObject *o) } PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; - if (m && m->sq_inplace_concat) { + if (m->sq_inplace_concat) { PyObject *res = m->sq_inplace_concat(s, o); assert(_Py_CheckSlotResult(s, "+=", res != NULL)); return res; } - if (m && m->sq_concat) { + if (m->sq_concat) { PyObject *res = m->sq_concat(s, o); assert(_Py_CheckSlotResult(s, "+", res != NULL)); return res; @@ -1811,12 +1787,12 @@ PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count) } PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (m && m->sq_inplace_repeat) { + if (m->sq_inplace_repeat) { PyObject *res = m->sq_inplace_repeat(o, count); assert(_Py_CheckSlotResult(o, "*=", res != NULL)); return res; } - if (m && m->sq_repeat) { + if (m->sq_repeat) { PyObject *res = m->sq_repeat(o, count); assert(_Py_CheckSlotResult(o, "*", res != NULL)); return res; @@ -1845,7 +1821,7 @@ PySequence_GetItem(PyObject *s, Py_ssize_t i) } PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; - if (m && m->sq_item) { + if (m->sq_item) { if (i < 0) { if (m->sq_length) { Py_ssize_t l = (*m->sq_length)(s); @@ -1861,7 +1837,7 @@ PySequence_GetItem(PyObject *s, Py_ssize_t i) return res; } - if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_subscript) { + if (Py_TYPE(s)->tp_as_mapping->mp_subscript) { return type_error("%.200s is not a sequence", s); } return type_error("'%.200s' object does not support indexing", s); @@ -1875,7 +1851,7 @@ PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) } PyMappingMethods *mp = Py_TYPE(s)->tp_as_mapping; - if (mp && mp->mp_subscript) { + if (mp->mp_subscript) { PyObject *slice = _PySlice_FromIndices(i1, i2); if (!slice) { return NULL; @@ -1898,7 +1874,7 @@ PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o) } PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; - if (m && m->sq_ass_item) { + if (m->sq_ass_item) { if (i < 0) { if (m->sq_length) { Py_ssize_t l = (*m->sq_length)(s); @@ -1914,7 +1890,7 @@ PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o) return res; } - if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_ass_subscript) { + if (Py_TYPE(s)->tp_as_mapping->mp_ass_subscript) { type_error("%.200s is not a sequence", s); return -1; } @@ -1931,7 +1907,7 @@ PySequence_DelItem(PyObject *s, Py_ssize_t i) } PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; - if (m && m->sq_ass_item) { + if (m->sq_ass_item) { if (i < 0) { if (m->sq_length) { Py_ssize_t l = (*m->sq_length)(s); @@ -1947,7 +1923,7 @@ PySequence_DelItem(PyObject *s, Py_ssize_t i) return res; } - if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_ass_subscript) { + if (Py_TYPE(s)->tp_as_mapping->mp_ass_subscript) { type_error("%.200s is not a sequence", s); return -1; } @@ -1964,7 +1940,7 @@ PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o) } PyMappingMethods *mp = Py_TYPE(s)->tp_as_mapping; - if (mp && mp->mp_ass_subscript) { + if (mp->mp_ass_subscript) { PyObject *slice = _PySlice_FromIndices(i1, i2); if (!slice) return -1; @@ -1987,7 +1963,7 @@ PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) } PyMappingMethods *mp = Py_TYPE(s)->tp_as_mapping; - if (mp && mp->mp_ass_subscript) { + if (mp->mp_ass_subscript) { PyObject *slice = _PySlice_FromIndices(i1, i2); if (!slice) { return -1; @@ -2240,7 +2216,7 @@ int PySequence_Contains(PyObject *seq, PyObject *ob) { PySequenceMethods *sqm = Py_TYPE(seq)->tp_as_sequence; - if (sqm != NULL && sqm->sq_contains != NULL) { + if (sqm->sq_contains != NULL) { int res = (*sqm->sq_contains)(seq, ob); assert(_Py_CheckSlotResult(seq, "__contains__", res >= 0)); return res; @@ -2268,8 +2244,7 @@ PySequence_Index(PyObject *s, PyObject *o) int PyMapping_Check(PyObject *o) { - return o && Py_TYPE(o)->tp_as_mapping && - Py_TYPE(o)->tp_as_mapping->mp_subscript; + return o && Py_TYPE(o)->tp_as_mapping->mp_subscript; } Py_ssize_t @@ -2281,13 +2256,13 @@ PyMapping_Size(PyObject *o) } PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping; - if (m && m->mp_length) { + if (m->mp_length) { Py_ssize_t len = m->mp_length(o); assert(_Py_CheckSlotResult(o, "__len__", len >= 0)); return len; } - if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_length) { + if (Py_TYPE(o)->tp_as_sequence->sq_length) { type_error("%.200s is not a mapping", o); return -1; } @@ -2838,7 +2813,7 @@ PyObject_GetAIter(PyObject *o) { PyTypeObject *t = Py_TYPE(o); unaryfunc f; - if (t->tp_as_async == NULL || t->tp_as_async->am_aiter == NULL) { + if (t->tp_as_async->am_aiter == NULL) { return type_error("'%.200s' object is not an async iterable", o); } f = t->tp_as_async->am_aiter; @@ -2864,8 +2839,7 @@ int PyAIter_Check(PyObject *obj) { PyTypeObject *tp = Py_TYPE(obj); - return (tp->tp_as_async != NULL && - tp->tp_as_async->am_anext != NULL && + return (tp->tp_as_async->am_anext != NULL && tp->tp_as_async->am_anext != &_PyObject_NextNotImplemented); } @@ -2932,7 +2906,7 @@ PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result) { assert(arg != NULL); assert(result != NULL); - if (Py_TYPE(iter)->tp_as_async && Py_TYPE(iter)->tp_as_async->am_send) { + if (Py_TYPE(iter)->tp_as_async->am_send) { PySendResult res = Py_TYPE(iter)->tp_as_async->am_send(iter, arg, result); assert(_Py_CheckSlotResult(iter, "am_send", res != PYGEN_ERROR)); return res; diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 117d8b56017b64..a916f3ba5a70d3 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -663,7 +663,7 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, arglen = -1; argidx = -2; } - if (Py_TYPE(args)->tp_as_mapping && Py_TYPE(args)->tp_as_mapping->mp_subscript && + if (Py_TYPE(args)->tp_as_mapping->mp_subscript && !PyTuple_Check(args) && !PyBytes_Check(args) && !PyUnicode_Check(args) && !PyByteArray_Check(args)) { dict = args; diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 4d2b5dc8e4613f..1c38ce97e6585b 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -1132,7 +1132,6 @@ static PyObject * actual_complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *res = NULL; - PyNumberMethods *nbr; if (PyTuple_GET_SIZE(args) > 1 || (kwargs != NULL && PyDict_GET_SIZE(kwargs))) { return complex_new(type, args, kwargs); @@ -1170,8 +1169,8 @@ actual_complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) Py_complex c = ((PyComplexObject*)arg)->cval; res = complex_subtype_from_doubles(type, c.real, c.imag); } - else if ((nbr = Py_TYPE(arg)->tp_as_number) != NULL && - (nbr->nb_float != NULL || nbr->nb_index != NULL)) + else if ((Py_TYPE(arg)->tp_as_number->nb_float != NULL + || Py_TYPE(arg)->tp_as_number->nb_index != NULL)) { /* The argument really is entirely real, and contributes nothing in the imaginary direction. @@ -1231,8 +1230,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) } nbr = Py_TYPE(r)->tp_as_number; - if (nbr == NULL || - (nbr->nb_float == NULL && nbr->nb_index == NULL && !PyComplex_Check(r))) + if (nbr->nb_float == NULL && nbr->nb_index == NULL && !PyComplex_Check(r)) { PyErr_Format(PyExc_TypeError, "complex() argument 'real' must be a real number, not %T", @@ -1244,8 +1242,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) } if (i != NULL) { nbi = Py_TYPE(i)->tp_as_number; - if (nbi == NULL || - (nbi->nb_float == NULL && nbi->nb_index == NULL && !PyComplex_Check(i))) + if (nbi->nb_float == NULL && nbi->nb_index == NULL && !PyComplex_Check(i)) { PyErr_Format(PyExc_TypeError, "complex() argument 'imag' must be a real number, not %T", @@ -1277,8 +1274,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) Py_DECREF(r); } nbr = Py_TYPE(orig_r)->tp_as_number; - if (nbr == NULL || - (nbr->nb_float == NULL && nbr->nb_index == NULL)) + if (nbr->nb_float == NULL && nbr->nb_index == NULL) { if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, "complex() argument 'real' must be a real number, not %T", diff --git a/Objects/floatobject.c b/Objects/floatobject.c index e379770e10031d..cf4a26b54361ea 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -260,8 +260,8 @@ PyFloat_AsDouble(PyObject *op) } nb = Py_TYPE(op)->tp_as_number; - if (nb == NULL || nb->nb_float == NULL) { - if (nb && nb->nb_index) { + if (nb->nb_float == NULL) { + if (nb->nb_index) { PyObject *res = _PyNumber_Index(op); if (!res) { return -1; diff --git a/Objects/genobject.c b/Objects/genobject.c index c313002c723e31..36ef3821cc1616 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1256,7 +1256,6 @@ gen_is_coroutine(PyObject *o) PyObject * _PyCoro_GetAwaitableIter(PyObject *o) { - unaryfunc getter = NULL; PyTypeObject *ot; if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) { @@ -1265,9 +1264,7 @@ _PyCoro_GetAwaitableIter(PyObject *o) } ot = Py_TYPE(o); - if (ot->tp_as_async != NULL) { - getter = ot->tp_as_async->am_await; - } + unaryfunc getter = ot->tp_as_async->am_await; if (getter != NULL) { PyObject *res = (*getter)(o); if (res != NULL) { diff --git a/Objects/object.c b/Objects/object.c index a83f8d4c04ca07..9ea0977442c09a 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2145,14 +2145,11 @@ PyObject_IsTrue(PyObject *v) return 0; if (v == Py_None) return 0; - else if (Py_TYPE(v)->tp_as_number != NULL && - Py_TYPE(v)->tp_as_number->nb_bool != NULL) + else if (Py_TYPE(v)->tp_as_number->nb_bool != NULL) res = (*Py_TYPE(v)->tp_as_number->nb_bool)(v); - else if (Py_TYPE(v)->tp_as_mapping != NULL && - Py_TYPE(v)->tp_as_mapping->mp_length != NULL) + else if (Py_TYPE(v)->tp_as_mapping->mp_length != NULL) res = (*Py_TYPE(v)->tp_as_mapping->mp_length)(v); - else if (Py_TYPE(v)->tp_as_sequence != NULL && - Py_TYPE(v)->tp_as_sequence->sq_length != NULL) + else if (Py_TYPE(v)->tp_as_sequence->sq_length != NULL) res = (*Py_TYPE(v)->tp_as_sequence->sq_length)(v); else return 1; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 30958310227af0..51810b7167908d 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -8735,7 +8735,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) if (type->tp_as_number != NULL && base->tp_as_number != NULL) { basebase = base->tp_base; - if (basebase->tp_as_number == NULL) + if (basebase != NULL && basebase->tp_as_number == NULL) basebase = NULL; COPYNUM(nb_add); COPYNUM(nb_subtract); @@ -8776,7 +8776,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) if (type->tp_as_async != NULL && base->tp_as_async != NULL) { basebase = base->tp_base; - if (basebase->tp_as_async == NULL) + if (basebase != NULL && basebase->tp_as_async == NULL) basebase = NULL; COPYASYNC(am_await); COPYASYNC(am_aiter); @@ -8785,7 +8785,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) if (type->tp_as_sequence != NULL && base->tp_as_sequence != NULL) { basebase = base->tp_base; - if (basebase->tp_as_sequence == NULL) + if (basebase != NULL && basebase->tp_as_sequence == NULL) basebase = NULL; COPYSEQ(sq_length); COPYSEQ(sq_concat); @@ -8799,7 +8799,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) if (type->tp_as_mapping != NULL && base->tp_as_mapping != NULL) { basebase = base->tp_base; - if (basebase->tp_as_mapping == NULL) + if (basebase != NULL && basebase->tp_as_mapping == NULL) basebase = NULL; COPYMAP(mp_length); COPYMAP(mp_subscript); @@ -8808,7 +8808,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) if (type->tp_as_buffer != NULL && base->tp_as_buffer != NULL) { basebase = base->tp_base; - if (basebase->tp_as_buffer == NULL) + if (basebase != NULL && basebase->tp_as_buffer == NULL) basebase = NULL; COPYBUF(bf_getbuffer); COPYBUF(bf_releasebuffer); @@ -9012,6 +9012,12 @@ type_ready_set_bases(PyTypeObject *type, int initial) } +static PyNumberMethods pynumber_methods_null = {0}; +static PySequenceMethods pysequence_methods_null = {0}; +static PyMappingMethods pymapping_methods_null = {0}; +static PyAsyncMethods pyasync_methods_null = {0}; +static PyBufferProcs pybuffer_procs_null = {0}; + static int type_ready_set_dict(PyTypeObject *type) { @@ -9172,6 +9178,30 @@ type_ready_mro(PyTypeObject *type, int initial) } +// If a "tp_as_xxx" member is NULL, set it to a structure filled with NULL +// pointers, so functions using "tp_as_xxx" members don't have to check if +// it's NULL. +static void +type_ready_copy_null_methods(PyTypeObject *type) +{ + if (type->tp_as_async == NULL) { + type->tp_as_async = &pyasync_methods_null; + } + if (type->tp_as_number == NULL) { + type->tp_as_number = &pynumber_methods_null; + } + if (type->tp_as_sequence == NULL) { + type->tp_as_sequence = &pysequence_methods_null; + } + if (type->tp_as_mapping == NULL) { + type->tp_as_mapping = &pymapping_methods_null; + } + if (type->tp_as_buffer == NULL) { + type->tp_as_buffer = &pybuffer_procs_null; + } +} + + // For static types, inherit tp_as_xxx structures from the base class // if it's NULL. // @@ -9232,6 +9262,7 @@ type_ready_inherit(PyTypeObject *type) if (base != NULL) { type_ready_inherit_as_structs(type, base); } + type_ready_copy_null_methods(type); /* Sanity check for tp_free. */ if (_PyType_IS_GC(type) && (type->tp_flags & Py_TPFLAGS_BASETYPE) && @@ -9928,7 +9959,7 @@ getindex(PyObject *self, PyObject *arg) return -1; if (i < 0) { PySequenceMethods *sq = Py_TYPE(self)->tp_as_sequence; - if (sq && sq->sq_length) { + if (sq->sq_length) { Py_ssize_t n = (*sq->sq_length)(self); if (n < 0) { assert(PyErr_Occurred()); @@ -10510,10 +10541,8 @@ FUNCNAME(PyObject *self, PyObject *other) \ PyObject* stack[2]; \ PyThreadState *tstate = _PyThreadState_GET(); \ int do_other = !Py_IS_TYPE(self, Py_TYPE(other)) && \ - Py_TYPE(other)->tp_as_number != NULL && \ Py_TYPE(other)->tp_as_number->SLOTNAME == TESTFUNC; \ - if (Py_TYPE(self)->tp_as_number != NULL && \ - Py_TYPE(self)->tp_as_number->SLOTNAME == TESTFUNC) { \ + if (Py_TYPE(self)->tp_as_number->SLOTNAME == TESTFUNC) { \ PyObject *r; \ if (do_other && PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) { \ int ok = method_is_overloaded(self, other, &_Py_ID(RDUNDER)); \ @@ -10690,10 +10719,8 @@ slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus) PyObject* stack[3]; PyThreadState *tstate = _PyThreadState_GET(); int do_other = !Py_IS_TYPE(self, Py_TYPE(other)) && - Py_TYPE(other)->tp_as_number != NULL && Py_TYPE(other)->tp_as_number->nb_power == slot_nb_power; - if (Py_TYPE(self)->tp_as_number != NULL && - Py_TYPE(self)->tp_as_number->nb_power == slot_nb_power) { + if (Py_TYPE(self)->tp_as_number->nb_power == slot_nb_power) { PyObject *r; if (do_other && PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) { int ok = method_is_overloaded(self, other, &_Py_ID(__rpow__)); @@ -11222,7 +11249,6 @@ bufferwrapper_releasebuf(PyObject *self, Py_buffer *view) // We only need to call bf_releasebuffer if it's a Python function. If it's a C // bf_releasebuf, it will be called when the memoryview is released. if (((PyMemoryViewObject *)mv)->view.obj != obj - && Py_TYPE(obj)->tp_as_buffer != NULL && Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer == slot_bf_releasebuffer) { releasebuffer_call_python(obj, view); } @@ -11322,8 +11348,7 @@ releasebuffer_maybe_call_super_unlocked(PyObject *self, Py_buffer *buffer) continue; } PyTypeObject *base_type = (PyTypeObject *)obj; - if (base_type->tp_as_buffer != NULL - && base_type->tp_as_buffer->bf_releasebuffer != NULL + if (base_type->tp_as_buffer->bf_releasebuffer != NULL && base_type->tp_as_buffer->bf_releasebuffer != slot_bf_releasebuffer) { return base_type->tp_as_buffer->bf_releasebuffer; } diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index d28e6fa9cd01ae..ba87fee649dc44 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1984,7 +1984,7 @@ builtin_anext_impl(PyObject *module, PyObject *aiterator, PyObject *awaitable; t = Py_TYPE(aiterator); - if (t->tp_as_async == NULL || t->tp_as_async->am_anext == NULL) { + if (t->tp_as_async->am_anext == NULL) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not an async iterator", t->tp_name); diff --git a/Python/bytecodes.c b/Python/bytecodes.c index fb0cdf4d65e060..6ee3f193e8b20f 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1286,13 +1286,11 @@ dummy_func( op(_GUARD_NOS_DICT_SUBSCRIPT, (nos, unused -- nos, unused)) { PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - DEOPT_IF(!Py_TYPE(o)->tp_as_mapping); DEOPT_IF(Py_TYPE(o)->tp_as_mapping->mp_subscript != _PyDict_Subscript); } op(_GUARD_NOS_DICT_STORE_SUBSCRIPT, (unused, nos, unused -- unused, nos, unused)) { PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - DEOPT_IF(!Py_TYPE(o)->tp_as_mapping); DEOPT_IF(Py_TYPE(o)->tp_as_mapping->mp_ass_subscript != _PyDict_StoreSubscript); } @@ -1605,15 +1603,11 @@ dummy_func( _RETURN_VALUE; inst(GET_AITER, (obj -- iter)) { - unaryfunc getter = NULL; PyObject *obj_o = PyStackRef_AsPyObjectBorrow(obj); PyObject *iter_o; PyTypeObject *type = Py_TYPE(obj_o); - if (type->tp_as_async != NULL) { - getter = type->tp_as_async->am_aiter; - } - + unaryfunc getter = type->tp_as_async->am_aiter; if (getter == NULL) { _PyErr_Format(tstate, PyExc_TypeError, "'async for' requires an object with " @@ -1627,8 +1621,7 @@ dummy_func( PyStackRef_CLOSE(obj); ERROR_IF(iter_o == NULL); - if (Py_TYPE(iter_o)->tp_as_async == NULL || - Py_TYPE(iter_o)->tp_as_async->am_anext == NULL) { + if (Py_TYPE(iter_o)->tp_as_async->am_anext == NULL) { _PyErr_Format(tstate, PyExc_TypeError, "'async for' received an object from __aiter__ " diff --git a/Python/ceval.c b/Python/ceval.c index 8cf02651d9a408..224d0933e011c6 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3546,7 +3546,7 @@ _PyEval_FormatExcUnbound(PyThreadState *tstate, PyCodeObject *co, int oparg) void _PyEval_FormatAwaitableError(PyThreadState *tstate, PyTypeObject *type, int oparg) { - if (type->tp_as_async == NULL || type->tp_as_async->am_await == NULL) { + if (type->tp_as_async->am_await == NULL) { if (oparg == 1) { _PyErr_Format(tstate, PyExc_TypeError, "'async with' received an object from __aenter__ " @@ -3609,16 +3609,12 @@ void Py_LeaveRecursiveCall(void) PyObject * _PyEval_GetANext(PyObject *aiter) { - unaryfunc getter = NULL; PyObject *next_iter = NULL; PyTypeObject *type = Py_TYPE(aiter); if (PyAsyncGen_CheckExact(aiter)) { return type->tp_as_async->am_anext(aiter); } - if (type->tp_as_async != NULL){ - getter = type->tp_as_async->am_anext; - } - + unaryfunc getter = type->tp_as_async->am_anext; if (getter != NULL) { next_iter = (*getter)(aiter); if (next_iter == NULL) { diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 9aad9e003765cf..a7e2163edf5a2b 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -7598,11 +7598,6 @@ _PyStackRef nos; nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!Py_TYPE(o)->tp_as_mapping) { - UOP_STAT_INC(uopcode, miss); - SET_CURRENT_CACHED_VALUES(0); - JUMP_TO_JUMP_TARGET(); - } if (Py_TYPE(o)->tp_as_mapping->mp_subscript != _PyDict_Subscript) { UOP_STAT_INC(uopcode, miss); SET_CURRENT_CACHED_VALUES(0); @@ -7624,12 +7619,6 @@ _PyStackRef _stack_item_0 = _tos_cache0; nos = stack_pointer[-1]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!Py_TYPE(o)->tp_as_mapping) { - UOP_STAT_INC(uopcode, miss); - _tos_cache0 = _stack_item_0; - SET_CURRENT_CACHED_VALUES(1); - JUMP_TO_JUMP_TARGET(); - } if (Py_TYPE(o)->tp_as_mapping->mp_subscript != _PyDict_Subscript) { UOP_STAT_INC(uopcode, miss); _tos_cache0 = _stack_item_0; @@ -7653,13 +7642,6 @@ _PyStackRef _stack_item_1 = _tos_cache1; nos = _stack_item_0; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!Py_TYPE(o)->tp_as_mapping) { - UOP_STAT_INC(uopcode, miss); - _tos_cache1 = _stack_item_1; - _tos_cache0 = nos; - SET_CURRENT_CACHED_VALUES(2); - JUMP_TO_JUMP_TARGET(); - } if (Py_TYPE(o)->tp_as_mapping->mp_subscript != _PyDict_Subscript) { UOP_STAT_INC(uopcode, miss); _tos_cache1 = _stack_item_1; @@ -7683,14 +7665,6 @@ _PyStackRef _stack_item_2 = _tos_cache2; nos = _stack_item_1; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!Py_TYPE(o)->tp_as_mapping) { - UOP_STAT_INC(uopcode, miss); - _tos_cache2 = _stack_item_2; - _tos_cache1 = nos; - _tos_cache0 = _stack_item_0; - SET_CURRENT_CACHED_VALUES(3); - JUMP_TO_JUMP_TARGET(); - } if (Py_TYPE(o)->tp_as_mapping->mp_subscript != _PyDict_Subscript) { UOP_STAT_INC(uopcode, miss); _tos_cache2 = _stack_item_2; @@ -7713,11 +7687,6 @@ _PyStackRef nos; nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!Py_TYPE(o)->tp_as_mapping) { - UOP_STAT_INC(uopcode, miss); - SET_CURRENT_CACHED_VALUES(0); - JUMP_TO_JUMP_TARGET(); - } if (Py_TYPE(o)->tp_as_mapping->mp_ass_subscript != _PyDict_StoreSubscript) { UOP_STAT_INC(uopcode, miss); SET_CURRENT_CACHED_VALUES(0); @@ -7740,12 +7709,6 @@ _PyStackRef _stack_item_0 = _tos_cache0; nos = stack_pointer[-1]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!Py_TYPE(o)->tp_as_mapping) { - UOP_STAT_INC(uopcode, miss); - _tos_cache0 = _stack_item_0; - SET_CURRENT_CACHED_VALUES(1); - JUMP_TO_JUMP_TARGET(); - } if (Py_TYPE(o)->tp_as_mapping->mp_ass_subscript != _PyDict_StoreSubscript) { UOP_STAT_INC(uopcode, miss); _tos_cache0 = _stack_item_0; @@ -7770,13 +7733,6 @@ _PyStackRef _stack_item_1 = _tos_cache1; nos = _stack_item_0; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!Py_TYPE(o)->tp_as_mapping) { - UOP_STAT_INC(uopcode, miss); - _tos_cache1 = _stack_item_1; - _tos_cache0 = nos; - SET_CURRENT_CACHED_VALUES(2); - JUMP_TO_JUMP_TARGET(); - } if (Py_TYPE(o)->tp_as_mapping->mp_ass_subscript != _PyDict_StoreSubscript) { UOP_STAT_INC(uopcode, miss); _tos_cache1 = _stack_item_1; @@ -7803,14 +7759,6 @@ _PyStackRef _stack_item_2 = _tos_cache2; nos = _stack_item_1; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!Py_TYPE(o)->tp_as_mapping) { - UOP_STAT_INC(uopcode, miss); - _tos_cache2 = _stack_item_2; - _tos_cache1 = nos; - _tos_cache0 = _stack_item_0; - SET_CURRENT_CACHED_VALUES(3); - JUMP_TO_JUMP_TARGET(); - } if (Py_TYPE(o)->tp_as_mapping->mp_ass_subscript != _PyDict_StoreSubscript) { UOP_STAT_INC(uopcode, miss); _tos_cache2 = _stack_item_2; @@ -8808,13 +8756,10 @@ _PyStackRef iter; _PyStackRef _stack_item_0 = _tos_cache0; obj = _stack_item_0; - unaryfunc getter = NULL; PyObject *obj_o = PyStackRef_AsPyObjectBorrow(obj); PyObject *iter_o; PyTypeObject *type = Py_TYPE(obj_o); - if (type->tp_as_async != NULL) { - getter = type->tp_as_async->am_aiter; - } + unaryfunc getter = type->tp_as_async->am_aiter; if (getter == NULL) { stack_pointer[0] = obj; stack_pointer += 1; @@ -8852,8 +8797,7 @@ SET_CURRENT_CACHED_VALUES(0); JUMP_TO_ERROR(); } - if (Py_TYPE(iter_o)->tp_as_async == NULL || - Py_TYPE(iter_o)->tp_as_async->am_anext == NULL) { + if (Py_TYPE(iter_o)->tp_as_async->am_anext == NULL) { assert(stack_pointer == _PyFrame_GetStackPointer(frame)); _PyFrame_StackPointerValidate(frame); _PyErr_Format(tstate, PyExc_TypeError, diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 77c18b3d61fefc..caeccc3f2ad433 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -661,11 +661,6 @@ { nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!Py_TYPE(o)->tp_as_mapping) { - UPDATE_MISS_STATS(BINARY_OP); - assert(_PyOpcode_Deopt[opcode] == (BINARY_OP)); - JUMP_TO_PREDICTED(BINARY_OP); - } if (Py_TYPE(o)->tp_as_mapping->mp_subscript != _PyDict_Subscript) { UPDATE_MISS_STATS(BINARY_OP); assert(_PyOpcode_Deopt[opcode] == (BINARY_OP)); @@ -6708,13 +6703,10 @@ _PyStackRef obj; _PyStackRef iter; obj = stack_pointer[-1]; - unaryfunc getter = NULL; PyObject *obj_o = PyStackRef_AsPyObjectBorrow(obj); PyObject *iter_o; PyTypeObject *type = Py_TYPE(obj_o); - if (type->tp_as_async != NULL) { - getter = type->tp_as_async->am_aiter; - } + unaryfunc getter = type->tp_as_async->am_aiter; if (getter == NULL) { _PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_StackPointerValidate(frame); @@ -6744,8 +6736,7 @@ if (iter_o == NULL) { JUMP_TO_LABEL(error); } - if (Py_TYPE(iter_o)->tp_as_async == NULL || - Py_TYPE(iter_o)->tp_as_async->am_anext == NULL) { + if (Py_TYPE(iter_o)->tp_as_async->am_anext == NULL) { assert(stack_pointer == _PyFrame_GetStackPointer(frame)); _PyFrame_StackPointerValidate(frame); _PyErr_Format(tstate, PyExc_TypeError, @@ -12683,11 +12674,6 @@ { nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!Py_TYPE(o)->tp_as_mapping) { - UPDATE_MISS_STATS(STORE_SUBSCR); - assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR)); - JUMP_TO_PREDICTED(STORE_SUBSCR); - } if (Py_TYPE(o)->tp_as_mapping->mp_ass_subscript != _PyDict_StoreSubscript) { UPDATE_MISS_STATS(STORE_SUBSCR); assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR)); diff --git a/Python/getargs.c b/Python/getargs.c index 3f423266bff7f4..bff72fad77971d 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1389,7 +1389,7 @@ convertbuffer(PyObject *arg, const void **p, const char **errmsg) *errmsg = NULL; *p = NULL; - if (pb != NULL && pb->bf_releasebuffer != NULL) { + if (pb->bf_releasebuffer != NULL) { *errmsg = "read-only bytes-like object"; return -1; } diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 5246e50633461b..81f87685958ccc 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -2210,8 +2210,7 @@ dummy_func(void) { tp = sym_get_probable_type(nos); definite = false; } - if (tp && tp->tp_as_mapping && - tp->tp_as_mapping->mp_subscript == _PyDict_Subscript) { + if (tp && tp->tp_as_mapping->mp_subscript == _PyDict_Subscript) { if (definite) { ADD_OP(_NOP, 0, 0); } @@ -2231,8 +2230,7 @@ dummy_func(void) { tp = sym_get_probable_type(nos); definite = false; } - if (tp && tp->tp_as_mapping && - tp->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript) { + if (tp && tp->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript) { if (definite) { ADD_OP(_NOP, 0, 0); } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 21f275f27cafe0..da36d02c1ac73e 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1494,8 +1494,7 @@ tp = sym_get_probable_type(nos); definite = false; } - if (tp && tp->tp_as_mapping && - tp->tp_as_mapping->mp_subscript == _PyDict_Subscript) { + if (tp && tp->tp_as_mapping->mp_subscript == _PyDict_Subscript) { if (definite) { ADD_OP(_NOP, 0, 0); } @@ -1518,8 +1517,7 @@ tp = sym_get_probable_type(nos); definite = false; } - if (tp && tp->tp_as_mapping && - tp->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript) { + if (tp && tp->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript) { if (definite) { ADD_OP(_NOP, 0, 0); } diff --git a/Python/specialize.c b/Python/specialize.c index 05cb76ff015ff4..297fb898274868 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1521,8 +1521,7 @@ store_subscr_fail_kind(PyObject *container, PyObject *sub) { PyTypeObject *container_type = Py_TYPE(container); PyMappingMethods *as_mapping = container_type->tp_as_mapping; - if (as_mapping && (as_mapping->mp_ass_subscript - == PyDict_Type.tp_as_mapping->mp_ass_subscript)) { + if (as_mapping->mp_ass_subscript == PyDict_Type.tp_as_mapping->mp_ass_subscript) { return SPEC_FAIL_SUBSCR_DICT_SUBCLASS_NO_OVERRIDE; } if (PyObject_CheckBuffer(container)) { @@ -1613,8 +1612,7 @@ _Py_Specialize_StoreSubscr(_PyStackRef container_st, _PyStackRef sub_st, _Py_COD return; } } - if (container_type->tp_as_mapping != NULL && - container_type->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript) + if (container_type->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript) { specialize(instr, STORE_SUBSCR_DICT); return; @@ -2425,8 +2423,7 @@ _Py_Specialize_BinaryOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *in } } } - if (Py_TYPE(lhs)->tp_as_mapping != NULL && - Py_TYPE(lhs)->tp_as_mapping->mp_subscript == _PyDict_Subscript) + if (Py_TYPE(lhs)->tp_as_mapping->mp_subscript == _PyDict_Subscript) { specialize(instr, BINARY_OP_SUBSCR_DICT); return; @@ -2824,15 +2821,15 @@ static int check_type_always_true(PyTypeObject *ty) { PyNumberMethods *nb = ty->tp_as_number; - if (nb && nb->nb_bool) { + if (nb->nb_bool) { return SPEC_FAIL_TO_BOOL_NUMBER; } PyMappingMethods *mp = ty->tp_as_mapping; - if (mp && mp->mp_length) { + if (mp->mp_length) { return SPEC_FAIL_TO_BOOL_MAPPING; } PySequenceMethods *sq = ty->tp_as_sequence; - if (sq && sq->sq_length) { + if (sq->sq_length) { return SPEC_FAIL_TO_BOOL_SEQUENCE; } return 0; diff --git a/Tools/build/generate_slots.py b/Tools/build/generate_slots.py index 1fdec6efa50933..4ac0afe1eab527 100755 --- a/Tools/build/generate_slots.py +++ b/Tools/build/generate_slots.py @@ -216,10 +216,14 @@ def add_case(slot): val = f'((PyHeapTypeObject*)tp)->{field}' else: table = TABLES[table_ident] - cond = f'tp->tp_{table}' + if not table.startswith('as_'): + cond = f'tp->tp_{table}' + else: + cond = None val = f'tp->tp_{table}->{field}' out(f'case {slot.name}:') - out(f' if (!({cond})) return NULL;') + if cond: + out(f' if (!({cond})) return NULL;') out(f' return (void*){val};') out(f'_PySlot_err_bad_slot("PyType_GetSlot", slot_id);') out(f'return NULL;')