Dynamically create function with typehint in memory

Viewed 136

I'd like to dynamically create a function in memory, with a type hint of the argument. I do have some working code, but it feels extremely hacky and fragile.

import typing

func_name = 'some_function_name'
req_type=int

a = None
exec(f'''def {func_name}(my_argument:{req_type.__name__}): pass
a = {func_name}''')

print(a) # <function some_function_name at 0x000001B89F3311F0>
print(typing.get_type_hints(a)) # {'my_argument': <class 'int'>}

There has got to be a better way to do this. Any suggestions?

1 Answers

You can use FunctionType to create new functions. You can copy a template function and change its type hints and name. You also can change the code of the function object with compile Python function.

I made an example that copy and change the name and the type hint of template function (without changing code)

import types
import typing


def copy_func(f, func_types, name=None):
    # add your code to first parameter
    new_func = types.FunctionType(f.__code__, f.__globals__, name or f.__name__,
        f.__defaults__, f.__closure__)
    new_func.__annotations__ = func_types
    return new_func

def template(arg):
     print('called template func')

a = copy_func(template, {'my_argument': int}, "test")
a(2) # can call it
print("types:", typing.get_type_hints(a)) # types: {'my_argument': <class 'type'>}
Related