-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Report unreachable except blocks #12086
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
Changes from 1 commit
1867387
14ee9a1
374e680
5b4d73d
0576eff
0c3d194
143ae23
329bd36
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1386,6 +1386,15 @@ def note_call(self, | |
def unreachable_statement(self, context: Context) -> None: | ||
self.fail("Statement is unreachable", context, code=codes.UNREACHABLE) | ||
|
||
def already_caught(self, typ: Type, context: Context) -> None: | ||
self.fail("Except is unreachable, {} has already been caught".format(format_type(typ)), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's add new simple errors to |
||
context, code=codes.UNREACHABLE) | ||
|
||
def superclass_already_caught(self, typ: Type, super_typ: Type, context: Context) -> None: | ||
self.fail("Except is unreachable, superclass {} of {} has already been caught" | ||
.format(format_type(super_typ), format_type(typ)), context, | ||
code=codes.UNREACHABLE) | ||
|
||
def redundant_left_operand(self, op_name: str, context: Context) -> None: | ||
"""Indicates that the left operand of a boolean expression is redundant: | ||
it does not change the truth value of the entire condition as a whole. | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -841,6 +841,38 @@ def baz(x: int) -> int: | |||||
return x | ||||||
[builtins fixtures/exception.pyi] | ||||||
|
||||||
[case testUnreachableFlagExcepts] | ||||||
# flags: --warn-unreachable | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need the same test (or simplified) without this flag to make sure it does not produce any errors in normal mode. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where should this test go? Still in In
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, |
||||||
from typing import Type, NoReturn, Tuple | ||||||
|
||||||
def error() -> NoReturn: ... | ||||||
|
||||||
ignore: Type[Exception] | ||||||
exclude: Tuple[Type[Exception], ...] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's also test |
||||||
class ContinueOnError: pass | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Is this what you meant? 🤔 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wanted to provoke I will add a test to make this more clear. |
||||||
|
||||||
try: | ||||||
error() | ||||||
except ignore: | ||||||
pass | ||||||
except exclude: | ||||||
pass | ||||||
except ContinueOnError: # E: Exception type must be derived from BaseException | ||||||
pass | ||||||
except Exception: | ||||||
pass | ||||||
except Exception as err: # E: Except is unreachable, "Exception" has already been caught | ||||||
pass | ||||||
except RuntimeError: # E: Except is unreachable, superclass "Exception" of "RuntimeError" has already been caught | ||||||
pass | ||||||
except (NotImplementedError, ): | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that this should be reported as unreachable as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean I should support tuples in general or only this special case? My feeling is that this already makes the code more complex, because the simple check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can defer this to the next PR I guess 🙂 |
||||||
pass | ||||||
except NotImplementedError: # E: Except is unreachable, superclass "Exception" of "NotImplementedError" has already been caught | ||||||
pass | ||||||
except NotImplementedError: # E: Except is unreachable, superclass "Exception" of "NotImplementedError" has already been caught | ||||||
pass | ||||||
[builtins fixtures/exception.pyi] | ||||||
|
||||||
[case testUnreachableFlagIgnoresSemanticAnalysisUnreachable] | ||||||
# flags: --warn-unreachable --python-version 3.7 --platform win32 --always-false FOOBAR | ||||||
import sys | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be a
Union
withAny
type as well 🤔There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you think of a case where this happens?
I would argue that his can only happen for variables and tuples (which are both filtered with the
if expr and isinstance(expr, NameExpr) and isinstance(expr.node, TypeInfo):
)For safety reasons: I can add Union to the check
if isinstance(typ, AnyType) or isinstance(typ, UnionType):