An extensive drop-in argument validator.
Project description
typekeeper
Overview
typekeeper is a lightweight Python library that injects comprehensive runtime validation into your functions with a single decorator. It automatically:
- Verifies that arguments conform to their type annotations (including nested generics).
- Warns when default values don’t match annotations or use mutable defaults.
- Enforces numeric ranges and sequence-length constraints via an easy spec string.
- Captures both the function definition and call site in all warnings for precise diagnostics.
Simply decorate your function with @print_param_info(...) to gain these safeguards during development, without changing your function signature.
Features
- Type validation: Recursively checks simple and generic types (
List[int],Dict[str, float],Optional[...],Union[...],Callable, etc.). - Default‐value checks: Detects mismatches between annotated types and default values, plus the classic mutable‐default gotcha.
- Range & length specs: Specify numeric or length constraints in one string (e.g.
"x=1-5; tags=2-4"). - Context‐aware warnings: All warnings include file paths and line numbers of both the decorator and the call site.
- Global control: Enable or disable checks at runtime with
set_arg_checks()or temporarily withinsuspended_arg_checks(). - Recursive _validate() Invocation: Recursively calls _validate() on variable if defined. Gives metadata of location of object in recursion path which fails _validate().
Installation
pip install typekeeper
Configuration
Global Toggle
Argument checks are controlled by an internal flag; direct access is not required. Use the provided APIs:
set_arg_checks(enabled: bool): Turn all checks on or off globally.suspended_arg_checks(): Context manager to disable checks within awithblock.
API Reference
print_param_info
def print_param_info(*, lengths: Optional[str] = None, ignore_defaults: bool = False) -> Callable
- lengths: Optional specification string for constraining numeric values or sequence lengths. It uses a semicolon-separated list of parameter specifications in the form:
name=token1,token2,...
where eachtokenis either:- A single number
N, enforcing an exact value (for numeric arguments) or exact length (for sequences). - A range
min-max, enforcing inclusive bounds (both endpoints inclusive). For example:
lengths="x=1,3-5; y=2"
enforces:xmust be either exactly1or between3and5.ymust be exactly2.
If omitted, no range or length constraints are applied.
- A single number
- ignore_defaults: Skip warnings for mutable default arguments if set to
True.
set_arg_checks
def set_arg_checks(enabled: bool) -> None
Globally enable or disable all argument validation.
suspended_arg_checks
@contextmanager
def suspended_arg_checks() -> None
Temporarily suspend argument checks within a with block.
Examples
# Example 1: Basic type‐and‐default validation
from typekeeper import validate_args
@validate_args()
def greet(name: str, times: int = 1):
return " ".join([name] * times)
# Valid call:
greet("Alice") # → "Alice"
# Invalid call (wrong type):
greet(42)
# UserWarning: Arg 'name' mismatches <class 'str'>; expected <class 'str'>, got <class 'int'>
# Example 2: Numeric‐range and length‐range constraints
from typekeeper import validate_args
@validate_args(lengths="x=1-3; data=2-4")
def process(x: int, data: list[int]):
return data * x
# Valid:
process(2, [10, 20, 30])
# Invalid x:
process(0, [1, 2])
# UserWarning: Param 'x'=0 not in ranges [(1.0, 3.0)]
# Invalid data length:
process(2, [1])
# UserWarning: Length of 'data'=1 not in ranges [(2.0, 4.0)]
# Example 3: Mutable‐default detection
from typekeeper import validate_args
@validate_args(ignore_defaults=False)
def append_item(items: list[int] = []):
items.append(1)
return items
# Decoration‐time warning:
# UserWarning: Mutable default for 'items' in '<function append_item>' : []
# Example 4: Custom _validate() on nested items
from typekeeper import validate_args
class Thing:
def __init__(self, v: int):
self.v = v
def _validate(self) -> bool:
return self.v >= 0
@validate_args()
def handle(things: list[Thing]):
return [t.v for t in things]
# Call with one bad element:
handle([Thing(1), Thing(-5), Thing(3)])
# UserWarning: Parameter 'things' failed at [1] in 'handle'; offending value: Thing(v=-5)
Contributing
Contributions are welcome! To contribute:
- Fork the repository.
- Create a feature branch.
- Submit a pull request.
License
MIT License
Author
Parth Mittal
Email: parth@privatepanda.co
Project details
Release history Release notifications | RSS feed
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 typekeeper-0.0.1.tar.gz.
File metadata
- Download URL: typekeeper-0.0.1.tar.gz
- Upload date:
- Size: 7.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1f69d1a1a1d48744dc30790abd8f749b336b9bbfa229792e725ca4d10d9872b
|
|
| MD5 |
0d6fb2b7ad3832a1126687b63cb89f03
|
|
| BLAKE2b-256 |
dec9bb1d31c910a1e9deee53144c88d07978352a23cddcc5f9af373359f44bff
|
File details
Details for the file typekeeper-0.0.1-py3-none-any.whl.
File metadata
- Download URL: typekeeper-0.0.1-py3-none-any.whl
- Upload date:
- Size: 7.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63b8aaeb84aa2bebfc92dd1eb5f4364833c558cc7f7156c412a093ee90ae40ad
|
|
| MD5 |
ad4543d960c747b2bf97b04dedfd59e8
|
|
| BLAKE2b-256 |
f120c9f77bba220e551bbb7aac4009607cda2cb404c30d6635eb85a747b1458f
|