Skip to content

Placement of # type: ignore on multi-line expression is iffy #1032

Closed

Description

@gvanrossum

Consider (this stands in for a longer example :-):

vars = {"table": "Users"}
sql = dict(vars,
           cols="username")

This currently gives an error due to #984. So I want to add # type: ignore. Unfortunately this doesn't work:

sql = dict(vars,
           cols="username")  # type: ignore

Instead I must use this:

sql = dict(vars,  # type: ignore
           cols="username")

which is a little unintuitive.

Activity

  1. gvanrossum commented on Dec 1, 2015

    @gvanrossum
    MemberAuthor

    (FWIW see #627 which seems to indicate that in the past the opposite was the case. :-)

  2. JukkaL commented on Dec 2, 2015

    @JukkaL
    Collaborator

    Yeah, it would make sense for mypy to allow # type: ignore on any line of a multi-line statement. It's unlikely that a single statement has multiple errors on different lines anyway, and it's possible that future mypy versions will change the exact line that gets reported, risking the invalidation of existing ignore annotations.

  3. lig commented on Mar 26, 2019

    @lig

    @gvanrossum @JukkaL any chance this could be implemented?

    maybe, it's better to allow something like

    # type: ignore_line
    foo = long.multiline.call(
        ...
    )
    
  4. gvanrossum commented on Mar 26, 2019

    @gvanrossum
    MemberAuthor

    The parsing of # type: ignore is done in typed_ast (and starting in Python 3.8, in the stdlib) and not something that's easily fixed in the mypy project. It is done independently from the # type: <type expression> parsing. Adding support for a different keyword would therefore be hard and probably require a PEP.

    However here's an idea: starting with the Python 3.8 ast, the end line and column offset of AST nodes is recorded. This means that we could change mypy so that a # type: ignore anywhere in an AST node would suppress errors anywhere in that AST node.

    Do we have a volunteer to attempt to implement this? The core mypy team is probably too busy with other projects for the rest of the year.

  5. lig commented on Mar 27, 2019

    @lig

    @gvanrossum thanks for the explanation. I'll add this to my list of "things I want to do" as the first item. This could lead to me doing this sometime before the end of the year:)

  6. ilevkivskyi commented on Apr 2, 2019

    @ilevkivskyi
    Member

    Do we have a volunteer to attempt to implement this? The core mypy team is probably too busy with other projects for the rest of the year.

    Yes, this should be not hard for an external contributor.

  7. JukkaL commented on Apr 2, 2019

    @JukkaL
    Collaborator

    Yes, this should be not hard for an external contributor.

    How would you find the start and end line for an arbitrary error, since we only pass a "local" context such as a subexpression when generating errors? May we could have an extra pass where we record the spans of all statements.

  8. ilevkivskyi commented on Apr 2, 2019

    @ilevkivskyi
    Member

    since we only pass a "local" context such as a subexpression when generating errors?

    I think this should be sufficient. We should just always give the correct context for error. In the original example we should only use # type: ignore in the span of CallExpr and not in arbitrary parent expressions.

    If somewhere we pass a wrong context that just happens to have the same start position then it should be fixed independently (I could imagine there is a bunch of such places in code currently).

  9. added a commit that references this issue on Apr 11, 2019
    153536b
  10. added a commit that references this issue on Oct 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions