@@ -240,7 +240,7 @@ type_id py_loader_impl_capi_to_value_type(PyObject * obj)
240240 {
241241 return TYPE_PTR ;
242242 }
243- else if (PyFunction_Check (obj ))
243+ else if (PyFunction_Check (obj ) || PyCFunction_Check ( obj ) )
244244 {
245245 return TYPE_FUNCTION ;
246246 }
@@ -304,7 +304,7 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject * obj, type_id id)
304304 {
305305 if (PyErr_Occurred () != NULL )
306306 {
307- loader_impl_py py_impl = loader_impl_get (py_func -> impl );
307+ loader_impl_py py_impl = loader_impl_get (impl );
308308
309309 py_loader_impl_error_print (py_impl );
310310 }
@@ -401,7 +401,7 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject * obj, type_id id)
401401 {
402402 if (PyErr_Occurred () != NULL )
403403 {
404- loader_impl_py py_impl = loader_impl_get (py_func -> impl );
404+ loader_impl_py py_impl = loader_impl_get (impl );
405405
406406 py_loader_impl_error_print (py_impl );
407407 }
@@ -448,7 +448,21 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject * obj, type_id id)
448448 }
449449 else if (id == TYPE_FUNCTION )
450450 {
451- int discover_args_count = py_loader_impl_discover_func_args_count (obj );
451+ int discover_args_count ;
452+
453+ /* Check if we are passing our own hook to the callback */
454+ if (PyCFunction_Check (obj ) && PyCFunction_GET_FUNCTION (obj ) == py_loader_impl_function_type_invoke )
455+ {
456+ loader_impl_py py_impl = loader_impl_get (impl );
457+
458+ loader_impl_py_function_type_invoke_state invoke_state ;
459+
460+ invoke_state = (loader_impl_py_function_type_invoke_state )PyModule_GetState (py_impl -> function_type_invoke_mod );
461+
462+ return value_create_function (invoke_state -> callback );
463+ }
464+
465+ discover_args_count = py_loader_impl_discover_func_args_count (obj );
452466
453467 if (discover_args_count >= 0 )
454468 {
@@ -483,8 +497,6 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject * obj, type_id id)
483497
484498 return value_create_function (f );
485499 }
486-
487- return NULL ;
488500 }
489501 else if (id == TYPE_NULL )
490502 {
@@ -493,7 +505,7 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject * obj, type_id id)
493505 }
494506 else
495507 {
496- log_write ("metacall" , LOG_LEVEL_ERROR , "Unrecognized return type" );
508+ log_write ("metacall" , LOG_LEVEL_ERROR , "Unrecognized python type" );
497509 }
498510
499511 return v ;
@@ -611,6 +623,10 @@ PyObject * py_loader_impl_value_to_capi(loader_impl impl, loader_impl_py py_impl
611623
612624 return py_impl -> function_type_invoke_func ;
613625 }
626+ else
627+ {
628+ log_write ("metacall" , LOG_LEVEL_ERROR , "Unrecognized value type" );
629+ }
614630
615631 return NULL ;
616632}
@@ -793,7 +809,7 @@ static PyObject * py_loader_impl_function_type_invoke(PyObject * self, PyObject
793809
794810 if (args_size != (size_t )callee_args_size )
795811 {
796- log_write ("metacall" , LOG_LEVEL_WARNING , "Callback being executed without different number of arguments %u != %u" , args_size , callee_args_size );
812+ log_write ("metacall" , LOG_LEVEL_WARNING , "Callback being executed without different number of arguments %u (signature) != %u (call) " , args_size , callee_args_size );
797813 }
798814
799815 value_args = min_args_size == 0 ? null_args : malloc (sizeof (void * ) * min_args_size );
@@ -1398,21 +1414,23 @@ type py_loader_impl_discover_type(loader_impl impl, PyObject * annotation)
13981414{
13991415 type t = NULL ;
14001416
1401- PyObject * annotation_qualname = PyObject_GetAttrString (annotation , "__qualname__" );
1417+ if (annotation != NULL )
1418+ {
1419+ PyObject * annotation_qualname = PyObject_GetAttrString (annotation , "__qualname__" );
14021420
1403- const char * annotation_name = PyUnicode_AsUTF8 (annotation_qualname );
1421+ const char * annotation_name = PyUnicode_AsUTF8 (annotation_qualname );
14041422
1405- if (strcmp (annotation_name , "_empty" ) != 0 )
1406- {
1407- t = loader_impl_type (impl , annotation_name );
1423+ if (strcmp (annotation_name , "_empty" ) != 0 )
1424+ {
1425+ t = loader_impl_type (impl , annotation_name );
14081426
1409- log_write ("metacall" , LOG_LEVEL_DEBUG , "Discover type (%p) (%p): %s" , (void * )annotation , (void * )type_derived (t ), annotation_name );
1427+ log_write ("metacall" , LOG_LEVEL_DEBUG , "Discover type (%p) (%p): %s" , (void * )annotation , (void * )type_derived (t ), annotation_name );
14101428
1411- Py_DECREF (annotation_qualname );
1429+ Py_DECREF (annotation_qualname );
1430+ }
14121431 }
14131432
14141433 return t ;
1415-
14161434}
14171435
14181436int py_loader_impl_discover_func_args_count (PyObject * func )
@@ -1452,6 +1470,21 @@ int py_loader_impl_discover_func_args_count(PyObject * func)
14521470
14531471 Py_DECREF (func_code );
14541472 }
1473+ else if (PyCFunction_Check (func ))
1474+ {
1475+ int flags = PyCFunction_GetFlags (func );
1476+
1477+ if (flags & METH_NOARGS )
1478+ {
1479+ args_count = 0 ;
1480+ }
1481+ else if (flags & METH_VARARGS )
1482+ {
1483+ /* TODO: Varidic arguments are not supported */
1484+ log_write ("metacall" , LOG_LEVEL_ERROR , "Builtins (C Python Functions) with varidic arguments are not supported" );
1485+ args_count = -1 ;
1486+ }
1487+ }
14551488 }
14561489
14571490 return args_count ;
@@ -1471,6 +1504,8 @@ int py_loader_impl_discover_func(loader_impl impl, PyObject * func, function f)
14711504 if (PyErr_Occurred () != NULL )
14721505 {
14731506 py_loader_impl_error_print (py_impl );
1507+
1508+ return 1 ;
14741509 }
14751510
14761511 result = PyObject_CallObject (py_impl -> inspect_signature , args );
@@ -1528,6 +1563,19 @@ int py_loader_impl_discover_func(loader_impl impl, PyObject * func, function f)
15281563
15291564 return 0 ;
15301565 }
1566+ else
1567+ {
1568+ /* TODO: Implement builtins with varidic arguments */
1569+ if (PyCFunction_Check (func ))
1570+ {
1571+ signature s = function_signature (f );
1572+
1573+ signature_set_return (s , NULL );
1574+
1575+ return 0 ;
1576+ }
1577+
1578+ }
15311579
15321580 return 1 ;
15331581}
0 commit comments