Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use TypeGuard for has in Python 3.10 and above #997

Merged
merged 8 commits into from Aug 16, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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__