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

Fixes generic inference in functions with TypeGuard, refs #11780 #11797

Merged
merged 6 commits into from
May 8, 2022
Merged

Fixes generic inference in functions with TypeGuard, refs #11780 #11797

merged 6 commits into from
May 8, 2022

Conversation

sobolevn
Copy link
Member

@sobolevn sobolevn commented Dec 19, 2021

Closes #11780, closes #11428

@intgr
Copy link
Contributor

intgr commented Jan 19, 2022

Thanks!

I have a similar use case with literals. I think this change helps a little, but my example runs into a different issue: Literal[...] expression is not considered a type in the type system:

from typing import Literal, TypeGuard, TypeVar, get_args

T = TypeVar('T')

def is_literal_value(value: str | int | None, literal_type: type[T]) -> TypeGuard[T]:
    return value in get_args(literal_type)

value: str = input()
if is_literal_value(value, Literal['on', 'off']):
    reveal_type(value)

Expected result: Revealed type is "Literal['on', 'off']"

Output in mypy master 😕

_local/typeguard.py:8: error: Argument 2 to "is_literal_value" has incompatible type "object"; expected "Type[<nothing>]"
_local/typeguard.py:9: note: Revealed type is "T`-1"

Output from this branch

_local/typeguard.py:8: error: Argument 2 to "is_literal_value" has incompatible type "object"; expected "Type[<nothing>]"
_local/typeguard.py:9: note: Revealed type is "<nothing>"

@JelleZijlstra
Copy link
Member

Obligatory reference to #9773.

@intgr
Copy link
Contributor

intgr commented Jan 19, 2022

Thanks @JelleZijlstra, I have been searching for discussion on this topic, but had not found that issue.

@sobolevn sobolevn mentioned this pull request Feb 6, 2022
@goodoldneon
Copy link

Running into this problem, too.

I get these errors:

main.py:23: note: Revealed type is "builtins.list[Any]"
main.py:26: note: Revealed type is "builtins.list[T`-1]"
main.py:27: error: Argument 1 to "do_stuff" has incompatible type "List[T]"; expected "List[Foo]"
Found 1 error in 1 file (checked 1 source file)

When I run this code:

from typing import Any, TypeGuard, Type, TypeVar

def do_stuff(foos: list[Foo]) -> None:
    pass

class Foo:
    pass

T = TypeVar("T")

def is_list_of(value: list, type: Type[T]) -> TypeGuard[list[T]]:
    for item in value:
        if isinstance(item, type) is False:
            return False

    return True

foos: list[Any] = [Foo()]
reveal_type(foos)

if is_list_of(foos, Foo):
    reveal_type(foos)
    do_stuff(foos)

@sobolevn
Copy link
Member Author

I think we can merge this. CC @JukkaL

Copy link
Collaborator

@hauntsaninja hauntsaninja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great!

I think this might change behaviour if you have a function called _ that is type guarded, but that's fine. edit: Github's diff view is out of date

@hauntsaninja hauntsaninja reopened this May 7, 2022
test-data/unit/check-typeguard.test Outdated Show resolved Hide resolved
test-data/unit/check-typeguard.test Outdated Show resolved Hide resolved
test-data/unit/check-typeguard.test Outdated Show resolved Hide resolved
@github-actions

This comment has been minimized.

1 similar comment
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

1 similar comment
@github-actions
Copy link
Contributor

github-actions bot commented May 8, 2022

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

@hauntsaninja hauntsaninja merged commit fb11c98 into python:master May 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TypeGuard doesn't work with TypeVar TypeGuard functions not properly recognizing generic types
5 participants