Lightweight utilities for dynamic and declarative function signature manipulation, inspection, and validation.
Project description
simplibs-signature
Lightweight utilities for dynamic and declarative function signature manipulation. Inspect, copy, assemble, and apply
inspect.Signatureobjects — with a clean API and no magic.
# Assemble a signature from multiple sources
sig = create_signature(extra_param, base_func=my_func)
# Or use the decorator shorthand
@signature_from(extra_param, base_func_first=False)
def my_func(*args, **kwargs):
...
@signature_copy(MyClass.__init__, return_type=MyClass)
def create(*args, **kwargs):
...
Contents
- Installation
- Quick start
- Decorators
- Signature operations
- Parameter creators
- SignatureCreator
- Constants
- About the simplibs ecosystem
Installation
pip install simplibs-signature
from simplibs.signature import create_signature, signature_from, signature_copy
Note: This library automatically installs
simplibs-exceptionandsimplibs-sentinelsas 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_from, 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_from, create_keyword_parameter
extra = create_keyword_parameter("timeout", annotation=int, default=30)
@signature_from(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_from
Assembles a new signature from the decorated function and any additional
parameter sources. The decorated function becomes base_func.
from simplibs.signature import signature_from
@signature_from(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_from 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 bysimplibs-signatureare structuredSimpleExceptionsubclasses, catchable asSignatureErroror the more specificSignatureParameterErrorandSignatureBuildError:
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.UNSETis used throughoutsimplibs-signatureto distinguish between a parameter that was not provided and one explicitly set toNone:
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.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file simplibs_signature-0.2.0.tar.gz.
File metadata
- Download URL: simplibs_signature-0.2.0.tar.gz
- Upload date:
- Size: 63.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6120304bc78dc17d309c119acfa51877dc9950a57c411c28de574226662834b2
|
|
| MD5 |
d73626cd00c9315b023c7d4d5dfd6960
|
|
| BLAKE2b-256 |
eae82ea38b603c515cb8cc671d91e96e061f756e797247b44b1ed98dcc258971
|
File details
Details for the file simplibs_signature-0.2.0-py3-none-any.whl.
File metadata
- Download URL: simplibs_signature-0.2.0-py3-none-any.whl
- Upload date:
- Size: 94.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5261903c950cf39cceb16a323183fa7d712023b0248a21d7858b674232d292d7
|
|
| MD5 |
62a0e949cfdb107ed79637c99c061508
|
|
| BLAKE2b-256 |
73357ac5830939bba3fc4b63072e9b01008fb1a9a0b6a18a567262524f7f729b
|