better alternative to flake8's "E902 TokenError: EOF in multi-line statement"

1.2k Views Asked by At

I do understand the E902 error, however I do think it's a bit "messy". This is for 2 reasons:

  • It feels to me that it should be F902 (a failure rather than an error). After all, as I see it in Flake's world, errors are things that are wrong in the style guide (e.g. having 3 newlines in a row), whereas Failures are things that will not make the program run (e.g. referencing a variable before declaration). In other words, when I save a python file in my IDE, I should be happy to ignore any errors (as long as I'm just hacking away), but want to be alerted of anything that is obviously a mistake (and not just me not caring about things). Obviously writing not valid python is even worse than using a variable before declaring it (which in some cases, will actually run).
  • More importantly, I feel that it's very unhelpful that this error always points to line 1 character 1. This means it's up to me to start looking in the code (of files sometimes 1000s lines long) to the exact spot where I forgot to close a parenthesis, or run another tool (such as just running python on the file) to find the exact line. Also, this means that my editor (VIM) will not show any error for the line I'm working on; I will only see the error if I scroll up all the way.

I guess my questions are threefold:

  • Why is E902 an error instead of a failure (not super important, but if there's a rationale behind it' I'd be happy to learn it)
  • Is there a good reason that E902 error is always on line 1 col 1, or is this just that not enough resources have been spent (yet) to have it point to the right spot in the code).
  • Most importantly: is there an accepted / better way for this? Perhaps a wrapper around flake8 that, in case of a E902 error uses some other way to find a more accurate spot (note that pyflakes, which is part of flake8, does find the correct line; probably not a good idea to run python since there does not seem to be a way to tell python to only parse the file but not actually run it.). I'm sure I can create such a wrapper myself, but if other/smarter people already made one, I'd prefer to reuse their work.

For completeness, the following code shows the issue:

def x():
    pass


x(
a = 1
b = 2

Both pyflakes and python show an error in line 7 (which at least is very close to where the error is made), whereas flake8 will just show the error on 1:1

1

There are 1 best solutions below

0
On

answering all three of the questions (usually separate questions should be separate questions on SO but...):

  1. the E / F / W codes do not mean error / failure / warning -- the prefix is a coincidence. F codes come from pyflakes, E and W codes come from pycodestyle (though there are two special E codes inherited from pycodestyle that remain -- E902 and E999 for OSError and SyntaxError -- I'd love to change this but the sheer number of people using flake8 makes breaking changes tricky)

  2. it is col 1 line 1 because this error comes from the tokenizer and it reports the error out-of-bounds on the last line of the file. the tokenizer is not very good about giving precise error locations

  3. it is considered a bug, but nobody has volunteered to work on it yet, if I'm reading it correctly it should be a 2 line fix -- you can read more about the bug here: https://github.com/PyCQA/flake8/issues/740


disclaimer: I'm the current flake8 maintainer