-
-
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
Function line number information is not always correct #3871
Comments
IMO asking for the line number where the return annotation should go (i.e.
where the '):' is) is overkill, but asking for the line number for the
'def' is reasonable.
|
Hm, that is probably true now that I think about it more. That would also have the added bonus of better error messages if a function name is redefined. I was thinking that since on larger functions it is common to split arguments over multiple lines, it would be nice to give an exact line number of where to put the annotation, but now that I think about it, if we point to the name, it shouldn't be too bad for the user to modify the return of that function. Perhaps we could add a |
That sounds reasonable. |
I think we should do the same for classes (i.e. add |
I think I would have been confused too if that ignore comment had not been on the decorator line. :) |
I agree with @ilevkivskyi adding a If nothing else, it will correctly report name re-definitions better.
I got busy with a PEP, so this is up for grabs |
I should mention there is an open bpo issue about this exact problem. https://bugs.python.org/issue33211 |
So if we do this, it will require a change from:
to
everywhere, which is semantically more correct, but shows up a fair amount in typeshed (cc @JelleZijlstra, I'm happy to work on changing the occurrences of this). That also means pytype will need to make a similar patch. @matthiaskramm, since Google already patches their ast, I hope it wouldn't hurt to patch it a bit more? The totality of changes to the ast are a handful of lines (see ethanhs/typed_ast@51b8d3e and note only the first file is the patch you'd need). |
For pytype, Matthias is no longer on that project, @rchen152 is his replacement. |
So if I understand correctly, the problem is that in typeshed, "# type: ignore" comments are going to move from the first line of the first decorator to the line on which "def" appears, so pytype will need to change its pyi parsing to handle this? If that's it, then everything is fine! Pytype ignores "# type: ignore" in a pyi file. |
Ah, I didn't know that! Apologies.
Yes exactly.
Excellent! I will work on the changes tomorrow then. |
Should we do this or not? I worry that just changing the lineno attribute of FunctionDef and ClassDef nodes will break tons of users' code since it changes where OTOH in Python 3.8 the ast module moves the lineno attributes of these nodes, so in the long run we may have no choice (and to do it we would have to update typed_ast first, see python/typed_ast#50). |
I recently had a PR merged (#6648) that recognizes If this seems like a viable solution, I'd be happy to write a PR. |
But that will only affect 3.8, right? Maybe that’s okay and we should just keep the existing behavior for older versions—and not modify typed-ast. |
Correct, 3.8 only. It would probably make any planned transition smoother too, since 3.8 users will have the option of the "correct" line (i.e. in new 3.8 code) or the "compatibility" line (i.e. in typeshed). |
Yeah, this sounds like a good thing to have. |
Awesome, I'll begin work on this. |
Fixes #3871. This change fixes a few things concerning class/function definition line numbers. For users running mypy with Python 3.8+: - Function definitions are now reported on the correct line, rather than the line of the first decorator plus the number of decorators. - Class definitions are now reported on the correct line, rather than the line of the first decorator. - **These changes are fully backward compatible with respect to `# type: ignore` lines**. In other words, existing comments will _not_ need to be moved. This is accomplished by defining an ignore "scope" just like we added to expressions with #6648. See the recent discussion at #3871 for reasoning. For other users (running mypy with Python 3.7 or earlier): - Class definition lines are reported by using the same decorator-offset estimate as functions. This is both more accurate, and necessary to get 15 or so tests to pass for both pre- and post-3.8 versions. This seems fine, since there [doesn't appear](#6539 (comment)) to be a compelling reason why it was different in the first place. - **This change is also backward-compatible with existing ignores, as above.** About 15 tests had to have their error messages / nodes moved down one line, and 4 new regression tests have been added to `check-38.test`.
Currently, the line number of the function definition is not correct leading to issues such as #3869.
In the Python ast (as well as type-ast) the
FunctionDef
node we use to, for example, report missing return annotations gives a line number of the beginning of the first decorator (if any). Therefore it can incorrectly report the line number information we need to report errors.Our currently logic increments the line number of any decorators, however, we cannot depend on this to be consistent. Consider this problematic (but completely valid!) example:
The
FunctionDef.lineno
would be 1, so mypy will reporttest.py:2: error: Function is missing a return type annotation
. However, the return should be on line 8! Note that blanks space between the body and end of the function definition node means we cannot decrement based on the first item in the body of the function.As a first possible solution, we could modify
typed_ast
to give the line number of thereturns
if the function is not typed (currently it just puts the attribute as None), so that the information is known, but it clearly indicates that the node is empty. This is certainly not an ideal solution.Corresponding issue opened in python/typed_ast#50
The text was updated successfully, but these errors were encountered: