bpo-43753: Add Py_Is() and Py_IsNone() functions (GH-25227)

Add the Py_Is(x, y) function to test if the 'x' object is the 'y'
object, the same as "x is y" in Python. Add also the Py_IsNone(),
Py_IsTrue(), Py_IsFalse() functions to test if an object is,
respectively, the None singleton, the True singleton or the False
singleton.
This commit is contained in:
Victor Stinner 2021-04-11 00:17:39 +02:00 committed by GitHub
parent 6e468cb16b
commit 09bbebea16
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 198 additions and 38 deletions

View file

@ -5401,32 +5401,98 @@ test_set_type_size(PyObject *self, PyObject *Py_UNUSED(ignored))
}
// Test Py_NewRef() and Py_XNewRef() functions
#define TEST_REFCOUNT() \
do { \
PyObject *obj = PyList_New(0); \
if (obj == NULL) { \
return NULL; \
} \
assert(Py_REFCNT(obj) == 1); \
\
/* test Py_NewRef() */ \
PyObject *ref = Py_NewRef(obj); \
assert(ref == obj); \
assert(Py_REFCNT(obj) == 2); \
Py_DECREF(ref); \
\
/* test Py_XNewRef() */ \
PyObject *xref = Py_XNewRef(obj); \
assert(xref == obj); \
assert(Py_REFCNT(obj) == 2); \
Py_DECREF(xref); \
\
assert(Py_XNewRef(NULL) == NULL); \
\
Py_DECREF(obj); \
Py_RETURN_NONE; \
} while (0) \
// Test Py_NewRef() and Py_XNewRef() macros
static PyObject*
test_refcount(PyObject *self, PyObject *Py_UNUSED(ignored))
test_refcount_macros(PyObject *self, PyObject *Py_UNUSED(ignored))
{
PyObject *obj = PyList_New(0);
if (obj == NULL) {
return NULL;
}
assert(Py_REFCNT(obj) == 1);
TEST_REFCOUNT();
}
// Test Py_NewRef()
PyObject *ref = Py_NewRef(obj);
assert(ref == obj);
assert(Py_REFCNT(obj) == 2);
Py_DECREF(ref);
#undef Py_NewRef
#undef Py_XNewRef
// Test Py_XNewRef()
PyObject *xref = Py_XNewRef(obj);
assert(xref == obj);
assert(Py_REFCNT(obj) == 2);
Py_DECREF(xref);
// Test Py_NewRef() and Py_XNewRef() functions, after undefining macros.
static PyObject*
test_refcount_funcs(PyObject *self, PyObject *Py_UNUSED(ignored))
{
TEST_REFCOUNT();
}
assert(Py_XNewRef(NULL) == NULL);
Py_DECREF(obj);
Py_RETURN_NONE;
// Test Py_Is() function
#define TEST_PY_IS() \
do { \
PyObject *o_none = Py_None; \
PyObject *o_true = Py_True; \
PyObject *o_false = Py_False; \
PyObject *obj = PyList_New(0); \
if (obj == NULL) { \
return NULL; \
} \
\
/* test Py_Is() */ \
assert(Py_Is(obj, obj)); \
assert(!Py_Is(obj, o_none)); \
\
/* test Py_None */ \
assert(Py_Is(o_none, o_none)); \
assert(!Py_Is(obj, o_none)); \
\
/* test Py_True */ \
assert(Py_Is(o_true, o_true)); \
assert(!Py_Is(o_false, o_true)); \
assert(!Py_Is(obj, o_true)); \
\
/* test Py_False */ \
assert(Py_Is(o_false, o_false)); \
assert(!Py_Is(o_true, o_false)); \
assert(!Py_Is(obj, o_false)); \
\
Py_DECREF(obj); \
Py_RETURN_NONE; \
} while (0)
// Test Py_Is() macro
static PyObject*
test_py_is_macros(PyObject *self, PyObject *Py_UNUSED(ignored))
{
TEST_PY_IS();
}
#undef Py_Is
// Test Py_Is() function, after undefining its macro.
static PyObject*
test_py_is_funcs(PyObject *self, PyObject *Py_UNUSED(ignored))
{
TEST_PY_IS();
}
@ -5716,7 +5782,10 @@ static PyMethodDef TestMethods[] = {
{"pynumber_tobase", pynumber_tobase, METH_VARARGS},
{"without_gc", without_gc, METH_O},
{"test_set_type_size", test_set_type_size, METH_NOARGS},
{"test_refcount", test_refcount, METH_NOARGS},
{"test_refcount_macros", test_refcount_macros, METH_NOARGS},
{"test_refcount_funcs", test_refcount_funcs, METH_NOARGS},
{"test_py_is_macros", test_py_is_macros, METH_NOARGS},
{"test_py_is_funcs", test_py_is_funcs, METH_NOARGS},
{"fatal_error", test_fatal_error, METH_VARARGS,
PyDoc_STR("fatal_error(message, release_gil=False): call Py_FatalError(message)")},
{NULL, NULL} /* sentinel */