⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content
Open
1 change: 1 addition & 0 deletions changelog.d/1496.change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix type annotations for `optional` validator so it no longer rejects tuples of len > 1
2 changes: 1 addition & 1 deletion src/attr/validators.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def optional(
validator: (
_ValidatorType[_T]
| list[_ValidatorType[_T]]
| tuple[_ValidatorType[_T]]
| tuple[_ValidatorType[_T], ...]
),
) -> _ValidatorType[_T | None]: ...
def in_(options: Container[_T]) -> _ValidatorType[_T]: ...
Expand Down
13 changes: 13 additions & 0 deletions typing-examples/baseline.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,19 @@ class Validated:
num: int = attrs.field(validator=attrs.validators.ge(0))


@attrs.define
class ValidatedOptionalOverTuple:
num: int | None = attrs.field(
validator=attrs.validators.optional(
(attrs.validators.instance_of(int), attrs.validators.ge(0))
# `int(0)` needed to avoid false positive
# `invalid-argument-type` when checking with
# ty 0.0.8 (aa7559db8 2025-12-29): ty assumes `ge`'s
# specialization is `Literal[0]` rather than `int`
)
)


@attrs.define
class ValidatedInconsistentOr:
num: int | str = attrs.field(
Expand Down
Loading