Skip to main content

simplibs-signature

Lightweight utilities for dynamic and declarative function signature manipulation. Inspect, copy, assemble, and apply inspect.Signature objects — with a clean API and no magic.

Python Licence PyPI

# Assemble a signature from multiple sources
sig = create_signature(extra_param, base_func=my_func)

# Or use the decorator shorthand
@signature(extra_param, base_func_first=False)
def my_func(*args, **kwargs):
    ...

@signature_copy(MyClass.__init__, return_type=MyClass)
def create(*args, **kwargs):
    ...

Contents


Installation

pip install simplibs-signature
from simplibs.signature import create_signature, signature, signature_copy

Note: This library automatically installs simplibs-exception and simplibs-sentinels as core dependencies.


Quick start

The library is built around SignatureCreator — a class that assembles an inspect.Signature from any combination of callables and inspect.Parameter instances. Its direct functional interface is create_signature, which accepts identical parameters and returns the assembled signature without exposing the builder instance.

On top of that, the library provides a set of utilities for working with signatures directly — retrieving, copying, applying — and two decorators, signature_copy and signature, that cover the most common use cases in a compact one-liner form.

Assemble a signature programmatically

from simplibs.signature import create_signature, create_keyword_parameter

extra = create_keyword_parameter("timeout", annotation=int, default=30)

sig = create_signature(extra, base_func=my_func)
# → (host: str, port: int, *, timeout: int = 30)

Copy a signature from an existing function

from simplibs.signature import signature_copy

class MyClass:
    def __init__(self, name: str, value: int = 0):
        ...

@signature_copy(MyClass.__init__, return_type=MyClass)
def create(*args, **kwargs):
    return MyClass(*args, **kwargs)

# create now reports: (name: str, value: int = 0, **kwargs) -> MyClass

Merge parameters from multiple sources

from simplibs.signature import signature, create_keyword_parameter

extra = create_keyword_parameter("timeout", annotation=int, default=30)

@signature(extra)
def connect(host: str, port: int):
    ...

# connect now reports: (host: str, port: int, *, timeout: int = 30)

Decorators

The two main decorators — the primary public interface of the library.

signature_copy

Copies and normalises a signature from an existing callable onto the decorated function. Always removes self/cls and appends **kwargs.

from simplibs.signature import signature_copy

@signature_copy(base_func, return_type=MyClass)
def my_func(*args, **kwargs):
    ...
Parameter Type Description
base_func Callable The function or method whose signature is copied
return_type type | None | UNSET Override the return annotation. UNSET preserves the original, None removes it

signature

Assembles a new signature from the decorated function and any additional parameter sources. The decorated function becomes base_func.

from simplibs.signature import signature

@signature(param_or_func, ..., base_func_first=True)
def my_func(*args, **kwargs):
    ...
Parameter Type Description
*sources inspect.Parameter | Callable Parameters or callables to merge into the signature
excluded_names tuple[str, ...] Parameter names to exclude
return_type type | Callable | None | UNSET Return annotation. If UNSET and base_func has one, it is inherited
base_func_first bool If True, decorated function's parameters come first (default: True)
accept_double bool If True, duplicate parameter names are silently skipped (default: True)

Signature operations

Lower-level tools for working with inspect.Signature objects directly.

get_signature

Safely retrieves an inspect.Signature from any callable. Converts Python's raw ValueError and TypeError into structured SignatureBuildError instances:

from simplibs.signature import get_signature

sig = get_signature(my_func)

set_signature

Assigns an inspect.Signature directly to a function via __signature__. Returns the original function — allows inline assignment:

from simplibs.signature import set_signature

set_signature(my_func, my_signature)

create_copy_signature

Creates a modified copy of a signature from a callable — the lower-level counterpart to signature_copy. Use when you need full control over normalisation or want the inspect.Signature object directly rather than a decorator:

from simplibs.signature import create_copy_signature
from simplibs.sentinels import UNSET

sig = create_copy_signature(
    MyClass.__init__,
    return_type = MyClass,   # override return annotation
    normalize   = True,      # remove self/cls, append **kwargs (default: True)
)

apply_signature_to_wraps

Creates a new wrapper around a function and assigns a custom signature to it. The building block for decorators — use when you need a new callable, not just a modified one:

from simplibs.signature import apply_signature_to_wraps

wrapped = apply_signature_to_wraps(my_func, my_signature)

create_signature_decorator

Produces a reusable decorator from an inspect.Signature. Use when the same signature needs to be applied to multiple functions:

from simplibs.signature import create_signature_decorator

decorator = create_signature_decorator(my_signature)

@decorator
def func_a(*args, **kwargs): ...

@decorator
def func_b(*args, **kwargs): ...

Parameter creators

Convenience factories for building inspect.Parameter instances without touching the inspect module directly.

create_positional_parameter

from simplibs.signature import create_positional_parameter

param = create_positional_parameter("name", annotation=str)
param = create_positional_parameter("x", annotation=int, default=0, positional_only=True)

create_keyword_parameter

from simplibs.signature import create_keyword_parameter

param = create_keyword_parameter("timeout", annotation=int, default=30)

Both factories accept:

Parameter Type Description
name str Parameter name
annotation type Type annotation — omit for no annotation
default Any Default value — omit for no default
positional_only bool create_positional_parameter only — produces POSITIONAL_ONLY if True

