Skip to main content

Provides a lightweight `attr()` descriptor factory that adds runtime validation to dataclass fields.

Project description

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.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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

validating-0.0.4.tar.gz (22.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

validating-0.0.4-py3-none-any.whl (17.7 kB view details)

Uploaded Python 3

File details

Details for the file validating-0.0.4.tar.gz.

File metadata

  • Download URL: validating-0.0.4.tar.gz
  • Upload date:
  • Size: 22.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for validating-0.0.4.tar.gz
Algorithm Hash digest
SHA256 d3d171eb1226e0559b1c27eaf1a3d48285b1d788132e79e8274cc78782ddad78
MD5 e65ee0738bd22db97e95edc094778fc0
BLAKE2b-256 58ba175669b942d040c474c455552cdeb8e509db88798f6103dc6baabcf8590d

See more details on using hashes here.

File details

Details for the file validating-0.0.4-py3-none-any.whl.

File metadata

  • Download URL: validating-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 17.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for validating-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 2644d30589cbd7d22461c9129a376ced5eee6921f67f25b0609276d57f20a699
MD5 196235ab72c516eb1f627843e96cd73d
BLAKE2b-256 4ef4ccc214f4c0abd32a2c27b1a5c7f2ebd8ea9f6ab538d207a4fac49f67e77b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page