Thanks to visit codestin.com
Credit goes to github.com

Skip to content

provide more verbosity for mismatched type types #13878

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

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

altendky
Copy link

@altendky altendky commented Oct 12, 2022

When assigning to a protocol hinted name or attribute invalid values are clearly described as
to how they do not satisfy the hinted protocol. This is presently not the case for Type[]
hints. This PR enables the verbosity and clarity for the Type[] hints as well.

Draft for:

  • Consideration of other implications
  • Consideration of handling more cases

Example source

from typing import Generic, Protocol, Type, TypeVar

T = TypeVar("T")


class AProtocol(Protocol):
    def m(self, x: int) -> str:
        ...


def check(o: AProtocol) -> None:
    ...


class C:
    def m(self, x: bytes) -> str:
        ...


check(C())
check(o=C())
o: AProtocol = C()


class ProtocolChecker(Generic[T]):
    """Instances of this class can be used as decorators that will result in type hint
    checks to verifying that other classes implement a given protocol.
    from typing import Protocol
    class MyProtocol(Protocol):
       def a_method(self) -> int:
           ...
    @ProtocolChecker[MyProtocol]()
    class AnotherClass:
       def a_method(self) -> int:
           return 53
    """

    def __call__(self, cls: Type[T]) -> Type[T]:
        return cls

check_aprotocol = ProtocolChecker[AProtocol]()

check_aprotocol(cls=C)

@check_aprotocol
class D:
    def m(self, x: bytes) -> str:
        ...

Output from mypy main branch showing the minimal messaging has incompatible type "Type[C]"; expected "Type[AProtocol]" for Type[AProtocol] errors.

$ venv/bin/mypy ../x.py
../x.py:16: error: Missing return statement  [empty-body]
../x.py:20: error: Argument 1 to "check" has incompatible type "C"; expected "AProtocol"  [arg-type]
../x.py:20: note: Following member(s) of "C" have conflicts:
../x.py:20: note:     Expected:
../x.py:20: note:         def m(self, x: int) -> str
../x.py:20: note:     Got:
../x.py:20: note:         def m(self, x: bytes) -> str
../x.py:21: error: Argument "o" to "check" has incompatible type "C"; expected "AProtocol"  [arg-type]
../x.py:21: note: Following member(s) of "C" have conflicts:
../x.py:21: note:     Expected:
../x.py:21: note:         def m(self, x: int) -> str
../x.py:21: note:     Got:
../x.py:21: note:         def m(self, x: bytes) -> str
../x.py:22: error: Incompatible types in assignment (expression has type "C", variable has type "AProtocol")  [assignment]
../x.py:22: note: Following member(s) of "C" have conflicts:
../x.py:22: note:     Expected:
../x.py:22: note:         def m(self, x: int) -> str
../x.py:22: note:     Got:
../x.py:22: note:         def m(self, x: bytes) -> str
../x.py:43: error: Argument "cls" to "__call__" of "ProtocolChecker" has incompatible type "Type[C]"; expected "Type[AProtocol]"  [arg-type]
../x.py:45: error: Argument 1 to "__call__" of "ProtocolChecker" has incompatible type "Type[D]"; expected "Type[AProtocol]"  [arg-type]
../x.py:47: error: Missing return statement  [empty-body]
Found 7 errors in 1 file (checked 1 source file)

Output from this branch showing the desired verbosity when checking the Type[AProtocol] hints.

$ venv/bin/mypy ../x.py
../x.py:16: error: Missing return statement  [empty-body]
../x.py:20: error: Argument 1 to "check" has incompatible type "C"; expected "AProtocol"  [arg-type]
../x.py:20: note: Following member(s) of "C" have conflicts:
../x.py:20: note:     Expected:
../x.py:20: note:         def m(self, x: int) -> str
../x.py:20: note:     Got:
../x.py:20: note:         def m(self, x: bytes) -> str
../x.py:21: error: Argument "o" to "check" has incompatible type "C"; expected "AProtocol"  [arg-type]
../x.py:21: note: Following member(s) of "C" have conflicts:
../x.py:21: note:     Expected:
../x.py:21: note:         def m(self, x: int) -> str
../x.py:21: note:     Got:
../x.py:21: note:         def m(self, x: bytes) -> str
../x.py:22: error: Incompatible types in assignment (expression has type "C", variable has type "AProtocol")  [assignment]
../x.py:22: note: Following member(s) of "C" have conflicts:
../x.py:22: note:     Expected:
../x.py:22: note:         def m(self, x: int) -> str
../x.py:22: note:     Got:
../x.py:22: note:         def m(self, x: bytes) -> str
../x.py:43: error: Argument "cls" to "__call__" of "ProtocolChecker" has incompatible type "Type[C]"; expected "Type[AProtocol]"  [arg-type]
../x.py:43: note: Following member(s) of "C" have conflicts:
../x.py:43: note:     Expected:
../x.py:43: note:         def m(self, x: int) -> str
../x.py:43: note:     Got:
../x.py:43: note:         def m(self, x: bytes) -> str
../x.py:45: error: Argument 1 to "__call__" of "ProtocolChecker" has incompatible type "Type[D]"; expected "Type[AProtocol]"  [arg-type]
../x.py:45: note: Following member(s) of "D" have conflicts:
../x.py:45: note:     Expected:
../x.py:45: note:         def m(self, x: int) -> str
../x.py:45: note:     Got:
../x.py:45: note:         def m(self, x: bytes) -> str
../x.py:47: error: Missing return statement  [empty-body]
Found 7 errors in 1 file (checked 1 source file)

@github-actions

This comment has been minimized.

@altendky
Copy link
Author

Welp, I managed to get to green CI over at altendky#157. I'll try to take another pass at some point to add test coverage for this of some form as well as to consider if there's a more general solution to this. I feel like the conditions are a bit specific to the case I want covered. I presume other devs experienced with the mypy code would know both of these points a lot better offhand and I would appreciate any pointers.

Copy link
Contributor

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

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.

1 participant