summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2019-11-21 09:45:33 +0100
committerClaudiu Popa <pcmanticore@gmail.com>2019-11-21 09:45:33 +0100
commit42c6fa232e24ab28891e63541f6f832a703a770d (patch)
tree8a4d54b772afdfb48257a527471c53fc2e9040c0
parentca6a644ffb67ae5867424507afdc4d64dd0c3136 (diff)
downloadpylint-git-42c6fa232e24ab28891e63541f6f832a703a770d.tar.gz
Fixed an ``AttributeError`` caused by improper handling of ``dataclasses`` inference in ``pyreverse``
Close #3256
-rw-r--r--ChangeLog7
-rw-r--r--pylint/pyreverse/inspector.py3
-rw-r--r--tests/regrtest_data/dataclasses_pyreverse/__init__.py13
-rw-r--r--tests/unittest_pyreverse_diadefs.py14
4 files changed, 34 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index fc7b8a1d1..e90c5e230 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,11 +11,14 @@ Release date: TBA
Close #2242
-* Don't emit ``line-too-long`` for multilines when a
- `pylint:disable=line-too-long` comment stands at their end
+* Don't emit ``line-too-long`` for multilines when `disable=line-too-long` comment stands at their end
Close #2957
+* Fixed an ``AttributeError`` caused by improper handling of ``dataclasses`` inference in ``pyreverse``
+
+ Close #3256
+
* Do not exempt bare except from ``undefined-variable`` and similar checks
If a node was wrapped in a ``TryExcept``, ``pylint`` was taking a hint
diff --git a/pylint/pyreverse/inspector.py b/pylint/pyreverse/inspector.py
index 702b1084a..0a933afcc 100644
--- a/pylint/pyreverse/inspector.py
+++ b/pylint/pyreverse/inspector.py
@@ -163,7 +163,8 @@ class Linker(IdGeneratorMixIn, utils.LocalsVisitor):
node.instance_attrs_type = collections.defaultdict(list)
for assignattrs in node.instance_attrs.values():
for assignattr in assignattrs:
- self.handle_assignattr_type(assignattr, node)
+ if not isinstance(assignattr, astroid.Unknown):
+ self.handle_assignattr_type(assignattr, node)
# resolve implemented interface
try:
node.implements = list(interfaces(node, self.inherited_interfaces))
diff --git a/tests/regrtest_data/dataclasses_pyreverse/__init__.py b/tests/regrtest_data/dataclasses_pyreverse/__init__.py
new file mode 100644
index 000000000..e4c923343
--- /dev/null
+++ b/tests/regrtest_data/dataclasses_pyreverse/__init__.py
@@ -0,0 +1,13 @@
+from dataclasses import dataclass
+
+
+@dataclass
+class InventoryItem:
+ """Class for keeping track of an item in inventory."""
+
+ name: str
+ unit_price: float
+ quantity_on_hand: int = 0
+
+ def total_cost(self) -> float:
+ return self.unit_price * self.quantity_on_hand
diff --git a/tests/unittest_pyreverse_diadefs.py b/tests/unittest_pyreverse_diadefs.py
index 0659a5b11..307f22a94 100644
--- a/tests/unittest_pyreverse_diadefs.py
+++ b/tests/unittest_pyreverse_diadefs.py
@@ -13,6 +13,9 @@
unit test for the extensions.diadefslib modules
"""
+import sys
+from pathlib import Path
+
import astroid
import pytest
@@ -173,3 +176,14 @@ def test_known_values2(HANDLER, PROJECT):
(True, "DoNothing"),
(True, "Specialization"),
]
+
+
+@pytest.mark.skipif(sys.version_info < (3, 8), reason="Requires dataclasses")
+def test_regression_dataclasses_inference(HANDLER):
+ project_path = Path("regrtest_data") / "dataclasses_pyreverse"
+ path = get_project(str(project_path))
+
+ cdg = ClassDiadefGenerator(Linker(path), HANDLER)
+ special = "regrtest_data.dataclasses_pyreverse.InventoryItem"
+ cd = cdg.class_diagram(path, special)
+ assert cd.title == special