attrs-validation
Small typed validation helpers for attrs classes.
attrs-validation wraps selected attrs.validators and raises one stable
exception type: attrs_validation.ValidationError. The original attrs
validators remain responsible for validation rules; this package makes their
errors easier to handle in application code, APIs, CLIs, and tests.
Requirements
- Python 3.13+
- attrs 26.1+
Installation
python -m pip install attrs-validation
For local development from this repository:
uv sync --all-groups
Quick Start
import attrs
from attrs_validation import ValidationError, ge, instance_of, max_len, min_len
@attrs.define
class User:
name: str = attrs.field(validator=[instance_of(str), min_len(2), max_len(40)])
age: int = attrs.field(validator=[instance_of(int), ge(18)])
user = User(name="Ada", age=36)
print(user)
# User(name='Ada', age=36)
try:
User(name="A", age=17)
except ValidationError as exc:
print(exc.field)
print(exc.code)
print(exc.message)
print(exc.value)
Why Use It?
attrs already provides excellent validators. They intentionally raise
standard exceptions such as TypeError and ValueError.
attrs-validation keeps the same validation behavior while adding a stable
error shape:
except ValidationError as exc:
assert exc.field == "age"
assert exc.code == "greater_than_or_equal"
assert exc.value == 17
This is useful when validation errors need to be serialized, mapped to API responses, shown in forms, or asserted in tests.
Validators
The package currently exposes wrappers for these attrs.validators helpers:
| Validator | Error code |
|---|---|
instance_of(type) |
invalid_type |
ge(value) |
greater_than_or_equal |
gt(value) |
greater_than |
le(value) |
less_than_or_equal |
lt(value) |
less_than |
in_(options) |
not_in |
not_(*validators) |
forbidden_value |
or_(*validators) |
no_valid_option |
is_callable() |
not_callable |
matches_re(regex, flags=0, func=None) |
pattern_mismatch |
max_len(length) |
max_length |
min_len(length) |
min_length |
ValidationError
ValidationError is the public exception raised by wrapped validators.
class ValidationError(Exception):
field: str
code: str
message: str
value: Any
fieldis the attrs field name.codeis a machine-readable error code.messageis the original validator message.valueis the rejected value.
Composition
Wrapped validators can be composed with attrs in the usual way:
import attrs
from attrs_validation import in_, instance_of, not_, or_
@attrs.define
class Account:
username: str = attrs.field(validator=[instance_of(str), not_(in_({"root", "admin"}))])
identifier: str | int = attrs.field(validator=or_(instance_of(str), instance_of(int)))
Development
Install the project with all development groups:
uv sync --all-groups
Run the standard checks:
uv run ruff format --check .
uv run ruff check .
uv run pyright
uv run pytest -q
Build distributions:
uv build
Inspect artifacts:
tar -tf dist/attrs_validation-*.tar.gz
python -m zipfile -l dist/attrs_validation-*-py3-none-any.whl
Release Checklist
Before publishing a release:
- Ensure
CHANGELOG.mdhas an entry for the release. - Ensure the repository is tagged with the release version, for example
v0.2.0. - Run formatting, linting, type checking, and tests.
- Build wheel and sdist with
uv build. - Install the built wheel into a clean environment and run a smoke test.
License
MIT. See LICENSE.
Metadata
Release files for attrs-validation 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| attrs_validation-0.2.0.tar.gz | 7.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| attrs_validation-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.0 kB
Release files / attrs_validation-0.2.0.tar.gz
| Download URL | attrs_validation-0.2.0.tar.gz |
|---|---|
| Size | 7.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b8a7c1cfe031c55782771e87b5fd613d2654bc6d737841cc13949db4f7d01602
|
|
BLAKE2b-256 checksum How to use checksums |
e9fa13127bb368c28f0cde7e99dc2319dbe6cd59feb45fe191769268ff560615
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / attrs_validation-0.2.0-py3-none-any.whl
| Download URL | attrs_validation-0.2.0-py3-none-any.whl |
|---|---|
| Size | 6.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0fadacbf417f6fcc633aa24df320c5f9bd2f085413af501531ba6acc9d0dcd1e
|
|
BLAKE2b-256 checksum How to use checksums |
5e8cb5a1eeff6e7f36e99352542d32349b0d1484da182fa4ae87a7a3f98d472a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|