SignatureCreator

The engine behind signature and create_signature — assembles an inspect.Signature from any combination of callables and inspect.Parameter instances. Use it directly when you need the builder instance itself, or reach for create_signature for the one-liner functional form:

from simplibs.signature import SignatureCreator, create_signature

# Builder form — access the instance if needed
creator = SignatureCreator(extra_param, base_func=my_func)
sig = creator.signature

# Functional form — when only the signature is needed
sig = create_signature(extra_param, base_func=my_func)
Parameter Type Description
*sources inspect.Parameter | Callable Parameters or callables to merge in
excluded_names tuple[str, ...] Parameter names to exclude
return_type type | Callable | None | UNSET Return annotation source — type, callable, None, or UNSET
base_func Callable | None Base function — its parameters and return type are the starting point
base_func_first bool If True, base_func parameters come first (default: True)
accept_double bool If True, duplicate names are silently skipped (default: True)

return_type priority

Value Behaviour
a type Used directly as the return annotation
a callable Its return annotation is extracted and used
None Return annotation is removed
UNSET Inherited from base_func if available, otherwise empty

Constants

Pre-built inspect.Parameter instances and a frozenset of default exclusions — ready to use without touching the inspect module:

from simplibs.signature import ARGS, KWARGS, EXCLUDED

# ARGS     — *args     (VAR_POSITIONAL)
# KWARGS   — **kwargs  (VAR_KEYWORD)
# EXCLUDED — frozenset({"self", "cls"})

EXCLUDED is the default exclusion set used by ParameterCollector and create_copy_signature — self and cls are always skipped automatically.


About the simplibs ecosystem

simplibs-signature is part of the simplibs ecosystem — a collection of small, self-contained Python libraries united under a common namespace and philosophy. The name simplibs is short for simple libraries.

This library builds on two other simplibs packages:

  • simplibs-exception — a structured exception that communicates with the developer: describing not just what went wrong, but pointing towards a fix. All errors raised by simplibs-signature are structured SimpleException subclasses, catchable as SignatureError or the more specific SignatureParameterError and SignatureBuildError:
from simplibs.signature import SignatureError, SignatureBuildError, SignatureParameterError

try:
    create_signature()  # no sources provided
except SignatureBuildError:
    ...  # signature could not be built

try:
    create_keyword_parameter(name=123)  # wrong type
except SignatureParameterError:
    ...  # invalid argument

try:
    ...
except SignatureError:
    ...  # catches all simplibs-signature errors
  • simplibs-sentinels — sentinel values shared across the ecosystem. UNSET is used throughout simplibs-signature to distinguish between a parameter that was not provided and one explicitly set to None:
from simplibs.sentinels import UNSET
from simplibs.signature import create_copy_signature

sig = create_copy_signature(my_func, return_type=UNSET)  # preserve original
sig = create_copy_signature(my_func, return_type=None)   # remove annotation

All libraries in the simplibs ecosystem share a common philosophy:

Dyslexia-friendly — minimise mental load. Atomise code into self-contained units, name files after the logic they contain, write explanations that describe why — not just what.

Programmer's zen — nothing should be missing and nothing should be superfluous. The journey is the destination: code should be fully understood; better to go slowly and correctly than quickly and with mistakes. The crystallisation approach — not perfection on the first try, but gradual refinement towards it.

Defensive style — anticipate all possible failure modes so that only safe paths remain. Never raise unexpected errors; degrade gracefully.

Minimalism — find the path to the goal in as few steps as possible, but leave nothing out. Each file has one responsibility.

Code as craft — code should be pleasant to look at and evoke a sense of harmony. Treat code as a small work of art — like a carpenter carving a sculpture. Optimise for the user: everything should make sense without having to study the documentation at length.

These are aspirations — a sense of direction. And that is exactly what the note about the journey becoming the destination is all about. 🙂


The library is covered by unit tests across all modules. Tests are part of the repository and serve as living documentation of the expected behaviour.

Release files for simplibs-signature 0.2.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for simplibs-signature 0.2.3
File Size Uploaded
simplibs_signature-0.2.3.tar.gz 64.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for simplibs-signature 0.2.3
File Interpreter ABI Platform
simplibs_signature-0.2.3-py3-none-any.whl Python 3 none any Details

Total release size: 159.1 kB

Release files / simplibs_signature-0.2.3.tar.gz

Download URL simplibs_signature-0.2.3.tar.gz
Size 64.2 kB
Tags Source
SHA-256 checksum
How to use checksums
0c793955e0cad52b33cbe432d0de22f34144cd292e1e0c784f1f4aab0b2a2d07
BLAKE2b-256 checksum
How to use checksums
80146f39f979b75f574af426560633beb82542ba16728f5030f72cd8ec7429ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.9

Release files / simplibs_signature-0.2.3-py3-none-any.whl

Download URL simplibs_signature-0.2.3-py3-none-any.whl
Size 94.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d1db8d680cec7a44d79299d97efa587802865d003ed9306e6089023b2ecec0ca
BLAKE2b-256 checksum
How to use checksums
0920e77800d4b30c794541efe9a5755ddd6f9fd35e5f0aa53523f453ea9a28d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.9

Release history Release notifications | RSS feed

This release

0.2.3 This release

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page