Skip to content
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

ruff exits with code 0 if there's a SyntaxError but rule E999 is not selected #8447

Open
gavriil-deshaw opened this issue Nov 2, 2023 · 9 comments
Labels
bug Something isn't working help wanted Contributions especially welcome

Comments

@gavriil-deshaw
Copy link

As per the title, if the rule with code E999 is not included in the configuration, then ruff will terminate successfully even if there's a SyntaxError. So, for example, if one wanted to run ruff against only the Pylfakes rules, the logical configuration for the rules would be --select F, but this doesn't work as expected.

Specifically, running ruff --select F <filename.py> exits with code 0 even if there's a SyntaxError - it does print error: Failed to parse but it doesn't raise an error. I believe this shouldn't be the default behavior as it would allow ruff to succeed in automated pipelines even with a SyntaxError (and possibly other F code errors). As a workaround for the mentioned use-case, one can also include E999 in the selected rules. However, this isn't very intuitive since having a SyntaxError means that an AST can't be generated and so, even if E999 isn't really a Pyflakes error, the python code can't be run.

FWIW, ruff rules list E999 as a pycodestyle error code, while in reality it's a code returned by flake8 when it can't generate an AST for a given file. The equivalent pycodestyle code is E901 SyntaxError or IndentationError as listed here.

@zanieb
Copy link
Member

zanieb commented Nov 2, 2023

Seems reasonable to change the exit code if we fail to parse any files — I'm unsure of the difficulty to implement this.

@zanieb zanieb added bug Something isn't working help wanted Contributions especially welcome labels Nov 2, 2023
@gavriil-deshaw
Copy link
Author

Thanks for your prompt response!

Would it be unreasonable to exit with code 1 after a ParseError? I'm not Rust expert, so I might be missing something, but I seem to have that working with a 2-line change. It works as intended and all the tests pass (cargo test | rg '; [1-9]?* failed' | wc -l outputs 0). If this isn't the desired behavior, an alternative would be to add cli option that would trigger this.

What do you think?

@zanieb
Copy link
Member

zanieb commented Nov 2, 2023

What's the two line change? :)

I think we want to still lint the remaining files, so only exit at the end.

@gavriil-deshaw
Copy link
Author

@zanieb I did it by just exiting with code 1 after displaying the ParseError, but that indeed means that the remaining files aren't linted. IMHO, this is a more intuitive behavior, but I imagine that it might break things for people who accommodate for the current behavior.

@charliermarsh what if you just add a cli option to exit if there's a ParseError? I think that's reasonable, if it's easily doable.

In any case, you obviously know the codebase (and other related issues logged) better than I do, so I'll leave this up to you :))

Thanks!

@zanieb
Copy link
Member

zanieb commented Nov 2, 2023

I don't think exiting on the first error is an acceptable solution, unfortunately. We have people that rely on the current behavior and we can perform some lints despite syntax errors in a file.

@tusharsadhwani
Copy link
Contributor

This affects writing rules as well, you write a new rule E123, and you run:

$ cargo run -p ruff -- check foo.py --no-cache --preview --select E123
    Finished dev [unoptimized + debuginfo] target(s) in 0.13s
     Running `target/debug/ruff check foo.py --no-cache --preview --select E123`
error: Failed to parse foo.py:1:5: Simple statements must be separated by newlines or semicolons
All checks passed!

The last line gives a false sense of everything working.


I think putting a seen_parse_error boolean flag in LinterResult and propagating it up to Diagnostics would be an okay strategy to implement this?

@zanieb
Copy link
Member

zanieb commented May 2, 2024

I believe @dhruvmanila might eventually be looking into how we can surface parse errors as diagnostics?

@dhruvmanila
Copy link
Member

Yes, ideally the syntax errors should be surfaced using the same diagnostic system Ruff uses to display lint errors. There are still some outstanding questions with regards to the exit code and how should E999 be used here but it should get clear when I start working on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Contributions especially welcome
Projects
None yet
Development

No branches or pull requests

5 participants