Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-39573: Use Py_IS_TYPE for type checking #18789

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Include/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ typedef struct {
#define Py_TYPE(ob) (_PyObject_CAST(ob)->ob_type)
#define Py_SIZE(ob) (_PyVarObject_CAST(ob)->ob_size)

static inline int _Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
static inline int _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
return ob->ob_type == type;
}
#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST(ob), type)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to have a new private _PyObject_CAST_CONST() macro rather than casting directly.

I prefer macros because maybe tomorrow we might be able to check if the pointer is valid PyObject in debug mode. Maybe using _PyObject_CheckConsistency().

Would you mind to move these changes (add the macro and modify Py_IS_TYPE to use const) into a separated PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll make two separate PRs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are now in #18798 and #18799

#define Py_IS_TYPE(ob, type) _Py_IS_TYPE((const PyObject*)(ob), type)

static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
ob->ob_refcnt = refcnt;
Expand Down
2 changes: 1 addition & 1 deletion Modules/_functoolsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ keyobject_richcompare(PyObject *ko, PyObject *other, int op)
PyObject *answer;
PyObject* stack[2];

if (Py_TYPE(other) != &keyobject_type){
if (!Py_IS_TYPE(other, &keyobject_type)) {
PyErr_Format(PyExc_TypeError, "other argument must be K instance");
return NULL;
}
Expand Down
4 changes: 2 additions & 2 deletions Modules/_threadmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ local_getattro(localobject *self, PyObject *name)
if (r == -1)
return NULL;

if (Py_TYPE(self) != &localtype)
if (!Py_IS_TYPE(self, &localtype))
/* use generic lookup for subtypes */
return _PyObject_GenericGetAttrWithDict(
(PyObject *)self, name, ldict, 0);
Expand Down Expand Up @@ -1400,7 +1400,7 @@ static PyStructSequence_Desc ExceptHookArgs_desc = {
static PyObject *
thread_excepthook(PyObject *self, PyObject *args)
{
if (Py_TYPE(args) != &ExceptHookArgsType) {
if (!Py_IS_TYPE(args, &ExceptHookArgsType)) {
PyErr_SetString(PyExc_TypeError,
"_thread.excepthook argument type "
"must be ExceptHookArgs");
Expand Down
2 changes: 1 addition & 1 deletion Modules/itertoolsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ itertools_teedataobject_impl(PyTypeObject *type, PyObject *it,

if (len == LINKCELLS) {
if (next != Py_None) {
if (Py_TYPE(next) != &teedataobject_type)
if (!Py_IS_TYPE(next, &teedataobject_type))
goto err;
assert(tdo->nextlink == NULL);
Py_INCREF(next);
Expand Down
3 changes: 1 addition & 2 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -6380,8 +6380,7 @@ convert_sched_param(PyObject *param, struct sched_param *res)
{
long priority;

PyObject *SchedParamType = _posixstate_global->SchedParamType;
if (Py_TYPE(param) != (PyTypeObject *)SchedParamType) {
if (!Py_IS_TYPE(param, (PyTypeObject *)_posixstate_global->SchedParamType)) {
PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
return 0;
}
Expand Down
5 changes: 2 additions & 3 deletions Objects/abstract.c
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,7 @@ binary_op1(PyObject *v, PyObject *w, const int op_slot)

if (Py_TYPE(v)->tp_as_number != NULL)
slotv = NB_BINOP(Py_TYPE(v)->tp_as_number, op_slot);
if (Py_TYPE(w) != Py_TYPE(v) &&
if (!Py_IS_TYPE(w, Py_TYPE(v)) &&
Py_TYPE(w)->tp_as_number != NULL) {
slotw = NB_BINOP(Py_TYPE(w)->tp_as_number, op_slot);
if (slotw == slotv)
Expand Down Expand Up @@ -925,8 +925,7 @@ ternary_op(PyObject *v,
mw = Py_TYPE(w)->tp_as_number;
if (mv != NULL)
slotv = NB_TERNOP(mv, op_slot);
if (Py_TYPE(w) != Py_TYPE(v) &&
mw != NULL) {
if (!Py_IS_TYPE(w, Py_TYPE(v)) && mw != NULL) {
slotw = NB_TERNOP(mw, op_slot);
if (slotw == slotv)
slotw = NULL;
Expand Down
6 changes: 3 additions & 3 deletions Objects/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ _PyObject_CheckConsistency(PyObject *op, int check_content)
CHECK(!_PyObject_IsFreed(op));
CHECK(Py_REFCNT(op) >= 1);

CHECK(Py_TYPE(op) != NULL);
CHECK(!Py_IS_TYPE(op, NULL));
_PyType_CheckConsistency(Py_TYPE(op));

if (PyUnicode_Check(op)) {
Expand Down Expand Up @@ -665,7 +665,7 @@ do_richcompare(PyThreadState *tstate, PyObject *v, PyObject *w, int op)
PyObject *res;
int checked_reverse_op = 0;

if (Py_TYPE(v) != Py_TYPE(w) &&
if (!Py_IS_TYPE(v, Py_TYPE(w)) &&
PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v)) &&
(f = Py_TYPE(w)->tp_richcompare) != NULL) {
checked_reverse_op = 1;
Expand Down Expand Up @@ -1915,7 +1915,7 @@ _Py_GetObjects(PyObject *self, PyObject *args)
return NULL;
for (i = 0; (n == 0 || i < n) && op != &refchain; i++) {
while (op == self || op == args || op == res || op == t ||
(t != NULL && Py_TYPE(op) != (PyTypeObject *) t)) {
(t != NULL && !Py_IS_TYPE(op, (PyTypeObject *) t))) {
op = op->_ob_next;
if (op == &refchain)
return res;
Expand Down
2 changes: 1 addition & 1 deletion Objects/setobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ set_repr(PySetObject *so)
goto done;
listrepr = tmp;

if (Py_TYPE(so) != &PySet_Type)
if (!Py_IS_TYPE(so, &PySet_Type))
result = PyUnicode_FromFormat("%s({%U})",
Py_TYPE(so)->tp_name,
listrepr);
Expand Down
2 changes: 1 addition & 1 deletion Objects/tupleobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,7 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
Py_ssize_t oldsize;

v = (PyTupleObject *) *pv;
if (v == NULL || Py_TYPE(v) != &PyTuple_Type ||
if (v == NULL || !Py_IS_TYPE(v, &PyTuple_Type) ||
(Py_SIZE(v) != 0 && Py_REFCNT(v) != 1)) {
*pv = 0;
Py_XDECREF(v);
Expand Down
6 changes: 3 additions & 3 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1889,7 +1889,7 @@ mro_invoke(PyTypeObject *type)
{
PyObject *mro_result;
PyObject *new_mro;
int custom = (Py_TYPE(type) != &PyType_Type);
const int custom = !Py_IS_TYPE(type, &PyType_Type);

if (custom) {
int unbound;
Expand Down Expand Up @@ -6191,7 +6191,7 @@ FUNCNAME(PyObject *self, PyObject *other) \
PyThreadState *tstate = _PyThreadState_GET(); \
_Py_static_string(op_id, OPSTR); \
_Py_static_string(rop_id, ROPSTR); \
int do_other = Py_TYPE(self) != Py_TYPE(other) && \
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 && \
Expand Down Expand Up @@ -7901,7 +7901,7 @@ super_descr_get(PyObject *self, PyObject *obj, PyObject *type)
Py_INCREF(self);
return self;
}
if (Py_TYPE(su) != &PySuper_Type)
if (!Py_IS_TYPE(su, &PySuper_Type))
/* If su is an instance of a (strict) subclass of super,
call its type */
return PyObject_CallFunctionObjArgs((PyObject *)Py_TYPE(su),
Expand Down
2 changes: 1 addition & 1 deletion Python/errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -1321,7 +1321,7 @@ _PyErr_WriteUnraisableDefaultHook(PyObject *args)
{
PyThreadState *tstate = _PyThreadState_GET();

if (Py_TYPE(args) != &UnraisableHookArgsType) {
if (!Py_IS_TYPE(args, &UnraisableHookArgsType)) {
_PyErr_SetString(tstate, PyExc_TypeError,
"sys.unraisablehook argument type "
"must be UnraisableHookArgs");
Expand Down