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

Cannot silence "unused 'type: ignore'" in version specific code #8823

Closed
serhiy-storchaka opened this issue May 14, 2020 · 24 comments · Fixed by #15164
Closed

Cannot silence "unused 'type: ignore'" in version specific code #8823

serhiy-storchaka opened this issue May 14, 2020 · 24 comments · Fixed by #15164
Labels
bug mypy got something wrong needs discussion priority-1-normal topic-reachability Detecting unreachable code topic-type-ignore # type: ignore comments

Comments

@serhiy-storchaka
Copy link
Member

I need to execute some code only on specific Python version (it is the use of TextIOWrapper.reconfigure() added in Python 3.7, but in following example I will use more abstract code).

import sys

if sys.version_info >= (3, 7):
    x: int = 'a'

Since MyPy on Python 3.7 raises an error for it (actually because of the error in typeshed) I need to add # type: ignore:

import sys

if sys.version_info >= (3, 7):
    x: int = 'a'  # type: ignore

But now I will get an error unused 'type: ignore' comment when run MyPy with warn_unused_ignores = True on Python 3.6.

So I cannot use variant 1, because it is an error on 3.7, and cannot use variant 2, because it is an error on 3.6.

MyPy should not complain about unused 'type: ignore' comment in the code which it does not analyze.

MyPy version is 0.770.

@hauntsaninja
Copy link
Collaborator

As a workaround for this issue, you can use cast

@serhiy-storchaka
Copy link
Member Author

It does not help in my particular issue.

The problem is that MyPy skips some parts of the code and complains about unused type: ignore in this code (which would be not ignored if this code be not skipped). It is not consistent and does not have a workaround.

@hauntsaninja
Copy link
Collaborator

hauntsaninja commented May 18, 2020

Agree that there is an issue, but I think it can be worked around using cast, since that lets you remove the type ignore altogether:

~/delete λ cat test84.py
import sys
from typing import cast, Any

if sys.version_info >= (3, 7):
    x: int = cast(Any, 'a')
~/delete λ mypy --python-version 3.6 --warn-unused-ignores --warn-redundant-casts test84.py
Success: no issues found in 1 source file
~/delete λ mypy --python-version 3.7 --warn-unused-ignores --warn-redundant-casts test84.py
Success: no issues found in 1 source file

Looking at the issue on typeshed, you'd need to do something like cast(Any, sys.stdout).reconfigure(errors="replace"). It's not pretty, but it should work.

@serhiy-storchaka
Copy link
Member Author

x: int = 'a' was just an example. It is the simplest way that I know to trigger an error. In real code I use

sys.stdout.reconfigure(errors="replace")

and I do not know how to silence an error in this case.

@serhiy-storchaka
Copy link
Member Author

Oh, and thank you for your suggestion. I tried similar workaround, but made an error in the code, so it did not work. Now I see my mistake and fixed it thank to you.

@msullivan
Copy link
Collaborator

I think we need a way to silence unused type ignore messages for individual type ignores short of disabling the warning.

@msullivan msullivan changed the title Cannot silence type checking in version specific code Cannot silence "unused 'type: ignore'" in version specific code May 20, 2020
@wsanchez
Copy link

wsanchez commented Oct 1, 2020

I'm running into a by-platform equivalent of this. If I try to import epoll from the select module on macOS, I get an [attr-defined] error, but on Linux, that's fine. Conversely, on Linux, one can't import KQ_FILTER_READ from select.

So, depending on which platform you run mypy, you get a different error, and I don't know how to suppress that class of error message.

That might be a different ticket, but it seems similar enough that maybe mentioning it in this one will do…?

@wsanchez
Copy link

wsanchez commented Oct 1, 2020

Note the select issue I mention above appears to be new between Mypy 0.770 and 0.782.

@gvanrossum
Copy link
Member

@wsanchez That is different. Are you using the right syntax for the platform check? Please ask on Gitter.

@wsanchez
Copy link

wsanchez commented Oct 1, 2020

@gvanrossum Oh, OK, I didn't realize that Mypy could be told to do platform-specific things. I'll read more. twisted/twisted#1416 (comment) describes the issue in a bit more detail.

dvarrazzo added a commit to psycopg/psycopg that referenced this issue Oct 27, 2020
`ignore` in unused branches triggers python/mypy#8823
so use `setattr()` to avoid python/mypy#2427.
dvarrazzo added a commit to psycopg/psycopg that referenced this issue Oct 28, 2020
`ignore` in unused branches triggers python/mypy#8823
so use `setattr()` to avoid python/mypy#2427.
@PatMyron
Copy link

PatMyron commented Dec 15, 2020

# type: ignore # noqa and # noqa don't work either? Used --no-warn-unused-ignores

@hauntsaninja
Copy link
Collaborator

hauntsaninja commented Dec 15, 2020

