summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2021-04-10 22:17:39 (GMT)
committerGitHub <noreply@github.com>2021-04-10 22:17:39 (GMT)
commit09bbebea163fe7303264cf4069c51d4d2f22fde4 (patch)
treeaf9449e38983bab8ebf5a667c149cb0d33e05543 /Modules
parent6e468cb16bde483ad73c1eb13b20a08d74e30846 (diff)
downloadcpython-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.c111
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 */