From d3f320e0cb3b4c74c29a2af8c1bd8d37ca724ed5 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Sun, 15 Dec 2024 06:45:26 +0100 Subject: [PATCH] typing: allow union types for instance_of (#1385) * typing: allow union types for instance_of fixes #1336 * Make hint meaningful albeit broken * Stop running mypy on 3.9 * Declare bankruptcy * Testing types only on 3.10+ now --- .github/workflows/ci.yml | 2 +- changelog.d/1385.change.md | 2 ++ pyproject.toml | 4 ++-- src/attr/validators.pyi | 3 +++ tests/typing_example.py | 3 +++ tox.ini | 2 +- 6 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 changelog.d/1385.change.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b025d69c..339569881 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,7 +66,7 @@ jobs: run: | DO_MYPY=1 - if [[ "$V" == "3.8" ]]; then + if [[ "$V" == "3.8" || "$V" == "3.9" ]]; then DO_MYPY=0 fi diff --git a/changelog.d/1385.change.md b/changelog.d/1385.change.md new file mode 100644 index 000000000..cccfe5243 --- /dev/null +++ b/changelog.d/1385.change.md @@ -0,0 +1,2 @@ +`attrs.validators.instance_of()`'s type hints now allow for union types. +For example: `instance_of(str | int)` diff --git a/pyproject.toml b/pyproject.toml index 0c981e3d0..0b598099f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,10 +30,10 @@ dynamic = ["version", "readme"] [project.optional-dependencies] tests-mypy = [ - 'pytest-mypy-plugins; platform_python_implementation == "CPython" and python_version >= "3.9"', + 'pytest-mypy-plugins; platform_python_implementation == "CPython" and python_version >= "3.10"', # Since the mypy error messages keep changing, we have to keep updating this # pin. - 'mypy>=1.11.1; platform_python_implementation == "CPython" and python_version >= "3.9"', + 'mypy>=1.11.1; platform_python_implementation == "CPython" and python_version >= "3.10"', ] tests = [ # For regression test to ensure cloudpickle compat doesn't break. diff --git a/src/attr/validators.pyi b/src/attr/validators.pyi index a04d43e14..a0fdda7c8 100644 --- a/src/attr/validators.pyi +++ b/src/attr/validators.pyi @@ -1,3 +1,4 @@ +from types import UnionType from typing import ( Any, AnyStr, @@ -44,6 +45,8 @@ def instance_of( ) -> _ValidatorType[_T1 | _T2 | _T3]: ... @overload def instance_of(type: tuple[type, ...]) -> _ValidatorType[Any]: ... +@overload +def instance_of(type: UnionType) -> _ValidatorType[Any]: ... def optional( validator: ( _ValidatorType[_T] diff --git a/tests/typing_example.py b/tests/typing_example.py index cfeb95188..b8d414ba8 100644 --- a/tests/typing_example.py +++ b/tests/typing_example.py @@ -228,6 +228,9 @@ class Validated: k: int | str | C = attr.ib( validator=attrs.validators.instance_of((int, C, str)) ) + kk: int | str | C = attr.ib( + validator=attrs.validators.instance_of(int | C | str) + ) l: Any = attr.ib( validator=attr.validators.not_(attr.validators.in_("abc")) diff --git a/tox.ini b/tox.ini index b1250f06c..4ccf8fe23 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ min_version = 4 env_list = pre-commit, py3{8,9,10,11,12,13}-tests, - py3{9,10,11,12,13}-mypy, + py3{10,11,12,13}-mypy, pypy3, pyright, docs{,-sponsors},