Skip to content

Pass msg_store and node to FileState #6558

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pylint/lint/parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ def check_parallel(
mapreduce_data,
) in pool.imap_unordered(_worker_check_single_file, files):
linter.file_state.base_name = base_name
linter.file_state._is_base_filestate = False
linter.set_current_module(module, file_path)
for msg in messages:
linter.reporter.handle_message(msg)
Expand Down
23 changes: 14 additions & 9 deletions pylint/lint/pylinter.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,13 @@ def __init__(
self._dynamic_plugins: set[str] = set()
"""Set of loaded plugin names."""

# Attributes related to registering messages and their handling
self.msgs_store = MessageDefinitionStore()
self.msg_status = 0
self._by_id_managed_msgs: list[ManagedMessage] = []

# Attributes related to visiting files
self.file_state = FileState()
self.file_state = FileState("", self.msgs_store, is_base_filestate=True)
self.current_name: str | None = None
self.current_file: str | None = None
self._ignore_file = False
Expand All @@ -300,11 +305,6 @@ def __init__(
"""List of message symbols on which pylint should fail, set by --fail-on."""
self._error_mode = False

# Attributes related to registering messages and their handling
self.msgs_store = MessageDefinitionStore()
self.msg_status = 0
self._by_id_managed_msgs: list[ManagedMessage] = []

reporters.ReportsHandlerMixIn.__init__(self)
checkers.BaseChecker.__init__(self, self)
# provided reports
Expand Down Expand Up @@ -694,7 +694,7 @@ def _check_file(

self._ignore_file = False

self.file_state = FileState(file.modpath)
self.file_state = FileState(file.modpath, self.msgs_store, ast_node)
# fix the current file (if the source file was not available or
# if it's actually a c extension)
self.current_file = ast_node.file
Expand Down Expand Up @@ -969,7 +969,11 @@ def generate_reports(self) -> int | None:
# Display whatever messages are left on the reporter.
self.reporter.display_messages(report_nodes.Section())

if self.file_state.base_name is not None:
# TODO: 3.0: Remove second half of if-statement
if (
not self.file_state._is_base_filestate
and self.file_state.base_name is not None
):
# load previous results if any
previous_stats = load_results(self.file_state.base_name)
self.reporter.on_close(self.stats, previous_stats)
Expand All @@ -994,7 +998,8 @@ def _report_evaluation(self) -> int | None:
# check with at least check 1 statements (usually 0 when there is a
# syntax error preventing pylint from further processing)
note = None
assert self.file_state.base_name
# TODO: 3.0: Remove assertion
assert self.file_state.base_name is not None
previous_stats = load_results(self.file_state.base_name)
if self.stats.statement == 0:
return note
Expand Down
31 changes: 29 additions & 2 deletions pylint/utils/file_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import collections
import sys
import warnings
from collections import defaultdict
from collections.abc import Iterator
from typing import TYPE_CHECKING, Dict
Expand Down Expand Up @@ -33,15 +34,41 @@
class FileState:
"""Hold internal state specific to the currently analyzed file."""

def __init__(self, modname: str | None = None) -> None:
def __init__(
self,
modname: str | None = None,
msg_store: MessageDefinitionStore | None = None,
node: nodes.Module | None = None,
*,
is_base_filestate: bool = False,
) -> None:
if modname is None:
warnings.warn(
"FileState needs a string as modname argument. "
"This argument will be required in pylint 3.0",
DeprecationWarning,
)
if msg_store is None:
warnings.warn(
"FileState needs a 'MessageDefinitionStore' as msg_store argument. "
"This argument will be required in pylint 3.0",
DeprecationWarning,
)
self.base_name = modname
self._module_msgs_state: MessageStateDict = {}
self._raw_module_msgs_state: MessageStateDict = {}
self._ignored_msgs: defaultdict[
tuple[str, int], set[int]
] = collections.defaultdict(set)
self._suppression_mapping: dict[tuple[str, int], int] = {}
self._effective_max_line_number: int | None = None
self._module = node
if node:
self._effective_max_line_number = node.tolineno
else:
self._effective_max_line_number = None
self._msgs_store = msg_store
self._is_base_filestate = is_base_filestate
"""If this FileState is the base state made during initialization of PyLinter."""

def collect_block_lines(
self, msgs_store: MessageDefinitionStore, module_node: nodes.Module
Expand Down
2 changes: 1 addition & 1 deletion tests/lint/unittest_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def reporter():
def initialized_linter(linter: PyLinter) -> PyLinter:
linter.open()
linter.set_current_module("toto", "mydir/toto")
linter.file_state = FileState("toto")
linter.file_state = FileState("toto", linter.msgs_store)
return linter


Expand Down
13 changes: 13 additions & 0 deletions tests/test_deprecation.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
ITokenChecker,
)
from pylint.lint import PyLinter
from pylint.message import MessageDefinitionStore
from pylint.reporters import BaseReporter
from pylint.reporters.ureports.nodes import Section
from pylint.utils import FileState


def test_mapreducemixin() -> None:
Expand Down Expand Up @@ -87,3 +89,14 @@ def test_load_and_save_results() -> None:
save_results(object(), "") # type: ignore[arg-type]
with pytest.warns(DeprecationWarning):
load_results("")


def test_filestate() -> None:
"""Test that FileState needs its arguments."""
with pytest.warns(DeprecationWarning):
FileState()
with pytest.warns(DeprecationWarning):
FileState("foo")
with pytest.warns(DeprecationWarning):
FileState(msg_store=MessageDefinitionStore())
FileState("foo", MessageDefinitionStore())