-
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
RSE102 error despite parentheses being necessary #5416
Comments
Thank you for the kind words :) So, I think the issue here is that a function call (rather than a class instantiation) is being passed to the
In other words, what we'd like to do here is guard against triggering |
I agree, the raising from a function example is a bit odd :). I encountered this in a situation closer to the following example (perhaps a bit less odd? Still raising from a function call though): class CustomError(Exception):
def __init__(self, msg: str):
self.msg = msg
@staticmethod
def timeout():
return CustomError("Operation timed out!")
raise CustomError.timeout() These kinds of instantiations of exceptions of course don't trigger RSE102 when they are called with arguments. But if you have a way of distinguishing function calls from class instantiations with no arguments, then that would of course be the perfect solution! |
This is being worked on in #5536. |
## Summary This PR enables us to resolve attribute accesses within files, at least for static and class methods. For example, we can now detect that this is a function access (and avoid a false-positive): ```python class Class: @staticmethod def error(): return ValueError("Something") # OK raise Class.error() ``` Closes #5487. Closes #5416.
Great work! Thank you for the quick response and fix. Looking forward to this in upcoming releases :) |
Still occurs to me in 0.0.285. Is that expected? |
I think the current version only works for definitions and |
Indeed, that's the problem.
class CustomError(Exception):
def __init__(self, msg: str):
self.msg = msg
@staticmethod
def timeout():
return CustomError("Operation timed out!")
from backend.ruff_bug.custom import CustomError
raise CustomError().timeout() Auto-fix will remove the method call:
from ruff_bug.custom import CustomError
raise CustomError().timeout |
Raising |
Wow, that's a function? That's a rough API. Anyway, we can special-case it. |
An example from the python standard library: from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor() as executor:
future = executor.submit(float, "a")
if future.exception():
raise future.exception() # RSE102 Unnecessary parentheses on raised exception |
@charliermarsh |
Fixed here: #10206 |
Hello, thank you for ruff, it's fantastic!
I encountered this small bug regarding rule RSE102.
Ruff version:
ruff 0.0.274
Ruff settings: All rules turned on (ignoring a few specific ones, not relevant here).
Minimal code snippet:
Commands to reproduce:
Resulting file after autofix:
Issue:
The line
raise return_error()
is diagnosed as violating RSE102 (Unecessary parentheses on raised exception), despite the parentheses being necessary.This gets autofixed as
raise return_error
, which raises aTypeError
(as the function isn't an exception) instead of aValueError
.Solution idea (I took a quick glance at the changes in #2596, but I'm not well versed enough in Rust to fully understand them.):
When autofixing, instead of removing any empty parentheses at the end of
raise ...
lines, only attempt to remove them when they come directly after the name of a built-in exception (e.g.ValueError
,TypeError
,(asyncio.)?CancelledError
, etc.).So lines like
can be autofixed into
but lines like
would require manual fixing.
Maybe you have some more clever solution to this than matching a long list of built-in exceptions, but I hope this helps though!
The text was updated successfully, but these errors were encountered: