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

mypy stops reporting errors when reveal_type is called #6748

Open
bwo opened this issue Apr 30, 2019 · 6 comments
Open

mypy stops reporting errors when reveal_type is called #6748

bwo opened this issue Apr 30, 2019 · 6 comments
Labels

Comments

@bwo
Copy link
Contributor

bwo commented Apr 30, 2019

Consider the following code; the relevant part is in map() but the rest is included for completeness:

from typing import Generic, TypeVar, Callable

R = TypeVar('R')
L = TypeVar('L')
T = TypeVar('T')
E = TypeVar('E')


class Either(Generic[L, R]):

    def map(self, f):
        # type: (Callable[[R], T]) -> Either[L, T]
        # reveal_type(self.bimap)               # a
        # return self.bimap(lambda x: x, f)     # b
        y = self.bimap(lambda x: x, f)          # c (includes following line)
        return y

    def bimap(self, f, g):
        # type: (Callable[[L], E], Callable[[R], T]) -> Either[E, T]
        if isinstance(self, Left):
            return self.left(f(self.val))
        elif isinstance(self, Right):
            return self.right(g(self.val))
        assert False

    @classmethod
    def left(cls, lft):
        # type: (L) -> Either[L, R]
        return Left(lft)

    @classmethod
    def right(cls, rght):
        # type: (R) -> Either[L, R]
        return Right(rght)


class Left(Either[L, R]):
    def __init__(self, left):
        # type: (L) -> None
        self.val = left


class Right(Either[L, R]):
    def __init__(self, right):
        # type: (R) -> None
        self.val = right

As given, (a) and (b) are commented out and (c) is not. If I run mypy (0.701) over it, it complains:

foo.py:15: error: Cannot infer type argument 1 of "bimap" of "Either"
foo.py:15: error: Cannot infer type argument 2 of "bimap" of "Either"

If (c) is commented out and (b) is uncommented, mypy complains like so:

foo.py:14: error: Argument 2 to "bimap" of "Either" has incompatible type "Callable[[R], T]"; expected "Callable[[T], T]"

This is already strange: I would have expected return EXPR and NAME = EXPR; return NAME to be the same.

But! If I uncomment (a), then the only output is

foo.py:13: error: Revealed type is 'def [E, T] (f: def (L`1) -> E`1, g: def (R`2) -> T`2) -> foo.Either[E`1, T`2]'

I.e., it no longer finds a type error. This is true regardless of whether (b) or (c) is uncommented!

@ilevkivskyi
Copy link
Member

Yes, this is definitely a bug. We had a similar issue before, caused by the fact that mypy considers all statements after an inferred <nothing> (bottom type) as unreachable, while it can be caused by simply lack of type context for inference. I thought I fixed that, but likely there is a corner case I missed.

@AlexWaygood AlexWaygood added the topic-reveal-type reveal_type() and reveal_locals() label Mar 26, 2022
@JelleZijlstra
Copy link
Member

I can't reproduce the errors the OP is seeing, even on mypy 0.701. I'm going to close this, but feel free to reopen if you have an example demonstrating this issue on the latest release.

@bwo
Copy link
Contributor Author

bwo commented Mar 26, 2022

Nothing simpler:

(meta3) Wolfson-Tower-1 ~/src/all-the-things 08:35:36 $ mypy -V                                                                                                            
mypy 0.942                                                                                                                                                                 
(meta3) Wolfson-Tower-1 ~/src/all-the-things 08:35:38 $ mypy bar.py                                                                                                        
bar.py:13: note: Revealed type is "def [E, T] (f: def (L`1) -> E`1, g: def (R`2) -> T`2) -> bar.Either[E`1, T`2]"                                                          
(meta3) Wolfson-Tower-1 ~/src/all-the-things 08:35:40 $ mypy foo.py                                                                                                        
foo.py:14: error: Argument 2 to "bimap" of "Either" has incompatible type "Callable[[R], T]"; expected "Callable[[T], T]"                                                  
Found 1 error in 1 file (checked 1 source file)                                                                                                                            
(meta3) Wolfson-Tower-1 ~/src/all-the-things 08:35:42 $ cat foo.py                                                                                                         
from typing import Generic, TypeVar, Callable                                                                                                                              

R = TypeVar('R')
L = TypeVar('L')
T = TypeVar('T')
E = TypeVar('E')


class Either(Generic[L, R]):

    def map(self, f):
        # type: (Callable[[R], T]) -> Either[L, T]
        # reveal_type(self.bimap)               # a
        return self.bimap(lambda x: x, f)     # b

    def bimap(self, f, g):
        # type: (Callable[[L], E], Callable[[R], T]) -> Either[E, T]
        assert False
(meta3) Wolfson-Tower-1 ~/src/all-the-things 08:35:44 $ cat bar.py                                                                                                         
from typing import Generic, TypeVar, Callable                                                                                                                              

R = TypeVar('R')
L = TypeVar('L')
T = TypeVar('T')
E = TypeVar('E')


class Either(Generic[L, R]):

    def map(self, f):
        # type: (Callable[[R], T]) -> Either[L, T]
        reveal_type(self.bimap)               # a
        return self.bimap(lambda x: x, f)     # b

    def bimap(self, f, g):
        # type: (Callable[[L], E], Callable[[R], T]) -> Either[E, T]
        assert False

@bwo
Copy link
Contributor Author

bwo commented Mar 26, 2022

I don't have the power to reopen the issue, but … seems like the problem is still there.

@bwo
Copy link
Contributor Author

bwo commented Mar 26, 2022

Even weirder (conceivably related?):

(meta3) Wolfson-Tower-1 ~/src/all-the-things 08:38:26 $ mypy foo.py                                                                                                        
foo.py:14: error: Argument 2 to "bimap" of "Either" has incompatible type "Callable[[R], T]"; expected "Callable[[T], T]"                                                  
Found 1 error in 1 file (checked 1 source file)                                                                                                                            
(meta3) Wolfson-Tower-1 ~/src/all-the-things 08:38:38 $ mypy -2 foo.py                                                                                                     
Success: no issues found in 1 source file   

@bwo
Copy link
Contributor Author

bwo commented Mar 26, 2022

it's a caching issue:

(meta3) Wolfson-Tower-1 ~/src/all-the-things 08:45:02 $ rm -rf .mypy_cache/                                                                                                
(meta3) Wolfson-Tower-1 ~/src/all-the-things 08:45:23 $ mypy foo.py                                                                                                        
Success: no issues found in 1 source file                                                                                                                                  
(meta3) Wolfson-Tower-1 ~/src/all-the-things 08:45:28 $ rm -rf .mypy_cache/                                                                                                
(meta3) Wolfson-Tower-1 ~/src/all-the-things 08:45:30 $ mypy bar.py                                                                                                        
bar.py:13: note: Revealed type is "def [E, T] (f: def (L`1) -> E`72, g: def (R`2) -> T`73) -> bar.Either[E`72, T`73]"                                                      
(meta3) Wolfson-Tower-1 ~/src/all-the-things 08:45:34 $ mypy foo.py                                                                                                        
foo.py:14: error: Argument 2 to "bimap" of "Either" has incompatible type "Callable[[R], T]"; expected "Callable[[T], T]"                                                  
Found 1 error in 1 file (checked 1 source file)   

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants