diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2022-05-26 23:39:28 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-26 23:39:28 (GMT) |
commit | 9303a5ac30c3fd4f04881d432b10be894959cfbd (patch) | |
tree | 64d14ae2491d6fd4c0513a38573f0b856df18e5d /Lib/test/_testcppext.cpp | |
parent | 33336e46daff556e3850b75045e33434a8f46378 (diff) | |
download | cpython-9303a5ac30c3fd4f04881d432b10be894959cfbd.zip cpython-9303a5ac30c3fd4f04881d432b10be894959cfbd.tar.gz cpython-9303a5ac30c3fd4f04881d432b10be894959cfbd.tar.bz2 |
gh-92898: Enhance _testcppext test on cast to PyObject* (GH-93111)
* Add StrongRef class.
* Rename and reformat functions of the _Py_CAST() implementation.
(cherry picked from commit 20d30ba2ccf9182e4f08db112f428c909148a40b)
Co-authored-by: Victor Stinner <vstinner@python.org>
Diffstat (limited to 'Lib/test/_testcppext.cpp')
-rw-r--r-- | Lib/test/_testcppext.cpp | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/Lib/test/_testcppext.cpp b/Lib/test/_testcppext.cpp index f6049ee..eade7cc 100644 --- a/Lib/test/_testcppext.cpp +++ b/Lib/test/_testcppext.cpp @@ -23,6 +23,26 @@ _testcppext_add(PyObject *Py_UNUSED(module), PyObject *args) } +// Class to test operator casting an object to PyObject* +class StrongRef +{ +public: + StrongRef(PyObject *obj) : m_obj(obj) { + Py_INCREF(this->m_obj); + } + + ~StrongRef() { + Py_DECREF(this->m_obj); + } + + // Cast to PyObject*: get a borrowed reference + inline operator PyObject*() const { return this->m_obj; } + +private: + PyObject *m_obj; // Strong reference +}; + + static PyObject * test_api_casts(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) { @@ -30,6 +50,8 @@ test_api_casts(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) if (obj == nullptr) { return nullptr; } + Py_ssize_t refcnt = Py_REFCNT(obj); + assert(refcnt >= 1); // gh-92138: For backward compatibility, functions of Python C API accepts // "const PyObject*". Check that using it does not emit C++ compiler @@ -38,22 +60,20 @@ test_api_casts(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) Py_INCREF(const_obj); Py_DECREF(const_obj); PyTypeObject *type = Py_TYPE(const_obj); - assert(Py_REFCNT(const_obj) >= 1); - - struct PyObjectProxy { - PyObject* obj; - operator PyObject *() { return obj; } - } proxy_obj = { obj }; - Py_INCREF(proxy_obj); - Py_DECREF(proxy_obj); - assert(Py_REFCNT(proxy_obj) >= 1); - - + assert(Py_REFCNT(const_obj) == refcnt); assert(type == &PyTuple_Type); assert(PyTuple_GET_SIZE(const_obj) == 2); PyObject *one = PyTuple_GET_ITEM(const_obj, 0); assert(PyLong_AsLong(one) == 1); + // gh-92898: StrongRef doesn't inherit from PyObject but has an operator to + // cast to PyObject*. + StrongRef strong_ref(obj); + assert(Py_TYPE(strong_ref) == &PyTuple_Type); + assert(Py_REFCNT(strong_ref) == (refcnt + 1)); + Py_INCREF(strong_ref); + Py_DECREF(strong_ref); + Py_DECREF(obj); Py_RETURN_NONE; } |