From 19ead930d545811865bf2d1f84bf1ffcec70450f Mon Sep 17 00:00:00 2001 From: Aaron Jomy Date: Thu, 16 Jul 2026 23:04:12 +0200 Subject: [PATCH 1/2] Syncup source with cppyy repos --- src/CPyCppyy/src/CPPEnum.cxx | 14 ++++------ src/CPyCppyy/src/TemplateProxy.cxx | 2 +- src/backend/clingwrapper.cxx | 45 ++++++++++++++++++++++-------- test/test_datatypes.py | 6 ++-- test/test_stltypes.py | 26 +++++++++++++++-- 5 files changed, 66 insertions(+), 27 deletions(-) diff --git a/src/CPyCppyy/src/CPPEnum.cxx b/src/CPyCppyy/src/CPPEnum.cxx index a2598ef..3012442 100644 --- a/src/CPyCppyy/src/CPPEnum.cxx +++ b/src/CPyCppyy/src/CPPEnum.cxx @@ -24,10 +24,11 @@ PyObject* CPyCppyy::pyval_from_enum(const std::string& enum_type, PyObject* pyty PyObject* btype, Cppyy::TCppScope_t enum_constant) { long long llval = Cppyy::GetEnumDataValue(enum_constant); - if (enum_type == "bool") { + if (enum_type == "bool" && !(pytype && btype)) { + // no enum class to instantiate; the singletons can not carry attributes PyObject* result = (bool)llval ? Py_True : Py_False; Py_INCREF(result); - return result; // <- immediate return; + return result; } PyObject* bval; @@ -210,12 +211,9 @@ CPyCppyy::CPPEnum* CPyCppyy::CPPEnum_New(const std::string& name, Cppyy::TCppSco PyObject* pydname = CPyCppyy_PyText_FromString(dname.c_str()); PyObject_SetAttr(pyenum, pydname, val); Py_DECREF(pydname); - if (resolved != "bool") { - // bool is special cased enum look at pyval_from_enum - PyObject* pydcppname = CPyCppyy_PyText_FromString((ename.empty() ? dname : (ename+"::"+dname)).c_str()); - PyObject_SetAttr(val, PyStrings::gCppName, pydcppname); - Py_DECREF(pydcppname); - } + PyObject* pydcppname = CPyCppyy_PyText_FromString((ename.empty() ? dname : (ename+"::"+dname)).c_str()); + PyObject_SetAttr(val, PyStrings::gCppName, pydcppname); + Py_DECREF(pydcppname); Py_DECREF(val); } diff --git a/src/CPyCppyy/src/TemplateProxy.cxx b/src/CPyCppyy/src/TemplateProxy.cxx index 197d452..b42a1b0 100644 --- a/src/CPyCppyy/src/TemplateProxy.cxx +++ b/src/CPyCppyy/src/TemplateProxy.cxx @@ -106,7 +106,7 @@ PyObject* TemplateProxy::Instantiate(const std::string& fname, PyTuple_SET_ITEM(tpArgs, i, f); bArgSet = true; } - PyObject* pytc; + PyObject* pytc = nullptr; if (!bArgSet && (pytc = PyObject_GetAttr(itemi, PyStrings::gTypeCode))) { Py_buffer bufinfo; memset(&bufinfo, 0, sizeof(Py_buffer)); diff --git a/src/backend/clingwrapper.cxx b/src/backend/clingwrapper.cxx index 60ce104..ee2644e 100644 --- a/src/backend/clingwrapper.cxx +++ b/src/backend/clingwrapper.cxx @@ -52,7 +52,7 @@ static bool gEnableFastPath = true; // global initialization ----------------------------------------------------- namespace { -const int kMAXSIGNALS = 16; +//const int kMAXSIGNALS = 16; // names copied from TUnixSystem #ifdef WIN32 @@ -68,6 +68,7 @@ const int SIGUSR1 = 0; const int SIGUSR2 = 0; #endif +#if 0 static struct Signalmap_t { int fCode; const char *fSigName; @@ -89,6 +90,7 @@ static struct Signalmap_t { { SIGUSR1, "user-defined signal 1" }, { SIGUSR2, "user-defined signal 2" } }; +#endif static inline void push_tokens_from_string(char *s, std::vector &tokens) { @@ -705,6 +707,13 @@ Cppyy::TCppScope_t Cppyy::GetScope(const std::string& name, bool added_new_type = !Cppyy::AppendTypesSlow(name, types, /*parent=*/parent_scope); std::lock_guard Lock(InterOpMutex); if (added_new_type && types.size() == 1) { + // A pointer or reference spelling (e.g. "std::chrono::nanoseconds *", + // the return type of std::array::begin()) does not + // name a scope; GetScopeFromType would silently strip the pointer and + // return the pointee's scope, misclassifying the name. + if (Cpp::IsPointerType(types[0].m_Type) || + Cpp::IsReferenceType(types[0].m_Type)) + return nullptr; TCppScope_t scope = Cpp::GetScopeFromType(types[0].m_Type); // Naming the type as a template argument above does not instantiate // it, so the specialization may still be declared-but-undefined. @@ -899,7 +908,7 @@ static inline bool WrapperCall(Cppyy::TCppMethod_t method, size_t nargs, void* args_, void* self, void* result) { Parameter* args = (Parameter*)args_; - bool is_direct = nargs & DIRECT_CALL; + //bool is_direct = nargs & DIRECT_CALL; nargs = CALL_NARGS(nargs); // if (!is_ready(wrap, is_direct)) @@ -995,7 +1004,7 @@ char* Cppyy::CallS( } Cppyy::TCppObject_t Cppyy::CallConstructor( - TCppMethod_t method, TCppScope_t klass, size_t nargs, void* args) + TCppMethod_t method, TCppScope_t /*klass*/, size_t nargs, void* args) { void* obj = nullptr; WrapperCall(method, nargs, args, nullptr, &obj); @@ -1018,7 +1027,7 @@ Cppyy::TCppObject_t Cppyy::CallO(TCppMethod_t method, return TCppObject_t{}; } -Cppyy::TCppFuncAddr_t Cppyy::GetFunctionAddress(TCppMethod_t method, bool check_enabled) +Cppyy::TCppFuncAddr_t Cppyy::GetFunctionAddress(TCppMethod_t method, bool /*check_enabled*/) { std::lock_guard Lock(InterOpMutex); return Cpp::GetFunctionAddress(method); @@ -1310,7 +1319,7 @@ bool Cppyy::GetSmartPtrInfo( // type offsets -------------------------------------------------------------- ptrdiff_t Cppyy::GetBaseOffset(TCppScope_t derived, TCppScope_t base, - TCppObject_t address, int direction, bool rerror) + TCppObject_t /*address*/, int direction, bool rerror) { std::lock_guard Lock(InterOpMutex); intptr_t offset = Cpp::GetBaseClassOffset(derived, base); @@ -1414,7 +1423,7 @@ std::string Cppyy::GetMethodArgDefault(TCppMethod_t method, TCppIndex_t iarg) return Cpp::GetFunctionArgDefault(method, iarg); } -Cppyy::TCppIndex_t Cppyy::CompareMethodArgType(TCppMethod_t method, TCppIndex_t iarg, const std::string &req_type) +Cppyy::TCppIndex_t Cppyy::CompareMethodArgType(TCppMethod_t /*method*/, TCppIndex_t iarg, const std::string &req_type) { // if (method) { // TFunction* f = m2f(method); @@ -1519,7 +1528,7 @@ void Cppyy::GetTemplatedMethods(TCppScope_t scope, std::vector Lock(InterOpMutex); std::vector mc; @@ -1597,11 +1606,23 @@ Cppyy::TCppMethod_t Cppyy::GetMethodTemplate( cppmeth = Cpp::BestOverloadFunctionMatch( unresolved_candidate_methods, templ_params, arg_types); - if (!cppmeth && unresolved_candidate_methods.size() == 1 && - !templ_params.empty()) { - cppmeth = Cpp::InstantiateTemplate( - TCppScope_t(unresolved_candidate_methods[0].data), templ_params.data(), - templ_params.size(), /*instantiate_body=*/false).data; + // If overload resolution failed but explicit template arguments were + // supplied, fall back to direct template-argument substitution: ask Sema + // to instantiate each candidate with the explicit args. Sema's SFINAE + // rejects overloads whose substitution fails (e.g. the initializer_list + // form of std::make_any with non-init-list explicit args), so iterating + // gives back exactly the viable specialisation. The wrapper-side argument + // conversion then handles e.g. taking the address of an instance when the + // substituted parameter is a pointer. + if (!cppmeth && !templ_params.empty()) { + for (const auto& cand : unresolved_candidate_methods) { + if (Cpp::DeclRef spec = Cpp::InstantiateTemplate( + TCppScope_t(cand.data), templ_params.data(), + templ_params.size(), /*instantiate_body=*/false)) { + cppmeth = spec.data; + break; + } + } } return TCppMethod_t(cppmeth.data); diff --git a/test/test_datatypes.py b/test/test_datatypes.py index d6123c5..cc668eb 100644 --- a/test/test_datatypes.py +++ b/test/test_datatypes.py @@ -764,8 +764,9 @@ class Test { assert sc.vraioufaux.faux == False assert sc.vraioufaux.vrai == True - assert type(sc.vraioufaux.faux) == bool # no bool as base class - assert isinstance(sc.vraioufaux.faux, bool) + assert type(sc.vraioufaux.faux) == sc.vraioufaux + assert isinstance(sc.vraioufaux.faux, int) # no bool as base class + assert 'bool' in repr(sc.vraioufaux.faux) def test12_enum_scopes(self): """Enum accessibility and scopes""" @@ -2339,7 +2340,6 @@ def test50_int8_uint8_global_arrays(self): assert [ns.test[i] for i in range(6)] == [-0x12, -0x34, -0x56, -0x78, 0x0, 0x0] assert [ns.utest[i] for i in range(6)] == [ 0x12, 0x34, 0x56, 0x78, 0x0, 0x0] - @mark.xfail(reason="enum class : bool is broken, doesn't populate underlying _member_names_, for example") def test51_enum_integrity(self): import cppyy import enum diff --git a/test/test_stltypes.py b/test/test_stltypes.py index 33df170..8cfd5cf 100644 --- a/test/test_stltypes.py +++ b/test/test_stltypes.py @@ -1697,7 +1697,6 @@ def test04_array_from_aggregate(self): with raises(TypeError): cppyy.gbl.std.array["double",3](['a', 1.0, 1.0]) - @mark.xfail(reason="std::array iteration fails") def test05_array_of_chrono_types_should_be_iterable(self): import cppyy cppyy.cppdef(""" @@ -1706,9 +1705,7 @@ def test05_array_of_chrono_types_should_be_iterable(self): std::vector vtimes = {10ns, 500ns, 1us}; std::array atimes = {10ns, 500ns, 1us}; """) - # this works normally... assert sum([v.count() for v in cppyy.gbl.vtimes]) == 1510 - # ... but this doesn't, fails complaining about not being able to iterate assert sum([v.count() for v in cppyy.gbl.atimes]) == 1510 @@ -2288,3 +2285,26 @@ def test02_span_argument_conversions(self): # 6) const span behaves the same (already checked above, but explicit case) assert cppyy.gbl.sum_span_const["double"](np_arr) == expected + + +class TestSTLANY: + + def test01_make_any(self): + """ + Test that std::make_any can be used for class types. + """ + import cppyy + + cppyy.cppdef(""" + #include + + namespace STLANY { + + class MyClass{}; + + } // namespace STLANY + """) + + my_inst = cppyy.gbl.STLANY.MyClass() + + cppyy.gbl.std.make_any["STLANY::MyClass*", "STLANY::MyClass*"](my_inst) From 57c14f8a223af6e327be3b378124c35eb9238ec7 Mon Sep 17 00:00:00 2001 From: Aaron Jomy Date: Thu, 16 Jul 2026 23:04:12 +0200 Subject: [PATCH 2/2] [cmake] Bump CppInterOp pin to 3103be9 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e0e15e2..2c220d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ include(GNUInstallDirs) # Perhaps this should permanently be OFF and users can build their own CppInterOp if they want to run the tests? option(CPPJIT_ENABLE_CPPINTEROP_TESTS "enable CppInterOp tests" OFF) set(CPPINTEROP_GIT_REPOSITORY "https://github.com/compiler-research/CppInterOp.git" CACHE STRING "") -set(CPPINTEROP_GIT_TAG "91a0c1e47696e9f08771e38c3bd751c4103e96c1" CACHE STRING "") +set(CPPINTEROP_GIT_TAG "3103be92baa66a5e78e3a7c6207d83d4623ca956" CACHE STRING "") set(Python_FIND_VIRTUALENV ONLY) find_package(Python COMPONENTS Interpreter Development)