-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Change end line and column for untyped function defs to line of function definition #17006
base: master
Are you sure you want to change the base?
Changes from all commits
5f88e5d
c780ac1
707e4aa
8b7802c
6dee499
37ee833
081c8cb
b835494
5a7c0ec
38f311a
796d6ee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -178,6 +178,79 @@ if int(): | |
def g(x): # E:5: Function is missing a type annotation | ||
pass | ||
|
||
[case testPrettyFunctionMissingTypeAnnotation] | ||
# flags: --disallow-untyped-defs --pretty | ||
def function_with_long_name(): | ||
pass | ||
[out] | ||
main:2:1: error: Function is missing a return type annotation | ||
def function_with_long_name(): | ||
^ | ||
main:2:1: note: Use "-> None" if function does not return a value | ||
|
||
[case testColumnEndFunctionMissingTypeAnnotation] | ||
# flags: --disallow-untyped-defs --show-error-end | ||
from typing import Any, Optional | ||
if int(): | ||
def f(): | ||
pass | ||
|
||
def f_no_return(x: int, foo: Optional[str]): | ||
pass | ||
|
||
def f_default(x: int, foo: Optional[str] = None): | ||
pass | ||
|
||
def f_default_untyped(x, foo = None): | ||
pass | ||
|
||
def f_args(x, *args): | ||
pass | ||
|
||
def f_kwargs(x, *args, **kwargs): | ||
pass | ||
[builtins fixtures/tuple.pyi] | ||
[out] | ||
main:4:5:4:5: error: Function is missing a return type annotation | ||
main:4:5:4:5: note: Use "-> None" if function does not return a value | ||
main:7:5:7:47: error: Function is missing a return type annotation | ||
main:10:5:10:52: error: Function is missing a return type annotation | ||
main:13:5:13:40: error: Function is missing a type annotation | ||
main:16:5:16:24: error: Function is missing a type annotation | ||
main:19:5:19:36: error: Function is missing a type annotation | ||
|
||
[case testColumnEndFunctionMissingTypeAnnotationWithReturnType] | ||
# flags: --disallow-untyped-defs --show-error-end | ||
def f() -> None: | ||
pass | ||
|
||
def f_partially_typed(x: int, foo) -> None: | ||
pass | ||
|
||
def f_untyped(x, foo, *args, **kwargs) -> None: | ||
pass | ||
[builtins fixtures/tuple.pyi] | ||
[out] | ||
main:5:1:5:43: error: Function is missing a type annotation for one or more arguments | ||
main:8:1:8:47: error: Function is missing a type annotation for one or more arguments | ||
|
||
[case testColumnEndMultiline] | ||
# flags: --disallow-untyped-defs --warn-no-return --show-error-end | ||
def f( | ||
x: int, | ||
y: int, | ||
): | ||
pass | ||
|
||
def g( | ||
x: int, | ||
y: int, | ||
) -> int: | ||
x = 1 | ||
[out] | ||
main:2:1:4:11: error: Function is missing a return type annotation | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's unfortunate that the closing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree. I unfortunately don't know how this could be fixed since it is unavailable in the AST. For reference: I did find There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand. I'm still struggling with this case (as well as the one above where if the function has no annotations at all, we emit a one-character range); I'm worried this PR may lead to more confusing output in some cases. However, on balance it's probably fine and we can apply this change, but consider reverting it if there's a lot of negative feedback. We could also consider looking at the first start position in the body of the function, but then the whitespace between the colon and the first statement would be included in the range. |
||
main:8:1:11:9: error: Missing return statement | ||
|
||
[case testColumnNameIsNotDefined] | ||
((x)) # E:3: Name "x" is not defined | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the new attributes will also need to be serialized, or they may get lost in incremental mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked in
nodes.py
and no node serializesend_line
orend_column
. The same forline
andcolumn
with the exception of theTypeAlias
node (it's unclear to me why).I did a quick test invoking mypy with
--incremental --disallow-untyped-defs --show-error-end
on the same file twice which resulted in consistent results.