Skip to content

Commit

Permalink
Support cyclic-import message with --jobs
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobtylerwalls committed Jun 30, 2023
1 parent 3a99820 commit f31d375
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 1 deletion.
3 changes: 3 additions & 0 deletions doc/whatsnew/fragments/4171.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Support ``cyclic-import`` message when parallelizing with ``--jobs``.

Closes #4171
13 changes: 12 additions & 1 deletion pylint/checkers/imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ def __init__(self, linter: PyLinter) -> None:
("RP0401", "External dependencies", self._report_external_dependencies),
("RP0402", "Modules dependencies graph", self._report_dependencies_graph),
)
self._excluded_edges: defaultdict[str, set[str]] = defaultdict(set)

def open(self) -> None:
"""Called before visiting project (i.e set of modules)."""
Expand All @@ -463,7 +464,6 @@ def open(self) -> None:
self.import_graph = defaultdict(set)
self._module_pkg = {} # mapping of modules to the pkg they belong in
self._current_module_package = False
self._excluded_edges: defaultdict[str, set[str]] = defaultdict(set)
self._ignored_modules: Sequence[str] = self.linter.config.ignored_modules
# Build a mapping {'module': 'preferred-module'}
self.preferred_modules = dict(
Expand All @@ -488,6 +488,17 @@ def close(self) -> None:
for cycle in get_cycles(graph, vertices=vertices):
self.add_message("cyclic-import", args=" -> ".join(cycle))

def get_map_data(self) -> defaultdict[str, set[str]]:
return self.import_graph

def reduce_map_data(
self, linter: PyLinter, data: list[defaultdict[str, set[str]]]
) -> None:
self.import_graph = defaultdict(set)
for graph in data:
self.import_graph.update(graph)
self.close()

def deprecated_modules(self) -> set[str]:
"""Callback returning the deprecated modules."""
# First get the modules the user indicated
Expand Down
28 changes: 28 additions & 0 deletions tests/test_check_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import sys
from concurrent.futures import ProcessPoolExecutor
from concurrent.futures.process import BrokenProcessPool
from pathlib import Path
from pickle import PickleError
from typing import TYPE_CHECKING
from unittest.mock import patch
Expand All @@ -23,6 +24,7 @@
import pylint.interfaces
import pylint.lint.parallel
from pylint.checkers import BaseRawFileChecker
from pylint.checkers.imports import ImportsChecker
from pylint.lint import PyLinter, augmented_sys_path
from pylint.lint.parallel import _worker_check_single_file as worker_check_single_file
from pylint.lint.parallel import _worker_initialize as worker_initialize
Expand All @@ -34,6 +36,8 @@
if TYPE_CHECKING:
from astroid import nodes

HERE = Path(__file__).parent


def _gen_file_data(idx: int = 0) -> FileItem:
"""Generates a file to use as a stream."""
Expand Down Expand Up @@ -625,3 +629,27 @@ def test_no_deadlock_due_to_initializer_error(self) -> None:
# because arguments has to be an Iterable.
extra_packages_paths=1, # type: ignore[arg-type]
)

@pytest.mark.needs_two_cores
def test_cyclic_import_parallel(self) -> None:
package_path = HERE / "input" / "func_w0401_package"
linter = PyLinter(reporter=Reporter())
linter.register_checker(ImportsChecker(linter))

check_parallel(
linter,
jobs=2,
files=[
FileItem(
name="tests.input.func_w0401_package.all_the_things",
filepath=str(package_path / "all_the_things.py"),
modpath="tests.input.func_w0401_package",
),
FileItem(
name="tests.input.func_w0401_package.thing2",
filepath=str(package_path / "thing2.py"),
modpath="tests.input.func_w0401_package",
),
],
)
assert "cyclic-import" in linter.stats.by_msg

0 comments on commit f31d375

Please sign in to comment.