Skip to content

Commit 93b0984

Browse files
committed
Sync TemplateProxy
1 parent edf404a commit 93b0984

File tree

1 file changed

+70
-17
lines changed

1 file changed

+70
-17
lines changed

src/TemplateProxy.cxx

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ static inline PyObject* SelectAndForward(TemplateProxy* pytmpl, CPPOverload* pym
493493
static inline PyObject* CallMethodImp(TemplateProxy* pytmpl, PyObject*& pymeth,
494494
CPyCppyy_PyArgs_t args, size_t nargsf, PyObject* kwds, bool impOK, uint64_t sighash)
495495
{
496-
// Actual call of a given overload: takes care of handling of "self" and
496+
// Actual call of a given overload: takes care of handlign of "self" and
497497
// dereferences the overloaded method after use.
498498

499499
PyObject* result;
@@ -654,13 +654,13 @@ static PyObject* tpp_call(TemplateProxy* pytmpl, PyObject* args, PyObject* kwds)
654654
result = SelectAndForward(pytmpl, pytmpl->fTI->fNonTemplated, args, nargsf, kwds,
655655
true /* implicitOkay */, false /* use_targs */, sighash, errors);
656656
if (result)
657-
return result;
657+
TPPCALL_RETURN;
658658

659659
// case 3: select known template overload
660660
result = SelectAndForward(pytmpl, pytmpl->fTI->fTemplated, args, nargsf, kwds,
661661
false /* implicitOkay */, true /* use_targs */, sighash, errors);
662662
if (result)
663-
return result;
663+
TPPCALL_RETURN;
664664

665665
// case 4: auto-instantiation from types of arguments
666666
for (auto pref : {Utility::kReference, Utility::kPointer, Utility::kValue}) {
@@ -681,7 +681,7 @@ static PyObject* tpp_call(TemplateProxy* pytmpl, PyObject* args, PyObject* kwds)
681681
result = SelectAndForward(pytmpl, pytmpl->fTI->fLowPriority, args, nargsf, kwds,
682682
false /* implicitOkay */, false /* use_targs */, sighash, errors);
683683
if (result)
684-
return result;
684+
TPPCALL_RETURN;
685685

686686
// error reporting is fraud, given the numerous steps taken, but more details seems better
687687
if (!errors.empty()) {
@@ -790,20 +790,67 @@ static PyObject* tpp_overload(TemplateProxy* pytmpl, PyObject* args)
790790
{
791791
// Select and call a specific C++ overload, based on its signature.
792792
const char* sigarg = nullptr;
793+
PyObject* sigarg_tuple = nullptr;
793794
int want_const = -1;
794-
if (!PyArg_ParseTuple(args, const_cast<char*>("s|i:__overload__"), &sigarg, &want_const))
795+
796+
Cppyy::TCppScope_t scope = (Cppyy::TCppScope_t) 0;
797+
Cppyy::TCppMethod_t cppmeth = (Cppyy::TCppMethod_t) 0;
798+
std::string proto;
799+
800+
if (PyArg_ParseTuple(args, const_cast<char*>("s|i:__overload__"), &sigarg, &want_const)) {
801+
want_const = PyTuple_GET_SIZE(args) == 1 ? -1 : want_const;
802+
803+
// check existing overloads in order
804+
PyObject* ol = pytmpl->fTI->fNonTemplated->FindOverload(sigarg, want_const);
805+
if (ol) return ol;
806+
PyErr_Clear();
807+
ol = pytmpl->fTI->fTemplated->FindOverload(sigarg, want_const);
808+
if (ol) return ol;
809+
PyErr_Clear();
810+
ol = pytmpl->fTI->fLowPriority->FindOverload(sigarg, want_const);
811+
if (ol) return ol;
812+
813+
proto = Utility::ConstructTemplateArgs(nullptr, args);
814+
815+
scope = ((CPPClass*)pytmpl->fTI->fPyClass)->fCppType;
816+
cppmeth = Cppyy::GetMethodTemplate(
817+
scope, pytmpl->fTI->fCppName, proto.substr(1, proto.size()-2));
818+
} else if (PyArg_ParseTuple(args, const_cast<char*>("O|i:__overload__"), &sigarg_tuple, &want_const)) {
819+
PyErr_Clear();
820+
want_const = PyTuple_GET_SIZE(args) == 1 ? -1 : want_const;
821+
822+
// check existing overloads in order
823+
PyObject* ol = pytmpl->fTI->fNonTemplated->FindOverload(sigarg_tuple, want_const);
824+
if (ol) return ol;
825+
PyErr_Clear();
826+
ol = pytmpl->fTI->fTemplated->FindOverload(sigarg_tuple, want_const);
827+
if (ol) return ol;
828+
PyErr_Clear();
829+
ol = pytmpl->fTI->fLowPriority->FindOverload(sigarg_tuple, want_const);
830+
if (ol) return ol;
831+
832+
proto.reserve(128);
833+
proto.push_back('<');
834+
Py_ssize_t n = PyTuple_Size(sigarg_tuple);
835+
for (int i = 0; i < n; i++) {
836+
PyObject *pItem = PyTuple_GetItem(sigarg_tuple, i);
837+
if(!CPyCppyy_PyText_Check(pItem)) {
838+
PyErr_Format(PyExc_LookupError, "argument types should be in string format");
839+
return (PyObject*) nullptr;
840+
}
841+
proto.append(CPyCppyy_PyText_AsString(pItem));
842+
if (i < n - 1)
843+
proto.push_back(',');
844+
}
845+
proto.push_back('>');
846+
847+
scope = ((CPPClass*)pytmpl->fTI->fPyClass)->fCppType;
848+
cppmeth = Cppyy::GetMethodTemplate(
849+
scope, pytmpl->fTI->fCppName, proto.substr(1, proto.size()-2));
850+
} else {
851+
PyErr_Format(PyExc_TypeError, "Unexpected arguments to __overload__");
795852
return nullptr;
796-
want_const = PyTuple_GET_SIZE(args) == 1 ? -1 : want_const;
797-
798-
// check existing overloads in order
799-
PyObject* ol = pytmpl->fTI->fNonTemplated->FindOverload(sigarg, want_const);
800-
if (ol) return ol;
801-
PyErr_Clear();
802-
ol = pytmpl->fTI->fTemplated->FindOverload(sigarg, want_const);
803-
if (ol) return ol;
804-
PyErr_Clear();
805-
ol = pytmpl->fTI->fLowPriority->FindOverload(sigarg, want_const);
806-
if (ol) return ol;
853+
}
807854

808855
// else attempt instantiation
809856
PyObject* pytype = 0, *pyvalue = 0, *pytrace = 0;
@@ -877,7 +924,7 @@ PyTypeObject TemplateProxy_Type = {
877924
#if PY_VERSION_HEX >= 0x03080000
878925
| Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_METHOD_DESCRIPTOR
879926
#endif
880-
, // tp_flags
927+
, // tp_flags
881928
(char*)"cppyy template proxy (internal)", // tp_doc
882929
(traverseproc)tpp_traverse, // tp_traverse
883930
(inquiry)tpp_clear, // tp_clear
@@ -912,6 +959,12 @@ PyTypeObject TemplateProxy_Type = {
912959
#if PY_VERSION_HEX >= 0x03040000
913960
, 0 // tp_finalize
914961
#endif
962+
#if PY_VERSION_HEX >= 0x03080000
963+
, 0 // tp_vectorcall
964+
#endif
965+
#if PY_VERSION_HEX >= 0x030c0000
966+
, 0 // tp_watched
967+
#endif
915968
};
916969

917970
} // namespace CPyCppyy

0 commit comments

Comments
 (0)