-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Expression-scoped ignores in Python 3.8. (#6648)
Fixes #1032. On Python 3.8, we use `end_lineno` information to scope `# type: ignore` comments to enclosing expressions. Auto-formatter users, rejoice! The `--warn-unused-ignores` semantics should be clear from the test cases. Basically, ignores in inner scopes take precedence over ignores in enclosing scopes, and the first of multiple ignores in a scope "wins". A few notes: - This adds a new slot, `Context.end_line`. It defaults to `None` in the absence of an `end_lineno` or if `Context` is not an expression. - `ErrorInfo.origin` now has a third member, representing the end line of the error context. It is used to determine the range of lines to search for `# type: ignore` comments. If unavailable, it defaults to the same value as the origin line. - Because this uses 3.8-only AST features, a new `check-38.test` file has been created, and is hidden behind a version guard in `testcheck.py`.
- Loading branch information
1 parent
94746d6
commit 153536b
Showing
6 changed files
with
121 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
[case testIgnoreScopeIssue1032] | ||
def f(a: int): ... | ||
f( | ||
"IGNORE" | ||
) # type: ignore | ||
|
||
[case testIgnoreScopeNested1] | ||
def f(a: int) -> int: ... | ||
f( | ||
f( | ||
"IGNORE" | ||
) # type: ignore | ||
) | ||
|
||
[case testIgnoreScopeNested2] | ||
[ | ||
"IGNORE" # type: ignore | ||
& | ||
"IGNORE", | ||
] | ||
[builtins fixtures/list.pyi] | ||
|
||
[case testIgnoreScopeNested3] | ||
{ | ||
"IGNORE" | ||
| # type: ignore | ||
"IGNORE", | ||
} | ||
[builtins fixtures/set.pyi] | ||
|
||
[case testIgnoreScopeNested4] | ||
{ | ||
None: "IGNORE" | ||
^ | ||
"IGNORE", # type: ignore | ||
} | ||
[builtins fixtures/dict.pyi] | ||
|
||
[case testIgnoreScopeNestedNonOverlapping] | ||
def f(x: int): ... | ||
def g(x: int): ... | ||
( | ||
f("ERROR"), # E: Argument 1 to "f" has incompatible type "str"; expected "int" | ||
g("IGNORE"), # type: ignore | ||
f("ERROR"), # E: Argument 1 to "f" has incompatible type "str"; expected "int" | ||
) | ||
|
||
[case testIgnoreScopeNestedOverlapping] | ||
def f(x: int): ... | ||
def g(x: int): ... | ||
( | ||
f("ERROR"), g( # E: Argument 1 to "f" has incompatible type "str"; expected "int" | ||
"IGNORE" # type: ignore | ||
), f("ERROR"), # E: Argument 1 to "f" has incompatible type "str"; expected "int" | ||
) | ||
|
||
[case testIgnoreScopeUnused1] | ||
# flags: --warn-unused-ignores | ||
( # type: ignore # N: unused 'type: ignore' comment | ||
"IGNORE" # type: ignore | ||
+ # type: ignore # N: unused 'type: ignore' comment | ||
0 # type: ignore # N: unused 'type: ignore' comment | ||
) # type: ignore # N: unused 'type: ignore' comment | ||
|
||
[case testIgnoreScopeUnused2] | ||
# flags: --warn-unused-ignores | ||
( # type: ignore # N: unused 'type: ignore' comment | ||
"IGNORE" | ||
- # type: ignore | ||
0 # type: ignore # N: unused 'type: ignore' comment | ||
) # type: ignore # N: unused 'type: ignore' comment | ||
|
||
[case testIgnoreScopeUnused3] | ||
# flags: --warn-unused-ignores | ||
( # type: ignore # N: unused 'type: ignore' comment | ||
"IGNORE" | ||
/ | ||
0 # type: ignore | ||
) # type: ignore # N: unused 'type: ignore' comment |