[Python-checkins] GH-92898: Make _Py_Cast C++ version compatible with cast operator (gh-92951)

corona10 webhook-mailer at python.org
Sat May 21 09:16:52 EDT 2022


https://github.com/python/cpython/commit/5b71b519f966e1017c868ea2b27c61a5eac38c1f
commit: 5b71b519f966e1017c868ea2b27c61a5eac38c1f
branch: main
author: serge-sans-paille <serge.guelton at telecom-bretagne.eu>
committer: corona10 <donghee.na92 at gmail.com>
date: 2022-05-21T22:16:37+09:00
summary:

GH-92898: Make _Py_Cast C++ version compatible with cast operator (gh-92951)

files:
M Include/pyport.h
M Lib/test/_testcppext.cpp

diff --git a/Include/pyport.h b/Include/pyport.h
index 614a2789fb078..086ed4204e4ff 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -26,8 +26,32 @@
 // _Py_CAST(const PyObject*, expr) fails with a compiler error.
 #ifdef __cplusplus
 #  define _Py_STATIC_CAST(type, expr) static_cast<type>(expr)
-#  define _Py_CAST(type, expr) \
-       const_cast<type>(reinterpret_cast<const type>(expr))
+
+extern "C++" {
+namespace {
+template <typename type, typename expr_type>
+inline type _Py_reinterpret_cast_impl(expr_type *expr) {
+  return reinterpret_cast<type>(expr);
+}
+
+template <typename type, typename expr_type>
+inline type _Py_reinterpret_cast_impl(expr_type const *expr) {
+  return reinterpret_cast<type>(const_cast<expr_type *>(expr));
+}
+
+template <typename type, typename expr_type>
+inline type _Py_reinterpret_cast_impl(expr_type &expr) {
+  return static_cast<type>(expr);
+}
+
+template <typename type, typename expr_type>
+inline type _Py_reinterpret_cast_impl(expr_type const &expr) {
+  return static_cast<type>(const_cast<expr_type &>(expr));
+}
+} // namespace
+}
+#  define _Py_CAST(type, expr) _Py_reinterpret_cast_impl<type>(expr)
+
 #else
 #  define _Py_STATIC_CAST(type, expr) ((type)(expr))
 #  define _Py_CAST(type, expr) ((type)(expr))
diff --git a/Lib/test/_testcppext.cpp b/Lib/test/_testcppext.cpp
index f38b4870e0edb..f6049eedd0004 100644
--- a/Lib/test/_testcppext.cpp
+++ b/Lib/test/_testcppext.cpp
@@ -40,6 +40,15 @@ test_api_casts(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
     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(type == &PyTuple_Type);
     assert(PyTuple_GET_SIZE(const_obj) == 2);
     PyObject *one = PyTuple_GET_ITEM(const_obj, 0);



More information about the Python-checkins mailing list