@@ -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+ */
373394PyObject* 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// ----------------------------------------------------------------------------
661722bool CPyCppyy::CPPMethod::Initialize (CallContext* ctxt)
0 commit comments