validating
validating is a lightweight runtime validation library focused on making
dataclass fields and function arguments safer and easier to validate.
It exposes three main entry points:
attr(...): declare validated fields (type checks, bounds, allow/deny lists, custom validators)@dataclass(...): a compatible enhancement ofdataclasses.dataclasswith automatic validation integration@validate: a decorator that validates function arguments using type annotations
Installation
pip install validating
Quick Start
from validating import attr, dataclass
@dataclass
class UserConfig:
age: int = attr(lb=0)
role: str = attr(allowlist=["admin", "user"])
cfg = UserConfig(age=18, role="admin")
cfg.age = 20 # ✅
cfg.role = "user" # ✅
# cfg.age = -1 # ❌ ValueError
# cfg.role = "guest" # ❌ ValueError
Core API
attr(...)
Declares a descriptor-backed field that validates values on initialization and assignment.
Common parameters:
default: default valuedefault_factory: lazy default factory (mutually exclusive withdefault)allowlist: whitelist of allowed valuesdenylist: blacklist of forbidden valueslb/ub: inclusive lower / upper boundsslb/sub: exclusive lower / upper boundsvalidator: custom validator function with signatureCallable[[Any], bool]init/repr/hash/compare/kw_only: forwarded dataclass field behavior controls
Error semantics:
- Misconfiguration at class-definition time (for example, default type mismatch) raises
ValidatorError - Invalid runtime values raise
TypeErrororValueError
@dataclass(...)
validating.dataclass is a compatible enhanced wrapper around dataclasses.dataclass.
Enhancements:
- Automatic default promotion:
x: int = 1is promoted toattr(default=1) - Method argument validation: when
validate_methods=True(by defaultFalse), all public methods are wrapped withvalidate(including@staticmethodand@classmethod)
from validating import dataclass
@dataclass(validate_methods=True)
class Service:
retries: int = 3
def run(self, timeout: int) -> int:
return timeout + self.retries
svc = Service()
svc.run(1) # ✅
# svc.run("1") # ❌ TypeError
@validate
Enables call-time argument validation based on type annotations.
from typing import Literal
from validating import validate
@validate
def configure(mode: Literal["dev", "prod"], workers: int):
return mode, workers
configure("dev", 4) # ✅
# configure("test", 4) # ❌ TypeError
@validate also handles assert statements in validated functions:
assert <expr>, "custom message"keeps the originalAssertionErrorwith your message.assert <expr>(without message) is converted to aValueErrorwhen<expr>is a direct assertion on function arguments, with a message likeexpected <expr>, got <value> instead.- Assertions that are not direct checks on function arguments are left as regular
AssertionError.
from validating import validate
@validate
def check_score(score: int) -> int:
assert score >= 60
return score
check_score(80) # ✅
# check_score(59) # ❌ ValueError: expected score >= 60, got 59 instead
More Examples
1) default_factory
from validating import attr, dataclass
@dataclass
class Cache:
items: list[int] = attr(default_factory=list)
2) Complex type hints
from typing import Literal
from validating import attr, dataclass
@dataclass
class AppConfig:
mode: Literal["dev", "prod"] = attr()
token: int | str = attr()
mapping: dict[str, int] = attr()
3) Custom validator
from validating import attr, dataclass
@dataclass
class EvenNumber:
value: int = attr(validator=lambda x: x % 2 == 0)
Notes
- Dataclasses with
slots=Trueare currently not supported. - This project focuses on runtime validation and does not replace static type checking.
See Also
License
This project falls under the BSD 3-Clause License.
History
v0.0.5
- Added
typing.dataclass_transformmetadata tovalidating.dataclass(withattranddataclasses.Fieldspecifiers) to improve IDE/static-analysis support, including better Pylance hints.
v0.0.4
- Updated error messages when validating typed dicts.
v0.0.3
- Improved support for
PEP 585generics with quoted builtin annotations (for examplelist["int"]) to ensure consistent runtime type validation.
v0.0.2
- Fixed runtime checking for
TypedDictand several special typing hints to avoid invalidisinstancepaths. - Added runtime validation support for
typing.Unpack-style annotations. - Improved forward-reference handling under
TYPE_CHECKINGimports, including deferred annotation resolution and safer fallback behavior when references are temporarily unresolved. - Refined the
@validateargument-checking path for better robustness and consistency across annotated call patterns.
v0.0.1
- Initial release.
Metadata
Release files for validating 0.0.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| validating-0.0.5.tar.gz | 22.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| validating-0.0.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.0 kB
Release files / validating-0.0.5.tar.gz
| Download URL | validating-0.0.5.tar.gz |
|---|---|
| Size | 22.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ef464baf48e5fdcab5473eaf2b4639ddefce2f608d0a9e87a2d62cd7442b70ea
|
|
BLAKE2b-256 checksum How to use checksums |
56dadfcebd2df7ce4814352274b383d2b0628c1d2787004c7ce649a2ec8d10d4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.7
|
Release files / validating-0.0.5-py3-none-any.whl
| Download URL | validating-0.0.5-py3-none-any.whl |
|---|---|
| Size | 17.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
00fa2d851d1f0ef5f363173769d05772b43f9ddac3c8eec79c0cd9e153e18e05
|
|
BLAKE2b-256 checksum How to use checksums |
3c21d08bcab03ee553b91f657235d74fd0dc1da0485cc103979f0ea39313ce8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.7
|