summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdoc/exts/pylint_extensions.py58
-rw-r--r--pylint/checkers/base_checker.py6
-rw-r--r--pylint/checkers/imports.py37
-rw-r--r--pylint/checkers/spelling.py2
-rw-r--r--pylint/checkers/variables.py16
-rw-r--r--pylint/config/__init__.py6
-rw-r--r--pylint/config/arguments_manager.py10
-rw-r--r--pylint/config/configuration_mixin.py9
-rw-r--r--pylint/config/option.py21
-rw-r--r--pylint/config/option_manager_mixin.py13
-rw-r--r--pylint/config/option_parser.py2
-rw-r--r--pylint/config/options_provider_mixin.py2
-rw-r--r--setup.cfg1
-rw-r--r--tests/lint/unittest_expand_modules.py6
-rw-r--r--tests/pyreverse/test_utils.py10
-rw-r--r--tests/reporters/unittest_reporting.py5
-rw-r--r--tests/test_func.py4
17 files changed, 132 insertions, 76 deletions
diff --git a/doc/exts/pylint_extensions.py b/doc/exts/pylint_extensions.py
index a973e1b13..e5949b1ed 100755
--- a/doc/exts/pylint_extensions.py
+++ b/doc/exts/pylint_extensions.py
@@ -6,22 +6,42 @@
"""Script used to generate the extensions file before building the actual documentation."""
+from __future__ import annotations
+
import os
import re
import sys
import warnings
-from typing import Optional
+from typing import Any
import sphinx
from sphinx.application import Sphinx
+from pylint.checkers import BaseChecker
from pylint.constants import MAIN_CHECKER_NAME
from pylint.lint import PyLinter
+from pylint.typing import MessageDefinitionTuple, OptionDict, ReportsCallable
from pylint.utils import get_rst_title
+if sys.version_info >= (3, 8):
+ from typing import TypedDict
+else:
+ from typing_extensions import TypedDict
+
+
+class _CheckerInfo(TypedDict):
+ """Represents data about a checker."""
+
+ checker: BaseChecker
+ options: list[tuple[str, OptionDict, Any]]
+ msgs: dict[str, MessageDefinitionTuple]
+ reports: list[tuple[str, str, ReportsCallable]]
+ doc: str
+ module: str
+
# pylint: disable-next=unused-argument
-def builder_inited(app: Optional[Sphinx]) -> None:
+def builder_inited(app: Sphinx | None) -> None:
"""Output full documentation in ReST format for all extension modules."""
# PACKAGE/docs/exts/pylint_extensions.py --> PACKAGE/
base_path = os.path.dirname(
@@ -30,7 +50,7 @@ def builder_inited(app: Optional[Sphinx]) -> None:
# PACKAGE/ --> PACKAGE/pylint/extensions
ext_path = os.path.join(base_path, "pylint", "extensions")
modules = []
- doc_files = {}
+ doc_files: dict[str, str] = {}
for filename in os.listdir(ext_path):
name, ext = os.path.splitext(filename)
if name[0] == "_":
@@ -79,18 +99,26 @@ def builder_inited(app: Optional[Sphinx]) -> None:
checker, information = checker_information
j = -1
checker = information["checker"]
- del information["checker"]
if i == max_len - 1:
# Remove the \n\n at the end of the file
j = -3
print(
- checker.get_full_documentation(**information, show_options=False)[:j],
+ checker.get_full_documentation(
+ msgs=information["msgs"],
+ options=information["options"],
+ reports=information["reports"],
+ doc=information["doc"],
+ module=information["module"],
+ show_options=False,
+ )[:j],
file=stream,
)
-def get_plugins_info(linter, doc_files):
- by_checker = {}
+def get_plugins_info(
+ linter: PyLinter, doc_files: dict[str, str]
+) -> dict[BaseChecker, _CheckerInfo]:
+ by_checker: dict[BaseChecker, _CheckerInfo] = {}
for checker in linter.get_checkers():
if checker.name == MAIN_CHECKER_NAME:
continue
@@ -116,14 +144,14 @@ def get_plugins_info(linter, doc_files):
except KeyError:
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=DeprecationWarning)
- by_checker[checker] = {
- "checker": checker,
- "options": list(checker.options_and_values()),
- "msgs": dict(checker.msgs),
- "reports": list(checker.reports),
- "doc": doc,
- "module": module,
- }
+ by_checker[checker] = _CheckerInfo(
+ checker=checker,
+ options=list(checker.options_and_values()),
+ msgs=dict(checker.msgs),
+ reports=list(checker.reports),
+ doc=doc,
+ module=module,
+ )
return by_checker
diff --git a/pylint/checkers/base_checker.py b/pylint/checkers/base_checker.py
index 778345de8..e075ea413 100644
--- a/pylint/checkers/base_checker.py
+++ b/pylint/checkers/base_checker.py
@@ -7,7 +7,7 @@ from __future__ import annotations
import abc
import functools
import warnings
-from collections.abc import Iterator
+from collections.abc import Iterable, Sequence
from inspect import cleandoc
from tokenize import TokenInfo
from typing import TYPE_CHECKING, Any
@@ -105,8 +105,8 @@ class BaseChecker(_ArgumentsProvider):
def get_full_documentation(
self,
msgs: dict[str, MessageDefinitionTuple],
- options: Iterator[tuple[str, OptionDict, Any]],
- reports: tuple[tuple[str, str, ReportsCallable], ...],
+ options: Iterable[tuple[str, OptionDict, Any]],
+ reports: Sequence[tuple[str, str, ReportsCallable]],
doc: str | None = None,
module: str | None = None,
show_options: bool = True,
diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py
index 7cab78586..256d973ce 100644
--- a/pylint/checkers/imports.py
+++ b/pylint/checkers/imports.py
@@ -11,8 +11,8 @@ import copy
import os
import sys
from collections import defaultdict
-from collections.abc import Sequence
-from typing import TYPE_CHECKING, Any
+from collections.abc import ItemsView, Sequence
+from typing import TYPE_CHECKING, Any, Dict, List, Union
import astroid
from astroid import nodes
@@ -37,6 +37,9 @@ from pylint.utils.linterstats import LinterStats
if TYPE_CHECKING:
from pylint.lint import PyLinter
+# The dictionary with Any should actually be a _ImportTree again
+# but mypy doesn't support recursive types yet
+_ImportTree = Dict[str, Union[List[Dict[str, Any]], List[str]]]
DEPRECATED_MODULES = {
(0, 0, 0): {"tkinter.tix", "fpectl"},
@@ -148,35 +151,37 @@ def _ignore_import_failure(
# utilities to represents import dependencies as tree and dot graph ###########
-def _make_tree_defs(mod_files_list):
+def _make_tree_defs(mod_files_list: ItemsView[str, set[str]]) -> _ImportTree:
"""Get a list of 2-uple (module, list_of_files_which_import_this_module),
it will return a dictionary to represent this as a tree.
"""
- tree_defs = {}
+ tree_defs: _ImportTree = {}
for mod, files in mod_files_list:
- node = (tree_defs, ())
+ node: list[_ImportTree | list[str]] = [tree_defs, []]
for prefix in mod.split("."):
- node = node[0].setdefault(prefix, [{}, []])
+ assert isinstance(node[0], dict)
+ node = node[0].setdefault(prefix, ({}, [])) # type: ignore[arg-type,assignment]
+ assert isinstance(node[1], list)
node[1] += files
return tree_defs
-def _repr_tree_defs(data, indent_str=None):
+def _repr_tree_defs(data: _ImportTree, indent_str: str | None = None) -> str:
"""Return a string which represents imports as a tree."""
lines = []
nodes_items = data.items()
for i, (mod, (sub, files)) in enumerate(sorted(nodes_items, key=lambda x: x[0])):
- files = "" if not files else f"({','.join(sorted(files))})"
+ files_list = "" if not files else f"({','.join(sorted(files))})"
if indent_str is None:
- lines.append(f"{mod} {files}")
+ lines.append(f"{mod} {files_list}")
sub_indent_str = " "
else:
- lines.append(rf"{indent_str}\-{mod} {files}")
+ lines.append(rf"{indent_str}\-{mod} {files_list}")
if i == len(nodes_items) - 1:
sub_indent_str = f"{indent_str} "
else:
sub_indent_str = f"{indent_str}| "
- if sub:
+ if sub and isinstance(sub, dict):
lines.append(_repr_tree_defs(sub, sub_indent_str))
return "\n".join(lines)
@@ -420,7 +425,7 @@ class ImportsChecker(DeprecatedMixin, BaseChecker):
def __init__(self, linter: PyLinter) -> None:
BaseChecker.__init__(self, linter)
self.import_graph: defaultdict[str, set[str]] = defaultdict(set)
- self._imports_stack: list[tuple[Any, Any]] = []
+ self._imports_stack: list[tuple[ImportNode, str]] = []
self._first_non_import_node = None
self._module_pkg: dict[
Any, Any
@@ -696,7 +701,7 @@ class ImportsChecker(DeprecatedMixin, BaseChecker):
imports = [import_node for (import_node, _) in imports]
return any(astroid.are_exclusive(import_node, node) for import_node in imports)
- def _check_imports_order(self, _module_node):
+ def _check_imports_order(self, _module_node: nodes.Module):
"""Checks imports of module `node` are grouped by category.
Imports must follow this order: standard, 3rd party, local
@@ -707,9 +712,9 @@ class ImportsChecker(DeprecatedMixin, BaseChecker):
# need of a list that holds third or first party ordered import
external_imports = []
local_imports = []
- third_party_not_ignored = []
- first_party_not_ignored = []
- local_not_ignored = []
+ third_party_not_ignored: list[tuple[ImportNode, str]] = []
+ first_party_not_ignored: list[tuple[ImportNode, str]] = []
+ local_not_ignored: list[tuple[ImportNode, str]] = []
isort_driver = IsortDriver(self.linter.config)
for node, modname in self._imports_stack:
if modname.startswith("."):
diff --git a/pylint/checkers/spelling.py b/pylint/checkers/spelling.py
index e16377ab7..267efd7e5 100644
--- a/pylint/checkers/spelling.py
+++ b/pylint/checkers/spelling.py
@@ -133,6 +133,8 @@ class ForwardSlashChunker(Chunker):
'after'.
"""
+ _text: str
+
def next(self):
while True:
if not self._text:
diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py
index 0644b4d07..b0600ea54 100644
--- a/pylint/checkers/variables.py
+++ b/pylint/checkers/variables.py
@@ -527,15 +527,15 @@ class NamesConsumer:
)
self.node = node
- def __repr__(self):
- to_consumes = [f"{k}->{v}" for k, v in self._atomic.to_consume.items()]
- consumed = [f"{k}->{v}" for k, v in self._atomic.consumed.items()]
- consumed_uncertain = [
+ def __repr__(self) -> str:
+ _to_consumes = [f"{k}->{v}" for k, v in self._atomic.to_consume.items()]
+ _consumed = [f"{k}->{v}" for k, v in self._atomic.consumed.items()]
+ _consumed_uncertain = [
f"{k}->{v}" for k, v in self._atomic.consumed_uncertain.items()
]
- to_consumes = ", ".join(to_consumes)
- consumed = ", ".join(consumed)
- consumed_uncertain = ", ".join(consumed_uncertain)
+ to_consumes = ", ".join(_to_consumes)
+ consumed = ", ".join(_consumed)
+ consumed_uncertain = ", ".join(_consumed_uncertain)
return f"""
to_consume : {to_consumes}
consumed : {consumed}
@@ -2838,7 +2838,7 @@ class VariablesChecker(BaseChecker):
consumed = [] # [(scope_locals, consumed_key)]
metaclass = klass.metaclass()
- name = None
+ name = ""
if isinstance(klass._metaclass, nodes.Name):
name = klass._metaclass.name
elif isinstance(klass._metaclass, nodes.Attribute) and klass._metaclass.expr:
diff --git a/pylint/config/__init__.py b/pylint/config/__init__.py
index 7dc96f0cf..9a0d71f40 100644
--- a/pylint/config/__init__.py
+++ b/pylint/config/__init__.py
@@ -31,8 +31,10 @@ from pylint.config.find_default_config_files import (
)
from pylint.config.option import Option
from pylint.config.option_manager_mixin import OptionsManagerMixIn
-from pylint.config.option_parser import OptionParser
-from pylint.config.options_provider_mixin import OptionsProviderMixIn
+from pylint.config.option_parser import OptionParser # type: ignore[attr-defined]
+from pylint.config.options_provider_mixin import ( # type: ignore[attr-defined]
+ OptionsProviderMixIn,
+)
from pylint.constants import PYLINT_HOME, USER_HOME
from pylint.utils import LinterStats
diff --git a/pylint/config/arguments_manager.py b/pylint/config/arguments_manager.py
index eda1a583d..92bbfac0f 100644
--- a/pylint/config/arguments_manager.py
+++ b/pylint/config/arguments_manager.py
@@ -38,8 +38,10 @@ from pylint.config.exceptions import (
)
from pylint.config.help_formatter import _HelpFormatter
from pylint.config.option import Option
-from pylint.config.option_parser import OptionParser
-from pylint.config.options_provider_mixin import OptionsProviderMixIn
+from pylint.config.option_parser import OptionParser # type: ignore[attr-defined]
+from pylint.config.options_provider_mixin import ( # type: ignore[attr-defined]
+ OptionsProviderMixIn,
+)
from pylint.config.utils import _convert_option_to_argument, _parse_rich_type_value
from pylint.constants import MAIN_CHECKER_NAME
from pylint.typing import DirectoryNamespaceDict, OptionDict
@@ -287,7 +289,7 @@ class _ArgumentsManager:
)
# command line parser
self.cmdline_parser = OptionParser(Option, usage=usage)
- self.cmdline_parser.options_manager = self # type: ignore[attr-defined]
+ self.cmdline_parser.options_manager = self
self._optik_option_attrs = set(self.cmdline_parser.option_class.ATTRS)
def register_options_provider(
@@ -632,7 +634,7 @@ class _ArgumentsManager:
if value is None:
continue
setattr(config, attr, value)
- return args
+ return args # type: ignore[return-value]
def help(self, level: int | None = None) -> str:
"""Return the usage string based on the available options."""
diff --git a/pylint/config/configuration_mixin.py b/pylint/config/configuration_mixin.py
index 7854ff733..e92faa2d6 100644
--- a/pylint/config/configuration_mixin.py
+++ b/pylint/config/configuration_mixin.py
@@ -3,9 +3,12 @@
# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt
import warnings
+from typing import Any
from pylint.config.option_manager_mixin import OptionsManagerMixIn
-from pylint.config.options_provider_mixin import OptionsProviderMixIn
+from pylint.config.options_provider_mixin import ( # type: ignore[attr-defined]
+ OptionsProviderMixIn,
+)
class ConfigurationMixIn(OptionsManagerMixIn, OptionsProviderMixIn):
@@ -13,7 +16,7 @@ class ConfigurationMixIn(OptionsManagerMixIn, OptionsProviderMixIn):
manager / providers model.
"""
- def __init__(self, *args, **kwargs):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
# TODO: 3.0: Remove deprecated class
warnings.warn(
"ConfigurationMixIn has been deprecated and will be removed in pylint 3.0",
@@ -24,7 +27,7 @@ class ConfigurationMixIn(OptionsManagerMixIn, OptionsProviderMixIn):
OptionsManagerMixIn.__init__(self, *args, **kwargs)
OptionsProviderMixIn.__init__(self)
if not getattr(self, "option_groups", None):
- self.option_groups = []
+ self.option_groups: list[tuple[str, str]] = []
for _, optdict in self.options:
try:
gdef = (optdict["group"].upper(), "")
diff --git a/pylint/config/option.py b/pylint/config/option.py
index 1cef7aba2..b3924c4aa 100644
--- a/pylint/config/option.py
+++ b/pylint/config/option.py
@@ -9,7 +9,7 @@ import optparse # pylint: disable=deprecated-module
import pathlib
import re
import warnings
-from collections.abc import Sequence
+from collections.abc import Callable, Sequence
from re import Pattern
from typing import Any
@@ -107,7 +107,7 @@ def _py_version_validator(_, name, value):
return value
-VALIDATORS = {
+VALIDATORS: dict[str, Callable[[Any, str, Any], Any] | Callable[[Any], Any]] = {
"string": utils._unquote,
"int": int,
"float": float,
@@ -128,14 +128,14 @@ VALIDATORS = {
}
-def _call_validator(opttype, optdict, option, value):
+def _call_validator(opttype: str, optdict: Any, option: str, value: Any) -> Any:
if opttype not in VALIDATORS:
raise Exception(f'Unsupported type "{opttype}"')
try:
- return VALIDATORS[opttype](optdict, option, value)
+ return VALIDATORS[opttype](optdict, option, value) # type: ignore[call-arg]
except TypeError:
try:
- return VALIDATORS[opttype](value)
+ return VALIDATORS[opttype](value) # type: ignore[call-arg]
except Exception as e:
raise optparse.OptionValueError(
f"{option} value ({value!r}) should be of type {opttype}"
@@ -186,23 +186,23 @@ class Option(optparse.Option):
DeprecationWarning,
)
super().__init__(*opts, **attrs)
- if hasattr(self, "hide") and self.hide:
+ if hasattr(self, "hide") and self.hide: # type: ignore[attr-defined]
self.help = optparse.SUPPRESS_HELP
def _check_choice(self):
if self.type in {"choice", "multiple_choice", "confidence"}:
- if self.choices is None:
+ if self.choices is None: # type: ignore[attr-defined]
raise optparse.OptionError(
"must supply a list of choices for type 'choice'", self
)
- if not isinstance(self.choices, (tuple, list)):
+ if not isinstance(self.choices, (tuple, list)): # type: ignore[attr-defined]
raise optparse.OptionError(
# pylint: disable-next=consider-using-f-string
"choices must be a list of strings ('%s' supplied)"
- % str(type(self.choices)).split("'")[1],
+ % str(type(self.choices)).split("'")[1], # type: ignore[attr-defined]
self,
)
- elif self.choices is not None:
+ elif self.choices is not None: # type: ignore[attr-defined]
raise optparse.OptionError(
f"must not supply choices for type {self.type!r}", self
)
@@ -210,6 +210,7 @@ class Option(optparse.Option):
optparse.Option.CHECK_METHODS[2] = _check_choice # type: ignore[index]
def process(self, opt, value, values, parser): # pragma: no cover # Argparse
+ assert isinstance(self.dest, str)
if self.callback and self.callback.__module__ == "pylint.lint.run":
return 1
# First, convert the value(s) to the right type. Howl if any
diff --git a/pylint/config/option_manager_mixin.py b/pylint/config/option_manager_mixin.py
index 2f0aac75f..a07865ff6 100644
--- a/pylint/config/option_manager_mixin.py
+++ b/pylint/config/option_manager_mixin.py
@@ -2,6 +2,7 @@
# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt
+
# pylint: disable=duplicate-code
from __future__ import annotations
@@ -19,7 +20,7 @@ from typing import Any, TextIO
from pylint import utils
from pylint.config.option import Option
-from pylint.config.option_parser import OptionParser
+from pylint.config.option_parser import OptionParser # type: ignore[attr-defined]
from pylint.typing import OptionDict
if sys.version_info >= (3, 11):
@@ -56,10 +57,10 @@ def _patch_optparse():
# pylint: disable = redefined-variable-type
orig_default = optparse.HelpFormatter
try:
- optparse.HelpFormatter.expand_default = _expand_default
+ optparse.HelpFormatter.expand_default = _expand_default # type: ignore[assignment]
yield
finally:
- optparse.HelpFormatter.expand_default = orig_default
+ optparse.HelpFormatter.expand_default = orig_default # type: ignore[assignment]
class OptionsManagerMixIn:
@@ -131,7 +132,7 @@ class OptionsManagerMixIn:
# add section to the config file
if (
group_name != "DEFAULT"
- and group_name not in self.cfgfile_parser._sections
+ and group_name not in self.cfgfile_parser._sections # type: ignore[attr-defined]
):
self.cfgfile_parser.add_section(group_name)
# add provider's specific options
@@ -256,11 +257,11 @@ class OptionsManagerMixIn:
with open(config_file, encoding="utf_8_sig") as fp:
parser.read_file(fp)
# normalize each section's title
- for sect, values in list(parser._sections.items()):
+ for sect, values in list(parser._sections.items()): # type: ignore[attr-defined]
if sect.startswith("pylint."):
sect = sect[len("pylint.") :]
if not sect.isupper() and values:
- parser._sections[sect.upper()] = values
+ parser._sections[sect.upper()] = values # type: ignore[attr-defined]
if not verbose:
return
diff --git a/pylint/config/option_parser.py b/pylint/config/option_parser.py
index b58fad3a4..78984db34 100644
--- a/pylint/config/option_parser.py
+++ b/pylint/config/option_parser.py
@@ -2,6 +2,8 @@
# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt
+# type: ignore # Deprecated module.
+
import optparse # pylint: disable=deprecated-module
import warnings
diff --git a/pylint/config/options_provider_mixin.py b/pylint/config/options_provider_mixin.py
index 5b20a290f..ef85149a9 100644
--- a/pylint/config/options_provider_mixin.py
+++ b/pylint/config/options_provider_mixin.py
@@ -2,6 +2,8 @@
# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt
+# type: ignore # Deprecated module.
+
import optparse # pylint: disable=deprecated-module
import warnings
diff --git a/setup.cfg b/setup.cfg
index 8256945a2..51d6131da 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -45,6 +45,7 @@ warn_unused_ignores = True
disallow_any_generics = True
show_error_codes = True
enable_error_code = ignore-without-code
+check_untyped_defs = True
[mypy-astroid.*]
ignore_missing_imports = True
diff --git a/tests/lint/unittest_expand_modules.py b/tests/lint/unittest_expand_modules.py
index 15f72d0c5..6a3123aab 100644
--- a/tests/lint/unittest_expand_modules.py
+++ b/tests/lint/unittest_expand_modules.py
@@ -119,7 +119,8 @@ class TestExpandModules(CheckerTestCase):
@set_config(ignore_paths="")
def test_expand_modules(self, files_or_modules, expected):
"""Test expand_modules with the default value of ignore-paths."""
- ignore_list, ignore_list_re = [], []
+ ignore_list: list[str] = []
+ ignore_list_re: list[re.Pattern[str]] = []
modules, errors = expand_modules(
files_or_modules,
ignore_list,
@@ -145,7 +146,8 @@ class TestExpandModules(CheckerTestCase):
@set_config(ignore_paths=".*/lint/.*")
def test_expand_modules_with_ignore(self, files_or_modules, expected):
"""Test expand_modules with a non-default value of ignore-paths."""
- ignore_list, ignore_list_re = [], []
+ ignore_list: list[str] = []
+ ignore_list_re: list[re.Pattern[str]] = []
modules, errors = expand_modules(
files_or_modules,
ignore_list,
diff --git a/tests/pyreverse/test_utils.py b/tests/pyreverse/test_utils.py
index 70d95346f..adf7579b1 100644
--- a/tests/pyreverse/test_utils.py
+++ b/tests/pyreverse/test_utils.py
@@ -48,8 +48,10 @@ def test_get_visibility(names, expected):
)
def test_get_annotation_annassign(assign, label):
"""AnnAssign."""
- node = astroid.extract_node(assign)
- got = get_annotation(node.value).name
+ node: nodes.AnnAssign = astroid.extract_node(assign)
+ annotation = get_annotation(node.value)
+ assert annotation is not None
+ got = annotation.name
assert isinstance(node, nodes.AnnAssign)
assert got == label, f"got {got} instead of {label} for value {node}"
@@ -75,7 +77,9 @@ def test_get_annotation_assignattr(init_method, label):
instance_attrs = node.instance_attrs
for assign_attrs in instance_attrs.values():
for assign_attr in assign_attrs:
- got = get_annotation(assign_attr).name
+ annotation = get_annotation(assign_attr)
+ assert annotation is not None
+ got = annotation.name
assert isinstance(assign_attr, nodes.AssignAttr)
assert got == label, f"got {got} instead of {label} for value {node}"
diff --git a/tests/reporters/unittest_reporting.py b/tests/reporters/unittest_reporting.py
index ebc4a225f..c81590359 100644
--- a/tests/reporters/unittest_reporting.py
+++ b/tests/reporters/unittest_reporting.py
@@ -17,7 +17,7 @@ import pytest
from pylint import checkers
from pylint.lint import PyLinter
-from pylint.reporters import BaseReporter
+from pylint.reporters import BaseReporter, MultiReporter
from pylint.reporters.text import ParseableTextReporter, TextReporter
from pylint.typing import FileItem
@@ -195,6 +195,7 @@ def test_multi_format_output(tmp_path):
linter.reporter.writeln("direct output")
# Ensure the output files are flushed and closed
+ assert isinstance(linter.reporter, MultiReporter)
linter.reporter.close_output_files()
del linter.reporter
@@ -337,5 +338,5 @@ def test_display_results_is_renamed():
reporter = CustomReporter()
with pytest.raises(AttributeError) as exc:
# pylint: disable=no-member
- reporter.display_results()
+ reporter.display_results() # type: ignore[attr-defined]
assert "no attribute 'display_results'" in str(exc)
diff --git a/tests/test_func.py b/tests/test_func.py
index 23f5ff102..b799cf12b 100644
--- a/tests/test_func.py
+++ b/tests/test_func.py
@@ -100,7 +100,7 @@ class LintTestUpdate(LintTestUsingModule):
except OSError:
expected = ""
if got != expected:
- with open(self.output, "w", encoding="utf-8") as f:
+ with open(self.output or "", "w", encoding="utf-8") as f:
f.write(got)
@@ -109,7 +109,7 @@ def gen_tests(filter_rgx):
is_to_run = re.compile(filter_rgx).search
else:
is_to_run = (
- lambda x: 1 # pylint: disable=unnecessary-lambda-assignment
+ lambda x: 1 # type: ignore[assignment] # pylint: disable=unnecessary-lambda-assignment
) # noqa: E731 We're going to throw all this anyway
tests = []
for module_file, messages_file in _get_tests_info(INPUT_DIR, MSG_DIR, "func_", ""):