Skip to content

Commit

Permalink
Use TypeGuard for has in Python 3.10 and above (#997)
Browse files Browse the repository at this point in the history
* Use `TypeGuard` for `has` in Python 3.10 and above

* fixup! Use `TypeGuard` for `has` in Python 3.10 and above

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Test the negative case

* Add type guard example

Co-authored-by: Hynek Schlawack <hs@ox.cx>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
3 people committed Aug 16, 2022
1 parent 006b31f commit ca6ce8c
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/attr/__init__.pyi
Expand Up @@ -27,6 +27,11 @@ from . import validators as validators
from ._cmp import cmp_using as cmp_using
from ._version_info import VersionInfo

if sys.version_info >= (3, 10):
from typing import TypeGuard
else:
from typing_extensions import TypeGuard

__version__: str
__version_info__: VersionInfo
__title__: str
Expand Down Expand Up @@ -470,7 +475,7 @@ def astuple(
tuple_factory: Type[Sequence[Any]] = ...,
retain_collection_types: bool = ...,
) -> Tuple[Any, ...]: ...
def has(cls: type) -> bool: ...
def has(cls: type) -> TypeGuard[Type[AttrsInstance]]: ...
def assoc(inst: _T, **changes: Any) -> _T: ...
def evolve(inst: _T, **changes: Any) -> _T: ...

Expand Down
12 changes: 12 additions & 0 deletions tests/test_mypy.yml
Expand Up @@ -1371,3 +1371,15 @@
b: str
fields(A) # E: Argument 1 to "fields" has incompatible type "Type[A]"; expected "Type[AttrsInstance]"
- case: testHasTypeGuard
main: |
from attrs import define, has
@define
class A:
pass
reveal_type(A) # N: Revealed type is "def () -> main.A"
if has(A):
reveal_type(A) # N: Revealed type is "Type[attr.AttrsInstance]"
6 changes: 6 additions & 0 deletions tests/typing_example.py
Expand Up @@ -416,3 +416,9 @@ def accessing_from_attrs() -> None:
attrs.setters.frozen
attrs.validators.and_
attrs.cmp_using


def has_typeguard() -> None:
foo = object
if attrs.has(foo):
foo.__attrs_attrs__

0 comments on commit ca6ce8c

Please sign in to comment.