makefun is a small Python library for dynamically creating functions and modifying existing function signatures at runtime. It is currently at version 1.16.0 and maintains an active development cycle with regular updates, including support for new Python versions and bug fixes.
Install & Compatibility
Where this runs
tested against v1.16.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.930 runs
installs and imports cleanly · install 0.0s · import 0.042s · 17.9MB
glibcpy 3.10–3.930 runs
installs and imports cleanly · install 1.5s · import 0.037s · 18MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
create_function
✓ from makefun import create_function
Used to create new functions from a signature and an implementation.
create_wrapper
✓ from makefun import create_wrapper
Used to create a wrapper around an existing function, potentially with a modified signature.
wraps
✓ from makefun import wraps
A decorator for creating a wrapper for a function, similar to `functools.wraps` but with more control over signature manipulation.
with_signature
✓ from makefun import with_signature
A decorator to apply a new signature to an existing function.
This quickstart demonstrates the core functionalities: creating a new function with `create_function` by specifying its signature and implementation, and wrapping an existing function while modifying its signature using the `wraps` decorator.
from makefun import create_function, wraps
from inspect import Signature, Parameter
# Example 1: Creating a function from scratch
def my_implementation(a, b):
return f"a={a}, b={b}"
sig = Signature([
Parameter('a', Parameter.POSITIONAL_OR_KEYWORD),
Parameter('b', Parameter.POSITIONAL_OR_KEYWORD, default=2)
])
dynamic_func = create_function(sig, my_implementation, doc="A dynamically created function")
print(dynamic_func(1)) # Output: a=1, b=2
print(dynamic_func(10, b=20)) # Output: a=10, b=20
# Example 2: Wrapping an existing function and changing its signature
def original(x, y):
return x * y
@wraps(original, new_sig=Signature([Parameter('val', Parameter.POSITIONAL_OR_KEYWORD)]))
def my_wrapper(val):
# original expects x, y. Let's map 'val' to both.
return original(val, val)
print(my_wrapper(val=5)) # Output: 25
Debug
Known issues
breakingVersion 1.16.0 (and later) drops official support for Python versions older than 3.9. If you are using Python 3.8 or earlier, you must pin makefun to a version less than 1.16.0.fixUpgrade your Python environment to 3.9+ or pin makefun to an older version (e.g., `makefun<1.16.0`) in your requirements.
affects: < 1.16.0 (for users on Python < 3.9)
gotchaThe behavior of `wraps` was updated in version 1.15.0 to be more compliant with PEP 362 regarding the setting of `__wrapped__` and `__signature__` attributes. While generally an improvement, this could subtly change behavior for applications inadvertently relying on the pre-1.15.0 `wraps` implementation.fixReview code that inspects `__wrapped__` or `__signature__` on functions decorated with `makefun.wraps` after upgrading to 1.15.0+.
affects: < 1.15.0
gotchaPrior to version 1.15.3, creating functions where a default argument's value was a subclass of a basic primitive (e.g., `int` or `str`) could lead to a `SyntaxError: invalid syntax`.fixUpgrade to makefun 1.15.3 or newer to resolve this `SyntaxError`.
affects: < 1.15.3
gotchaVersions prior to 1.15.2 could raise a `SyntaxError` if a native coroutine function's name contained the substring `'return'`.fixUpgrade to makefun 1.15.2 or newer, or rename problematic coroutine functions.
affects: < 1.15.2
gotchaIn Python 2, prior to version 1.15.1, creating functions with names starting or ending with `_`, or containing `__`, could result in a `ValueError: Invalid co_name`.fixUpgrade to makefun 1.15.1 or newer, or ensure function names follow standard Python naming conventions for `co_name` compatibility.
affects: < 1.15.1 (Python 2 only)
Errors
Common errors & fixes
TypeError: <function_name>() got an unexpected keyword argument 'arg_name'
makefun wrappers perform strict signature checking, raising TypeError early if provided arguments do not match the dynamically defined function's signature. This is an intended feature to ensure argument compliance before the wrapper body executes.
fixEnsure the arguments passed to the makefun-created function strictly match its defined signature, including positional/keyword usage and required arguments.
NameError: name 'some_variable' is not defined
When makefun dynamically creates a function, its code relies on the scope where it is defined. If the function's implementation uses variables or functions that are not locally or globally available at the point of its creation, a NameError will occur when the created function is called.
fixEnsure all symbols (variables, functions) used within the dynamically created function's implementation are accessible from the scope where the makefun function is defined, or pass them explicitly if they are intended to be arguments.
SyntaxError: invalid syntax
The signature string provided to makefun functions (e.g., `func_signature` in `create_function` or `@with_signature`) does not conform to valid Python function signature syntax.
fixCarefully review the function signature string to ensure it follows correct Python syntax for function definitions (e.g., proper parameter names, default values, type hints, parentheses).
ValueError: Invalid co_name
This error occurs when the internal `co_name` (code object name) provided or derived for the dynamically created function is not a valid Python identifier, often due to special characters or invalid formatting.
fixEnsure the `func_name` argument (if provided) or the name derived from the `func_signature` is a valid Python identifier (alphanumeric and underscores, not starting with a number).
Audit
Dependencies
No dependency data recorded yet.