Skip to content

Commit 5d362c7

Browse files
committed
[cppyy] Allow passing of const ref to ptr args
This commit follows up on d35e114 wehere interfaces taking references to pointers were disallowed from being used in Python. That was a nice change, but we should continue to allow immutable references to pointers since that prevents pointer rebinding and can be used safely from Python. This commit enables the same and updates the `VoidPtrRefConverter` to map only to the const case.
1 parent 1c7f55b commit 5d362c7

1 file changed

Lines changed: 10 additions & 9 deletions

File tree

bindings/pyroot/cppyy/CPyCppyy/src/Converters.cxx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3365,19 +3365,19 @@ CPyCppyy::Converter* CPyCppyy::CreateConverter(const std::string& fullType, cdim
33653365
const std::string& cpd = TypeManip::compound(resolvedType);
33663366
std::string realType = TypeManip::clean_type(resolvedType, false, true);
33673367

3368-
// mutable pointer references (T*&) are incompatible with Python's object model
3369-
if (cpd == "*&") {
3370-
return new NotImplementedConverter{PyExc_TypeError,
3371-
"argument type '" + resolvedType + "' is not supported: non-const references to pointers (T*&) allow a"
3372-
" function to replace the pointer itself. Python cannot represent this safely. Consider changing the"
3373-
" C++ API to return the new pointer or use a wrapper"};
3374-
}
3375-
33763368
// accept unqualified type (as python does not know about qualifiers)
33773369
h = gConvFactories.find((isConst ? "const " : "") + realType + cpd);
33783370
if (h != gConvFactories.end())
33793371
return (h->second)(dims);
33803372

3373+
// mutable pointer references (T*&) are incompatible with Python's object model
3374+
if (!isConst && cpd == "*&") {
3375+
return new NotImplementedConverter{PyExc_TypeError,
3376+
"argument type '" + resolvedType + "' is not supported: non-const references to pointers (T*&) allow a"
3377+
" function to replace the pointer itself. Python cannot represent this safely. Consider changing the"
3378+
" C++ API to return the new pointer or use a wrapper"};
3379+
}
3380+
33813381
// drop const, as that is mostly meaningless to python (with the exception
33823382
// of c-strings, but those are specialized in the converter map)
33833383
if (isConst) {
@@ -3827,7 +3827,8 @@ static struct InitConvFactories_t {
38273827
gf["const std::wstring&"] = gf["std::wstring"];
38283828
gf["const " WSTRING1 "&"] = gf["std::wstring"];
38293829
gf["const " WSTRING2 "&"] = gf["std::wstring"];
3830-
gf["void*&"] = (cf_t)+[](cdims_t) { static VoidPtrRefConverter c{}; return &c; };
3830+
// VoidPtrRefConverter should only be used for const references to pointers
3831+
gf["const void*&"] = (cf_t)+[](cdims_t) { static VoidPtrRefConverter c{}; return &c; };
38313832
gf["void**"] = (cf_t)+[](cdims_t d) { return new VoidPtrPtrConverter{d}; };
38323833
gf["void ptr"] = gf["void**"];
38333834
gf["PyObject*"] = (cf_t)+[](cdims_t) { static PyObjectConverter c{}; return &c; };

0 commit comments

Comments
 (0)