Mypy: Ignore typing errors in individual blocks

Created on 7 Jun 2019  路  5Comments  路  Source: python/mypy

It is already possible to silence errors using # type: ignore on individual lines, and - since #626) also for a whole file.

Additionally it would be nice to ignore errors on individual blocks. Especially on a class/function level when abstracting away an untyped library. For example:

class MyAbstraction:

    def __init__(self, url: str) -> None:
        self.hostname = url.host  # <-- I want this to be caught by the type-checker

    def some_call(self) -> int:
        # type: ignore
        result = api.untyped_call()
        return result

    def another_large_call(self) -> int:
        # type: ignore
        result_1 = api.untyped_call_1()
        result_2 = api.untyped_call_2()
        result = result_1 + result_2
        return result

When running mypy in "strict" mode the code will be littered with messages like Call to an untyped function ... in a typed context. Currently the only options are:

  • Add # type: ignore on each line causing errors by the external library

    • Disadvantage: Cumbersome (many type-comments needed)

    • Advantage: Only the problematic calls are silenced

  • Add # type: ignore to the file

    • Disadvantage: Typing errors unrelated to the external library become invisible

    • Advantage: Only one line to add

The second option is best used if a module contains only calls to the external library. For new projects this is doable, but older/larger code-bases often need some refactoring for this. And this can be error-prone and seems risky to do only for type-hinting.

Having the option to disable errors on either a class-level or block-level would add a lot of flexibility.

Most helpful comment

You can use the @typing.no_type_check decorator for this.

All 5 comments

See #6830 (the PR that closed #626). It鈥檚 not currently possible to get the line number of the colon that immediately precedes an indented block from the AST alone... at least not without resorting to error-prone guessing. We can't reliably tell the difference between this:

def f() -> (
    None
):  # type: ignore
    ...

And this:

def f() -> (
    None):
    # type: ignore
    ...

So I think block-scoped ignores using a # type: ignore comment on the first line are not very likely. Perhaps there is another way, like @no_type_check, but with preserved annotations in the function signature.

I wanted this also, but I don't think it's worth changing mypy's source parsing 馃檨.

You can use the @typing.no_type_check decorator for this.

@typing.no_type_check works perfectly (thanks @JelleZijlstra).

Why is this issue still open?

The original issue asked for something slightly different (block-scoped type-ignore), which is a bit different from @no_type_check, which is always function-scoped.

I'm not sure block-scoped type-ignores are all that necessary, but it's a reasonable request.

Try with:

from typing import Any, cast

import api as untype_api # It is import to use a different name to untyped module
api = cast(Any, untype_api)

class MyAbstraction:
     def some_call(self) -> int:
        result = api.untyped_call() # this shouldn't show type warnings.
        return result
Was this page helpful?
0 / 5 - 0 ratings