Skip to content

Commit

Permalink
Added support for astroid ≥ 2.6.0 (#38)
Browse files Browse the repository at this point in the history
The code in astroid underwent a minor refactoring and broke the public
interface (`ALL_NODE_CLASSES` were moved to `astroid.nodes` module).
This had repercussions on pyicontract-lint since an assertion depends on
it.

This patch examines the version of astroid and adapts the assertion
according to the version so that both older and newer versions of
astroid are supported.

Fixes #37.
  • Loading branch information
mristin committed Jul 1, 2021
1 parent 42138dc commit a6c8043
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
21 changes: 19 additions & 2 deletions icontract_lint/__init__.py
Expand Up @@ -7,7 +7,7 @@
import re
import sys
import traceback
from typing import Set, List, Mapping, Optional, TextIO, Any
from typing import Set, List, Mapping, Optional, TextIO, Any, Tuple

import astroid
import astroid.modutils
Expand All @@ -26,6 +26,13 @@
__license__ = pyicontract_lint_meta.__license__
__copyright__ = pyicontract_lint_meta.__copyright__

# noinspection PyBroadException
try:
_ASTROID_VERSION_TUPLE = tuple(
int(part) for part in re.split('.', astroid.__version__)) # type: Optional[Tuple[int, ...]]
except Exception: # pylint: disable=broad-except
_ASTROID_VERSION_TUPLE = None


class ErrorID(enum.Enum):
"""Enumerate error identifiers."""
Expand Down Expand Up @@ -101,7 +108,17 @@ class _AstroidVisitor:
If the visit function has not been defined, ``visit_generic`` is invoked.
"""

assert "generic" not in [cls.__class__.__name__ for cls in astroid.ALL_NODE_CLASSES]
if _ASTROID_VERSION_TUPLE is not None and _ASTROID_VERSION_TUPLE < (2, 6, 0):
_ALL_NODE_CLASSES = [cls.__class__.__name__ for cls in astroid.ALL_NODE_CLASSES]
else:
_ALL_NODE_CLASSES = [cls.__class__.__name__ for cls in astroid.nodes.ALL_NODE_CLASSES]

assert "generic" not in _ALL_NODE_CLASSES, \
(
"We need ``generic`` as reserved name for the visitor (``visit_generic``). "
"However, if there is a class in the astroid with the same name, it would break the visitor. "
"(The version of astroid is: {}.)".format(astroid.__version__)
)

def visit(self, node: astroid.node_classes.NodeNG):
"""Enter the visitor."""
Expand Down
7 changes: 6 additions & 1 deletion setup.py
Expand Up @@ -40,7 +40,12 @@
license='License :: OSI Approved :: MIT License',
keywords='design-by-contract precondition postcondition validation lint',
packages=find_packages(exclude=['tests']),
install_requires=['icontract>=2.0.0,<3', 'astroid>=2.4.2,<3'],
install_requires=[
# yapf: disable
'icontract>=2.0.0,<3',
'astroid>=2.4.2,<3'
# yapf: enable
],
extras_require={
'dev': [
# yapf: disable
Expand Down

0 comments on commit a6c8043

Please sign in to comment.