diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 3178636e29..042fbfcefb 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -724,6 +724,10 @@ RUN(NAME callback_01 LABELS cpython llvm c) RUN(NAME callback_02 LABELS cpython llvm c) RUN(NAME callback_03 LABELS cpython llvm c) + +# callback_04 is to test emulation. So just run with cpython +RUN(NAME callback_04 IMPORT_PATH .. LABELS cpython) + # Intrinsic Functions RUN(NAME intrinsics_01 LABELS cpython llvm NOFAST) # any diff --git a/integration_tests/callback_04.py b/integration_tests/callback_04.py new file mode 100644 index 0000000000..8268574f28 --- /dev/null +++ b/integration_tests/callback_04.py @@ -0,0 +1,18 @@ +import lpython +from lpython import i32 +from types import FunctionType +import callback_04_module + +lpython.CTypes.emulations = {k: v for k, v in callback_04_module.__dict__.items() + if isinstance(v, FunctionType)} + + +def foo(x : i32) -> i32: + assert x == 3 + print(x) + return x + +def entry_point() -> None: + callback_04_module.bar(foo, 3) + +entry_point() diff --git a/integration_tests/callback_04_module.py b/integration_tests/callback_04_module.py new file mode 100644 index 0000000000..13cfef375e --- /dev/null +++ b/integration_tests/callback_04_module.py @@ -0,0 +1,4 @@ +from lpython import i32, Callable + +def bar(func : Callable[[i32], i32], arg : i32) -> i32: + return func(arg) diff --git a/src/runtime/lpython/lpython.py b/src/runtime/lpython/lpython.py index e238d2f6d9..2f0eee0b55 100644 --- a/src/runtime/lpython/lpython.py +++ b/src/runtime/lpython/lpython.py @@ -287,6 +287,8 @@ def convert_type_to_ctype(arg): return c_double_complex elif arg == bool: return ctypes.c_bool + elif arg == Callable: + return ctypes.PYFUNCTYPE(None) elif arg is None: raise NotImplementedError("Type cannot be None") elif isinstance(arg, Array):