Skip to content

Commit

Permalink
[CPyCppyy] Remove implicit conversion of any ctypes ptr type to void*
Browse files Browse the repository at this point in the history
The `IsCTypesArrayOrPointer` gives false positives in Python 3.13,
resulting the void pointer converter to take the wrong code path and
crash. See:
wlav/cppyy#272

This code path is used for implicit conversion from other `ctypes`
pointer types to `void*`, which is not strictly required. One can
always do an explicit cast:  `ctypes.cast(my_ptr, ctypes.c_void_p )`.

Given that this a niche feature that broke Python 3.13 support for
functions taking `void*`, which is quite common, it can be argued that
it's better to remove this implicit conversion.

This commit fixes the following tests under Python 3.13:

```
roottest-python-basic-datatype
roottest-python-cpp-cpp
```

This reverts the following commit from upstream:
wlav/CPyCppyy@80a0205
  • Loading branch information
guitargeek committed Nov 4, 2024
1 parent 30a6542 commit 1ec1d64
Showing 1 changed file with 0 additions and 33 deletions.
33 changes: 0 additions & 33 deletions bindings/pyroot/cppyy/CPyCppyy/src/Converters.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -203,24 +203,6 @@ static bool IsPyCArgObject(PyObject* pyobject)
return Py_TYPE(pyobject) == pycarg_type;
}

static bool IsCTypesArrayOrPointer(PyObject* pyobject)
{
static PyTypeObject* cstgdict_type = nullptr;
if (!cstgdict_type) {
// get any pointer type to initialize the extended dictionary type
PyTypeObject* ct_int = GetCTypesType(ct_c_int);
if (ct_int && ct_int->tp_dict) {
cstgdict_type = Py_TYPE(ct_int->tp_dict);
}
}

PyTypeObject* pytype = Py_TYPE(pyobject);
if (pytype->tp_dict && Py_TYPE(pytype->tp_dict) == cstgdict_type)
return true;
return false;
}


//- helper to establish life lines -------------------------------------------
static inline bool SetLifeLine(PyObject* holder, PyObject* target, intptr_t ref)
{
Expand Down Expand Up @@ -1506,16 +1488,6 @@ bool CPyCppyy::VoidArrayConverter::SetArg(
return true;
}

// allow any other ctypes pointer type
if (IsCTypesArrayOrPointer(pyobject)) {
void** payload = (void**)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr;
if (payload) {
para.fValue.fVoidp = *payload;
para.fTypeCode = 'p';
return true;
}
}

// final try: attempt to get buffer
Py_ssize_t buflen = Utility::GetBuffer(pyobject, '*', 1, para.fValue.fVoidp, false);

Expand Down Expand Up @@ -1628,11 +1600,6 @@ bool CPyCppyy::name##ArrayConverter::SetArg( \
para.fValue.fVoidp = (void*)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr;\
para.fTypeCode = 'p'; \
convOk = true; \
} else if (Py_TYPE(pyobject) == GetCTypesType(ct_c_void_p)) { \
/* special case: pass address of c_void_p buffer to return the address */\
para.fValue.fVoidp = (void*)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr;\
para.fTypeCode = 'p'; \
convOk = true; \
} else if (LowLevelView_Check(pyobject) && \
((LowLevelView*)pyobject)->fBufInfo.ndim == 2 && \
strchr(((LowLevelView*)pyobject)->fBufInfo.format, code)) { \
Expand Down

0 comments on commit 1ec1d64

Please sign in to comment.