aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniƫl van Noord <13665637+DanielNoord@users.noreply.github.com>2021-09-16 16:58:37 +0200
committerGitHub <noreply@github.com>2021-09-16 16:58:37 +0200
commit0d246e55a3d13d4fb0829c000064fa26fcbd4183 (patch)
treee63a3ebb6a6370a54073cbab46ff7c1f15a16111
parentdc0c7e97b1e92beffa36f76c5c56164f69b81a2a (diff)
downloadpylint-0d246e55a3d13d4fb0829c000064fa26fcbd4183.tar.gz
Add typing to ``filepath`` (#4980)
* Change tests for ``filepath`` changes * Add pylint/typing.py and FileItem NamedTuple * Use NamedTuple more efficiently * Fix errors and tests after adding warning * Add deprecation for future API change in Checker Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
-rw-r--r--pylint/config/option_manager_mixin.py2
-rw-r--r--pylint/lint/expand_modules.py8
-rw-r--r--pylint/lint/parallel.py20
-rw-r--r--pylint/lint/pylinter.py92
-rw-r--r--pylint/lint/utils.py9
-rw-r--r--pylint/reporters/base_reporter.py4
-rw-r--r--pylint/reporters/multi_reporter.py5
-rw-r--r--pylint/reporters/text.py3
-rw-r--r--pylint/testutils/reporter_for_tests.py8
-rw-r--r--pylint/typing.py40
-rw-r--r--tests/benchmark/test_baseline_benchmarks.py3
-rw-r--r--tests/checkers/unittest_variables.py2
-rw-r--r--tests/extensions/test_broad_try_clause.py3
-rw-r--r--tests/extensions/test_comparetozero.py3
-rw-r--r--tests/lint/test_utils.py6
-rw-r--r--tests/lint/unittest_lint.py10
-rw-r--r--tests/test_check_parallel.py22
-rw-r--r--tests/test_import_graph.py2
-rw-r--r--tests/test_regr.py34
-rw-r--r--tests/unittest_reporting.py3
20 files changed, 164 insertions, 115 deletions
diff --git a/pylint/config/option_manager_mixin.py b/pylint/config/option_manager_mixin.py
index c48d20713..f18fcfeca 100644
--- a/pylint/config/option_manager_mixin.py
+++ b/pylint/config/option_manager_mixin.py
@@ -332,7 +332,7 @@ class OptionsManagerMixIn:
provider = self._all_options[opt]
provider.set_option(opt, opt_value)
- def load_command_line_configuration(self, args=None):
+ def load_command_line_configuration(self, args=None) -> List[str]:
"""Override configuration according to command line parameters
return additional arguments
diff --git a/pylint/lint/expand_modules.py b/pylint/lint/expand_modules.py
index 11927eb32..1d4432322 100644
--- a/pylint/lint/expand_modules.py
+++ b/pylint/lint/expand_modules.py
@@ -4,6 +4,8 @@ from typing import List, Pattern, Tuple
from astroid import modutils
+from pylint.typing import ErrorDescriptionDict, ModuleDescriptionDict
+
def _modpath_from_file(filename, is_namespace, path=None):
def _is_package_cb(path, parts):
@@ -42,12 +44,12 @@ def expand_modules(
ignore_list: List[str],
ignore_list_re: List[Pattern],
ignore_list_paths_re: List[Pattern],
-) -> Tuple[List[dict], List[dict]]:
+) -> Tuple[List[ModuleDescriptionDict], List[ErrorDescriptionDict]]:
"""take a list of files/modules/packages and return the list of tuple
(file, module name) which have to be actually checked
"""
- result = []
- errors = []
+ result: List[ModuleDescriptionDict] = []
+ errors: List[ErrorDescriptionDict] = []
path = sys.path.copy()
for something in files_or_modules:
diff --git a/pylint/lint/parallel.py b/pylint/lint/parallel.py
index 2f3d0dd05..1896fc95f 100644
--- a/pylint/lint/parallel.py
+++ b/pylint/lint/parallel.py
@@ -3,12 +3,12 @@
import collections
import functools
-from typing import TYPE_CHECKING, Dict, List, Union
+from typing import TYPE_CHECKING, Any, DefaultDict, Dict, Iterable, List, Tuple, Union
from pylint import reporters
from pylint.lint.utils import _patch_sys_path
from pylint.message import Message
-from pylint.typing import CheckerStats
+from pylint.typing import CheckerStats, FileItem
if TYPE_CHECKING:
from typing import Counter # typing.Counter added in Python 3.6.1
@@ -67,11 +67,13 @@ def _worker_initialize(linter, arguments=None):
_patch_sys_path(arguments or ())
-def _worker_check_single_file(file_item):
- name, filepath, modname = file_item
-
+def _worker_check_single_file(
+ file_item: FileItem,
+) -> Tuple[int, Any, str, Any, List[Tuple[Any, ...]], Any, Any, DefaultDict[Any, List]]:
+ if not _worker_linter:
+ raise Exception("Worker linter not yet initialised")
_worker_linter.open()
- _worker_linter.check_single_file(name, filepath, modname)
+ _worker_linter.check_single_file_item(file_item)
mapreduce_data = collections.defaultdict(list)
for checker in _worker_linter.get_checkers():
try:
@@ -84,7 +86,7 @@ def _worker_check_single_file(file_item):
return (
id(multiprocessing.current_process()),
_worker_linter.current_name,
- filepath,
+ file_item.filepath,
_worker_linter.file_state.base_name,
msgs,
_worker_linter.stats,
@@ -114,7 +116,7 @@ def _merge_mapreduce_data(linter, all_mapreduce_data):
checker.reduce_map_data(linter, collated_map_reduce_data[checker.name])
-def check_parallel(linter, jobs, files, arguments=None):
+def check_parallel(linter, jobs, files: Iterable[FileItem], arguments=None):
"""Use the given linter to lint the files with given amount of workers (jobs)
This splits the work filestream-by-filestream. If you need to do work across
multiple files, as in the similarity-checker, then inherit from MapReduceMixin and
@@ -156,7 +158,7 @@ def check_parallel(linter, jobs, files, arguments=None):
linter.set_current_module(module, file_path)
for msg in messages:
msg = Message(*msg)
- linter.reporter.handle_message(msg)
+ linter.reporter.handle_message(msg) # type: ignore # linter.set_reporter() call above makes linter have a reporter attr
all_stats.append(stats)
all_mapreduce_data[worker_idx].append(mapreduce_data)
linter.msg_status |= msg_status
diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py
index d731e71b3..e8efc2fcd 100644
--- a/pylint/lint/pylinter.py
+++ b/pylint/lint/pylinter.py
@@ -11,6 +11,7 @@ import tokenize
import traceback
import warnings
from io import TextIOWrapper
+from typing import Iterable, Iterator, List, Optional, Sequence, Union
import astroid
from astroid import AstroidError, nodes
@@ -31,7 +32,7 @@ from pylint.lint.utils import (
)
from pylint.message import MessageDefinitionStore, MessagesHandlerMixIn
from pylint.reporters.ureports import nodes as report_nodes
-from pylint.typing import CheckerStats
+from pylint.typing import CheckerStats, FileItem, ModuleDescriptionDict
from pylint.utils import ASTWalker, FileState, utils
from pylint.utils.pragma_parser import (
OPTION_PO,
@@ -938,16 +939,20 @@ class PyLinter(
if not msg.may_be_emitted():
self._msgs_state[msg.msgid] = False
- def check(self, files_or_modules):
+ def check(self, files_or_modules: Union[Sequence[str], str]) -> None:
"""main checking entry: check a list of files or modules from their name.
files_or_modules is either a string or list of strings presenting modules to check.
"""
self.initialize()
-
if not isinstance(files_or_modules, (list, tuple)):
- files_or_modules = (files_or_modules,)
-
+ # pylint: disable-next=fixme
+ # TODO: Update typing and docstring for 'files_or_modules' when removing the deprecation
+ warnings.warn(
+ "In pylint 3.0, the checkers check function will only accept sequence of string",
+ DeprecationWarning,
+ )
+ files_or_modules = (files_or_modules,) # type: ignore
if self.config.from_stdin:
if len(files_or_modules) != 1:
raise exceptions.InvalidArgsError(
@@ -973,46 +978,47 @@ class PyLinter(
files_or_modules,
)
- def check_single_file(self, name, filepath, modname):
- """Check single file
+ def check_single_file(self, name: str, filepath: str, modname: str) -> None:
+ warnings.warn(
+ "In pylint 3.0, the checkers check_single_file function will be removed. "
+ "Use check_single_file_item instead.",
+ DeprecationWarning,
+ )
+ self.check_single_file_item(FileItem(name, filepath, modname))
+
+ def check_single_file_item(self, file: FileItem) -> None:
+ """Check single file item
The arguments are the same that are documented in _check_files
The initialize() method should be called before calling this method
"""
with self._astroid_module_checker() as check_astroid_module:
- self._check_file(
- self.get_ast, check_astroid_module, name, filepath, modname
- )
-
- def _check_files(self, get_ast, file_descrs):
- """Check all files from file_descrs
-
- The file_descrs should be iterable of tuple (name, filepath, modname)
- where
- - name: full name of the module
- - filepath: path of the file
- - modname: module name
- """
+ self._check_file(self.get_ast, check_astroid_module, file)
+
+ def _check_files(
+ self,
+ get_ast,
+ file_descrs: Iterable[FileItem],
+ ) -> None:
+ """Check all files from file_descrs"""
with self._astroid_module_checker() as check_astroid_module:
- for name, filepath, modname in file_descrs:
+ for file in file_descrs:
try:
- self._check_file(
- get_ast, check_astroid_module, name, filepath, modname
- )
+ self._check_file(get_ast, check_astroid_module, file)
except Exception as ex: # pylint: disable=broad-except
template_path = prepare_crash_report(
- ex, filepath, self.crash_file_path
+ ex, file.filepath, self.crash_file_path
)
- msg = get_fatal_error_message(filepath, template_path)
+ msg = get_fatal_error_message(file.filepath, template_path)
if isinstance(ex, AstroidError):
symbol = "astroid-error"
- msg = (filepath, msg)
+ self.add_message(symbol, args=(file.filepath, msg))
else:
symbol = "fatal"
- self.add_message(symbol, args=msg)
+ self.add_message(symbol, args=msg)
- def _check_file(self, get_ast, check_astroid_module, name, filepath, modname):
+ def _check_file(self, get_ast, check_astroid_module, file: FileItem):
"""Check a file using the passed utility functions (get_ast and check_astroid_module)
:param callable get_ast: callable returning AST from defined file taking the following arguments
@@ -1020,19 +1026,17 @@ class PyLinter(
- name: Python module name
:param callable check_astroid_module: callable checking an AST taking the following arguments
- ast: AST of the module
- :param str name: full name of the module
- :param str filepath: path to checked file
- :param str modname: name of the checked Python module
+ :param FileItem file: data about the file
"""
- self.set_current_module(name, filepath)
+ self.set_current_module(file.name, file.filepath)
# get the module representation
- ast_node = get_ast(filepath, name)
+ ast_node = get_ast(file.filepath, file.name)
if ast_node is None:
return
self._ignore_file = False
- self.file_state = FileState(modname)
+ self.file_state = FileState(file.modpath)
# 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 # pylint: disable=maybe-no-member
@@ -1045,7 +1049,7 @@ class PyLinter(
self.add_message(msgid, line, None, args)
@staticmethod
- def _get_file_descr_from_stdin(filepath):
+ def _get_file_descr_from_stdin(filepath: str) -> FileItem:
"""Return file description (tuple of module name, file path, base name) from given file path
This method is used for creating suitable file description for _check_files when the
@@ -1059,9 +1063,9 @@ class PyLinter(
except ImportError:
modname = os.path.splitext(os.path.basename(filepath))[0]
- return (modname, filepath, filepath)
+ return FileItem(modname, filepath, filepath)
- def _iterate_file_descrs(self, files_or_modules):
+ def _iterate_file_descrs(self, files_or_modules) -> Iterator[FileItem]:
"""Return generator yielding file descriptions (tuples of module name, file path, base name)
The returned generator yield one item for each Python module that should be linted.
@@ -1069,9 +1073,9 @@ class PyLinter(
for descr in self._expand_files(files_or_modules):
name, filepath, is_arg = descr["name"], descr["path"], descr["isarg"]
if self.should_analyze_file(name, filepath, is_argument=is_arg):
- yield (name, filepath, descr["basename"])
+ yield FileItem(name, filepath, descr["basename"])
- def _expand_files(self, modules):
+ def _expand_files(self, modules) -> List[ModuleDescriptionDict]:
"""get modules and errors from a list of modules and handle errors"""
result, errors = expand_modules(
modules,
@@ -1088,7 +1092,7 @@ class PyLinter(
self.add_message(key, args=message)
return result
- def set_current_module(self, modname, filepath=None):
+ def set_current_module(self, modname, filepath: Optional[str] = None):
"""set the name of the currently analyzed module and
init statistics for it
"""
@@ -1097,10 +1101,10 @@ class PyLinter(
self.reporter.on_set_current_module(modname, filepath)
self.current_name = modname
self.current_file = filepath or modname
- self.stats["by_module"][modname] = {}
- self.stats["by_module"][modname]["statement"] = 0
+ self.stats["by_module"][modname] = {} # type: ignore # Refactor of PyLinter.stats necessary
+ self.stats["by_module"][modname]["statement"] = 0 # type: ignore
for msg_cat in MSG_TYPES.values():
- self.stats["by_module"][modname][msg_cat] = 0
+ self.stats["by_module"][modname][msg_cat] = 0 # type: ignore
@contextlib.contextmanager
def _astroid_module_checker(self):
diff --git a/pylint/lint/utils.py b/pylint/lint/utils.py
index 280b144b7..ed0cefb77 100644
--- a/pylint/lint/utils.py
+++ b/pylint/lint/utils.py
@@ -5,8 +5,7 @@ import contextlib
import sys
import traceback
from datetime import datetime
-from pathlib import Path, PosixPath
-from typing import Union
+from pathlib import Path
from pylint.config import PYLINT_HOME
from pylint.lint.expand_modules import get_python_path
@@ -16,9 +15,7 @@ class ArgumentPreprocessingError(Exception):
"""Raised if an error occurs during argument preprocessing."""
-def prepare_crash_report(
- ex: Exception, filepath: PosixPath, crash_file_path: Union[Path, str]
-) -> Path:
+def prepare_crash_report(ex: Exception, filepath: str, crash_file_path: str) -> Path:
issue_template_path = (
Path(PYLINT_HOME) / datetime.now().strftime(str(crash_file_path))
).resolve()
@@ -63,7 +60,7 @@ pylint crashed with a ``{ex.__class__.__name__}`` and with the following stacktr
return issue_template_path
-def get_fatal_error_message(filepath: str, issue_template_path: str) -> str:
+def get_fatal_error_message(filepath: str, issue_template_path: Path) -> str:
return (
f"Fatal error while checking '{filepath}'. "
f"Please open an issue in our bug tracker so we address this. "
diff --git a/pylint/reporters/base_reporter.py b/pylint/reporters/base_reporter.py
index 4cf5d5895..e74ffdd89 100644
--- a/pylint/reporters/base_reporter.py
+++ b/pylint/reporters/base_reporter.py
@@ -3,7 +3,7 @@
import os
import sys
-from typing import List
+from typing import List, Optional
from pylint.message import Message
from pylint.typing import CheckerStats
@@ -63,7 +63,7 @@ class BaseReporter:
# Event callbacks
- def on_set_current_module(self, module, filepath):
+ def on_set_current_module(self, module: str, filepath: Optional[str]) -> None:
"""Hook called when a module starts to be analysed."""
def on_close(
diff --git a/pylint/reporters/multi_reporter.py b/pylint/reporters/multi_reporter.py
index 2ac361b38..445e9b32e 100644
--- a/pylint/reporters/multi_reporter.py
+++ b/pylint/reporters/multi_reporter.py
@@ -3,7 +3,7 @@
import os
-from typing import IO, Any, AnyStr, Callable, List, Optional, Union
+from typing import IO, Any, AnyStr, Callable, List, Optional
from pylint.interfaces import IReporter
from pylint.message import Message
@@ -12,7 +12,6 @@ from pylint.reporters.ureports.nodes import BaseLayout
from pylint.typing import CheckerStats
AnyFile = IO[AnyStr]
-AnyPath = Union[str, bytes, os.PathLike]
PyLinter = Any
@@ -89,7 +88,7 @@ class MultiReporter:
for rep in self._sub_reporters:
rep.display_messages(layout)
- def on_set_current_module(self, module: str, filepath: Optional[AnyPath]) -> None:
+ def on_set_current_module(self, module: str, filepath: Optional[str]) -> None:
"""hook called when a module starts to be analysed"""
for rep in self._sub_reporters:
rep.on_set_current_module(module, filepath)
diff --git a/pylint/reporters/text.py b/pylint/reporters/text.py
index 6d9a05f78..32c75fd7f 100644
--- a/pylint/reporters/text.py
+++ b/pylint/reporters/text.py
@@ -25,6 +25,7 @@
import os
import sys
import warnings
+from typing import Optional
from pylint import utils
from pylint.interfaces import IReporter
@@ -136,7 +137,7 @@ class TextReporter(BaseReporter):
self._modules = set()
self._template = self.line_format
- def on_set_current_module(self, module, filepath):
+ def on_set_current_module(self, module: str, filepath: Optional[str]) -> None:
self._template = str(self.linter.config.msg_template or self._template)
def write_message(self, msg):
diff --git a/pylint/testutils/reporter_for_tests.py b/pylint/testutils/reporter_for_tests.py
index b9e01b5a4..9527544a0 100644
--- a/pylint/testutils/reporter_for_tests.py
+++ b/pylint/testutils/reporter_for_tests.py
@@ -3,7 +3,7 @@
from io import StringIO
from os import getcwd, linesep, sep
-from typing import Dict, List
+from typing import Dict, List, Optional
from pylint import interfaces
from pylint.message import Message
@@ -51,7 +51,7 @@ class GenericTestReporter(BaseReporter):
return result
# pylint: disable=unused-argument
- def on_set_current_module(self, module, filepath):
+ def on_set_current_module(self, module: str, filepath: Optional[str]) -> None:
pass
# pylint: enable=unused-argument
@@ -63,14 +63,14 @@ class GenericTestReporter(BaseReporter):
class MinimalTestReporter(BaseReporter):
- def on_set_current_module(self, module, filepath):
+ def on_set_current_module(self, module: str, filepath: Optional[str]) -> None:
self.messages = []
_display = None
class FunctionalTestReporter(BaseReporter):
- def on_set_current_module(self, module, filepath):
+ def on_set_current_module(self, module: str, filepath: Optional[str]) -> None:
self.messages = []
def display_reports(self, layout):
diff --git a/pylint/typing.py b/pylint/typing.py
index 9ce1c587f..4c12710de 100644
--- a/pylint/typing.py
+++ b/pylint/typing.py
@@ -2,11 +2,49 @@
# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
"""A collection of typing utilities."""
-from typing import TYPE_CHECKING, Dict, List, Union
+import sys
+from typing import TYPE_CHECKING, Dict, List, NamedTuple, Union
if TYPE_CHECKING:
from typing import Counter # typing.Counter added in Python 3.6.1
+if sys.version_info >= (3, 8):
+ from typing import Literal, TypedDict
+else:
+ from typing_extensions import Literal, TypedDict
+
+
+class FileItem(NamedTuple):
+ """Represents data about a file handled by pylint
+
+ Each file item has:
+ - name: full name of the module
+ - filepath: path of the file
+ - modname: module name
+ """
+
+ name: str
+ filepath: str
+ modpath: str
+
+
+class ModuleDescriptionDict(TypedDict):
+ """Represents data about a checked module"""
+
+ path: str
+ name: str
+ isarg: bool
+ basepath: str
+ basename: str
+
+
+class ErrorDescriptionDict(TypedDict):
+ """Represents data about errors collected during checking of a module"""
+
+ key: Literal["fatal"]
+ mod: str
+ ex: Union[ImportError, SyntaxError]
+
# The base type of the "stats" attribute of a checker
CheckerStats = Dict[
diff --git a/tests/benchmark/test_baseline_benchmarks.py b/tests/benchmark/test_baseline_benchmarks.py
index 27dada39d..9b64cd01c 100644
--- a/tests/benchmark/test_baseline_benchmarks.py
+++ b/tests/benchmark/test_baseline_benchmarks.py
@@ -22,6 +22,7 @@ import pylint.interfaces
from pylint.checkers.base_checker import BaseChecker
from pylint.lint import PyLinter, Run, check_parallel
from pylint.testutils import GenericTestReporter as Reporter
+from pylint.typing import FileItem
from pylint.utils import register_plugins
@@ -111,7 +112,7 @@ class TestEstablishBaselineBenchmarks:
impact everything else"""
empty_filepath = _empty_filepath()
- empty_file_info = (
+ empty_file_info = FileItem(
"name-emptyfile-file",
_empty_filepath(),
"modname-emptyfile-mod",
diff --git a/tests/checkers/unittest_variables.py b/tests/checkers/unittest_variables.py
index 7ab79bf6f..62a9ca3d0 100644
--- a/tests/checkers/unittest_variables.py
+++ b/tests/checkers/unittest_variables.py
@@ -368,7 +368,7 @@ class TestMissingSubmodule(CheckerTestCase):
sys.path.insert(0, REGR_DATA_DIR)
try:
- linter.check(os.path.join(REGR_DATA_DIR, "package_all"))
+ linter.check([os.path.join(REGR_DATA_DIR, "package_all")])
got = linter.reporter.finalize().strip()
assert got == "E: 3: Undefined variable name 'missing' in __all__"
finally:
diff --git a/tests/extensions/test_broad_try_clause.py b/tests/extensions/test_broad_try_clause.py
index 21c79fed0..a41a7ab3d 100644
--- a/tests/extensions/test_broad_try_clause.py
+++ b/tests/extensions/test_broad_try_clause.py
@@ -13,6 +13,7 @@
"""Tests for the pylint checker in :mod:`pylint.extensions.broad_try_clause`"""
import unittest
from os import path as osp
+from typing import Optional
from pylint import checkers
from pylint.extensions.broad_try_clause import BroadTryClauseChecker
@@ -21,7 +22,7 @@ from pylint.reporters import BaseReporter
class BroadTryClauseTestReporter(BaseReporter):
- def on_set_current_module(self, module: str, filepath: str) -> None:
+ def on_set_current_module(self, module: str, filepath: Optional[str]) -> None:
self.messages = []
def _display(self, layout):
diff --git a/tests/extensions/test_comparetozero.py b/tests/extensions/test_comparetozero.py
index 167a615ef..c90c21183 100644
--- a/tests/extensions/test_comparetozero.py
+++ b/tests/extensions/test_comparetozero.py
@@ -14,6 +14,7 @@
import os
import unittest
+from typing import Optional
from pylint import checkers
from pylint.extensions.comparetozero import CompareToZeroChecker
@@ -22,7 +23,7 @@ from pylint.reporters import BaseReporter
class CompareToZeroTestReporter(BaseReporter):
- def on_set_current_module(self, module: str, filepath: str) -> None:
+ def on_set_current_module(self, module: str, filepath: Optional[str]) -> None:
self.messages = []
def _display(self, layout):
diff --git a/tests/lint/test_utils.py b/tests/lint/test_utils.py
index 80e7287f0..f7294f353 100644
--- a/tests/lint/test_utils.py
+++ b/tests/lint/test_utils.py
@@ -1,4 +1,4 @@
-from pathlib import PosixPath
+from pathlib import Path, PosixPath
from pylint.lint.utils import get_fatal_error_message, prepare_crash_report
@@ -13,7 +13,7 @@ def test_prepare_crash_report(tmp_path: PosixPath) -> None:
raise Exception(exception_content)
except Exception as ex: # pylint: disable=broad-except
template_path = prepare_crash_report(
- ex, python_file, tmp_path / "pylint-crash-%Y.txt"
+ ex, str(python_file), str(tmp_path / "pylint-crash-%Y.txt")
)
assert str(tmp_path) in str(template_path)
with open(template_path, encoding="utf8") as f:
@@ -27,7 +27,7 @@ def test_prepare_crash_report(tmp_path: PosixPath) -> None:
def test_get_fatal_error_message() -> None:
python_path = "mypath.py"
crash_path = "crash.txt"
- msg = get_fatal_error_message(python_path, crash_path)
+ msg = get_fatal_error_message(python_path, Path(crash_path))
assert python_path in msg
assert crash_path in msg
assert "open an issue" in msg
diff --git a/tests/lint/unittest_lint.py b/tests/lint/unittest_lint.py
index c31cbdba0..d15686ba9 100644
--- a/tests/lint/unittest_lint.py
+++ b/tests/lint/unittest_lint.py
@@ -269,7 +269,7 @@ def test_pylint_visit_method_taken_in_account(linter: PyLinter) -> None:
linter.open()
out = StringIO()
linter.set_reporter(text.TextReporter(out))
- linter.check("abc")
+ linter.check(["abc"])
def test_enable_message(init_linter: PyLinter) -> None:
@@ -573,7 +573,7 @@ def test_init_hooks_called_before_load_plugins() -> None:
def test_analyze_explicit_script(linter: PyLinter) -> None:
linter.set_reporter(testutils.GenericTestReporter())
- linter.check(os.path.join(DATA_DIR, "ascript"))
+ linter.check([os.path.join(DATA_DIR, "ascript")])
assert ["C: 2: Line too long (175/100)"] == linter.reporter.messages
@@ -826,16 +826,16 @@ def test_filename_with__init__(init_linter: PyLinter) -> None:
def test_by_module_statement_value(init_linter: PyLinter) -> None:
"""Test "statement" for each module analized of computed correctly."""
linter = init_linter
- linter.check(os.path.join(os.path.dirname(__file__), "data"))
+ linter.check([os.path.join(os.path.dirname(__file__), "data")])
by_module_stats: Dict[str, Dict[str, int]] = linter.stats["by_module"] # type: ignore
for module, module_stats in by_module_stats.items():
linter2 = init_linter
if module == "data":
- linter2.check(os.path.join(os.path.dirname(__file__), "data/__init__.py"))
+ linter2.check([os.path.join(os.path.dirname(__file__), "data/__init__.py")])
else:
- linter2.check(os.path.join(os.path.dirname(__file__), module))
+ linter2.check([os.path.join(os.path.dirname(__file__), module)])
# Check that the by_module "statement" is equal to the global "statement"
# computed for that module
diff --git a/tests/test_check_parallel.py b/tests/test_check_parallel.py
index 66236ac8d..67cd23a81 100644
--- a/tests/test_check_parallel.py
+++ b/tests/test_check_parallel.py
@@ -11,7 +11,7 @@
import collections
import os
-from typing import List, Tuple
+from typing import List
import pytest
from astroid import nodes
@@ -24,15 +24,15 @@ from pylint.lint.parallel import _worker_check_single_file as worker_check_singl
from pylint.lint.parallel import _worker_initialize as worker_initialize
from pylint.lint.parallel import check_parallel
from pylint.testutils import GenericTestReporter as Reporter
-from pylint.typing import CheckerStats
+from pylint.typing import CheckerStats, FileItem
-def _gen_file_data(idx: int = 0) -> Tuple[str, str, str]:
+def _gen_file_data(idx: int = 0) -> FileItem:
"""Generates a file to use as a stream"""
filepath = os.path.abspath(
os.path.join(os.path.dirname(__file__), "input", "similar1")
)
- file_data = (
+ file_data = FileItem(
f"--test-file_data-name-{idx}--",
filepath,
f"--test-file_data-modname-{idx}--",
@@ -40,7 +40,7 @@ def _gen_file_data(idx: int = 0) -> Tuple[str, str, str]:
return file_data
-def _gen_file_datas(count: int = 1) -> List[Tuple[str, str, str]]:
+def _gen_file_datas(count: int = 1) -> List[FileItem]:
return [_gen_file_data(idx) for idx in range(count)]
@@ -178,7 +178,7 @@ class TestCheckParallelFramework:
def test_worker_check_single_file_uninitialised(self) -> None:
pylint.lint.parallel._worker_linter = None
with pytest.raises( # Objects that do not match the linter interface will fail
- AttributeError, match="'NoneType' object has no attribute 'open'"
+ Exception, match="Worker linter not yet initialised"
):
worker_check_single_file(_gen_file_data())
@@ -290,7 +290,9 @@ class TestCheckParallel:
# Invoke the lint process in a multiprocess way, although we only specify one
# job.
- check_parallel(linter, jobs=1, files=single_file_container, arguments=None)
+ check_parallel(
+ linter, jobs=1, files=iter(single_file_container), arguments=None
+ )
assert len(linter.get_checkers()) == 2, (
"We should only have the 'master' and 'sequential-checker' "
"checkers registered"
@@ -319,7 +321,7 @@ class TestCheckParallel:
# now run the regular mode of checking files and check that, in this proc, we
# collect the right data
- filepath = single_file_container[0][1] # get the filepath element
+ filepath = [single_file_container[0][1]] # get the filepath element
linter.check(filepath)
assert {
"by_module": {
@@ -357,7 +359,9 @@ class TestCheckParallel:
# Invoke the lint process in a multiprocess way, although we only specify one
# job.
- check_parallel(linter, jobs=1, files=single_file_container, arguments=None)
+ check_parallel(
+ linter, jobs=1, files=iter(single_file_container), arguments=None
+ )
assert {
"by_module": {
diff --git a/tests/test_import_graph.py b/tests/test_import_graph.py
index 802970718..42e3baf56 100644
--- a/tests/test_import_graph.py
+++ b/tests/test_import_graph.py
@@ -106,7 +106,7 @@ def test_checker_dep_graphs(linter: PyLinter) -> None:
linter.global_set_option("int-import-graph", "int_import.dot")
# ignore this file causing spurious MemoryError w/ some python version (>=2.3?)
linter.global_set_option("ignore", ("func_unknown_encoding.py",))
- linter.check("input")
+ linter.check(["input"])
linter.generate_reports()
assert exists("import.dot")
assert exists("ext_import.dot")
diff --git a/tests/test_regr.py b/tests/test_regr.py
index 12dd03406..afb5e69ac 100644
--- a/tests/test_regr.py
+++ b/tests/test_regr.py
@@ -23,7 +23,7 @@ to be incorporated in the automatic functional test framework
import os
import sys
from os.path import abspath, dirname, join
-from typing import Dict, Iterator
+from typing import Iterator
import astroid
import pytest
@@ -61,15 +61,15 @@ def Equals(expected):
@pytest.mark.parametrize(
"file_name, check",
[
- ("package.__init__", Equals("")),
- ("precedence_test", Equals("")),
- ("import_package_subpackage_module", Equals("")),
- ("pylint.checkers.__init__", lambda x: "__path__" not in x),
- (join(REGR_DATA, "classdoc_usage.py"), Equals("")),
- (join(REGR_DATA, "module_global.py"), Equals("")),
- (join(REGR_DATA, "decimal_inference.py"), Equals("")),
- (join(REGR_DATA, "absimp", "string.py"), Equals("")),
- (join(REGR_DATA, "bad_package"), lambda x: "Unused import missing" in x),
+ (["package.__init__"], Equals("")),
+ (["precedence_test"], Equals("")),
+ (["import_package_subpackage_module"], Equals("")),
+ (["pylint.checkers.__init__"], lambda x: "__path__" not in x),
+ ([join(REGR_DATA, "classdoc_usage.py")], Equals("")),
+ ([join(REGR_DATA, "module_global.py")], Equals("")),
+ ([join(REGR_DATA, "decimal_inference.py")], Equals("")),
+ ([join(REGR_DATA, "absimp", "string.py")], Equals("")),
+ ([join(REGR_DATA, "bad_package")], lambda x: "Unused import missing" in x),
],
)
def test_package(finalize_linter, file_name, check):
@@ -94,7 +94,7 @@ def test_crash(finalize_linter, file_name):
"fname", [x for x in os.listdir(REGR_DATA) if x.endswith("_crash.py")]
)
def test_descriptor_crash(fname: str, finalize_linter: PyLinter) -> None:
- finalize_linter.check(join(REGR_DATA, fname))
+ finalize_linter.check([join(REGR_DATA, fname)])
finalize_linter.reporter.finalize().strip()
@@ -109,16 +109,14 @@ def modify_path() -> Iterator:
@pytest.mark.usefixtures("modify_path")
def test_check_package___init__(finalize_linter: PyLinter) -> None:
- filename = "package.__init__"
+ filename = ["package.__init__"]
finalize_linter.check(filename)
- by_module_stats: Dict[str, Dict[str, int]] = finalize_linter.stats["by_module"] # type: ignore
- checked = list(by_module_stats.keys())
- assert checked == [filename]
+ checked = list(finalize_linter.stats["by_module"].keys()) # type: ignore # Refactor of PyLinter.stats necessary
+ assert checked == filename
os.chdir(join(REGR_DATA, "package"))
- finalize_linter.check("__init__")
- by_module_stats: Dict[str, Dict[str, int]] = finalize_linter.stats["by_module"] # type: ignore
- checked = list(by_module_stats.keys())
+ finalize_linter.check(["__init__"])
+ checked = list(finalize_linter.stats["by_module"].keys()) # type: ignore
assert checked == ["__init__"]
diff --git a/tests/unittest_reporting.py b/tests/unittest_reporting.py
index d1d483a35..88f9c43b5 100644
--- a/tests/unittest_reporting.py
+++ b/tests/unittest_reporting.py
@@ -29,6 +29,7 @@ from pylint.interfaces import IReporter
from pylint.lint import PyLinter
from pylint.reporters import BaseReporter
from pylint.reporters.text import ParseableTextReporter, TextReporter
+from pylint.typing import FileItem
@pytest.fixture(scope="module")
@@ -120,7 +121,7 @@ def test_multi_format_output(tmp_path):
linter.reporter.set_output(text)
linter.open()
- linter.check_single_file("somemodule", source_file, "somemodule")
+ linter.check_single_file_item(FileItem("somemodule", source_file, "somemodule"))
linter.add_message("line-too-long", line=1, args=(1, 2))
linter.generate_reports()
linter.reporter.writeln("direct output")