diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | pylint/checkers/utils.py | 8 | ||||
-rw-r--r-- | pylint/test/functional/try_except_raise_crash.py | 25 | ||||
-rw-r--r-- | pylint/test/functional/try_except_raise_crash.txt | 1 |
4 files changed, 42 insertions, 2 deletions
@@ -7,6 +7,16 @@ What's New in Pylint 2.3.0? Release date: TBA +* Protect against `NonDeducibleTypeHierarchy` when calling semi-private `is_subtype` + + `astroid.helpers.is_subtype` raises `NonDeducibleTypeHierarchy` when it cannot infer + the base classes of the given types, but that makes sense in its context given that + the method is mostly used to inform the inference process about the hierarchy of classes. + Doesn't make that much sense for ``pylint`` itself, which is why we're handling the + exception here, rather than in ``astroid`` + + Close PyCQA/astroid#644 + * Added a new command line option ``list-groups`` for listing all the check groups ``pylint`` knows about. * Allow ``BaseException`` for emitting ``broad-except``, just like ``Exception``. diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index 3cc292115..b4129389f 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -40,6 +40,7 @@ from typing import Optional, Iterable, Tuple, Callable, Set, Union, Match, Dict, import _string # pylint: disable=wrong-import-position, wrong-import-order import astroid +from astroid.exceptions import _NonDeducibleTypeHierarchy from astroid import bases as _bases from astroid import scoped_nodes @@ -1202,6 +1203,9 @@ def is_subclass_of(child: astroid.ClassDef, parent: astroid.ClassDef) -> bool: return False for ancestor in child.ancestors(): - if astroid.helpers.is_subtype(ancestor, parent): - return True + try: + if astroid.helpers.is_subtype(ancestor, parent): + return True + except _NonDeducibleTypeHierarchy: + continue return False diff --git a/pylint/test/functional/try_except_raise_crash.py b/pylint/test/functional/try_except_raise_crash.py new file mode 100644 index 000000000..7a1f8d972 --- /dev/null +++ b/pylint/test/functional/try_except_raise_crash.py @@ -0,0 +1,25 @@ +# pylint: disable=missing-docstring,too-many-ancestors, broad-except +import collections.abc +from typing import TYPE_CHECKING, Any, MutableMapping + +if TYPE_CHECKING: + BaseClass = MutableMapping[str, Any] +else: + BaseClass = collections.abc.MutableMapping + + +class TestBaseException(BaseClass): + pass + + +class TestException(TestBaseException): + pass + + +def test(): + try: + 1 / 0 + except TestException: # [try-except-raise] + raise + except Exception: + pass diff --git a/pylint/test/functional/try_except_raise_crash.txt b/pylint/test/functional/try_except_raise_crash.txt new file mode 100644 index 000000000..a99476ab9 --- /dev/null +++ b/pylint/test/functional/try_except_raise_crash.txt @@ -0,0 +1 @@ +try-except-raise:22:test:The except handler raises immediately |