-
-
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 all commits
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 |
---|---|---|
|
@@ -841,6 +841,103 @@ 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 | ||
|
||
def error() -> NoReturn: ... | ||
|
||
try: | ||
error() | ||
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, ): | ||
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 testUnreachableFlagIgnoreVariablesInExcept] | ||
# flags: --warn-unreachable | ||
from typing import NoReturn, Union, Type, Tuple | ||
|
||
def error() -> NoReturn: ... | ||
class MyError(BaseException): ... | ||
|
||
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 |
||
omit: Union[Type[RuntimeError], Type[MyError]] | ||
|
||
try: | ||
error() | ||
except ignore: | ||
pass | ||
except exclude: | ||
pass | ||
except omit: | ||
pass | ||
except RuntimeError: | ||
pass | ||
[builtins fixtures/exception.pyi] | ||
|
||
[case testUnreachableFlagExceptWithUnknownBaseClass] | ||
# flags: --warn-unreachable | ||
from typing import Any, NoReturn | ||
|
||
Parent: Any | ||
class MyError(Parent): ... | ||
def error() -> NoReturn: ... | ||
|
||
try: | ||
error() | ||
except MyError: | ||
pass | ||
except Exception: | ||
pass | ||
except MyError: # E: Except is unreachable, "MyError" has already been caught | ||
pass | ||
[builtins fixtures/exception.pyi] | ||
|
||
[case testUnreachableFlagExceptWithError] | ||
# flags: --warn-unreachable | ||
from typing import NoReturn | ||
|
||
# The following class is not derived from 'BaseException'. Thus an error is raised | ||
# resulting in Any as type for the class in the exception expression. Such cases | ||
# must be ignored in the rest of the reachability analysis. | ||
class NotFromBaseException: ... | ||
|
||
def error() -> NoReturn: ... | ||
|
||
try: | ||
error() | ||
except NotFromBaseException: # E: Exception type must be derived from BaseException | ||
pass | ||
except RuntimeError: | ||
pass | ||
except NotImplementedError: # E: Except is unreachable, superclass "RuntimeError" of "NotImplementedError" has already been caught | ||
pass | ||
[builtins fixtures/exception.pyi] | ||
|
||
[case testUnreachableExceptWithoutUnreachableFlag] | ||
from typing import NoReturn | ||
|
||
def error() -> NoReturn: ... | ||
|
||
try: | ||
error() | ||
except Exception: | ||
pass | ||
except RuntimeError: | ||
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.
Sorry, this is not what I meant 🙂
Theoretically we can have a case when some var has
type[SomeException] | Any
type. For example, from unresolved import or some runtime magic.Is there anything we can do to handle this case here? Or shall we ignore it?
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.
I think I know what you mean. So, we do not have a variable, but a class whose type might be a Union.
I do not how how to construct such a case for testing, can you help me with that? I was also not able to find something in
check-statements.test
The tests already cover:
Nevertheless, it think this scenario would not pass the new
or isinstance(typ, UnionType)
filter, thus we would just ignore it.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.
@sobolevn any updates here? ;)