diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2019-11-21 09:45:33 +0100 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2019-11-21 09:45:33 +0100 |
commit | 42c6fa232e24ab28891e63541f6f832a703a770d (patch) | |
tree | 8a4d54b772afdfb48257a527471c53fc2e9040c0 | |
parent | ca6a644ffb67ae5867424507afdc4d64dd0c3136 (diff) | |
download | pylint-git-42c6fa232e24ab28891e63541f6f832a703a770d.tar.gz |
Fixed an ``AttributeError`` caused by improper handling of ``dataclasses`` inference in ``pyreverse``
Close #3256
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | pylint/pyreverse/inspector.py | 3 | ||||
-rw-r--r-- | tests/regrtest_data/dataclasses_pyreverse/__init__.py | 13 | ||||
-rw-r--r-- | tests/unittest_pyreverse_diadefs.py | 14 |
4 files changed, 34 insertions, 3 deletions
@@ -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 |