Skip to content

Commit cdda6f2

Browse files
committed
Sync CPPMethod
1 parent 2fe00d1 commit cdda6f2

File tree

2 files changed

+66
-3
lines changed

2 files changed

+66
-3
lines changed

src/CPPMethod.cxx

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,40 @@ CPyCppyy::CPPMethod::~CPPMethod()
370370

371371

372372
//- public members -----------------------------------------------------------
373+
/**
374+
* @brief Construct a Python string from the method's prototype
375+
*
376+
* @param fa Show formal arguments of the method
377+
* @return PyObject* A Python string with the full method prototype, namespaces included.
378+
*
379+
* For example, given:
380+
*
381+
* int foo(int x);
382+
*
383+
* namespace a {
384+
* namespace b {
385+
* namespace c {
386+
* int foo(int x);
387+
* }}}
388+
*
389+
* This function returns:
390+
*
391+
* 'int foo(int x)'
392+
* 'int a::b::c::foo(int x)'
393+
*/
373394
PyObject* CPyCppyy::CPPMethod::GetPrototype(bool fa)
374395
{
375-
// construct python string from the method's prototype
376-
return CPyCppyy_PyText_FromFormat("%s%s %s%s",
396+
// Gather the fully qualified final scope of the method. This includes
397+
// all namespaces up to the one where the method is declared, for example:
398+
// namespace a { namespace b { void foo(); }}
399+
// gives
400+
// a::b
401+
std::string finalscope = Cppyy::GetScopedFinalName(fScope);
402+
return CPyCppyy_PyText_FromFormat("%s%s %s%s%s%s",
377403
(Cppyy::IsStaticMethod(fMethod) ? "static " : ""),
378404
Cppyy::GetMethodReturnTypeAsString(fMethod).c_str(),
405+
finalscope.c_str(),
406+
(finalscope.empty() ? "" : "::"), // Add final set of '::' if the method is scoped in namespace(s)
379407
Cppyy::GetScopedFinalName(fMethod).c_str(),
380408
GetSignatureString(fa).c_str());
381409
}
@@ -488,7 +516,7 @@ int CPyCppyy::CPPMethod::GetPriority()
488516
const std::string& clean_name = TypeManip::clean_type(aname, false);
489517
Cppyy::TCppScope_t scope = Cppyy::GetScope(clean_name);
490518
if (scope)
491-
priority += (int)Cppyy::GetNumBases(scope);
519+
priority += static_cast<int>(Cppyy::GetNumBasesLongestBranch(scope));
492520

493521
if (Cppyy::IsEnumScope(scope))
494522
priority -= 100;
@@ -656,6 +684,39 @@ Cppyy::TCppFuncAddr_t CPyCppyy::CPPMethod::GetFunctionAddress()
656684
return Cppyy::GetFunctionAddress(fMethod, false /* don't check fast path envar */);
657685
}
658686

687+
//----------------------------------------------------------------------------
688+
int CPyCppyy::CPPMethod::GetArgMatchScore(PyObject* args_tuple)
689+
{
690+
Py_ssize_t n = PyTuple_Size(args_tuple);
691+
692+
int req_args = Cppyy::GetMethodReqArgs(fMethod);
693+
694+
// Not enough arguments supplied: no match
695+
if (req_args > n)
696+
return INT_MAX;
697+
698+
size_t score = 0;
699+
for (int i = 0; i < n; i++) {
700+
PyObject *pItem = PyTuple_GetItem(args_tuple, i);
701+
if(!CPyCppyy_PyText_Check(pItem)) {
702+
PyErr_SetString(PyExc_TypeError, "argument types should be in string format");
703+
return INT_MAX;
704+
}
705+
std::string req_type(CPyCppyy_PyText_AsString(pItem));
706+
707+
size_t arg_score = Cppyy::CompareMethodArgType(fMethod, i, req_type);
708+
709+
// Method is not compatible if even one argument does not match
710+
if (arg_score >= 10) {
711+
score = INT_MAX;
712+
break;
713+
}
714+
715+
score += arg_score;
716+
}
717+
718+
return score;
719+
}
659720

660721
//----------------------------------------------------------------------------
661722
bool CPyCppyy::CPPMethod::Initialize(CallContext* ctxt)

src/CPPMethod.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ class CPPMethod : public PyCallable {
6969

7070
virtual PyCallable* Clone() { return new CPPMethod(*this); }
7171

72+
virtual int GetArgMatchScore(PyObject* args_tuple);
73+
7274
public:
7375
virtual PyObject* Call(CPPInstance*& self,
7476
CPyCppyy_PyArgs_t args, size_t nargsf, PyObject* kwds, CallContext* ctxt = nullptr);

0 commit comments

Comments
 (0)