From e5fcec564f62db5b54244e6a9ef544a669f091a3 Mon Sep 17 00:00:00 2001 From: Baidyanath Kundu Date: Thu, 3 Aug 2023 21:45:53 +0530 Subject: [PATCH] Add type info in the error msg of func arg conv --- src/CPPMethod.cxx | 2 +- src/Converters.cxx | 22 ++++++++++++---------- src/Converters.h | 10 +++++++--- src/DeclareConverters.h | 35 ++++++++++++++++++++++++++++++++++- 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/CPPMethod.cxx b/src/CPPMethod.cxx index a8c97dff..bb3bc5b3 100644 --- a/src/CPPMethod.cxx +++ b/src/CPPMethod.cxx @@ -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; } diff --git a/src/Converters.cxx b/src/Converters.cxx index 745c7713..f41e51f6 100644 --- a/src/Converters.cxx +++ b/src/Converters.cxx @@ -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; } @@ -3144,6 +3144,7 @@ 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 @@ -3151,7 +3152,7 @@ CPyCppyy::Converter* CPyCppyy::CreateConverter(const std::string& fullType, cdim if (h != gConvFactories.end()) return (h->second)(dims); // else, unhandled moves - result = new NotImplementedConverter(); + result = new NotImplementedConverter(failure_msg); } if (!result && h != gConvFactories.end()) @@ -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; @@ -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 @@ -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()) { @@ -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 } } diff --git a/src/Converters.h b/src/Converters.h index 4d68fe3c..e7cdd05a 100644 --- a/src/Converters.h +++ b/src/Converters.h @@ -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) @@ -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; @@ -55,8 +59,8 @@ class VoidArrayConverter : public Converter { template 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); diff --git a/src/DeclareConverters.h b/src/DeclareConverters.h index 99524c1c..e049b35e 100644 --- a/src/DeclareConverters.h +++ b/src/DeclareConverters.h @@ -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]"; }\ } @@ -34,12 +36,14 @@ 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) \ @@ -47,6 +51,7 @@ 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) \ @@ -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; \ @@ -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; @@ -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 { @@ -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; @@ -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; @@ -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; @@ -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 fBuffer; @@ -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 @@ -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 { @@ -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; @@ -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 @@ -279,6 +295,7 @@ class InstancePtrPtrConverter : public InstancePtrConverter { 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 { @@ -292,6 +309,7 @@ class InstanceArrayConverter : public InstancePtrConverter { 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; @@ -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 fBuffer; @@ -318,6 +337,7 @@ 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 @@ -325,18 +345,21 @@ class STLIteratorConverter : public Converter { 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); @@ -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; \ } @@ -371,6 +395,7 @@ class STLStringMoveConverter : public STLStringConverter { public: virtual bool SetArg(PyObject*, Parameter&, CallContext* = nullptr); + virtual std::string GetFailureMsg() { return "[STLStringMoveConverter]"; }; }; @@ -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; @@ -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; @@ -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; } @@ -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(); @@ -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