Skip to content

Commit c4367c6

Browse files
committed
Update CPyCppyy to use InterOp API
This updates converter creation, templateproxy, dispatcher, cppdatamember, cppinstance and cppenum to enable parts of the API that required modifications to work with CppInterOp
1 parent 5a65140 commit c4367c6

File tree

8 files changed

+31
-47
lines changed

8 files changed

+31
-47
lines changed

src/CPPDataMember.cxx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,6 @@ static PyObject* dm_get(CPPDataMember* dm, CPPInstance* pyobj, PyObject* /* kls
4848
}
4949
}
5050

51-
// non-initialized or public data accesses through class (e.g. by help())
52-
void* address = dm->GetAddress(pyobj);
53-
if (!address || (intptr_t)address == -1 /* Cling error */)
54-
return nullptr;
5551

5652
if (dm->fFlags & (kIsEnumPrep | kIsEnumType)) {
5753
if (dm->fFlags & kIsEnumPrep) {
@@ -92,7 +88,6 @@ static PyObject* dm_get(CPPDataMember* dm, CPPInstance* pyobj, PyObject* /* kls
9288
return pyval_from_enum(Cppyy::ResolveEnum(dm->fScope), nullptr, nullptr, dm->fScope);
9389
}
9490
}
95-
9691
// non-initialized or public data accesses through class (e.g. by help())
9792
void* address = dm->GetAddress(pyobj);
9893
if (!address || (intptr_t)address == -1 /* Cling error */)

src/CPPEnum.cxx

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ static PyObject* pytype_from_enum_type(const std::string& enum_type)
1919
}
2020

2121
//----------------------------------------------------------------------------
22-
static PyObject* pyval_from_enum(const std::string& enum_type, PyObject* pytype,
23-
PyObject* btype, Cppyy::TCppEnum_t etype, Cppyy::TCppIndex_t idata) {
24-
long long llval = Cppyy::GetEnumDataValue(etype, idata);
22+
PyObject* CPyCppyy::pyval_from_enum(const std::string& enum_type, PyObject* pytype,
23+
PyObject* btype, Cppyy::TCppScope_t enum_constant) {
24+
long long llval = Cppyy::GetEnumDataValue(enum_constant);
2525

2626
if (enum_type == "bool") {
2727
PyObject* result = (bool)llval ? Py_True : Py_False;
@@ -38,14 +38,15 @@ static PyObject* pyval_from_enum(const std::string& enum_type, PyObject* pytype,
3838
else
3939
bval = PyLong_FromLongLong(llval);
4040

41+
if (pytype && btype) {
4142
PyObject* args = PyTuple_New(1);
4243
PyTuple_SET_ITEM(args, 0, bval);
43-
PyObject* result = ((PyTypeObject*)btype)->tp_new((PyTypeObject*)pytype, args, nullptr);
44+
bval = ((PyTypeObject*)btype)->tp_new((PyTypeObject*)pytype, args, nullptr);
4445
Py_DECREF(args);
45-
return result;
46+
}
47+
return bval;
4648
}
4749

48-
4950
//- enum methods -------------------------------------------------------------
5051
static int enum_setattro(PyObject* /* pyclass */, PyObject* /* pyname */, PyObject* /* pyval */)
5152
{
@@ -59,6 +60,8 @@ static PyObject* enum_repr(PyObject* self)
5960
{
6061
using namespace CPyCppyy;
6162

63+
PyObject* kls_scope = PyObject_GetAttr((PyObject*)Py_TYPE(self), PyStrings::gThisModule);
64+
if (!kls_scope) PyErr_Clear();
6265
PyObject* kls_cppname = PyObject_GetAttr((PyObject*)Py_TYPE(self), PyStrings::gCppName);
6366
if (!kls_cppname) PyErr_Clear();
6467
PyObject* obj_cppname = PyObject_GetAttr(self, PyStrings::gCppName);
@@ -67,7 +70,7 @@ static PyObject* enum_repr(PyObject* self)
6770

6871
PyObject* repr = nullptr;
6972
if (kls_cppname && obj_cppname && obj_str) {
70-
const std::string resolved = Cppyy::ResolveEnum(CPyCppyy_PyText_AsString(kls_cppname));
73+
const std::string resolved = Cppyy::ResolveEnum(PyLong_AsVoidPtr(kls_scope));
7174
repr = CPyCppyy_PyText_FromFormat("(%s::%s) : (%s) %s",
7275
CPyCppyy_PyText_AsString(kls_cppname), CPyCppyy_PyText_AsString(obj_cppname),
7376
resolved.c_str(), CPyCppyy_PyText_AsString(obj_str));
@@ -137,12 +140,12 @@ CPyCppyy::CPPEnum* CPyCppyy::CPPEnum_New(const std::string& name, Cppyy::TCppSco
137140

138141
CPPEnum* pyenum = nullptr;
139142

140-
const std::string& ename = scope == Cppyy::gGlobalScope ? name : Cppyy::GetScopedFinalName(scope)+"::"+name;
141-
Cppyy::TCppEnum_t etype = Cppyy::GetEnum(scope, name);
143+
Cppyy::TCppScope_t etype = scope;
144+
const std::string& ename = Cppyy::GetScopedFinalName(scope);
142145
if (etype) {
143146
// create new enum type with labeled values in place, with a meta-class
144147
// to make sure the enum values are read-only
145-
const std::string& resolved = Cppyy::ResolveEnum(ename);
148+
const std::string& resolved = Cppyy::ResolveEnum(etype);
146149
PyObject* pyside_type = pytype_from_enum_type(resolved);
147150
PyObject* pymetabases = PyTuple_New(1);
148151
PyObject* btype = (PyObject*)Py_TYPE(pyside_type);
@@ -169,7 +172,7 @@ CPyCppyy::CPPEnum* CPyCppyy::CPPEnum_New(const std::string& name, Cppyy::TCppSco
169172
PyObject* pyresolved = CPyCppyy_PyText_FromString(resolved.c_str());
170173
PyDict_SetItem(dct, PyStrings::gUnderlying, pyresolved);
171174
Py_DECREF(pyresolved);
172-
175+
173176
// add the __module__ to allow pickling
174177
std::string modname = TypeManip::extract_namespace(ename);
175178
TypeManip::cppscope_to_pyscope(modname); // :: -> .
@@ -191,10 +194,10 @@ CPyCppyy::CPPEnum* CPyCppyy::CPPEnum_New(const std::string& name, Cppyy::TCppSco
191194
((PyTypeObject*)pyenum)->tp_str = ((PyTypeObject*)pyside_type)->tp_repr;
192195

193196
// collect the enum values
194-
Cppyy::TCppIndex_t ndata = Cppyy::GetNumEnumData(etype);
195-
for (Cppyy::TCppIndex_t idata = 0; idata < ndata; ++idata) {
196-
PyObject* val = pyval_from_enum(resolved, pyenum, pyside_type, etype, idata);
197-
PyObject* pydname = CPyCppyy_PyText_FromString(Cppyy::GetEnumDataName(etype, idata).c_str());
197+
std::vector<Cppyy::TCppScope_t> econstants = Cppyy::GetEnumConstants(etype);
198+
for (auto *econstant : econstants) {
199+
PyObject* val = pyval_from_enum(resolved, pyenum, pyside_type, econstant);
200+
PyObject* pydname = CPyCppyy_PyText_FromString(Cppyy::GetFinalName(econstant).c_str());
198201
PyObject_SetAttr(pyenum, pydname, val);
199202
PyObject_SetAttr(val, PyStrings::gCppName, pydname);
200203
Py_DECREF(pydname);
@@ -215,4 +218,4 @@ CPyCppyy::CPPEnum* CPyCppyy::CPPEnum_New(const std::string& name, Cppyy::TCppSco
215218
}
216219

217220
return pyenum;
218-
}
221+
}

src/CPPInstance.cxx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -358,10 +358,6 @@ static PyObject* op_item(CPPInstance* self, Py_ssize_t idx)
358358
return nullptr;
359359
}
360360

361-
Py_ssize_t idx = PyInt_AsSsize_t(pyidx);
362-
if (idx == (Py_ssize_t)-1 && PyErr_Occurred())
363-
return nullptr;
364-
365361
if (idx < 0) {
366362
// this is debatable, and probably should not care, but the use case is pretty
367363
// circumscribed anyway, so might as well keep the functionality simple
@@ -413,8 +409,6 @@ static PyMethodDef op_methods[] = {
413409
(char*)"dispatch to selected overload"},
414410
{(char*)"__smartptr__", (PyCFunction)op_get_smartptr, METH_NOARGS,
415411
(char*)"get associated smart pointer, if any"},
416-
{(char*)"__getitem__", (PyCFunction)op_getitem, METH_O,
417-
(char*)"pointer dereferencing"},
418412
{(char*)"__reshape__", (PyCFunction)op_reshape, METH_O,
419413
(char*)"cast pointer to 1D array type"},
420414
{(char*)nullptr, nullptr, 0, nullptr}

src/Converters.cxx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3373,8 +3373,7 @@ CPyCppyy::Converter* CPyCppyy::CreateConverter(Cppyy::TCppType_t type, cdims_t d
33733373
} else
33743374
cnv = CreateConverter(value_type);
33753375
if (cnv || use_byte_cnv)
3376-
return new InitializerListConverter(Cppyy::GetScopeFromType(realType),
3377-
CreateConverter(value_type), cnv, Cppyy::SizeOf(value_type));
3376+
return new InitializerListConverter(Cppyy::GetScopeFromType(realType), value_type);
33783377
}
33793378

33803379
//-- still nothing? use a generalized converter

src/Dispatcher.cxx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,11 @@ namespace {
146146
using namespace Cppyy;
147147

148148
static inline
149-
std::vector<TCppIndex_t> FindBaseMethod(TCppScope_t tbase, const std::string mtCppName)
149+
std::vector<TCppMethod_t> FindBaseMethod(TCppScope_t tbase, const std::string mtCppName)
150150
{
151151
// Recursively walk the inheritance tree to find the overloads of the named method
152-
std::vector<TCppIndex_t> result;
153-
result = GetMethodIndicesFromName(tbase, mtCppName);
152+
std::vector<TCppMethod_t> result;
153+
result = GetMethodsFromName(tbase, mtCppName);
154154
if (result.empty()) {
155155
for (TCppIndex_t ibase = 0; ibase < GetNumBases(tbase); ++ibase) {
156156
TCppScope_t b = GetScope(GetBaseName(tbase, ibase));
@@ -366,10 +366,10 @@ bool CPyCppyy::InsertDispatcher(CPPScope* klass, PyObject* bases, PyObject* dct,
366366
// TODO: should probably invert this looping; but that makes handling overloads clunky
367367
PyObject* key = PyList_GET_ITEM(keys, i);
368368
std::string mtCppName = CPyCppyy_PyText_AsString(key);
369-
const auto& v = FindBaseMethod(tbase, mtCppName);
370-
for (auto idx : v)
371-
InjectMethod(Cppyy::GetMethod(tbase, idx), mtCppName, code);
372-
if (!v.empty()) {
369+
const auto& methods = FindBaseMethod(tbase, mtCppName);
370+
for (auto method : methods)
371+
InjectMethod(method, mtCppName, code);
372+
if (!methods.empty()) {
373373
if (PyDict_DelItem(clbs, key) != 0) PyErr_Clear();
374374
}
375375
}

src/Executors.cxx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -809,10 +809,8 @@ CPyCppyy::Executor* CPyCppyy::CreateExecutor(const std::string& fullType, cdims_
809809
//
810810
// If all fails, void is used, which will cause the return type to be ignored on use
811811

812-
// FIXME:
813-
//assert(!fullType.empty() && "This routine assumes non-empty fullType");
814-
if (fullType.empty())
815-
return nullptr;
812+
if (fullType.empty())
813+
return nullptr;
816814

817815
// an exactly matching executor is best
818816
ExecFactories_t::iterator h = gExecFactories.find(fullType);

src/Pythonize.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,9 +568,9 @@ static PyObject* vector_iter(PyObject* v) {
568568
if (!vi->vi_klass) {
569569
// look for a special case of pointer to a class type (which is a builtin, but it
570570
// is more useful to treat it polymorphically by allowing auto-downcasts)
571-
const std::string& clean_type = TypeManip::clean_type(value_type, false, false);
571+
const std::string& clean_type = TypeManip::clean_type(Cppyy::GetTypeAsString(value_type), false, false);
572572
Cppyy::TCppScope_t c = Cppyy::GetScope(clean_type);
573-
if (c && TypeManip::compound(value_type) == "*") {
573+
if (c && TypeManip::compound(Cppyy::GetTypeAsString(value_type)) == "*") {
574574
vi->vi_klass = c;
575575
vi->vi_flags = vectoriterobject::kIsPolymorphic;
576576
}

src/TemplateProxy.cxx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -856,11 +856,6 @@ static PyObject* tpp_overload(TemplateProxy* pytmpl, PyObject* args)
856856
PyObject* pytype = 0, *pyvalue = 0, *pytrace = 0;
857857
PyErr_Fetch(&pytype, &pyvalue, &pytrace);
858858

859-
std::string proto = Utility::ConstructTemplateArgs(nullptr, args);
860-
Cppyy::TCppScope_t scope = ((CPPClass*)pytmpl->fTI->fPyClass)->fCppType;
861-
Cppyy::TCppMethod_t cppmeth = Cppyy::GetMethodTemplate(
862-
scope, pytmpl->fTI->fCppName, proto.substr(1, proto.size()-2));
863-
864859
if (!cppmeth) {
865860
PyErr_Restore(pytype, pyvalue, pytrace);
866861
return nullptr;

0 commit comments

Comments
 (0)