summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--pylint/checkers/utils.py8
-rw-r--r--pylint/test/functional/try_except_raise_crash.py25
-rw-r--r--pylint/test/functional/try_except_raise_crash.txt1
4 files changed, 42 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 4e7fc9874..dad70c637 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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