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

Plugin hook to selectively silence error messages #7468

Open
stereobutter opened this issue Sep 5, 2019 · 7 comments
Open

Plugin hook to selectively silence error messages #7468

stereobutter opened this issue Sep 5, 2019 · 7 comments
Labels
feature priority-1-normal topic-plugins The plugin API and ideas for new plugins

Comments

@stereobutter
Copy link

stereobutter commented Sep 5, 2019

For developing an Either-like monad that types correctly and also behaves nicely at runtime I currently use the following pattern to independently declare the types for mypy and the runtime implementation

from typing import Generic, TypeVar, TYPE_CHECKING

L = TypeVar('L')
R = TypeVar('R')

if TYPE_CHECKING:  # type declarations

    class Either(Generic[L, R]): pass
    Left = Either[L, None]
    Right = Either[None, R]

else:  # runtime implementation

    class Either(): pass
    class Left(Either): pass
    class Right(Either): pass


# type checking features
a: Left[int] 
b: Either[int, None]

a = b  # typechecks
b = a  # typechecks 

# runtime features
isinstance(Left(), Left)  #works at runtime 
isinstance(Left(), Either)  #works at runtime

During static analysis it is important that Left and Right get treated as aliases for Either so that assignments get typechecked correctly (even though at runtime they are subclasses (and thus subtypes) of Either). Additionally I'd like to be able and use isinstance checks at runtime to determine whether a result is an instance of Left or Right (or more general if something is an instance of Either). This mostly works (assignments typecheck and runtime behavior is as excepted), however mypy (rightfully) complains about the isinstance checks that

Parameterized generics cannot be used with class or instance checks mypy(error)

In cases like these it would be useful if one could tell mypy that a generic class can be used with instance checks. This would also be somewhat similar to how one can declare protocol classes to support runtime instance checks with the @runtime_checkable decorator.


This would also allow user defined generics to behave similar to types from typing like List where

isinstance([1,2,3], List)  # typechecks
isinstance([1,2,3], List[int])  # Parameterized generics cannot be ...

vs

isinstance(Left(1), Left)  # should typecheck, currently doesn't
isinstance(Left(1), Left[int])  # Parameterized generics cannot be ...

I'd propose that @runtime_checkable marks an Generic accordingly so that in the example it would be

#...
if TYPE_CHECKING:  # type declarations

    @runtime_checkable
    class Either(Generic[L, R]): pass

#...

Addendum

The issue is actually not with Either per se but rather with the type aliases Left and Right. For mypy

isinstance(Left(1), Left)  #looks similar to 'isinstance([1,2,3], List)'

actually is

isinstance(Left(1), Either[L, None])  # looks similar to 'isinstance([1,2,3], List[int])'

I still think this would be a useful feature to be able and better support the dynamic nature of Python with the if TYPE_CHECKING pattern.

@ilevkivskyi
Copy link
Member

I am quite sure there was a very similar feature request but can't find it. I think a better idea is to add a plugin hook to selectively suppress some error codes (now that we have them) on a given line. Otherwise it sounds too niche.

@ilevkivskyi ilevkivskyi added feature priority-1-normal topic-plugins The plugin API and ideas for new plugins labels Sep 5, 2019
@stereobutter
Copy link
Author

Yes, I agree that this is a special case of "there is this error that I know I want to ignore". For this a plugin that gets called at the very end, when everything else is done, would be very useful. Is there already a way to filter out error messages/error codes in the plugin hooks that are already available?

@ilevkivskyi
Copy link
Member

Well, technically I can't say no, because I would be lying, but I really think you should not do this, better wait for the public API. The error manager is exposed though private type checker API ctx.api.msg.errors but trying to do something there is super-fragile.

@stereobutter
Copy link
Author

Even if this were not fragile (at the moment), I wonder to which symbol one would attach such a plugin to, isinstance or Either?

@ilevkivskyi
Copy link
Member

@SaschaSchlemmer get_function_hook() for isinstance(). But this is the last thing I say here :-)

@Netzeband
Copy link
Contributor

@ilevkivskyi As discussed in the pull request about ignoring errors by regex, I would like to help you with improving the plugin system, so errors could be ignored from a plugin.

First I need to get more familiar with the plugin system of mypy. I will learn more about it in the next days. However my current idea would be to add a hook, which is called every time when an error should reported. This hook can than decide, if the error should be ignored or not.
For this the hook would need the info object of the error, which holds many useful information to do this decision.

However, this would mean to introduce a new hook and to make the class of the info object public for plugins. When I understand your discussion in this thread correctly, both are think you normally avoid, right? Do you have another approach in mind?

Thanks for your assistance here,
André

@hunterC90
Copy link

Should this have the label topic-pep-604? This seems like it might given other open issues with that label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature priority-1-normal topic-plugins The plugin API and ideas for new plugins
Projects
None yet
Development

No branches or pull requests

4 participants