Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
14 changes: 6 additions & 8 deletions src/CPyCppyy/src/CPPEnum.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion src/CPyCppyy/src/TemplateProxy.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
45 changes: 33 additions & 12 deletions src/backend/clingwrapper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -68,6 +68,7 @@ const int SIGUSR1 = 0;
const int SIGUSR2 = 0;
#endif

#if 0
static struct Signalmap_t {
int fCode;
const char *fSigName;
Expand All @@ -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 <const char*> &tokens) {
Expand Down Expand Up @@ -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<std::recursive_mutex> 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<nanoseconds, N>::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.
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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);
Expand All @@ -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<std::recursive_mutex> Lock(InterOpMutex);
return Cpp::GetFunctionAddress(method);
Expand Down Expand Up @@ -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<std::recursive_mutex> Lock(InterOpMutex);
intptr_t offset = Cpp::GetBaseClassOffset(derived, base);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1519,7 +1528,7 @@ void Cppyy::GetTemplatedMethods(TCppScope_t scope, std::vector<Cppyy::TCppMethod
Cpp::GetFunctionTemplatedDecls(scope, methods);
}

Cppyy::TCppIndex_t Cppyy::GetNumTemplatedMethods(TCppScope_t scope, bool accept_namespace)
Cppyy::TCppIndex_t Cppyy::GetNumTemplatedMethods(TCppScope_t scope, bool /*accept_namespace*/)
{
std::lock_guard<std::recursive_mutex> Lock(InterOpMutex);
std::vector<Cppyy::TCppMethod_t> mc;
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions test/test_datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"""
Expand Down Expand Up @@ -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
Expand Down
26 changes: 23 additions & 3 deletions test/test_stltypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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<nanoseconds> iteration fails")
def test05_array_of_chrono_types_should_be_iterable(self):
import cppyy
cppyy.cppdef("""
Expand All @@ -1706,9 +1705,7 @@ def test05_array_of_chrono_types_should_be_iterable(self):
std::vector<std::chrono::nanoseconds> vtimes = {10ns, 500ns, 1us};
std::array<std::chrono::nanoseconds, 3> 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


Expand Down Expand Up @@ -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 <any>

namespace STLANY {

class MyClass{};

} // namespace STLANY
""")

my_inst = cppyy.gbl.STLANY.MyClass()

cppyy.gbl.std.make_any["STLANY::MyClass*", "STLANY::MyClass*"](my_inst)
Loading