or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

compilation.mddecorators.mdfunction-creation.mdindex.mdpartial.mdsignature-utils.mdwrapping.md
tile.json

tessl/pypi-makefun

Small library to dynamically create python functions.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/makefun@1.16.x

To install, run

npx @tessl/cli install tessl/pypi-makefun@1.16.0

index.mddocs/

Makefun

A comprehensive Python library for dynamically creating functions at runtime, enabling developers to programmatically generate functions with custom signatures, parameters, and behavior. Makefun provides advanced capabilities for function introspection, signature manipulation, and dynamic code generation, making it particularly useful for creating decorators, proxies, and meta-programming utilities.

Package Information

  • Package Name: makefun
  • Language: Python
  • Installation: pip install makefun

Core Imports

import makefun

Common import pattern for main functionality:

from makefun import create_function, with_signature, wraps, partial

For signature manipulation utilities:

from makefun import add_signature_parameters, remove_signature_parameters

For exception handling:

from makefun import UndefinedSymbolError, UnsupportedForCompilation, SourceUnavailable

For version information:

from makefun import __version__

Basic Usage

from makefun import create_function, with_signature, wraps
from inspect import signature

# Create a function from a signature string
def my_impl(a, b, c=None):
    return f"Called with a={a}, b={b}, c={c}"

# Generate a function with specific signature
dynamic_func = create_function("foo(x: int, y: str, z=42)", my_impl)
print(dynamic_func(1, "hello"))  # "Called with a=1, b=hello, c=42"

# Use as decorator to change function signature  
@with_signature("(name: str, age: int = 0)")
def greet(name, age):
    return f"Hello {name}, you are {age} years old"

print(greet("Alice", 30))  # "Hello Alice, you are 30 years old"

# Enhanced wrapper with signature preservation
@wraps(greet, new_sig="(person_name: str, person_age: int = 25)")
def enhanced_greet(person_name, person_age):
    return greet(person_name, person_age)

print(enhanced_greet("Bob"))  # "Hello Bob, you are 25 years old"

Architecture

Makefun's design centers around three core concepts:

  • Dynamic Function Creation: Functions are generated at runtime from signature specifications, either as strings or Signature objects
  • Signature Preservation: All generated functions maintain proper introspection capabilities, working seamlessly with inspect.signature() and help()
  • Enhanced Wrappers: Improved alternatives to functools.wraps and functools.partial with better signature control and documentation

The library handles complex scenarios including generators, coroutines, async generators, and maintains compatibility across Python versions (2.7+ and 3.5+) using appropriate backports.

Capabilities

Dynamic Function Creation

Core functionality for creating functions dynamically from signature specifications, supporting both string and Signature object inputs with comprehensive metadata control.

def create_function(
    func_signature: Union[str, Signature],
    func_impl: Callable[[Any], Any],
    func_name: str = None,
    inject_as_first_arg: bool = False,
    add_source: bool = True,
    add_impl: bool = True,
    doc: str = None,
    qualname: str = None,
    co_name: str = None,
    module_name: str = None,
    **attrs
) -> FunctionType:
    """
    Creates a function with signature func_signature that calls func_impl.
    
    Parameters:
    - func_signature: Union[str, Signature], signature specification
    - func_impl: Callable[[Any], Any], implementation function to call
    - func_name: str, optional name override
    - inject_as_first_arg: bool, inject created function as first arg
    - add_source: bool, add __source__ attribute
    - add_impl: bool, add __func_impl__ attribute  
    - doc: str, optional docstring override
    - qualname: str, optional qualified name
    - co_name: str, optional code object name
    - module_name: str, optional module name
    - **attrs: additional attributes to set
    
    Returns:
    FunctionType: Generated function with specified signature
    """

Dynamic Function Creation

Signature-based Decorators

Decorators for modifying function signatures while preserving metadata and introspection capabilities, offering enhanced alternatives to standard Python decorators.

def with_signature(
    func_signature: Union[str, Signature],
    func_name: str = None,
    inject_as_first_arg: bool = False,
    add_source: bool = True,
    add_impl: bool = True,
    doc: str = None,
    qualname: str = None,
    co_name: str = None,
    module_name: str = None,
    **attrs
) -> Callable[[Callable], Callable]:
    """
    Decorator to change function signature.
    
    Parameters:
    - func_signature: Union[str, Signature], new signature specification
    - func_name: str, optional name override
    - inject_as_first_arg: bool, inject created function as first arg
    - add_source: bool, add __source__ attribute
    - add_impl: bool, add __func_impl__ attribute
    - doc: str, optional docstring override
    - qualname: str, optional qualified name
    - co_name: str, optional code object name
    - module_name: str, optional module name
    - **attrs: additional attributes to set
    
    Returns:
    Callable[[Callable], Callable]: Decorator function
    """

Signature-based Decorators

Enhanced Wrapping

Advanced function wrapping capabilities that extend functools.wraps with signature modification, parameter addition/removal, and better introspection support.

