diff options
author | Victor Stinner <vstinner@python.org> | 2021-04-10 22:17:39 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-10 22:17:39 (GMT) |
commit | 09bbebea163fe7303264cf4069c51d4d2f22fde4 (patch) | |
tree | af9449e38983bab8ebf5a667c149cb0d33e05543 /Modules | |
parent | 6e468cb16bde483ad73c1eb13b20a08d74e30846 (diff) | |
download | cpython-09bbebea163fe7303264cf4069c51d4d2f22fde4.zip cpython-09bbebea163fe7303264cf4069c51d4d2f22fde4.tar.gz cpython-09bbebea163fe7303264cf4069c51d4d2f22fde4.tar.bz2 |
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.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_testcapimodule.c | 111 |
1 files changed, 90 insertions, 21 deletions
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 20107f2..db62aea 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -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(); +} + +#undef Py_NewRef +#undef Py_XNewRef + +// Test Py_NewRef() and Py_XNewRef() functions, after undefining macros. +static PyObject* +test_refcount_funcs(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + TEST_REFCOUNT(); +} - // 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); +// 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(); +} - assert(Py_XNewRef(NULL) == NULL); +#undef Py_Is - Py_DECREF(obj); - Py_RETURN_NONE; +// 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 */ |