Skip to main content

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 of dataclasses.dataclass with 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 value
  • default_factory: lazy default factory (mutually exclusive with default)
  • allowlist: whitelist of allowed values
  • denylist: blacklist of forbidden values
  • lb / ub: inclusive lower / upper bounds
  • slb / sub: exclusive lower / upper bounds
  • validator: custom validator function with signature Callable[[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 TypeError or ValueError

@dataclass(...)

validating.dataclass is a compatible enhanced wrapper around dataclasses.dataclass.

Enhancements:

  1. Automatic default promotion: x: int = 1 is promoted to attr(default=1)
  2. Method argument validation: when validate_methods=True (by default False), all public methods are wrapped with validate (including @staticmethod and @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 original AssertionError with your message.
  • assert <expr> (without message) is converted to a ValueError when <expr> is a direct assertion on function arguments, with a message like expected <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=True are 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_transform metadata to validating.dataclass (with attr and dataclasses.Field specifiers) 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 585 generics with quoted builtin annotations (for example list["int"]) to ensure consistent runtime type validation.

v0.0.2

  • Fixed runtime checking for TypedDict and several special typing hints to avoid invalid isinstance paths.
  • Added runtime validation support for typing.Unpack-style annotations.
  • Improved forward-reference handling under TYPE_CHECKING imports, including deferred annotation resolution and safer fallback behavior when references are temporarily unresolved.
  • Refined the @validate argument-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)

Source distribution for validating 0.0.5
File Size Uploaded
validating-0.0.5.tar.gz 22.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for validating 0.0.5
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.0.5 This release

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page