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

Support 3.10 `types.UnionType` #80

Open ROpdebee opened 1 year ago

ROpdebee commented 1 year ago

Describe the bug 3.10 introduced PEP-604 which allows writing unions as X | Y over Union[X, Y]. However, internally the type of such annotation is not typing.Union, it's types.UnionType. attrs-strict doesn't recognise it, leading to validation errors.

To Reproduce

from attrs import define, field
from attrs_strict import type_validator

@define
class X:
  a: int | None = field(validator=type_validator())

X(a=10)

Expected behavior The above example should work.

Actual behavior attrs_strict._error.AttributeTypeError: a must be int | None (got 10 that is a <class 'int'>)

Environment (please complete the following information):

Additional context

>>> X.__annotations__
{'a': int | None}
>>> X.__annotations__['a']
int | None
>>> type(X.__annotations__['a'])
<class 'types.UnionType'>
>>> X.__annotations__['a'].__args__
(<class 'int'>, <class 'NoneType'>)

Here's a similar issue in pydantic related to union types as a reference: https://github.com/pydantic/pydantic/issues/3300

gaborbernat commented 1 year ago

PR welcome.