[Python-checkins] gh-93442: Make C++ version of _Py_CAST work with 0/NULL. (#93500)

nascheme webhook-mailer at python.org
Sat Jun 4 21:49:51 EDT 2022


https://github.com/python/cpython/commit/8bcc3fa3453e28511d04eaa0aa7d8e1a3495d518
commit: 8bcc3fa3453e28511d04eaa0aa7d8e1a3495d518
branch: main
author: Neil Schemenauer <nas-github at arctrix.com>
committer: nascheme <nas-github at arctrix.com>
date: 2022-06-04T18:49:39-07:00
summary:

gh-93442: Make C++ version of _Py_CAST work with 0/NULL. (#93500)

Add C++ overloads for _Py_CAST_impl() to handle 0/NULL.  This will allow
C++ extensions that pass 0 or NULL to macros using _Py_CAST() to
continue to compile.  Without this, you get an error like:

    invalid ‘static_cast’ from type ‘int’ to type ‘_object*’

The modern way to use a NULL value in C++ is to use nullptr.  However,
we want to not break extensions that do things the old way.

Co-authored-by: serge-sans-paille

files:
A Misc/NEWS.d/next/C API/2022-06-04-13-15-41.gh-issue-93442.4M4NDb.rst
M Include/pyport.h
M Lib/test/_testcppext.cpp

diff --git a/Include/pyport.h b/Include/pyport.h
index 6ea2bba232b3d..faaeb83291811 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -24,9 +24,23 @@
 //
 // The type argument must not be a constant type.
 #ifdef __cplusplus
+#include <cstddef>
 #  define _Py_STATIC_CAST(type, expr) static_cast<type>(expr)
 extern "C++" {
     namespace {
+        template <typename type>
+        inline type _Py_CAST_impl(long int ptr) {
+            return reinterpret_cast<type>(ptr);
+        }
+        template <typename type>
+        inline type _Py_CAST_impl(int ptr) {
+            return reinterpret_cast<type>(ptr);
+        }
+        template <typename type>
+        inline type _Py_CAST_impl(std::nullptr_t) {
+            return static_cast<type>(nullptr);
+        }
+
         template <typename type, typename expr_type>
             inline type _Py_CAST_impl(expr_type *expr) {
                 return reinterpret_cast<type>(expr);
diff --git a/Lib/test/_testcppext.cpp b/Lib/test/_testcppext.cpp
index eade7ccdaaff7..70f434e6789ad 100644
--- a/Lib/test/_testcppext.cpp
+++ b/Lib/test/_testcppext.cpp
@@ -74,6 +74,10 @@ test_api_casts(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
     Py_INCREF(strong_ref);
     Py_DECREF(strong_ref);
 
+    // gh-93442: Pass 0 as NULL for PyObject*
+    Py_XINCREF(0);
+    Py_XDECREF(0);
+
     Py_DECREF(obj);
     Py_RETURN_NONE;
 }
diff --git a/Misc/NEWS.d/next/C API/2022-06-04-13-15-41.gh-issue-93442.4M4NDb.rst b/Misc/NEWS.d/next/C API/2022-06-04-13-15-41.gh-issue-93442.4M4NDb.rst
new file mode 100644
index 0000000000000..f48ed37c81445
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2022-06-04-13-15-41.gh-issue-93442.4M4NDb.rst	
@@ -0,0 +1,3 @@
+Add C++ overloads for _Py_CAST_impl() to handle 0/NULL.  This will allow C++
+extensions that pass 0 or NULL to macros using _Py_CAST() to continue to
+compile.



More information about the Python-checkins mailing list