https://github.com/python/cpython/commit/748fea0033f23422e9e0877d61a537ff8a3b77ff commit: 748fea0033f23422e9e0877d61a537ff8a3b77ff branch: 3.15 author: Miss Islington (bot) <[email protected]> committer: serhiy-storchaka <[email protected]> date: 2026-10-10T14:00:58+03:00 summary:
[3.15] gh-121617: Fix Py_CLEAR() in C++: replace NULL with _Py_NULL (GH-157067) (GH-157186) * Enhance Py_CLEAR() test in test_cext and test_cppext. Check that Py_CLEAR(obj) sets obj to NULL. * Add also tests on Py_SETREF() and Py_BEGIN_CRITICAL_SECTION(). (cherry picked from commit 36c7440c480da622735788af656c728af28cd9eb) Co-authored-by: Victor Stinner <[email protected]> files: M Include/refcount.h M Lib/test/test_cext/extension.c M Lib/test/test_cppext/extension.cpp diff --git a/Include/refcount.h b/Include/refcount.h index 80fe7ff70a11e87..b21697ae1780fa8 100644 --- a/Include/refcount.h +++ b/Include/refcount.h @@ -484,7 +484,7 @@ static inline Py_ALWAYS_INLINE void Py_DECREF(PyObject *op) do { \ _Py_TYPEOF(op)* _tmp_op_ptr = &(op); \ _Py_TYPEOF(op) _tmp_old_op = (*_tmp_op_ptr); \ - if (_tmp_old_op != NULL) { \ + if (_tmp_old_op != _Py_NULL) { \ *_tmp_op_ptr = _Py_NULL; \ Py_DECREF(_tmp_old_op); \ } \ @@ -494,7 +494,7 @@ static inline Py_ALWAYS_INLINE void Py_DECREF(PyObject *op) do { \ PyObject **_tmp_op_ptr = _Py_CAST(PyObject**, &(op)); \ PyObject *_tmp_old_op = (*_tmp_op_ptr); \ - if (_tmp_old_op != NULL) { \ + if (_tmp_old_op != _Py_NULL) { \ PyObject *_null_ptr = _Py_NULL; \ memcpy(_tmp_op_ptr, &_null_ptr, sizeof(PyObject*)); \ Py_DECREF(_tmp_old_op); \ diff --git a/Lib/test/test_cext/extension.c b/Lib/test/test_cext/extension.c index e5f09e5518238fd..b58c889ba8bcb3b 100644 --- a/Lib/test/test_cext/extension.c +++ b/Lib/test/test_cext/extension.c @@ -95,9 +95,17 @@ _testcext_exec(PyObject *module) Py_BUILD_ASSERT(sizeof(int) == sizeof(unsigned int)); assert(Py_BUILD_ASSERT_EXPR(sizeof(int) == sizeof(unsigned int)) == 0); - // Test Py_CLEAR() - obj = NULL; + // Test Py_CLEAR(): use typeof()/__typeof__() if available, or memcpy() + obj = Py_None; Py_CLEAR(obj); + assert(obj == NULL); + +#ifndef Py_LIMITED_API + // Test Py_SETREF(): use typeof()/__typeof__() if available, or memcpy() + obj = Py_None; + Py_SETREF(obj, NULL); + assert(obj == NULL); +#endif // Test that Py_BEGIN_CRITICAL_SECTION is available Py_BEGIN_CRITICAL_SECTION(module); diff --git a/Lib/test/test_cppext/extension.cpp b/Lib/test/test_cppext/extension.cpp index 1e485f516adf2cf..7496581c6756dac 100644 --- a/Lib/test/test_cppext/extension.cpp +++ b/Lib/test/test_cppext/extension.cpp @@ -302,6 +302,22 @@ _testcppext_exec(PyObject *module) Py_BUILD_ASSERT(sizeof(int) == sizeof(unsigned int)); assert(Py_BUILD_ASSERT_EXPR(sizeof(int) == sizeof(unsigned int)) == 0); + // Test Py_CLEAR(): use typeof()/__typeof__() if available, or memcpy() + PyObject *obj = Py_None; + Py_CLEAR(obj); + assert(obj == _Py_NULL); + +#ifndef Py_LIMITED_API + // Test Py_SETREF(): use typeof()/__typeof__() if available, or memcpy() + obj = Py_None; + Py_SETREF(obj, _Py_NULL); + assert(obj == _Py_NULL); +#endif + + // Test that Py_BEGIN_CRITICAL_SECTION is available + Py_BEGIN_CRITICAL_SECTION(module); + Py_END_CRITICAL_SECTION(); + return 0; } _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
