pvv is a lightweight Python utility that brings runtime argument validation to functions using standard type hints, with a deliberately minimal design: zero dependencies, small surface area, and predictable behavior. It is built for cases where you want an extra safety net in dynamic Python codebases—without pulling in heavyweight validation frameworks.
Why pvv
Python type hints improve readability and tooling, but they are not enforced at runtime. In many real systems (data pipelines, integrations, APIs, internal libraries), runtime type mistakes surface late and can be costly to debug.
pvv exists to provide a pragmatic middle ground:
- preserve Python’s ergonomics
- enforce types where it matters
- keep overhead and complexity low
What it does
pvv provides a single decorator, validate, with two modes:
- Validate all annotated parameters by default
- Validate a subset of parameters by name when you want fine control
If an argument does not match the annotated type, pvv raises a TypeError. If the decorator is configured incorrectly (e.g., non-string parameter names), it raises a ValidatorError. :contentReference[oaicite:0]{index=0}
Key characteristics
- Zero dependencies (native Python only) :contentReference[oaicite:1]{index=1}
- Minimal API (
validatedecorator) :contentReference[oaicite:2]{index=2} - Ignores un-annotated parameters instead of guessing :contentReference[oaicite:3]{index=3}
- Deterministic behavior: simple instance checks aligned with type hints :contentReference[oaicite:4]{index=4}
Installation
pip install pvvUsage
Validate all parameters:
from pvv import validate
@validate
def function(a: str, b: int, c):
...Validate only selected parameters:
from pvv import validate
@validate("a", "c")
def function(a: str, b: int, c: bool | None):
...Limitations (by design)
pvv intentionally keeps validation strict and simple:
- It only supports type hints that can be checked via class / instance checks (i.e., the type must be usable with runtime
isinstance-style logic). - Parameters without type hints are ignored, not validated.
This trade-off keeps the library compact and predictable, and avoids the complexity of full type-system emulation.