@@ -62,6 +62,8 @@ class TPythonCallback : public PyCallable {
6262 PyObject* GetSignature (bool /* show_formalargs*/ = true ) override {
6363 return CPyCppyy_PyText_FromString (" *args, **kwargs" );
6464 }
65+ PyObject *GetSignatureNames () override { return PyTuple_New (0 ); }
66+ PyObject *GetSignatureTypes () override { return PyTuple_New (0 ); }
6567 PyObject* GetPrototype (bool /* show_formalargs*/ = true ) override {
6668 return CPyCppyy_PyText_FromString (" <callback>" );
6769 }
@@ -285,6 +287,54 @@ static int mp_doc_set(CPPOverload* pymeth, PyObject *val, void *)
285287 return 0 ;
286288}
287289
290+ /* *
291+ * @brief Returns a dictionary with the input parameter names for all overloads.
292+ *
293+ * This dictionary may look like:
294+ *
295+ * {'double ::foo(int a, float b, double c)': ('a', 'b', 'c'),
296+ * 'float ::foo(float b)': ('b',),
297+ * 'int ::foo(int a)': ('a',),
298+ * 'int ::foo(int a, float b)': ('a', 'b')}
299+ */
300+ static PyObject *mp_func_overloads_names (CPPOverload *pymeth)
301+ {
302+
303+ const CPPOverload::Methods_t &methods = pymeth->fMethodInfo ->fMethods ;
304+
305+ PyObject *overloads_names_dict = PyDict_New ();
306+
307+ for (PyCallable *method : methods) {
308+ PyDict_SetItem (overloads_names_dict, method->GetPrototype (), method->GetSignatureNames ());
309+ }
310+
311+ return overloads_names_dict;
312+ }
313+
314+ /* *
315+ * @brief Returns a dictionary with the types of all overloads.
316+ *
317+ * This dictionary may look like:
318+ *
319+ * {'double ::foo(int a, float b, double c)': {'input_types': ('int', 'float', 'double'), 'return_type': 'double'},
320+ * 'float ::foo(float b)': {'input_types': ('float',), 'return_type': 'float'},
321+ * 'int ::foo(int a)': {'input_types': ('int',), 'return_type': 'int'},
322+ * 'int ::foo(int a, float b)': {'input_types': ('int', 'float'), 'return_type': 'int'}}
323+ */
324+ static PyObject *mp_func_overloads_types (CPPOverload *pymeth)
325+ {
326+
327+ const CPPOverload::Methods_t &methods = pymeth->fMethodInfo ->fMethods ;
328+
329+ PyObject *overloads_types_dict = PyDict_New ();
330+
331+ for (PyCallable *method : methods) {
332+ PyDict_SetItem (overloads_types_dict, method->GetPrototype (), method->GetSignatureTypes ());
333+ }
334+
335+ return overloads_types_dict;
336+ }
337+
288338// ----------------------------------------------------------------------------
289339static PyObject* mp_meth_func (CPPOverload* pymeth, void *)
290340{
@@ -565,44 +615,43 @@ static PyObject* mp_getcppname(CPPOverload* pymeth, void*)
565615
566616// ----------------------------------------------------------------------------
567617static PyGetSetDef mp_getset[] = {
568- {(char *)" __name__" , (getter)mp_name, nullptr , nullptr , nullptr },
569- {(char *)" __module__" , (getter)mp_module, nullptr , nullptr , nullptr },
570- {(char *)" __doc__" , (getter)mp_doc, (setter)mp_doc_set, nullptr , nullptr },
571-
572- // to be more python-like, where these are duplicated as well; to actually
573- // derive from the python method or function type is too memory-expensive,
574- // given that most of the members of those types would not be used
575- {(char *)" im_func" , (getter)mp_meth_func, nullptr , nullptr , nullptr },
576- {(char *)" im_self" , (getter)mp_meth_self, nullptr , nullptr , nullptr },
577- {(char *)" im_class" , (getter)mp_meth_class, nullptr , nullptr , nullptr },
578-
579- {(char *)" func_closure" , (getter)mp_func_closure, nullptr , nullptr , nullptr },
580- {(char *)" func_code" , (getter)mp_func_code, nullptr , nullptr , nullptr },
581- {(char *)" func_defaults" , (getter)mp_func_defaults, nullptr , nullptr , nullptr },
582- {(char *)" func_globals" , (getter)mp_func_globals, nullptr , nullptr , nullptr },
583- {(char *)" func_doc" , (getter)mp_doc, (setter)mp_doc_set, nullptr , nullptr },
584- {(char *)" func_name" , (getter)mp_name, nullptr , nullptr , nullptr },
585-
586-
587- // flags to control behavior
588- {(char *)" __creates__" , (getter)mp_getcreates, (setter)mp_setcreates,
589- (char *)" For ownership rules of result: if true, objects are python-owned" , nullptr },
590- {(char *)" __mempolicy__" , (getter)mp_getmempolicy, (setter)mp_setmempolicy,
591- (char *)" For argument ownership rules: like global, either heuristic or strict" , nullptr },
592- {(char *)" __set_lifeline__" , (getter)mp_getlifeline, (setter)mp_setlifeline,
593- (char *)" If true, set a lifeline from the return value onto self" , nullptr },
594- {(char *)" __release_gil__" , (getter)mp_getthreaded, (setter)mp_setthreaded,
595- (char *)" If true, releases GIL on call into C++" , nullptr },
596- {(char *)" __useffi__" , (getter)mp_getuseffi, (setter)mp_setuseffi,
597- (char *)" not implemented" , nullptr },
598- {(char *)" __sig2exc__" , (getter)mp_getsig2exc, (setter)mp_setsig2exc,
599- (char *)" If true, turn signals into Python exceptions" , nullptr },
600-
601- // basic reflection information
602- {(char *)" __cpp_name__" , (getter)mp_getcppname, nullptr , nullptr , nullptr },
603-
604- {(char *)nullptr , nullptr , nullptr , nullptr , nullptr }
605- };
618+ {(char *)" __name__" , (getter)mp_name, nullptr , nullptr , nullptr },
619+ {(char *)" __module__" , (getter)mp_module, nullptr , nullptr , nullptr },
620+ {(char *)" __doc__" , (getter)mp_doc, (setter)mp_doc_set, nullptr , nullptr },
621+
622+ // to be more python-like, where these are duplicated as well; to actually
623+ // derive from the python method or function type is too memory-expensive,
624+ // given that most of the members of those types would not be used
625+ {(char *)" im_func" , (getter)mp_meth_func, nullptr , nullptr , nullptr },
626+ {(char *)" im_self" , (getter)mp_meth_self, nullptr , nullptr , nullptr },
627+ {(char *)" im_class" , (getter)mp_meth_class, nullptr , nullptr , nullptr },
628+
629+ {(char *)" func_closure" , (getter)mp_func_closure, nullptr , nullptr , nullptr },
630+ {(char *)" func_code" , (getter)mp_func_code, nullptr , nullptr , nullptr },
631+ {(char *)" func_defaults" , (getter)mp_func_defaults, nullptr , nullptr , nullptr },
632+ {(char *)" func_globals" , (getter)mp_func_globals, nullptr , nullptr , nullptr },
633+ {(char *)" func_doc" , (getter)mp_doc, (setter)mp_doc_set, nullptr , nullptr },
634+ {(char *)" func_name" , (getter)mp_name, nullptr , nullptr , nullptr },
635+ {(char *)" func_overloads_types" , (getter)mp_func_overloads_types, nullptr , nullptr , nullptr },
636+ {(char *)" func_overloads_names" , (getter)mp_func_overloads_names, nullptr , nullptr , nullptr },
637+
638+ // flags to control behavior
639+ {(char *)" __creates__" , (getter)mp_getcreates, (setter)mp_setcreates,
640+ (char *)" For ownership rules of result: if true, objects are python-owned" , nullptr },
641+ {(char *)" __mempolicy__" , (getter)mp_getmempolicy, (setter)mp_setmempolicy,
642+ (char *)" For argument ownership rules: like global, either heuristic or strict" , nullptr },
643+ {(char *)" __set_lifeline__" , (getter)mp_getlifeline, (setter)mp_setlifeline,
644+ (char *)" If true, set a lifeline from the return value onto self" , nullptr },
645+ {(char *)" __release_gil__" , (getter)mp_getthreaded, (setter)mp_setthreaded,
646+ (char *)" If true, releases GIL on call into C++" , nullptr },
647+ {(char *)" __useffi__" , (getter)mp_getuseffi, (setter)mp_setuseffi, (char *)" not implemented" , nullptr },
648+ {(char *)" __sig2exc__" , (getter)mp_getsig2exc, (setter)mp_setsig2exc,
649+ (char *)" If true, turn signals into Python exceptions" , nullptr },
650+
651+ // basic reflection information
652+ {(char *)" __cpp_name__" , (getter)mp_getcppname, nullptr , nullptr , nullptr },
653+
654+ {(char *)nullptr , nullptr , nullptr , nullptr , nullptr }};
606655
607656// = CPyCppyy method proxy function behavior ==================================
608657#if PY_VERSION_HEX >= 0x03080000
@@ -1250,4 +1299,4 @@ CPyCppyy::CPPOverload::MethodInfo_t::~MethodInfo_t()
12501299 Py_XDECREF (fDoc );
12511300}
12521301
1253- // TODO: something like PyMethod_Fini to clear up the free_list
1302+ // TODO: something like PyMethod_Fini to clear up the free_list
0 commit comments