If you read this issue, you'll notice that there's a workaround posted. I also looked at your code, and you could just fix it using https://mypy.readthedocs.io/en/stable/common_issues.html#python-version-and-system-platform-checks (so it's not really the problem discussed in this issue either)

@bryanforbes
Copy link
Contributor

I'm running into an issue writing stubs for sqlalchemy where it would be nice if I could silence this error (checking with strict mode on):

if sys.version_info >= (3, 7):
    class OrderedDict(Dict[_KT, _VT]): ...

else:
    class OrderedDict(Dict[_KT, _VT]):
                def keys(self) -> List[_KT]: ...  # type: ignore[override]

Without that ignore, type checking for 3.6 fails. With the ignore, type checking fails in 3.7+.

lav-patel added a commit to kumc-bmi/ds-determined-tools that referenced this issue Jul 3, 2021
lav-patel added a commit to kumc-bmi/ds-determined-tools that referenced this issue Jul 6, 2021
* issue fix by limiting only bringing records till s8

* updated import by isort

* ignore needing to add local package to requirements.txt

* staticaly type the code

* adding autopep8

* allow autopep8 goinside directory

* formatting/comment error for setup.cfg file

* add flake8-isort in requirements.txt

* use isort recursive

* mypy bug --no-warn-no-return github.com/python/mypy/issues/8823
@senarvi
Copy link

senarvi commented Mar 17, 2023

A possible workaround for the @stinovlas's import use case is to use getattr instead:

try:
    TestCase: Any = getattr(unittest, 'IsolatedAsyncioTestCase')
except AttributeError:  # pragma: no cover
    TestCase = getattr(asynctest, 'TestCase')

I've been struggling with this issue with try/except imports. I thought I had tried everything already, but this worked!

@matteosantama
Copy link

I know "me too!" comments aren't especially helpful, but here's an example where the suggested workaround (using cast) does not work.

import sys

from typing import cast, Callable

if sys.version_info >= (3, 8):
    from importlib.metadata import version
else:
    from importlib_metadata import version

cast(Callable[[str], str], version)

__version__ = version("my-lib")
❯ mypy --python-version 3.10
Success: no issues found in 37 source files
❯ mypy --python-version 3.7
my-lib/__init__.py:12: error: Call to untyped function "version" in typed context  [no-untyped-call]
Found 1 error in 1 file (checked 37 source files)
❯ mypy --version
mypy 1.1.1 (compiled: yes)

@hauntsaninja
Copy link
Collaborator

Try version: Callable[[str], str] before your if, or to cast in the same expression that you call e.g. cast(Callable[[str], str], version)("my-lib")

ssbarnea added a commit to ansible/ansible-lint that referenced this issue May 2, 2023
ilevkivskyi added a commit that referenced this issue May 2, 2023
…eal error code (#15164)

Fixes #8823 

The issue above makes `--warn-unused-ignores` problematic for
cross-platform/cross-version code (btw it is one of the most upvoted
bugs). Due to how the unused ignore errors are generated, it is hard to
not generate them in unreachable code without having precise span
information for blocks. So my fix will not work on Python 3.7, where end
lines are not available, but taking into account that 3.7 reaches end of
life in less than 2 month, it is not worth the effort.

Also this PR makes `unused-ignore` work much more like a regular error
code, so it can be used with
`--enable-error-code`/`--disable-error-code` (including per-file) etc.
More importantly this will also allow to use `--warn-unused-ignores` in
code that uses e.g. `try/except` imports (instead of `if` version
checks) with the help of `# type: ignore[import,unused-ignore]` (which
btw will also help on Python 3.7).

Note also currently line numbers for `Block`s are actually wrong (and
hence few TODOs in `fastparse.py`). So in this PR I set them all
correctly and update a lot of parse tests (I went through all test
updates and verified they are reasonable).

---------

Co-authored-by: Jukka Lehtosalo <jukka.lehtosalo@iki.fi>
@hauntsaninja
Copy link
Collaborator

Thanks to ilevkivskyi, in the next release of mypy # type: ignore[unused-ignore] should work.

spoorcc pushed a commit to dfetch-org/dfetch that referenced this issue Nov 15, 2023
ben-edna added a commit to dfetch-org/dfetch that referenced this issue Nov 15, 2023
axiomofjoy added a commit to Arize-ai/openinference that referenced this issue May 14, 2024
… langchain (#460)

The issue is that our type ignores are required on the old version of LangChain, but not required on the new version of LangChain. If we include the type ignore, the new version of LangChain complains about an usused type ignore. Found the solution [here](python/mypy#8823 (comment)).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong needs discussion priority-1-normal topic-reachability Detecting unreachable code topic-type-ignore # type: ignore comments
Projects
None yet
Development

Successfully merging a pull request may close this issue.