def wraps(
    wrapped_fun: Callable,
    new_sig: Union[str, Signature] = None,
    prepend_args: Union[str, Parameter, Iterable[Union[str, Parameter]]] = None,
    append_args: Union[str, Parameter, Iterable[Union[str, Parameter]]] = None,
    remove_args: Union[str, Iterable[str]] = None,
    func_name: str = None,
    co_name: str = None,
    inject_as_first_arg: bool = False,
    add_source: bool = True,
    add_impl: bool = True,
    doc: str = None,
    qualname: str = None,
    module_name: str = None,
    **attrs
) -> Callable[[Callable], Callable]:
    """
    Enhanced functools.wraps with signature modification capabilities.
    
    Parameters:
    - wrapped_fun: Callable, function to wrap
    - new_sig: Union[str, Signature], new signature specification
    - prepend_args: Union[str, Parameter, Iterable], arguments to prepend
    - append_args: Union[str, Parameter, Iterable], arguments to append
    - remove_args: Union[str, Iterable[str]], arguments to remove
    - func_name: str, optional name override
    - co_name: str, optional code object name
    - inject_as_first_arg: bool, inject created function as first arg
    - add_source: bool, add __source__ attribute
    - add_impl: bool, add __func_impl__ attribute
    - doc: str, optional docstring override
    - qualname: str, optional qualified name
    - module_name: str, optional module name
    - **attrs: additional attributes to set
    
    Returns:
    Callable[[Callable], Callable]: Decorator function
    """

def create_wrapper(
    wrapped: Callable,
    wrapper: Callable,
    new_sig: Union[str, Signature] = None,
    prepend_args: Union[str, Parameter, Iterable[Union[str, Parameter]]] = None,
    append_args: Union[str, Parameter, Iterable[Union[str, Parameter]]] = None,
    remove_args: Union[str, Iterable[str]] = None,
    func_name: str = None,
    inject_as_first_arg: bool = False,
    add_source: bool = True,
    add_impl: bool = True,
    doc: str = None,
    qualname: str = None,
    co_name: str = None,
    module_name: str = None,
    **attrs
) -> Callable:
    """
    Creates signature-preserving wrapper function.
    Equivalent to wraps(wrapped, **kwargs)(wrapper).
    
    Parameters: Same as wraps()
    
    Returns:
    Callable: Generated wrapper function
    """

Enhanced Wrapping

Partial Function Support

Enhanced partial function implementation with better introspection, documentation generation, and signature handling compared to functools.partial.

def partial(
    f: Callable,
    *preset_pos_args: Any,
    **preset_kwargs: Any
) -> Callable:
    """
    Enhanced functools.partial with better introspection and documentation.
    
    Parameters:
    - f: Callable, function to partially apply
    - *preset_pos_args: Any, positional arguments to preset
    - **preset_kwargs: Any, keyword arguments to preset
    
    Returns:
    Callable: Partial function with enhanced metadata
    """

def with_partial(
    *preset_pos_args: Any,
    **preset_kwargs: Any
) -> Callable[[Callable], Callable]:
    """
    Decorator version of partial function.
    
    Parameters:
    - *preset_pos_args: Any, positional arguments to preset
    - **preset_kwargs: Any, keyword arguments to preset
    
    Returns:
    Callable[[Callable], Callable]: Decorator function
    """

Partial Function Support

Signature Manipulation

Utilities for programmatically modifying function signatures by adding or removing parameters, enabling dynamic signature construction.

def add_signature_parameters(
    s: Signature,
    first: Union[str, Parameter, Iterable[Union[str, Parameter]]] = (),
    last: Union[str, Parameter, Iterable[Union[str, Parameter]]] = (),
    custom: Union[Parameter, Iterable[Parameter]] = (),
    custom_idx: int = -1
) -> Signature:
    """
    Adds parameters to an existing signature.
    
    Parameters:
    - s: Signature, original signature to modify
    - first: Union[str, Parameter, Iterable], parameters to add at beginning
    - last: Union[str, Parameter, Iterable], parameters to add at end
    - custom: Union[Parameter, Iterable[Parameter]], parameters to add at custom position
    - custom_idx: int, position for custom parameters
    
    Returns:
    Signature: New signature with added parameters
    """

def remove_signature_parameters(
    s: Signature,
    *param_names: str
) -> Signature:
    """
    Removes parameters from an existing signature.
    
    Parameters:
    - s: Signature, original signature to modify
    - *param_names: str, names of parameters to remove
    
    Returns:
    Signature: New signature with removed parameters
    """

Signature Manipulation

Compilation Utilities

Function compilation utilities for masking implementation details from debuggers while preserving source code access for development purposes.

def compile_fun(
    recurse: Union[bool, Callable] = True,
    except_names: Iterable[str] = ()
) -> Union[Callable, Callable[[Callable], Callable]]:
    """
    Decorator to compile functions for debugging convenience.
    
    Parameters:
    - recurse: Union[bool, Callable], recursively compile referenced functions
    - except_names: Iterable[str], function names to exclude from compilation
    
    Returns:
    Union[Callable, Callable[[Callable], Callable]]: Decorator or compiled function
    """

Compilation Utilities

Version Information

__version__: str
    """Package version string, managed by setuptools_scm."""

Exception Classes

class UndefinedSymbolError(NameError):
    """Exception raised by compile_fun when function requires undefined symbols."""

class UnsupportedForCompilation(TypeError):
    """Exception raised by compile_fun when target is not supported for compilation."""

class SourceUnavailable(OSError):
    """Exception raised by compile_fun when function source code is not available."""