bloomberg / attrs-strict

Provides runtime validation of attributes specified in Python 'attr'-based data classes.
Apache License 2.0
52 stars 19 forks source link

Proposal for a decorator which adds type validation to all fields #109

Open pohlt opened 10 months ago

pohlt commented 10 months ago

Here's a snipped for a class decorator define_strict which makes all fields strict.

I can prepare a PR if you are interested.

import attrs
from attrs_strict import type_validator

def define_strict(maybe_cls=None, **kwargs):
    def add_validators_hook(_, fields):
        return [attr.evolve(validator=type_validator()) for attr in fields]

    d = attrs.define(**kwargs | {"field_transformer": add_validators_hook})

    if maybe_cls:
        return d(maybe_cls)
    else:
        return lambda cls: d(cls)

@define_strict(frozen=False)
class C:
    x: int
    y: float
    s: str

print(C(5, 4.0, "works"))
print(C(5, "BAM!", 42))  # 💥
pohlt commented 10 months ago

Pitfalls:

pohlt commented 10 months ago

Small change to handle given field_transformers:

    def add_validators_hook(cls, fields):
        return kwargs.get("field_transformer", lambda _, v: v)(
            cls, [attr.evolve(validator=type_validator()) for attr in fields]
        )