-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
E712: Invalid parentheses removal #4925
Comments
\cc @MichaReiser - A parenthesized node would solve this (just tabulating). In the meantime, we'd need to rewrite with LibCST I think. |
Thanks for the ping. Mutating the tree instead of manually creating text edits would solve that too |
Ideally the edit would be "just" replacing |
Sadly would not work for the opposite reason: if a==True:
... would become if aisTrue:
... |
Just repro'ed another version of this w/ #4822 in libafl mode 😁 if(True) == TrueElement or x == TrueElement:
pass
assert (not Soo) in bar
assert {"x": not foo} in bar cargo run --bin ruff -- --fix ./minimized-from-crash-2c30da3ded030419
Finished dev [unoptimized + debuginfo] target(s) in 0.11s
Running `target/debug/ruff --fix ./minimized-from-crash-2c30da3ded030419`
warning: Detected debug build without --no-cache.
error: Autofix introduced a syntax error in `minimized-from-crash-2c30da3ded030419` with rule codes E712: invalid syntax. Got unexpected token Newline at byte offset 42
---
ifTrue is TrueElement or x == TrueElement:
pass
assert (not Soo) in bar
assert {"x": not foo} in bar
---
minimized-from-crash-2c30da3ded030419:1:4: E712 Comparison to `True` should be `cond is True` or `if cond:`
minimized-from-crash-2c30da3ded030419:1:13: F821 Undefined name `TrueElement`
minimized-from-crash-2c30da3ded030419:1:28: F821 Undefined name `x`
minimized-from-crash-2c30da3ded030419:1:33: F821 Undefined name `TrueElement`
minimized-from-crash-2c30da3ded030419:3:14: F821 Undefined name `Soo`
minimized-from-crash-2c30da3ded030419:3:22: F821 Undefined name `bar`
minimized-from-crash-2c30da3ded030419:4:18: F821 Undefined name `foo`
minimized-from-crash-2c30da3ded030419:4:26: F821 Undefined name `bar`
Found 8 errors. |
I found another, more exciting example of this; consider the following snippet: x = range(0, 10)
def y():
global x
for i in x:
if (yield i) == True:
print("even")
else:
print("odd")
v = y()
next(v)
for i in range(1, 10):
print(v.send(i % 2 == 0)) This is a really dumb program that uses generators wrong, but it gets the point across. Ruff attempts to fix this to: x = range(0, 10)
def y():
global x
for i in x:
if yield i is True:
print("even")
else:
print("odd")
v = y()
next(v)
for i in range(1, 10):
print(v.send(i % 2 == 0)) Which is invalid because the |
This seems like a regression as I can only reproduce this on |
A bisection search gives me 875e04e. Right, so the patch generation was moved from |
## Summary This PR exposes our `is_expression_parenthesized` logic such that we can use it to expand expressions when autofixing to include their parenthesized ranges. This solution has a few drawbacks: (1) we need to compute parenthesized ranges in more places, which also relies on backwards lexing; and (2) we need to make use of this in any relevant fixes. However, I still think it's worth pursuing. On (1), the implementation is very contained, so IMO we can easily swap this out for a more performant solution in the future if needed. On (2), this improves correctness and fixes some bad syntax errors detected by fuzzing, which means it has value even if it's not as robust as an _actual_ `ParenthesizedExpression` node in the AST itself. Closes #4925. ## Test Plan `cargo test` with new cases that previously failed the fuzzer.
E712 fix may remove parentheses in a way which causes invalid syntax:
Becomes:
Discovered by #4822.
The text was updated successfully, but these errors were encountered: