Skip to content

Commit

Permalink
Add type info in the error msg of func arg conv
Browse files Browse the repository at this point in the history
  • Loading branch information
sudo-panda committed Aug 3, 2023
1 parent a531b0e commit e5fcec5
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/CPPMethod.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ bool CPyCppyy::CPPMethod::ConvertAndSetArgs(CPyCppyy_PyArgs_t args, size_t nargs
Parameter* cppArgs = ctxt->GetArgs(argc);
for (int i = 0; i < (int)argc; ++i) {
if (!fConverters[i]->SetArg(CPyCppyy_PyArgs_GET_ITEM(args, i), cppArgs[i], ctxt)) {
SetPyError_(CPyCppyy_PyText_FromFormat("could not convert argument %d", i+1));
SetPyError_(CPyCppyy_PyText_FromFormat("could not convert argument %d: %s", i+1, fConverters[i]->GetFailureMsg().c_str()));
isOK = false;
break;
}
Expand Down
22 changes: 12 additions & 10 deletions src/Converters.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2355,8 +2355,8 @@ bool CPyCppyy::VoidPtrRefConverter::SetArg(
}

//----------------------------------------------------------------------------
CPyCppyy::VoidPtrPtrConverter::VoidPtrPtrConverter(cdims_t dims) :
fShape(dims) {
CPyCppyy::VoidPtrPtrConverter::VoidPtrPtrConverter(cdims_t dims, const std::string &failureMsg) :
fShape(dims), fFailureMsg (failureMsg) {
fIsFixed = dims ? fShape[0] != UNKNOWN_SIZE : false;
}

Expand Down Expand Up @@ -3144,14 +3144,15 @@ CPyCppyy::Converter* CPyCppyy::CreateConverter(const std::string& fullType, cdim
resolvedType.substr(0, pos1), resolvedType.substr(pos1+sm.length(), pos2-1));
}
}
const std::string failure_msg("Failed to convert type: " + fullType + "; resolved: " + resolvedType + "; real: " + realType + "; cpd: " + cpd);

if (!result && cpd == "&&") {
// for builtin, can use const-ref for r-ref
h = gConvFactories.find("const " + realType + "&");
if (h != gConvFactories.end())
return (h->second)(dims);
// else, unhandled moves
result = new NotImplementedConverter();
result = new NotImplementedConverter(failure_msg);
}

if (!result && h != gConvFactories.end())
Expand All @@ -3160,11 +3161,11 @@ CPyCppyy::Converter* CPyCppyy::CreateConverter(const std::string& fullType, cdim
else if (!result) {
// default to something reasonable, assuming "user knows best"
if (cpd.size() == 2 && cpd != "&&") // "**", "*[]", "*&"
result = new VoidPtrPtrConverter(dims.ndim());
result = new VoidPtrPtrConverter(dims.ndim(), failure_msg);
else if (!cpd.empty())
result = new VoidArrayConverter(); // "user knows best"
result = new VoidArrayConverter(/* keepControl= */ true, failure_msg); // "user knows best"
else
result = new NotImplementedConverter(); // fails on use
result = new NotImplementedConverter(failure_msg); // fails on use
}

return result;
Expand Down Expand Up @@ -3346,6 +3347,7 @@ CPyCppyy::Converter* CPyCppyy::CreateConverter(Cppyy::TCppType_t type, cdims_t d
result = new FunctionPointerConverter(
resolvedTypeStr.substr(0, pos1), resolvedTypeStr.substr(pos2+2, pos3-pos2-1));
}
const std::string failure_msg("Failed to convert type: " + fullType + "; resolved: " + resolvedTypeStr + "; real: " + realTypeStr + "; realUnresolvedType: " + realUnresolvedTypeStr + "; cpd: " + cpd);

if (!result && cpd == "&&") {
// for builtin, can use const-ref for r-ref
Expand All @@ -3357,7 +3359,7 @@ CPyCppyy::Converter* CPyCppyy::CreateConverter(Cppyy::TCppType_t type, cdims_t d
if (h != gConvFactories.end())
return (h->second)(dims);
// else, unhandled moves
result = new NotImplementedConverter();
result = new NotImplementedConverter(failure_msg);
}

if (!result && h != gConvFactories.end()) {
Expand All @@ -3366,11 +3368,11 @@ CPyCppyy::Converter* CPyCppyy::CreateConverter(Cppyy::TCppType_t type, cdims_t d
} else if (!result) {
// default to something reasonable, assuming "user knows best"
if (cpd.size() == 2 && cpd != "&&") {// "**", "*[]", "*&"
result = new VoidPtrPtrConverter(dims.ndim());
result = new VoidPtrPtrConverter(dims.ndim(), failure_msg);
} else if (!cpd.empty()) {
result = new VoidArrayConverter(); // "user knows best"
result = new VoidArrayConverter(/* keepControl= */ true, failure_msg); // "user knows best"
} else {
result = new NotImplementedConverter(); // fails on use
result = new NotImplementedConverter(failure_msg); // fails on use
}
}

Expand Down
10 changes: 7 additions & 3 deletions src/Converters.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class CPYCPPYY_CLASS_EXPORT Converter {
virtual PyObject* FromMemory(void* address);
virtual bool ToMemory(PyObject* value, void* address, PyObject* ctxt = nullptr);
virtual bool HasState() { return false; }
virtual std::string GetFailureMsg() { return "[Converter]"; }
};

// create/destroy converter from fully qualified type (public API)
Expand All @@ -36,17 +37,20 @@ CPYCPPYY_EXPORT bool UnregisterConverter(const std::string& name);
// converters for special cases (only here b/c of external use of StrictInstancePtrConverter)
class VoidArrayConverter : public Converter {
public:
VoidArrayConverter(bool keepControl = true) { fKeepControl = keepControl; }
VoidArrayConverter(bool keepControl = true, const std::string &failureMsg = std::string())
: fFailureMsg(failureMsg) { fKeepControl = keepControl; }

public:
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual PyObject* FromMemory(void* address);
virtual bool ToMemory(PyObject* value, void* address, PyObject* ctxt = nullptr);
virtual bool HasState() { return true; }
virtual std::string GetFailureMsg() { return "[VoidArrayConverter] " + fFailureMsg; }

protected:
virtual bool GetAddressSpecialCase(PyObject* pyobject, void*& address);
bool KeepControl() { return fKeepControl; }
const std::string fFailureMsg;

private:
bool fKeepControl;
Expand All @@ -55,8 +59,8 @@ class VoidArrayConverter : public Converter {
template <bool ISCONST>
class InstancePtrConverter : public VoidArrayConverter {
public:
InstancePtrConverter(Cppyy::TCppType_t klass, bool keepControl = false) :
VoidArrayConverter(keepControl), fClass(klass) {}
InstancePtrConverter(Cppyy::TCppType_t klass, bool keepControl = false, const std::string &failureMsg = std::string()) :
VoidArrayConverter(keepControl, failureMsg), fClass(klass) {}

public:
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
Expand Down
35 changes: 34 additions & 1 deletion src/DeclareConverters.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ public: \
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr); \
virtual PyObject* FromMemory(void*); \
virtual bool ToMemory(PyObject*, void*, PyObject* = nullptr); \
virtual std::string GetFailureMsg() { return "[" #name "Converter]"; } \
}; \
\
class Const##name##RefConverter : public Converter { \
public: \
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr); \
virtual PyObject* FromMemory(void*); \
virtual std::string GetFailureMsg() { return "[Const" #name "RefConverter]"; }\
}


Expand All @@ -34,19 +36,22 @@ class name##Converter : public base##Converter { \
public: \
virtual PyObject* FromMemory(void*); \
virtual bool ToMemory(PyObject*, void*, PyObject* = nullptr); \
virtual std::string GetFailureMsg() { return "[" #name "Converter]"; } \
}; \
\
class Const##name##RefConverter : public Converter { \
public: \
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr); \
virtual PyObject* FromMemory(void*); \
virtual std::string GetFailureMsg() { return "[Const" #name "RefConverter]"; }\
}

#define CPPYY_DECLARE_REFCONVERTER(name) \
class name##RefConverter : public Converter { \
public: \
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr); \
virtual PyObject* FromMemory(void*); \
virtual std::string GetFailureMsg() { return "[" #name "RefConverter]"; }\
};

#define CPPYY_DECLARE_ARRAY_CONVERTER(name) \
Expand All @@ -59,6 +64,7 @@ public: \
virtual PyObject* FromMemory(void*); \
virtual bool ToMemory(PyObject*, void*, PyObject* = nullptr); \
virtual bool HasState() { return true; } \
virtual std::string GetFailureMsg() { return "[" #name "ArrayConverter]"; }\
protected: \
dims_t fShape; \
bool fIsFixed; \
Expand Down Expand Up @@ -126,6 +132,7 @@ class CStringConverter : public Converter {
virtual PyObject* FromMemory(void* address);
virtual bool ToMemory(PyObject* value, void* address, PyObject* = nullptr);
virtual bool HasState() { return true; }
virtual std::string GetFailureMsg() { return "[CStringConverter]"; }

protected:
std::string fBuffer;
Expand All @@ -139,6 +146,7 @@ class NonConstCStringConverter : public CStringConverter {
public:
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual PyObject* FromMemory(void* address);
virtual std::string GetFailureMsg() { return "[NonConstCStringConverter]"; }
};

class WCStringConverter : public Converter {
Expand All @@ -154,6 +162,7 @@ class WCStringConverter : public Converter {
virtual PyObject* FromMemory(void* address);
virtual bool ToMemory(PyObject* value, void* address, PyObject* = nullptr);
virtual bool HasState() { return true; }
virtual std::string GetFailureMsg() { return "[WCStringConverter]"; };

protected:
wchar_t* fBuffer;
Expand All @@ -173,6 +182,7 @@ class CString16Converter : public Converter {
virtual PyObject* FromMemory(void* address);
virtual bool ToMemory(PyObject* value, void* address, PyObject* = nullptr);
virtual bool HasState() { return true; }
virtual std::string GetFailureMsg() { return "[CString16Converter]"; };

protected:
char16_t* fBuffer;
Expand All @@ -192,6 +202,7 @@ class CString32Converter : public Converter {
virtual PyObject* FromMemory(void* address);
virtual bool ToMemory(PyObject* value, void* address, PyObject* = nullptr);
virtual bool HasState() { return true; }
virtual std::string GetFailureMsg() { return "[CString32Converter]"; };

protected:
char32_t* fBuffer;
Expand Down Expand Up @@ -224,6 +235,7 @@ class CStringArrayConverter : public SCharArrayConverter {
using SCharArrayConverter::SCharArrayConverter;
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual PyObject* FromMemory(void* address);
virtual std::string GetFailureMsg() { return "[CStringArrayConverter]"; };

private:
std::vector<const char*> fBuffer;
Expand All @@ -233,6 +245,7 @@ class NonConstCStringArrayConverter : public CStringArrayConverter {
public:
using CStringArrayConverter::CStringArrayConverter;
virtual PyObject* FromMemory(void* address);
virtual std::string GetFailureMsg() { return "[NonConstCStringArrayConverter]"; };
};

// converters for special cases
Expand All @@ -247,6 +260,7 @@ class InstanceConverter : public StrictInstancePtrConverter {
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual PyObject* FromMemory(void*);
virtual bool ToMemory(PyObject*, void*, PyObject* = nullptr);
virtual std::string GetFailureMsg() { return "[InstanceConverter]"; };
};

class InstanceRefConverter : public Converter {
Expand All @@ -258,6 +272,7 @@ class InstanceRefConverter : public Converter {
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual PyObject* FromMemory(void* address);
virtual bool HasState() { return true; }
virtual std::string GetFailureMsg() { return "[InstanceRefConverter]"; };

protected:
Cppyy::TCppType_t fClass;
Expand All @@ -268,6 +283,7 @@ class InstanceMoveConverter : public InstanceRefConverter {
public:
InstanceMoveConverter(Cppyy::TCppType_t klass) : InstanceRefConverter(klass, true) {}
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual std::string GetFailureMsg() { return "[InstanceMoveConverter]"; };
};

template <bool ISREFERENCE>
Expand All @@ -279,6 +295,7 @@ class InstancePtrPtrConverter : public InstancePtrConverter<false> {
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual PyObject* FromMemory(void* address);
virtual bool ToMemory(PyObject* value, void* address, PyObject* = nullptr);
virtual std::string GetFailureMsg() { return "[InstancePtrPtrConverter]"; };
};

class InstanceArrayConverter : public InstancePtrConverter<false> {
Expand All @@ -292,6 +309,7 @@ class InstanceArrayConverter : public InstancePtrConverter<false> {
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual PyObject* FromMemory(void* address);
virtual bool ToMemory(PyObject* value, void* address, PyObject* = nullptr);
virtual std::string GetFailureMsg() { return "[InstanceArrayConverter]"; };

protected:
dims_t fShape;
Expand All @@ -307,6 +325,7 @@ class ComplexDConverter: public InstanceConverter {
virtual PyObject* FromMemory(void* address);
virtual bool ToMemory(PyObject* value, void* address, PyObject* = nullptr);
virtual bool HasState() { return true; }
virtual std::string GetFailureMsg() { return "[ComplexDConverter]"; };

private:
std::complex<double> fBuffer;
Expand All @@ -318,25 +337,29 @@ class ComplexDConverter: public InstanceConverter {
class STLIteratorConverter : public Converter {
public:
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual std::string GetFailureMsg() { return "[STLIteratorConverter]"; };
};
// -- END CLING WORKAROUND


class VoidPtrRefConverter : public Converter {
public:
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual std::string GetFailureMsg() { return "[VoidPtrRefConverter]"; };
};

class VoidPtrPtrConverter : public Converter {
public:
VoidPtrPtrConverter(cdims_t dims);
VoidPtrPtrConverter(cdims_t dims, const std::string &failureMsg = std::string());
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual PyObject* FromMemory(void* address);
virtual bool HasState() { return true; }
virtual std::string GetFailureMsg() { return "[VoidPtrPtrConverter] " + fFailureMsg; }

protected:
dims_t fShape;
bool fIsFixed;
const std::string fFailureMsg;
};

CPPYY_DECLARE_BASIC_CONVERTER(PyObject);
Expand All @@ -351,6 +374,7 @@ public: \
virtual PyObject* FromMemory(void* address); \
virtual bool ToMemory(PyObject*, void*, PyObject* = nullptr); \
virtual bool HasState() { return true; } \
virtual std::string GetFailureMsg() { return "[" #name "Converter]"; }; \
protected: \
strtype fBuffer; \
}
Expand All @@ -371,6 +395,7 @@ class STLStringMoveConverter : public STLStringConverter {

public:
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual std::string GetFailureMsg() { return "[STLStringMoveConverter]"; };
};


Expand All @@ -385,6 +410,7 @@ class FunctionPointerConverter : public Converter {
virtual PyObject* FromMemory(void* address);
virtual bool ToMemory(PyObject*, void*, PyObject* = nullptr);
virtual bool HasState() { return true; }
virtual std::string GetFailureMsg() { return "[FunctionPointerConverter]"; };

protected:
std::string fRetType;
Expand All @@ -404,6 +430,7 @@ class StdFunctionConverter : public FunctionPointerConverter {
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual PyObject* FromMemory(void* address);
virtual bool ToMemory(PyObject* value, void* address, PyObject* = nullptr);
virtual std::string GetFailureMsg() { return "[StdFunctionConverter]"; };

protected:
Converter* fConverter;
Expand All @@ -425,6 +452,7 @@ class SmartPtrConverter : public Converter {
virtual PyObject* FromMemory(void* address);
//virtual bool ToMemory(PyObject*, void*, PyObject* = nullptr);
virtual bool HasState() { return true; }
virtual std::string GetFailureMsg() { return "[SmartPtrConverter]"; };

protected:
virtual bool GetAddressSpecialCase(PyObject*, void*&) { return false; }
Expand All @@ -449,6 +477,7 @@ class InitializerListConverter : public InstanceConverter {
public:
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual bool HasState() { return true; }
virtual std::string GetFailureMsg() { return "[FunctionPointerConverter]"; };

protected:
void Clear();
Expand All @@ -464,7 +493,11 @@ class InitializerListConverter : public InstanceConverter {
// raising converter to take out overloads
class NotImplementedConverter : public Converter {
public:
NotImplementedConverter(const std::string &failureMsg = std::string()) : fFailureMsg{failureMsg} {}
virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr);
virtual std::string GetFailureMsg() { return "[NotImplementedConverter] " + fFailureMsg; }
protected:
const std::string fFailureMsg;
};

} // unnamed namespace
Expand Down

0 comments on commit e5fcec5

Please sign in to comment.