diff options
69 files changed, 965 insertions, 775 deletions
diff --git a/pylint/checkers/similar.py b/pylint/checkers/similar.py index 5a294e995..c65b1c893 100644 --- a/pylint/checkers/similar.py +++ b/pylint/checkers/similar.py @@ -49,7 +49,6 @@ import re import sys from collections import defaultdict from getopt import getopt -from io import TextIOWrapper from itertools import chain, groupby from typing import ( Any, @@ -61,6 +60,7 @@ from typing import ( NamedTuple, NewType, Set, + TextIO, Tuple, ) @@ -368,9 +368,7 @@ class Similar: self.ignore_signatures = ignore_signatures self.linesets: List["LineSet"] = [] - def append_stream( - self, streamid: str, stream: TextIOWrapper, encoding=None - ) -> None: + def append_stream(self, streamid: str, stream: TextIO, encoding=None) -> None: """append a file to search for similarities""" if encoding is None: readlines = stream.readlines diff --git a/pylint/lint/utils.py b/pylint/lint/utils.py index b1f8edfff..280b144b7 100644 --- a/pylint/lint/utils.py +++ b/pylint/lint/utils.py @@ -5,7 +5,7 @@ import contextlib import sys import traceback from datetime import datetime -from pathlib import Path +from pathlib import Path, PosixPath from typing import Union from pylint.config import PYLINT_HOME @@ -17,7 +17,7 @@ class ArgumentPreprocessingError(Exception): def prepare_crash_report( - ex: Exception, filepath: str, crash_file_path: Union[Path, str] + ex: Exception, filepath: PosixPath, crash_file_path: Union[Path, str] ) -> Path: issue_template_path = ( Path(PYLINT_HOME) / datetime.now().strftime(str(crash_file_path)) @@ -63,7 +63,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: Path) -> str: +def get_fatal_error_message(filepath: str, issue_template_path: str) -> 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/message/message_definition.py b/pylint/message/message_definition.py index f7f680590..30dacb32f 100644 --- a/pylint/message/message_definition.py +++ b/pylint/message/message_definition.py @@ -18,8 +18,8 @@ class MessageDefinition: description: str, symbol: str, scope: str, - minversion: Optional[Tuple[int, int, int, str, int]] = None, - maxversion: Optional[Tuple[int, int, int, str, int]] = None, + minversion: Optional[Tuple[int, int]] = None, + maxversion: Optional[Tuple[int, int]] = None, old_names: List[Tuple[str, str]] = None, ): self.checker_name = checker.name diff --git a/pylint/testutils/output_line.py b/pylint/testutils/output_line.py index 9d38b6847..4fb71b456 100644 --- a/pylint/testutils/output_line.py +++ b/pylint/testutils/output_line.py @@ -58,10 +58,10 @@ Try updating it with: 'python tests/test_functional.py {UPDATE_OPTION}'""" class OutputLine(NamedTuple): symbol: str lineno: int - column: int + column: str object: Any msg: str - confidence: str + confidence: interfaces.Confidence @classmethod def from_msg(cls, msg): diff --git a/requirements_test_min.txt b/requirements_test_min.txt index 40b88797f..fa6c3f83a 100644 --- a/requirements_test_min.txt +++ b/requirements_test_min.txt @@ -2,3 +2,4 @@ astroid==2.7.3 # Pinned to a specific version for tests pytest~=6.2 pytest-benchmark~=3.4 +mypy_extensions==0.4.3 diff --git a/tests/checkers/unittest_base.py b/tests/checkers/unittest_base.py index 6a20db922..a7ffa3c55 100644 --- a/tests/checkers/unittest_base.py +++ b/tests/checkers/unittest_base.py @@ -39,24 +39,24 @@ from pylint.testutils import CheckerTestCase, Message, set_config class TestDocstring(CheckerTestCase): CHECKER_CLASS: Type = base.DocStringChecker - def test_missing_docstring_module(self): + def test_missing_docstring_module(self) -> None: module = astroid.parse("something") message = Message("missing-module-docstring", node=module) with self.assertAddsMessages(message): self.checker.visit_module(module) - def test_missing_docstring_empty_module(self): + def test_missing_docstring_empty_module(self) -> None: module = astroid.parse("") with self.assertNoMessages(): self.checker.visit_module(module) - def test_empty_docstring_module(self): + def test_empty_docstring_module(self) -> None: module = astroid.parse("''''''") message = Message("empty-docstring", node=module, args=("module",)) with self.assertAddsMessages(message): self.checker.visit_module(module) - def test_empty_docstring_function(self): + def test_empty_docstring_function(self) -> None: func = astroid.extract_node( """ def func(tion): @@ -67,7 +67,7 @@ class TestDocstring(CheckerTestCase): self.checker.visit_functiondef(func) @set_config(docstring_min_length=2) - def test_short_function_no_docstring(self): + def test_short_function_no_docstring(self) -> None: func = astroid.extract_node( """ def func(tion): @@ -77,7 +77,7 @@ class TestDocstring(CheckerTestCase): self.checker.visit_functiondef(func) @set_config(docstring_min_length=2) - def test_long_function_no_docstring(self): + def test_long_function_no_docstring(self) -> None: func = astroid.extract_node( """ def func(tion): @@ -90,7 +90,7 @@ class TestDocstring(CheckerTestCase): self.checker.visit_functiondef(func) @set_config(docstring_min_length=2) - def test_long_function_nested_statements_no_docstring(self): + def test_long_function_nested_statements_no_docstring(self) -> None: func = astroid.extract_node( """ def func(tion): @@ -105,7 +105,7 @@ class TestDocstring(CheckerTestCase): self.checker.visit_functiondef(func) @set_config(docstring_min_length=2) - def test_function_no_docstring_by_name(self): + def test_function_no_docstring_by_name(self) -> None: func = astroid.extract_node( """ def __fun__(tion): @@ -114,7 +114,7 @@ class TestDocstring(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(func) - def test_class_no_docstring(self): + def test_class_no_docstring(self) -> None: klass = astroid.extract_node( """ class Klass(object): @@ -124,7 +124,7 @@ class TestDocstring(CheckerTestCase): with self.assertAddsMessages(message): self.checker.visit_classdef(klass) - def test_inner_function_no_docstring(self): + def test_inner_function_no_docstring(self) -> None: func = astroid.extract_node( """ def func(tion): @@ -146,7 +146,7 @@ class TestNameChecker(CheckerTestCase): attr_rgx=re.compile("[A-Z]+"), property_classes=("abc.abstractproperty", ".custom_prop"), ) - def test_property_names(self): + def test_property_names(self) -> None: # If a method is annotated with @property, its name should # match the attr regex. Since by default the attribute regex is the same # as the method regex, we override it here. @@ -189,7 +189,7 @@ class TestNameChecker(CheckerTestCase): self.checker.visit_functiondef(methods[1]) @set_config(attr_rgx=re.compile("[A-Z]+")) - def test_property_setters(self): + def test_property_setters(self) -> None: method = astroid.extract_node( """ class FooClass(object): @@ -204,7 +204,7 @@ class TestNameChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(method) - def test_module_level_names(self): + def test_module_level_names(self) -> None: assign = astroid.extract_node( """ import collections @@ -289,7 +289,7 @@ class TestMultiNamingStyle(CheckerTestCase): MULTI_STYLE_RE = re.compile("(?:(?P<UP>[A-Z]+)|(?P<down>[a-z]+))$") @set_config(class_rgx=MULTI_STYLE_RE) - def test_multi_name_detection_majority(self): + def test_multi_name_detection_majority(self) -> None: classes = astroid.extract_node( """ class classb(object): #@ @@ -317,7 +317,7 @@ class TestMultiNamingStyle(CheckerTestCase): self.checker.leave_module(cls.root) @set_config(class_rgx=MULTI_STYLE_RE) - def test_multi_name_detection_first_invalid(self): + def test_multi_name_detection_first_invalid(self) -> None: classes = astroid.extract_node( """ class class_a(object): #@ @@ -391,7 +391,7 @@ class TestMultiNamingStyle(CheckerTestCase): @set_config( function_rgx=re.compile("(?:(?P<ignore>FOO)|(?P<UP>[A-Z]+)|(?P<down>[a-z]+))$") ) - def test_multi_name_detection_exempt(self): + def test_multi_name_detection_exempt(self) -> None: function_defs = astroid.extract_node( """ def FOO(): #@ @@ -424,7 +424,7 @@ class TestMultiNamingStyle(CheckerTestCase): class TestComparison(CheckerTestCase): CHECKER_CLASS = base.ComparisonChecker - def test_comparison(self): + def test_comparison(self) -> None: node = astroid.extract_node("foo == True") message = Message( "singleton-comparison", @@ -545,15 +545,19 @@ class TestNamePresets(unittest.TestCase): SNAKE_CASE_NAMES | CAMEL_CASE_NAMES | UPPER_CASE_NAMES | PASCAL_CASE_NAMES ) - def _test_name_is_correct_for_all_name_types(self, naming_style, name): + def _test_name_is_correct_for_all_name_types( + self, naming_style: Type[base.NamingStyle], name: str + ) -> None: for name_type in base.KNOWN_NAME_TYPES: self._test_is_correct(naming_style, name, name_type) - def _test_name_is_incorrect_for_all_name_types(self, naming_style, name): + def _test_name_is_incorrect_for_all_name_types( + self, naming_style: Type[base.NamingStyle], name: str + ) -> None: for name_type in base.KNOWN_NAME_TYPES: self._test_is_incorrect(naming_style, name, name_type) - def _test_should_always_pass(self, naming_style): + def _test_should_always_pass(self, naming_style: Type[base.NamingStyle]) -> None: always_pass_data = [ ("__add__", "method"), ("__set_name__", "method"), @@ -564,18 +568,22 @@ class TestNamePresets(unittest.TestCase): self._test_is_correct(naming_style, name, name_type) @staticmethod - def _test_is_correct(naming_style, name, name_type): + def _test_is_correct( + naming_style: Type[base.NamingStyle], name: str, name_type: str + ) -> None: rgx = naming_style.get_regex(name_type) fail = f"{name!r} does not match pattern {rgx!r} (style: {naming_style}, type: {name_type})" assert rgx.match(name), fail @staticmethod - def _test_is_incorrect(naming_style, name, name_type): + def _test_is_incorrect( + naming_style: Type[base.NamingStyle], name: str, name_type: str + ) -> None: rgx = naming_style.get_regex(name_type) fail = f"{name!r} not match pattern {rgx!r} (style: {naming_style}, type: {name_type})" assert not rgx.match(name), fail - def test_snake_case(self): + def test_snake_case(self) -> None: naming_style = base.SnakeCaseStyle for name in self.SNAKE_CASE_NAMES: @@ -585,7 +593,7 @@ class TestNamePresets(unittest.TestCase): self._test_should_always_pass(naming_style) - def test_camel_case(self): + def test_camel_case(self) -> None: naming_style = base.CamelCaseStyle for name in self.CAMEL_CASE_NAMES: @@ -595,7 +603,7 @@ class TestNamePresets(unittest.TestCase): self._test_should_always_pass(naming_style) - def test_upper_case(self): + def test_upper_case(self) -> None: naming_style = base.UpperCaseStyle for name in self.UPPER_CASE_NAMES: @@ -606,7 +614,7 @@ class TestNamePresets(unittest.TestCase): self._test_should_always_pass(naming_style) - def test_pascal_case(self): + def test_pascal_case(self) -> None: naming_style = base.PascalCaseStyle for name in self.PASCAL_CASE_NAMES: @@ -618,7 +626,7 @@ class TestNamePresets(unittest.TestCase): class TestBaseChecker(unittest.TestCase): - def test_doc(self): + def test_doc(self) -> None: class OtherBasicChecker(BaseChecker): name = "basic" msgs = { diff --git a/tests/checkers/unittest_classes.py b/tests/checkers/unittest_classes.py index 1f60d1b32..13bcc5fc0 100644 --- a/tests/checkers/unittest_classes.py +++ b/tests/checkers/unittest_classes.py @@ -26,7 +26,7 @@ class TestVariablesChecker(CheckerTestCase): CHECKER_CLASS = classes.ClassChecker - def test_bitbucket_issue_164(self): + def test_bitbucket_issue_164(self) -> None: """Issue 164 report a false negative for access-member-before-definition""" n1, n2 = astroid.extract_node( """ @@ -43,7 +43,7 @@ class TestVariablesChecker(CheckerTestCase): self.walk(n1.root()) @set_config(exclude_protected=("_meta", "_manager")) - def test_exclude_protected(self): + def test_exclude_protected(self) -> None: """Test that exclude-protected can be used to exclude names from protected-access warning. """ @@ -67,7 +67,7 @@ class TestVariablesChecker(CheckerTestCase): ): self.walk(node.root()) - def test_regression_non_parent_init_called_tracemalloc(self): + def test_regression_non_parent_init_called_tracemalloc(self) -> None: # This used to raise a non-parent-init-called on Pylint 1.3 # See issue https://bitbucket.org/logilab/pylint/issue/308/ # for reference. @@ -82,7 +82,7 @@ class TestVariablesChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_super_init_not_called_regression(self): + def test_super_init_not_called_regression(self) -> None: # This should not emit a super-init-not-called # warning. It previously did this, because # ``next(node.infer())`` was used in that checker's @@ -100,7 +100,7 @@ class TestVariablesChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_uninferable_attribute(self): + def test_uninferable_attribute(self) -> None: """Make sure protect-access doesn't raise an exception Uninferable attributes""" node = astroid.extract_node( @@ -121,7 +121,7 @@ class TestVariablesChecker(CheckerTestCase): self.checker.visit_attribute(node.value) @set_config(check_protected_access_in_special_methods=True) - def test_check_protected_access_in_special_methods(self): + def test_check_protected_access_in_special_methods(self) -> None: """Test that check-protected-access-in-special-methods can be used to trigger protected-access message emission for single underscore prefixed names inside special methods @@ -170,7 +170,7 @@ class TestVariablesChecker(CheckerTestCase): self.walk(node.root()) @set_config(check_protected_access_in_special_methods=False) - def test_check_protected_access_in_special_methods_deact(self): + def test_check_protected_access_in_special_methods_deact(self) -> None: """Test that when check-protected-access-in-special-methods is False (default) no protected-access message emission for single underscore prefixed names inside special methods occur @@ -215,7 +215,7 @@ class TestVariablesChecker(CheckerTestCase): ): self.walk(node.root()) - def test_private_attribute_hides_method(self): + def test_private_attribute_hides_method(self) -> None: node = astroid.extract_node( """ class Parent: @@ -230,7 +230,7 @@ class TestVariablesChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_protected_attribute_hides_method(self): + def test_protected_attribute_hides_method(self) -> None: node = astroid.extract_node( """ class Parent: diff --git a/tests/checkers/unittest_deprecated.py b/tests/checkers/unittest_deprecated.py index f0142a1e6..686fb0cc3 100644 --- a/tests/checkers/unittest_deprecated.py +++ b/tests/checkers/unittest_deprecated.py @@ -1,3 +1,5 @@ +from typing import List, Optional, Set, Tuple, Union + import astroid from pylint.checkers import BaseChecker, DeprecatedMixin @@ -9,16 +11,20 @@ class _DeprecatedChecker(DeprecatedMixin, BaseChecker): __implements__ = (IAstroidChecker,) name = "deprecated" - def deprecated_methods(self): + def deprecated_methods(self) -> Set[str]: return {"deprecated_func", ".Deprecated.deprecated_method"} - def deprecated_modules(self): + def deprecated_modules(self) -> Set[str]: return {"deprecated_module"} - def deprecated_classes(self, module): + def deprecated_classes(self, module: str) -> List[str]: return ["DeprecatedClass"] if module == "deprecated" else [] - def deprecated_arguments(self, method): + def deprecated_arguments( + self, method: str + ) -> Union[ + Tuple[Tuple[Optional[int], str], ...], Tuple[Tuple[int, str], Tuple[int, str]] + ]: if method == "myfunction1": # def myfunction1(arg1, deprecated_arg1='spam') return ((1, "deprecated_arg1"),) @@ -42,14 +48,14 @@ class _DeprecatedChecker(DeprecatedMixin, BaseChecker): return ((0, "deprecated_arg"),) return () - def deprecated_decorators(self): + def deprecated_decorators(self) -> Set[str]: return {".deprecated_decorator"} class TestDeprecatedChecker(CheckerTestCase): CHECKER_CLASS = _DeprecatedChecker - def test_deprecated_function(self): + def test_deprecated_function(self) -> None: # Tests detecting deprecated function node = astroid.extract_node( """ @@ -69,7 +75,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_deprecated_method(self): + def test_deprecated_method(self) -> None: # Tests detecting deprecated method node = astroid.extract_node( """ @@ -91,7 +97,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_deprecated_method_alias(self): + def test_deprecated_method_alias(self) -> None: # Tests detecting deprecated method defined as alias # to existing method node = astroid.extract_node( @@ -116,7 +122,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_no_message(self): + def test_no_message(self) -> None: # Tests not raising error when no deprecated functions/methods are present. node = astroid.extract_node( """ @@ -135,7 +141,7 @@ class TestDeprecatedChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_call(node) - def test_function_deprecated_arg(self): + def test_function_deprecated_arg(self) -> None: # Tests raising error when calling function with deprecated argument node = astroid.extract_node( """ @@ -155,7 +161,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_function_deprecated_kwarg(self): + def test_function_deprecated_kwarg(self) -> None: # Tests raising error when calling function with deprecated keyword argument node = astroid.extract_node( """ @@ -175,7 +181,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_function_deprecated_not_used(self): + def test_function_deprecated_not_used(self) -> None: # Tests raising error when calling function without deprecated argument node = astroid.extract_node( """ @@ -188,7 +194,7 @@ class TestDeprecatedChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_call(node) - def test_function_deprecated_kwarg_only(self): + def test_function_deprecated_kwarg_only(self) -> None: # Tests raising error when calling function with deprecated keyword only argument node = astroid.extract_node( """ @@ -208,7 +214,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_method_deprecated_arg(self): + def test_method_deprecated_arg(self) -> None: # Tests raising error when calling method with deprecated argument node = astroid.extract_node( """ @@ -229,7 +235,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_method_deprecated_kwarg(self): + def test_method_deprecated_kwarg(self) -> None: # Tests raising error when calling method with deprecated keyword argument node = astroid.extract_node( """ @@ -250,7 +256,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_method_deprecated_not_used(self): + def test_method_deprecated_not_used(self) -> None: # Tests raising error when calling method without deprecated argument node = astroid.extract_node( """ @@ -264,7 +270,7 @@ class TestDeprecatedChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_call(node) - def test_method_deprecated_kwarg_only(self): + def test_method_deprecated_kwarg_only(self) -> None: # Tests raising error when calling method with deprecated keyword only argument node = astroid.extract_node( """ @@ -285,7 +291,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_function_deprecated_arg_kwargs(self): + def test_function_deprecated_arg_kwargs(self) -> None: # Tests raising error when calling function with deprecated argument # and keyword argument node = astroid.extract_node( @@ -312,7 +318,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_function_deprecated_kwarg_kwarg(self): + def test_function_deprecated_kwarg_kwarg(self) -> None: # Tests raising error when calling function with deprecated keyword arguments node = astroid.extract_node( """ @@ -338,7 +344,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_method_deprecated_arg_kwargs(self): + def test_method_deprecated_arg_kwargs(self) -> None: # Tests raising error when calling method with deprecated argument # and keyword argument node = astroid.extract_node( @@ -366,7 +372,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_method_deprecated_kwarg_kwarg(self): + def test_method_deprecated_kwarg_kwarg(self) -> None: # Tests raising error when calling method with deprecated keyword arguments node = astroid.extract_node( """ @@ -393,7 +399,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_class_deprecated_arguments(self): + def test_class_deprecated_arguments(self) -> None: node = astroid.extract_node( """ @@ -414,7 +420,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_deprecated_module(self): + def test_deprecated_module(self) -> None: # Tests detecting deprecated module node = astroid.extract_node( """ @@ -431,7 +437,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_import(node) - def test_deprecated_module_from(self): + def test_deprecated_module_from(self) -> None: # Tests detecting deprecated module node = astroid.extract_node( """ @@ -448,7 +454,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_importfrom(node) - def test_deprecated_class_import_from(self): + def test_deprecated_class_import_from(self) -> None: # Tests detecting deprecated class via import from node = astroid.extract_node( """ @@ -465,7 +471,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_importfrom(node) - def test_deprecated_class_import(self): + def test_deprecated_class_import(self) -> None: # Tests detecting deprecated class via import node = astroid.extract_node( """ @@ -482,7 +488,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_import(node) - def test_deprecated_class_call(self): + def test_deprecated_class_call(self) -> None: # Tests detecting deprecated class via call node = astroid.extract_node( """ @@ -500,7 +506,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_deprecated_decorator(self): + def test_deprecated_decorator(self) -> None: # Tests detecting deprecated decorator node = astroid.extract_node( """ @@ -524,7 +530,7 @@ class TestDeprecatedChecker(CheckerTestCase): ): self.checker.visit_decorators(node) - def test_deprecated_decorator_with_arguments(self): + def test_deprecated_decorator_with_arguments(self) -> None: # Tests detecting deprecated decorator with arguments node = astroid.extract_node( """ diff --git a/tests/checkers/unittest_design.py b/tests/checkers/unittest_design.py index cb2d22fb7..d65eba68e 100644 --- a/tests/checkers/unittest_design.py +++ b/tests/checkers/unittest_design.py @@ -20,7 +20,7 @@ class TestDesignChecker(CheckerTestCase): ignored_parents=(".Dddd",), max_parents=1, ) - def test_too_many_ancestors_ignored_parents_are_skipped(self): + def test_too_many_ancestors_ignored_parents_are_skipped(self) -> None: """Make sure that classes listed in ``ignored-parents`` aren't counted by the too-many-ancestors message. """ diff --git a/tests/checkers/unittest_exceptions.py b/tests/checkers/unittest_exceptions.py index 4a8ffc806..fe449d8ba 100644 --- a/tests/checkers/unittest_exceptions.py +++ b/tests/checkers/unittest_exceptions.py @@ -30,13 +30,13 @@ class TestExceptionsChecker(CheckerTestCase): # and `raise (Error, ...)` will be converted to # `raise Error(...)`, so it beats the purpose of the test. - def test_raising_bad_type_python3(self): + def test_raising_bad_type_python3(self) -> None: node = astroid.extract_node("raise (ZeroDivisionError, None) #@") message = Message("raising-bad-type", node=node, args="tuple") with self.assertAddsMessages(message): self.checker.visit_raise(node) - def test_bad_exception_context_function(self): + def test_bad_exception_context_function(self) -> None: node = astroid.extract_node( """ def function(): diff --git a/tests/checkers/unittest_format.py b/tests/checkers/unittest_format.py index 658a7e3f4..4023207bb 100644 --- a/tests/checkers/unittest_format.py +++ b/tests/checkers/unittest_format.py @@ -31,6 +31,7 @@ import os import tempfile import tokenize +from typing import Any import astroid @@ -42,7 +43,7 @@ from pylint.testutils import CheckerTestCase, Message, _tokenize_str class TestMultiStatementLine(CheckerTestCase): CHECKER_CLASS = FormatChecker - def testSingleLineIfStmts(self): + def testSingleLineIfStmts(self) -> None: stmt = astroid.extract_node( """ if True: pass #@ @@ -64,7 +65,7 @@ class TestMultiStatementLine(CheckerTestCase): with self.assertAddsMessages(Message("multiple-statements", node=stmt.body[0])): self.visitFirst(stmt) - def testSingleLineClassStmts(self): + def testSingleLineClassStmts(self) -> None: stmt = astroid.extract_node( """ class MyError(Exception): pass #@ @@ -101,7 +102,7 @@ class TestMultiStatementLine(CheckerTestCase): with self.assertAddsMessages(Message("multiple-statements", node=stmt.body[0])): self.visitFirst(stmt) - def testTryExceptFinallyNoMultipleStatement(self): + def testTryExceptFinallyNoMultipleStatement(self) -> None: tree = astroid.extract_node( """ try: #@ @@ -114,11 +115,11 @@ class TestMultiStatementLine(CheckerTestCase): with self.assertNoMessages(): self.visitFirst(tree) - def visitFirst(self, tree): + def visitFirst(self, tree: Any) -> None: self.checker.process_tokens([]) self.checker.visit_default(tree.body[0]) - def test_ellipsis_is_ignored(self): + def test_ellipsis_is_ignored(self) -> None: code = """ from typing import overload @overload @@ -139,7 +140,7 @@ class TestMultiStatementLine(CheckerTestCase): class TestSuperfluousParentheses(CheckerTestCase): CHECKER_CLASS = FormatChecker - def testCheckKeywordParensHandlesValidCases(self): + def testCheckKeywordParensHandlesValidCases(self) -> None: cases = [ "if foo:", "if foo():", @@ -160,7 +161,7 @@ class TestSuperfluousParentheses(CheckerTestCase): for code in cases: self.checker._check_keyword_parentheses(_tokenize_str(code), 0) - def testCheckKeywordParensHandlesUnnecessaryParens(self): + def testCheckKeywordParensHandlesUnnecessaryParens(self) -> None: cases = [ (Message("superfluous-parens", line=1, args="if"), "if (foo):", 0), (Message("superfluous-parens", line=1, args="if"), "if ((foo, bar)):", 0), @@ -184,7 +185,7 @@ class TestSuperfluousParentheses(CheckerTestCase): with self.assertAddsMessages(msg): self.checker._check_keyword_parentheses(_tokenize_str(code), offset) - def testNoSuperfluousParensWalrusOperatorIf(self): + def testNoSuperfluousParensWalrusOperatorIf(self) -> None: """Parenthesis change the meaning of assignment in the walrus operator and so are not always superfluous:""" cases = [ @@ -195,7 +196,7 @@ class TestSuperfluousParentheses(CheckerTestCase): with self.assertNoMessages(): self.checker.process_tokens(_tokenize_str(code)) - def testPositiveSuperfluousParensWalrusOperatorIf(self): + def testPositiveSuperfluousParensWalrusOperatorIf(self) -> None: """Test positive superfluous parens cases with the walrus operator""" cases = [ (Message("superfluous-parens", line=1, args="if"), "if ((x := y)):\n"), @@ -205,7 +206,7 @@ class TestSuperfluousParentheses(CheckerTestCase): with self.assertAddsMessages(msg): self.checker.process_tokens(_tokenize_str(code)) - def testCheckIfArgsAreNotUnicode(self): + def testCheckIfArgsAreNotUnicode(self) -> None: cases = [("if (foo):", 0), ("assert (1 == 1)", 0)] for code, offset in cases: @@ -213,7 +214,7 @@ class TestSuperfluousParentheses(CheckerTestCase): got = self.linter.release_messages() assert isinstance(got[-1].args, str) - def testFuturePrintStatementWithoutParensWarning(self): + def testFuturePrintStatementWithoutParensWarning(self) -> None: code = """from __future__ import print_function print('Hello world!') """ @@ -222,7 +223,7 @@ print('Hello world!') self.checker.process_module(tree) self.checker.process_tokens(_tokenize_str(code)) - def testKeywordParensFalsePositive(self): + def testKeywordParensFalsePositive(self) -> None: code = "if 'bar' in (DICT or {}):" with self.assertNoMessages(): self.checker._check_keyword_parentheses(_tokenize_str(code), start=2) @@ -231,7 +232,7 @@ print('Hello world!') class TestCheckSpace(CheckerTestCase): CHECKER_CLASS = FormatChecker - def test_encoding_token(self): + def test_encoding_token(self) -> None: """Make sure the encoding token doesn't change the checker's behavior _tokenize_str doesn't produce an encoding token, but @@ -247,7 +248,7 @@ class TestCheckSpace(CheckerTestCase): self.checker.process_tokens(tokens) -def test_disable_global_option_end_of_line(): +def test_disable_global_option_end_of_line() -> None: """ Test for issue with disabling tokenizer messages that extend beyond the scope of the ast tokens diff --git a/tests/checkers/unittest_imports.py b/tests/checkers/unittest_imports.py index 852177903..fe99a49f2 100644 --- a/tests/checkers/unittest_imports.py +++ b/tests/checkers/unittest_imports.py @@ -34,7 +34,7 @@ class TestImportsChecker(CheckerTestCase): CHECKER_CLASS = imports.ImportsChecker @set_config(allow_any_import_level=("astroid",)) - def test_import_outside_toplevel(self): + def test_import_outside_toplevel(self) -> None: node = astroid.extract_node( """ def f(): @@ -60,7 +60,7 @@ class TestImportsChecker(CheckerTestCase): @set_config( ignored_modules=("external_module", "fake_module.submodule", "foo", "bar") ) - def test_import_error_skipped(self): + def test_import_error_skipped(self) -> None: """Make sure that imports do not emit an 'import-error' when the module is configured to be ignored.""" @@ -122,7 +122,7 @@ class TestImportsChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_import(node) - def test_reimported_same_line(self): + def test_reimported_same_line(self) -> None: """ Test that duplicate imports on single line raise 'reimported'. """ @@ -131,7 +131,7 @@ class TestImportsChecker(CheckerTestCase): with self.assertAddsMessages(msg): self.checker.visit_importfrom(node) - def test_relative_beyond_top_level(self): + def test_relative_beyond_top_level(self) -> None: module = astroid.MANAGER.ast_from_module_name("beyond_top", REGR_DATA) import_from = module.body[0] @@ -143,14 +143,14 @@ class TestImportsChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_importfrom(module.body[2].body[0]) - def test_wildcard_import_init(self): + def test_wildcard_import_init(self) -> None: module = astroid.MANAGER.ast_from_module_name("init_wildcard", REGR_DATA) import_from = module.body[0] with self.assertNoMessages(): self.checker.visit_importfrom(import_from) - def test_wildcard_import_non_init(self): + def test_wildcard_import_non_init(self) -> None: module = astroid.MANAGER.ast_from_module_name("wildcard", REGR_DATA) import_from = module.body[0] diff --git a/tests/checkers/unittest_logging.py b/tests/checkers/unittest_logging.py index 551d6efd3..1cf6f6ff9 100644 --- a/tests/checkers/unittest_logging.py +++ b/tests/checkers/unittest_logging.py @@ -15,6 +15,7 @@ """Unittest for the logging checker.""" import sys +from typing import Optional, Tuple import astroid import pytest @@ -27,7 +28,7 @@ from pylint.testutils import CheckerTestCase, Message, set_config class TestLoggingModuleDetection(CheckerTestCase): CHECKER_CLASS = logging.LoggingChecker - def test_detects_standard_logging_module(self): + def test_detects_standard_logging_module(self) -> None: stmts = astroid.extract_node( """ import logging #@ @@ -41,7 +42,7 @@ class TestLoggingModuleDetection(CheckerTestCase): ): self.checker.visit_call(stmts[1]) - def test_dont_crash_on_invalid_format_string(self): + def test_dont_crash_on_invalid_format_string(self) -> None: node = astroid.parse( """ import logging @@ -50,7 +51,7 @@ class TestLoggingModuleDetection(CheckerTestCase): ) self.walk(node) - def test_detects_renamed_standard_logging_module(self): + def test_detects_renamed_standard_logging_module(self) -> None: stmts = astroid.extract_node( """ import logging as blogging #@ @@ -65,7 +66,7 @@ class TestLoggingModuleDetection(CheckerTestCase): self.checker.visit_call(stmts[1]) @set_config(logging_modules=["logging", "my.logging"]) - def test_nonstandard_logging_module(self): + def test_nonstandard_logging_module(self) -> None: stmts = astroid.extract_node( """ from my import logging as blogging #@ @@ -79,7 +80,7 @@ class TestLoggingModuleDetection(CheckerTestCase): ): self.checker.visit_call(stmts[1]) - def _assert_logging_format_no_messages(self, stmt): + def _assert_logging_format_no_messages(self, stmt: str) -> None: stmts = astroid.extract_node( """ import logging #@ @@ -93,7 +94,13 @@ class TestLoggingModuleDetection(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_call(stmts[1]) - def _assert_logging_format_message(self, msg, stmt, args=None, with_too_many=False): + def _assert_logging_format_message( + self, + msg: str, + stmt: str, + args: Optional[Tuple[str]] = None, + with_too_many: bool = False, + ) -> None: stmts = astroid.extract_node( """ import logging #@ @@ -112,14 +119,14 @@ class TestLoggingModuleDetection(CheckerTestCase): with self.assertAddsMessages(*messages): self.checker.visit_call(stmts[1]) - def _assert_logging_format_too_few_args(self, stmt): + def _assert_logging_format_too_few_args(self, stmt: str) -> None: self._assert_logging_format_message("logging-too-few-args", stmt) - def _assert_logging_format_too_many_args(self, stmt): + def _assert_logging_format_too_many_args(self, stmt: str) -> None: self._assert_logging_format_message("logging-too-many-args", stmt) @set_config(logging_format_style="new") - def test_brace_format_style_matching_arguments(self): + def test_brace_format_style_matching_arguments(self) -> None: self._assert_logging_format_no_messages("('constant string')") self._assert_logging_format_no_messages("('{}')") self._assert_logging_format_no_messages("('{}', 1)") @@ -129,7 +136,7 @@ class TestLoggingModuleDetection(CheckerTestCase): self._assert_logging_format_no_messages("('{0} {named}', 1, {'named': 1})") @set_config(logging_format_style="new") - def test_brace_format_style_too_few_args(self): + def test_brace_format_style_too_few_args(self) -> None: self._assert_logging_format_too_few_args("('{}, {}', 1)") self._assert_logging_format_too_few_args("('{0}, {1}', 1)") self._assert_logging_format_too_few_args( @@ -140,7 +147,7 @@ class TestLoggingModuleDetection(CheckerTestCase): self._assert_logging_format_too_few_args("('{0}, {named}', {'named': 1})") @set_config(logging_format_style="new") - def test_brace_format_style_not_enough_arguments(self): + def test_brace_format_style_not_enough_arguments(self) -> None: self._assert_logging_format_too_many_args("('constant string', 1, 2)") self._assert_logging_format_too_many_args("('{}', 1, 2)") self._assert_logging_format_too_many_args("('{0}', 1, 2)") @@ -151,7 +158,7 @@ class TestLoggingModuleDetection(CheckerTestCase): @pytest.mark.skipif(sys.version_info < (3, 6), reason="F-string require >=3.6") @set_config(logging_format_style="new") - def test_fstr_not_new_format_style_matching_arguments(self): + def test_fstr_not_new_format_style_matching_arguments(self) -> None: msg = "logging-fstring-interpolation" args = ("lazy %",) self._assert_logging_format_message(msg, "(f'{named}')", args) diff --git a/tests/checkers/unittest_misc.py b/tests/checkers/unittest_misc.py index 49f794fa8..adf96c202 100644 --- a/tests/checkers/unittest_misc.py +++ b/tests/checkers/unittest_misc.py @@ -24,7 +24,7 @@ from pylint.testutils import CheckerTestCase, Message, _tokenize_str, set_config class TestFixme(CheckerTestCase): CHECKER_CLASS = misc.EncodingChecker - def test_fixme_with_message(self): + def test_fixme_with_message(self) -> None: code = """a = 1 # FIXME message """ @@ -33,28 +33,28 @@ class TestFixme(CheckerTestCase): ): self.checker.process_tokens(_tokenize_str(code)) - def test_todo_without_message(self): + def test_todo_without_message(self) -> None: code = """a = 1 # TODO """ with self.assertAddsMessages(Message(msg_id="fixme", line=2, args="TODO")): self.checker.process_tokens(_tokenize_str(code)) - def test_xxx_without_space(self): + def test_xxx_without_space(self) -> None: code = """a = 1 #XXX """ with self.assertAddsMessages(Message(msg_id="fixme", line=2, args="XXX")): self.checker.process_tokens(_tokenize_str(code)) - def test_xxx_middle(self): + def test_xxx_middle(self) -> None: code = """a = 1 # midle XXX """ with self.assertNoMessages(): self.checker.process_tokens(_tokenize_str(code)) - def test_without_space_fixme(self): + def test_without_space_fixme(self) -> None: code = """a = 1 #FIXME """ @@ -62,7 +62,7 @@ class TestFixme(CheckerTestCase): self.checker.process_tokens(_tokenize_str(code)) @set_config(notes=[]) - def test_absent_codetag(self): + def test_absent_codetag(self) -> None: code = """a = 1 # FIXME # FIXME # TODO # TODO @@ -72,7 +72,7 @@ class TestFixme(CheckerTestCase): self.checker.process_tokens(_tokenize_str(code)) @set_config(notes=["CODETAG"]) - def test_other_present_codetag(self): + def test_other_present_codetag(self) -> None: code = """a = 1 # CODETAG # FIXME @@ -80,19 +80,19 @@ class TestFixme(CheckerTestCase): with self.assertAddsMessages(Message(msg_id="fixme", line=2, args="CODETAG")): self.checker.process_tokens(_tokenize_str(code)) - def test_issue_2321_should_not_trigger(self): + def test_issue_2321_should_not_trigger(self) -> None: code = 'print("# TODO this should not trigger a fixme")' with self.assertNoMessages(): self.checker.process_tokens(_tokenize_str(code)) - def test_issue_2321_should_trigger(self): + def test_issue_2321_should_trigger(self) -> None: code = "# TODO this should not trigger a fixme" with self.assertAddsMessages( Message(msg_id="fixme", line=1, args="TODO this should not trigger a fixme") ): self.checker.process_tokens(_tokenize_str(code)) - def test_dont_trigger_on_todoist(self): + def test_dont_trigger_on_todoist(self) -> None: code = """ # Todoist API: What is this task about? # Todoist API: Look up a task's due date diff --git a/tests/checkers/unittest_refactoring.py b/tests/checkers/unittest_refactoring.py index 8963e2236..4b132e218 100644 --- a/tests/checkers/unittest_refactoring.py +++ b/tests/checkers/unittest_refactoring.py @@ -6,7 +6,7 @@ import astroid from pylint.checkers.refactoring import LenChecker -def test_class_tree_detection(): +def test_class_tree_detection() -> None: module = astroid.parse( """ class ClassWithBool(list): diff --git a/tests/checkers/unittest_similar.py b/tests/checkers/unittest_similar.py index f27df9272..4ddf2029a 100644 --- a/tests/checkers/unittest_similar.py +++ b/tests/checkers/unittest_similar.py @@ -45,7 +45,7 @@ MULTILINE = str(INPUT / "multiline-import") HIDE_CODE_WITH_IMPORTS = str(INPUT / "hide_code_with_imports.py") -def test_ignore_comments(): +def test_ignore_comments() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run(["--ignore-comments", SIMILAR1, SIMILAR2]) @@ -74,7 +74,7 @@ TOTAL lines=62 duplicates=10 percent=16.13 ) -def test_ignore_docstrings(): +def test_ignore_docstrings() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run(["--ignore-docstrings", SIMILAR1, SIMILAR2]) @@ -109,7 +109,7 @@ TOTAL lines=62 duplicates=10 percent=16.13 ) -def test_ignore_imports(): +def test_ignore_imports() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run(["--ignore-imports", SIMILAR1, SIMILAR2]) @@ -122,7 +122,7 @@ TOTAL lines=62 duplicates=0 percent=0.00 ) -def test_multiline_imports(): +def test_multiline_imports() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run([MULTILINE, MULTILINE]) @@ -148,7 +148,7 @@ TOTAL lines=16 duplicates=8 percent=50.00 ) -def test_ignore_multiline_imports(): +def test_ignore_multiline_imports() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run(["--ignore-imports", MULTILINE, MULTILINE]) @@ -161,7 +161,7 @@ TOTAL lines=16 duplicates=0 percent=0.00 ) -def test_ignore_signatures_fail(): +def test_ignore_signatures_fail() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run([SIMILAR5, SIMILAR6]) @@ -199,7 +199,7 @@ TOTAL lines=35 duplicates=15 percent=42.86 ) -def test_ignore_signatures_pass(): +def test_ignore_signatures_pass() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run(["--ignore-signatures", SIMILAR5, SIMILAR6]) @@ -212,7 +212,7 @@ TOTAL lines=35 duplicates=0 percent=0.00 ) -def test_ignore_signatures_class_methods_fail(): +def test_ignore_signatures_class_methods_fail() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run([SIMILAR_CLS_B, SIMILAR_CLS_A]) @@ -258,7 +258,7 @@ TOTAL lines=54 duplicates=22 percent=40.74 ) -def test_ignore_signatures_class_methods_pass(): +def test_ignore_signatures_class_methods_pass() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run(["--ignore-signatures", SIMILAR_CLS_B, SIMILAR_CLS_A]) @@ -271,7 +271,7 @@ TOTAL lines=54 duplicates=0 percent=0.00 ) -def test_ignore_signatures_empty_functions_fail(): +def test_ignore_signatures_empty_functions_fail() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run([EMPTY_FUNCTION_1, EMPTY_FUNCTION_2]) @@ -295,7 +295,7 @@ TOTAL lines=14 duplicates=6 percent=42.86 ) -def test_ignore_signatures_empty_functions_pass(): +def test_ignore_signatures_empty_functions_pass() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run(["--ignore-signatures", EMPTY_FUNCTION_1, EMPTY_FUNCTION_2]) @@ -308,7 +308,7 @@ TOTAL lines=14 duplicates=0 percent=0.00 ) -def test_no_hide_code_with_imports(): +def test_no_hide_code_with_imports() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run(["--ignore-imports"] + 2 * [HIDE_CODE_WITH_IMPORTS]) @@ -316,7 +316,7 @@ def test_no_hide_code_with_imports(): assert "TOTAL lines=32 duplicates=16 percent=50.00" in output.getvalue() -def test_ignore_nothing(): +def test_ignore_nothing() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run([SIMILAR1, SIMILAR2]) @@ -339,7 +339,7 @@ TOTAL lines=62 duplicates=5 percent=8.06 ) -def test_lines_without_meaningful_content_do_not_trigger_similarity(): +def test_lines_without_meaningful_content_do_not_trigger_similarity() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run([SIMILAR3, SIMILAR4]) @@ -371,7 +371,7 @@ TOTAL lines=50 duplicates=14 percent=28.00 ) -def test_help(): +def test_help() -> None: output = StringIO() with redirect_stdout(output): try: @@ -382,7 +382,7 @@ def test_help(): pytest.fail("not system exit") -def test_no_args(): +def test_no_args() -> None: output = StringIO() with redirect_stdout(output): try: @@ -393,7 +393,7 @@ def test_no_args(): pytest.fail("not system exit") -def test_get_map_data(): +def test_get_map_data() -> None: """Tests that a SimilarChecker respects the MapReduceMixin interface""" linter = PyLinter(reporter=Reporter()) diff --git a/tests/checkers/unittest_stdlib.py b/tests/checkers/unittest_stdlib.py index cfec0d4c6..bbd8e044b 100644 --- a/tests/checkers/unittest_stdlib.py +++ b/tests/checkers/unittest_stdlib.py @@ -11,9 +11,12 @@ # For details: https://github.com/PyCQA/pylint/blob/main/LICENSE import contextlib +from typing import Any, Callable, Iterator, Optional, Union import astroid from astroid import nodes +from astroid.manager import AstroidManager +from astroid.nodes.node_classes import AssignAttr, Name from pylint.checkers import stdlib from pylint.interfaces import UNDEFINED @@ -21,7 +24,12 @@ from pylint.testutils import CheckerTestCase, Message @contextlib.contextmanager -def _add_transform(manager, node, transform, predicate=None): +def _add_transform( + manager: AstroidManager, + node: type, + transform: Callable, + predicate: Optional[Any] = None, +) -> Iterator: manager.register_transform(node, transform, predicate) try: yield @@ -32,7 +40,7 @@ def _add_transform(manager, node, transform, predicate=None): class TestStdlibChecker(CheckerTestCase): CHECKER_CLASS = stdlib.StdlibChecker - def test_deprecated_no_qname_on_unexpected_nodes(self): + def test_deprecated_no_qname_on_unexpected_nodes(self) -> None: # Test that we don't crash on nodes which don't have # a qname method. While this test might seem weird since # it uses a transform, it's actually testing a crash that @@ -41,7 +49,11 @@ class TestStdlibChecker(CheckerTestCase): # got to be the result of a function inference # beats me..) - def infer_func(node, context=None): # pylint: disable=unused-argument + def infer_func( + node: Name, context: Optional[Any] = None + ) -> Iterator[ + Union[Iterator, Iterator[AssignAttr]] + ]: # pylint: disable=unused-argument new_node = nodes.AssignAttr() new_node.parent = node yield new_node @@ -57,7 +69,7 @@ class TestStdlibChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_call(node) - def test_copy_environ(self): + def test_copy_environ(self) -> None: # shallow copy of os.environ should be reported node = astroid.extract_node( """ @@ -70,7 +82,7 @@ class TestStdlibChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_copy_environ_hidden(self): + def test_copy_environ_hidden(self) -> None: # shallow copy of os.environ should be reported # hide function names to be sure that checker is not just matching text node = astroid.extract_node( @@ -85,7 +97,7 @@ class TestStdlibChecker(CheckerTestCase): ): self.checker.visit_call(node) - def test_copy_dict(self): + def test_copy_dict(self) -> None: # copy of dict is OK node = astroid.extract_node( """ @@ -97,7 +109,7 @@ class TestStdlibChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_call(node) - def test_copy_uninferable(self): + def test_copy_uninferable(self) -> None: # copy of uninferable object should not raise exception, nor make # the checker crash node = astroid.extract_node( @@ -110,7 +122,7 @@ class TestStdlibChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_call(node) - def test_deepcopy_environ(self): + def test_deepcopy_environ(self) -> None: # deepcopy of os.environ is OK node = astroid.extract_node( """ diff --git a/tests/checkers/unittest_strings.py b/tests/checkers/unittest_strings.py index f0888fb0f..ed94759d5 100644 --- a/tests/checkers/unittest_strings.py +++ b/tests/checkers/unittest_strings.py @@ -40,13 +40,13 @@ TEST_TOKENS = ( class TestStringChecker(CheckerTestCase): CHECKER_CLASS = strings.StringFormatChecker - def test_format_bytes(self): + def test_format_bytes(self) -> None: code = "b'test'.format(1, 2)" node = astroid.extract_node(code) with self.assertNoMessages(): self.checker.visit_call(node) - def test_format_types(self): + def test_format_types(self) -> None: for code in ("'%s' % 1", "'%d' % 1", "'%f' % 1"): with self.assertNoMessages(): node = astroid.extract_node(code) @@ -87,6 +87,6 @@ class TestStringChecker(CheckerTestCase): self.checker.visit_binop(node) -def test_str_eval(): +def test_str_eval() -> None: for token in TEST_TOKENS: assert strings.str_eval(token) == "X" diff --git a/tests/checkers/unittest_typecheck.py b/tests/checkers/unittest_typecheck.py index 136d60fca..4ea132998 100644 --- a/tests/checkers/unittest_typecheck.py +++ b/tests/checkers/unittest_typecheck.py @@ -48,7 +48,7 @@ class TestTypeChecker(CheckerTestCase): "Tests for pylint.checkers.typecheck" CHECKER_CLASS = typecheck.TypeChecker - def test_no_member_in_getattr(self): + def test_no_member_in_getattr(self) -> None: """Make sure that a module attribute access is checked by pylint.""" node = astroid.extract_node( @@ -67,7 +67,7 @@ class TestTypeChecker(CheckerTestCase): self.checker.visit_attribute(node) @set_config(ignored_modules=("argparse",)) - def test_no_member_in_getattr_ignored(self): + def test_no_member_in_getattr_ignored(self) -> None: """Make sure that a module attribute access check is omitted with a module that is configured to be ignored. """ @@ -82,7 +82,7 @@ class TestTypeChecker(CheckerTestCase): self.checker.visit_attribute(node) @set_config(ignored_modules=("xml.etree.",)) - def test_ignored_modules_invalid_pattern(self): + def test_ignored_modules_invalid_pattern(self) -> None: node = astroid.extract_node( """ import xml @@ -96,7 +96,7 @@ class TestTypeChecker(CheckerTestCase): self.checker.visit_attribute(node) @set_config(ignored_modules=("xml",)) - def test_ignored_modules_root_one_applies_as_well(self): + def test_ignored_modules_root_one_applies_as_well(self) -> None: # Check that when a root module is completely ignored, submodules are skipped. node = astroid.extract_node( """ @@ -108,7 +108,7 @@ class TestTypeChecker(CheckerTestCase): self.checker.visit_attribute(node) @set_config(ignored_modules=("xml.etree*",)) - def test_ignored_modules_patterns(self): + def test_ignored_modules_patterns(self) -> None: node = astroid.extract_node( """ import xml @@ -119,7 +119,7 @@ class TestTypeChecker(CheckerTestCase): self.checker.visit_attribute(node) @set_config(ignored_classes=("xml.*",)) - def test_ignored_classes_no_recursive_pattern(self): + def test_ignored_classes_no_recursive_pattern(self) -> None: node = astroid.extract_node( """ import xml @@ -133,7 +133,7 @@ class TestTypeChecker(CheckerTestCase): self.checker.visit_attribute(node) @set_config(ignored_classes=("optparse.Values",)) - def test_ignored_classes_qualified_name(self): + def test_ignored_classes_qualified_name(self) -> None: """Test that ignored-classes supports qualified name for ignoring.""" node = astroid.extract_node( """ @@ -145,7 +145,7 @@ class TestTypeChecker(CheckerTestCase): self.checker.visit_attribute(node) @set_config(ignored_classes=("Values",)) - def test_ignored_classes_only_name(self): + def test_ignored_classes_only_name(self) -> None: """Test that ignored_classes works with the name only.""" node = astroid.extract_node( """ @@ -158,7 +158,7 @@ class TestTypeChecker(CheckerTestCase): @set_config(suggestion_mode=False) @needs_c_extension - def test_nomember_on_c_extension_error_msg(self): + def test_nomember_on_c_extension_error_msg(self) -> None: node = astroid.extract_node( """ from coverage import tracer @@ -173,7 +173,7 @@ class TestTypeChecker(CheckerTestCase): @set_config(suggestion_mode=True) @needs_c_extension - def test_nomember_on_c_extension_info_msg(self): + def test_nomember_on_c_extension_info_msg(self) -> None: node = astroid.extract_node( """ from coverage import tracer @@ -211,7 +211,7 @@ class TestTypeChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_with(node) - def test_invalid_metaclass(self): + def test_invalid_metaclass(self) -> None: module = astroid.parse( """ class InvalidAsMetaclass(object): @@ -243,7 +243,7 @@ class TestTypeChecker(CheckerTestCase): with self.assertAddsMessages(message): self.checker.visit_classdef(classdef) - def test_invalid_metaclass_function_metaclasses(self): + def test_invalid_metaclass_function_metaclasses(self) -> None: module = astroid.parse( """ def invalid_metaclass_1(name, bases, attrs): @@ -264,7 +264,7 @@ class TestTypeChecker(CheckerTestCase): with self.assertAddsMessages(message): self.checker.visit_classdef(classdef) - def test_typing_namedtuple_not_callable_issue1295(self): + def test_typing_namedtuple_not_callable_issue1295(self) -> None: module = astroid.parse( """ import typing @@ -279,7 +279,7 @@ class TestTypeChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_call(call) - def test_typing_namedtuple_unsubscriptable_object_issue1295(self): + def test_typing_namedtuple_unsubscriptable_object_issue1295(self) -> None: module = astroid.parse( """ import typing @@ -290,7 +290,7 @@ class TestTypeChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_subscript(subscript) - def test_staticmethod_multiprocessing_call(self): + def test_staticmethod_multiprocessing_call(self) -> None: """Make sure not-callable isn't raised for descriptors astroid can't process descriptors correctly so @@ -308,7 +308,7 @@ class TestTypeChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_call(call) - def test_not_callable_uninferable_property(self): + def test_not_callable_uninferable_property(self) -> None: """Make sure not-callable isn't raised for uninferable properties """ @@ -326,7 +326,7 @@ class TestTypeChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_call(call) - def test_descriptor_call(self): + def test_descriptor_call(self) -> None: call = astroid.extract_node( """ def func(): @@ -345,7 +345,7 @@ class TestTypeChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_call(call) - def test_unknown_parent(self): + def test_unknown_parent(self) -> None: """Make sure the callable check does not crash when a node's parent cannot be determined. """ @@ -366,7 +366,7 @@ class TestTypeCheckerOnDecorators(CheckerTestCase): "Tests for pylint.checkers.typecheck on decorated functions." CHECKER_CLASS = typecheck.TypeChecker - def test_issue3882_class_decorators(self): + def test_issue3882_class_decorators(self) -> None: decorators = """ class Unsubscriptable: def __init__(self, f): @@ -389,7 +389,7 @@ class TestTypeCheckerOnDecorators(CheckerTestCase): self.decorated_by_subscriptable_then_unsubscriptable_class(decorators) self.decorated_by_unsubscriptable_then_subscriptable_class(decorators) - def getitem_on_modules(self): + def getitem_on_modules(self) -> None: """Mainly validate the code won't crash if we're not having a function.""" module = astroid.parse( """ @@ -408,7 +408,7 @@ class TestTypeCheckerOnDecorators(CheckerTestCase): ): self.checker.visit_subscript(subscript) - def typing_objects_are_subscriptable(self, generic): + def typing_objects_are_subscriptable(self, generic: str) -> None: module = astroid.parse( f""" import typing @@ -419,7 +419,7 @@ class TestTypeCheckerOnDecorators(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_subscript(subscript) - def decorated_by_a_subscriptable_class(self, decorators): + def decorated_by_a_subscriptable_class(self, decorators: str) -> None: module = astroid.parse( decorators + """ @@ -434,7 +434,9 @@ class TestTypeCheckerOnDecorators(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_subscript(subscript) - def decorated_by_subscriptable_then_unsubscriptable_class(self, decorators): + def decorated_by_subscriptable_then_unsubscriptable_class( + self, decorators: str + ) -> None: module = astroid.parse( decorators + """ @@ -457,7 +459,9 @@ class TestTypeCheckerOnDecorators(CheckerTestCase): ): self.checker.visit_subscript(subscript) - def decorated_by_unsubscriptable_then_subscriptable_class(self, decorators): + def decorated_by_unsubscriptable_then_subscriptable_class( + self, decorators: str + ) -> None: module = astroid.parse( decorators + """ @@ -473,7 +477,7 @@ class TestTypeCheckerOnDecorators(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_subscript(subscript) - def decorated_by_an_unsubscriptable_class(self, decorators): + def decorated_by_an_unsubscriptable_class(self, decorators: str) -> None: module = astroid.parse( decorators + """ diff --git a/tests/checkers/unittest_utils.py b/tests/checkers/unittest_utils.py index 5703d4e29..b94807a17 100644 --- a/tests/checkers/unittest_utils.py +++ b/tests/checkers/unittest_utils.py @@ -18,6 +18,8 @@ """Tests for the pylint.checkers.utils module.""" +from typing import Dict, Union + import astroid import pytest @@ -43,7 +45,9 @@ def testIsBuiltin(name, expected): "fn,kw", [("foo(3)", {"keyword": "bar"}), ("foo(one=a, two=b, three=c)", {"position": 1})], ) -def testGetArgumentFromCallError(fn, kw): +def testGetArgumentFromCallError( + fn: str, kw: Union[Dict[str, int], Dict[str, str]] +) -> None: with pytest.raises(utils.NoSuchArgumentError): node = astroid.extract_node(fn) utils.get_argument_from_call(node, **kw) @@ -52,12 +56,14 @@ def testGetArgumentFromCallError(fn, kw): @pytest.mark.parametrize( "fn,kw", [("foo(bar=3)", {"keyword": "bar"}), ("foo(a, b, c)", {"position": 1})] ) -def testGetArgumentFromCallExists(fn, kw): +def testGetArgumentFromCallExists( + fn: str, kw: Union[Dict[str, int], Dict[str, str]] +) -> None: node = astroid.extract_node(fn) assert utils.get_argument_from_call(node, **kw) is not None -def testGetArgumentFromCall(): +def testGetArgumentFromCall() -> None: node = astroid.extract_node("foo(a, not_this_one=1, this_one=2)") arg = utils.get_argument_from_call(node, position=2, keyword="this_one") assert arg.value == 2 @@ -71,7 +77,7 @@ def testGetArgumentFromCall(): assert name.name == "a" -def test_error_of_type(): +def test_error_of_type() -> None: nodes = astroid.extract_node( """ try: pass @@ -90,7 +96,7 @@ def test_error_of_type(): assert utils.error_of_type(nodes[1], Exception) -def test_node_ignores_exception(): +def test_node_ignores_exception() -> None: nodes = astroid.extract_node( """ try: @@ -117,7 +123,7 @@ def test_node_ignores_exception(): assert not utils.node_ignores_exception(nodes[3], ZeroDivisionError) -def test_is_subclass_of_node_b_derived_from_node_a(): +def test_is_subclass_of_node_b_derived_from_node_a() -> None: nodes = astroid.extract_node( """ class Superclass: #@ @@ -130,7 +136,7 @@ def test_is_subclass_of_node_b_derived_from_node_a(): assert utils.is_subclass_of(nodes[1], nodes[0]) -def test_is_subclass_of_node_b_not_derived_from_node_a(): +def test_is_subclass_of_node_b_not_derived_from_node_a() -> None: nodes = astroid.extract_node( """ class OneClass: #@ @@ -143,7 +149,7 @@ def test_is_subclass_of_node_b_not_derived_from_node_a(): assert not utils.is_subclass_of(nodes[1], nodes[0]) -def test_is_subclass_of_not_classdefs(): +def test_is_subclass_of_not_classdefs() -> None: node = astroid.extract_node( """ class OneClass: #@ @@ -155,7 +161,7 @@ def test_is_subclass_of_not_classdefs(): assert not utils.is_subclass_of(None, None) -def test_parse_format_method_string(): +def test_parse_format_method_string() -> None: samples = [ ("{}", 1), ("{}:{}", 2), @@ -178,7 +184,7 @@ def test_parse_format_method_string(): assert keyword_args + num_args + pos_args == count -def test_inherit_from_std_ex_recursive_definition(): +def test_inherit_from_std_ex_recursive_definition() -> None: node = astroid.extract_node( """ import datetime @@ -193,7 +199,7 @@ def test_inherit_from_std_ex_recursive_definition(): assert not utils.inherit_from_std_ex(node) -def test_get_node_last_lineno_simple(): +def test_get_node_last_lineno_simple() -> None: node = astroid.extract_node( """ pass @@ -202,7 +208,7 @@ def test_get_node_last_lineno_simple(): assert utils.get_node_last_lineno(node) == 2 -def test_get_node_last_lineno_if_simple(): +def test_get_node_last_lineno_if_simple() -> None: node = astroid.extract_node( """ if True: @@ -213,7 +219,7 @@ def test_get_node_last_lineno_if_simple(): assert utils.get_node_last_lineno(node) == 4 -def test_get_node_last_lineno_if_elseif_else(): +def test_get_node_last_lineno_if_elseif_else() -> None: node = astroid.extract_node( """ if True: @@ -227,7 +233,7 @@ def test_get_node_last_lineno_if_elseif_else(): assert utils.get_node_last_lineno(node) == 7 -def test_get_node_last_lineno_while(): +def test_get_node_last_lineno_while() -> None: node = astroid.extract_node( """ while True: @@ -237,7 +243,7 @@ def test_get_node_last_lineno_while(): assert utils.get_node_last_lineno(node) == 3 -def test_get_node_last_lineno_while_else(): +def test_get_node_last_lineno_while_else() -> None: node = astroid.extract_node( """ while True: @@ -249,7 +255,7 @@ def test_get_node_last_lineno_while_else(): assert utils.get_node_last_lineno(node) == 5 -def test_get_node_last_lineno_for(): +def test_get_node_last_lineno_for() -> None: node = astroid.extract_node( """ for x in range(0, 5): @@ -259,7 +265,7 @@ def test_get_node_last_lineno_for(): assert utils.get_node_last_lineno(node) == 3 -def test_get_node_last_lineno_for_else(): +def test_get_node_last_lineno_for_else() -> None: node = astroid.extract_node( """ for x in range(0, 5): @@ -271,7 +277,7 @@ def test_get_node_last_lineno_for_else(): assert utils.get_node_last_lineno(node) == 5 -def test_get_node_last_lineno_try(): +def test_get_node_last_lineno_try() -> None: node = astroid.extract_node( """ try: @@ -285,7 +291,7 @@ def test_get_node_last_lineno_try(): assert utils.get_node_last_lineno(node) == 7 -def test_get_node_last_lineno_try_except_else(): +def test_get_node_last_lineno_try_except_else() -> None: node = astroid.extract_node( """ try: @@ -300,7 +306,7 @@ def test_get_node_last_lineno_try_except_else(): assert utils.get_node_last_lineno(node) == 8 -def test_get_node_last_lineno_try_except_finally(): +def test_get_node_last_lineno_try_except_finally() -> None: node = astroid.extract_node( """ try: @@ -314,7 +320,7 @@ def test_get_node_last_lineno_try_except_finally(): assert utils.get_node_last_lineno(node) == 7 -def test_get_node_last_lineno_try_except_else_finally(): +def test_get_node_last_lineno_try_except_else_finally() -> None: node = astroid.extract_node( """ try: @@ -330,7 +336,7 @@ def test_get_node_last_lineno_try_except_else_finally(): assert utils.get_node_last_lineno(node) == 9 -def test_get_node_last_lineno_with(): +def test_get_node_last_lineno_with() -> None: node = astroid.extract_node( """ with x as y: @@ -341,7 +347,7 @@ def test_get_node_last_lineno_with(): assert utils.get_node_last_lineno(node) == 4 -def test_get_node_last_lineno_method(): +def test_get_node_last_lineno_method() -> None: node = astroid.extract_node( """ def x(a, b): @@ -352,7 +358,7 @@ def test_get_node_last_lineno_method(): assert utils.get_node_last_lineno(node) == 4 -def test_get_node_last_lineno_decorator(): +def test_get_node_last_lineno_decorator() -> None: node = astroid.extract_node( """ @decor() @@ -364,7 +370,7 @@ def test_get_node_last_lineno_decorator(): assert utils.get_node_last_lineno(node) == 5 -def test_get_node_last_lineno_class(): +def test_get_node_last_lineno_class() -> None: node = astroid.extract_node( """ class C(object): @@ -381,7 +387,7 @@ def test_get_node_last_lineno_class(): assert utils.get_node_last_lineno(node) == 10 -def test_get_node_last_lineno_combined(): +def test_get_node_last_lineno_combined() -> None: node = astroid.extract_node( """ class C(object): diff --git a/tests/checkers/unittest_variables.py b/tests/checkers/unittest_variables.py index 32e4eca49..7ab79bf6f 100644 --- a/tests/checkers/unittest_variables.py +++ b/tests/checkers/unittest_variables.py @@ -39,7 +39,7 @@ class TestVariablesChecker(CheckerTestCase): CHECKER_CLASS = variables.VariablesChecker - def test_bitbucket_issue_78(self): + def test_bitbucket_issue_78(self) -> None: """Issue 78 report a false positive for unused-module""" module = astroid.parse( """ @@ -54,7 +54,7 @@ class TestVariablesChecker(CheckerTestCase): self.walk(module) @set_config(ignored_modules=("argparse",)) - def test_no_name_in_module_skipped(self): + def test_no_name_in_module_skipped(self) -> None: """Make sure that 'from ... import ...' does not emit a 'no-name-in-module' with a module that is configured to be ignored. @@ -68,7 +68,7 @@ class TestVariablesChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_importfrom(node) - def test_all_elements_without_parent(self): + def test_all_elements_without_parent(self) -> None: node = astroid.extract_node("__all__ = []") node.value.elts.append(astroid.Const("test")) root = node.root() @@ -76,7 +76,7 @@ class TestVariablesChecker(CheckerTestCase): self.checker.visit_module(root) self.checker.leave_module(root) - def test_redefined_builtin_ignored(self): + def test_redefined_builtin_ignored(self) -> None: node = astroid.parse( """ from future.builtins import open @@ -86,7 +86,7 @@ class TestVariablesChecker(CheckerTestCase): self.checker.visit_module(node) @set_config(redefining_builtins_modules=("os",)) - def test_redefined_builtin_custom_modules(self): + def test_redefined_builtin_custom_modules(self) -> None: node = astroid.parse( """ from os import open @@ -96,7 +96,7 @@ class TestVariablesChecker(CheckerTestCase): self.checker.visit_module(node) @set_config(redefining_builtins_modules=("os",)) - def test_redefined_builtin_modname_not_ignored(self): + def test_redefined_builtin_modname_not_ignored(self) -> None: node = astroid.parse( """ from future.builtins import open @@ -108,7 +108,7 @@ class TestVariablesChecker(CheckerTestCase): self.checker.visit_module(node) @set_config(redefining_builtins_modules=("os",)) - def test_redefined_builtin_in_function(self): + def test_redefined_builtin_in_function(self) -> None: node = astroid.extract_node( """ def test(): @@ -119,7 +119,7 @@ class TestVariablesChecker(CheckerTestCase): self.checker.visit_module(node.root()) self.checker.visit_functiondef(node) - def test_unassigned_global(self): + def test_unassigned_global(self) -> None: node = astroid.extract_node( """ def func(): @@ -131,7 +131,7 @@ class TestVariablesChecker(CheckerTestCase): with self.assertAddsMessages(msg): self.checker.visit_global(node) - def test_listcomp_in_decorator(self): + def test_listcomp_in_decorator(self) -> None: """Make sure class attributes in scope for listcomp in decorator. https://github.com/PyCQA/pylint/issues/511 @@ -157,7 +157,7 @@ class TestVariablesChecker(CheckerTestCase): with self.assertNoMessages(): self.walk(module) - def test_listcomp_in_ancestors(self): + def test_listcomp_in_ancestors(self) -> None: """Ensure list comprehensions in base classes are scoped correctly https://github.com/PyCQA/pylint/issues/3434 @@ -177,7 +177,7 @@ class TestVariablesChecker(CheckerTestCase): with self.assertNoMessages(): self.walk(module) - def test_return_type_annotation(self): + def test_return_type_annotation(self) -> None: """Make sure class attributes in scope for return type annotations. https://github.com/PyCQA/pylint/issues/1976 @@ -217,16 +217,16 @@ class TestVariablesCheckerWithTearDown(CheckerTestCase): CHECKER_CLASS = variables.VariablesChecker - def setup_method(self): + def setup_method(self) -> None: super().setup_method() self._to_consume_backup = self.checker._to_consume self.checker._to_consume = [] - def teardown_method(self): + def teardown_method(self) -> None: self.checker._to_consume = self._to_consume_backup @set_config(callbacks=("callback_", "_callback")) - def test_custom_callback_string(self): + def test_custom_callback_string(self) -> None: """Test the --calbacks option works.""" node = astroid.extract_node( """ @@ -273,7 +273,7 @@ class TestVariablesCheckerWithTearDown(CheckerTestCase): self.checker.leave_functiondef(node) @set_config(redefining_builtins_modules=("os",)) - def test_redefined_builtin_modname_not_ignored(self): + def test_redefined_builtin_modname_not_ignored(self) -> None: node = astroid.parse( """ from future.builtins import open @@ -285,7 +285,7 @@ class TestVariablesCheckerWithTearDown(CheckerTestCase): self.checker.visit_module(node) @set_config(redefining_builtins_modules=("os",)) - def test_redefined_builtin_in_function(self): + def test_redefined_builtin_in_function(self) -> None: node = astroid.extract_node( """ def test(): @@ -296,7 +296,7 @@ class TestVariablesCheckerWithTearDown(CheckerTestCase): self.checker.visit_module(node.root()) self.checker.visit_functiondef(node) - def test_import_as_underscore(self): + def test_import_as_underscore(self) -> None: node = astroid.parse( """ import math as _ @@ -305,7 +305,7 @@ class TestVariablesCheckerWithTearDown(CheckerTestCase): with self.assertNoMessages(): self.walk(node) - def test_lambda_in_classdef(self): + def test_lambda_in_classdef(self) -> None: # Make sure lambda doesn't raises # Undefined-method in class def @@ -321,7 +321,7 @@ class TestVariablesCheckerWithTearDown(CheckerTestCase): with self.assertNoMessages(): self.walk(node) - def test_nested_lambda(self): + def test_nested_lambda(self) -> None: """Make sure variables from parent lambdas aren't noted as undefined @@ -336,7 +336,7 @@ class TestVariablesCheckerWithTearDown(CheckerTestCase): self.walk(node) @set_config(ignored_argument_names=re.compile("arg")) - def test_ignored_argument_names_no_message(self): + def test_ignored_argument_names_no_message(self) -> None: """Make sure is_ignored_argument_names properly ignores function arguments""" node = astroid.parse( @@ -349,7 +349,7 @@ class TestVariablesCheckerWithTearDown(CheckerTestCase): self.walk(node) @set_config(ignored_argument_names=re.compile("args|kwargs")) - def test_ignored_argument_names_starred_args(self): + def test_ignored_argument_names_starred_args(self) -> None: node = astroid.parse( """ def fooby(*args, **kwargs): @@ -364,7 +364,7 @@ class TestMissingSubmodule(CheckerTestCase): CHECKER_CLASS = variables.VariablesChecker @staticmethod - def test_package_all(): + def test_package_all() -> None: sys.path.insert(0, REGR_DATA_DIR) try: diff --git a/tests/extensions/test_bad_builtin.py b/tests/extensions/test_bad_builtin.py index 71c4df011..549c3deb1 100644 --- a/tests/extensions/test_bad_builtin.py +++ b/tests/extensions/test_bad_builtin.py @@ -17,6 +17,7 @@ import pytest from pylint.extensions.bad_builtin import BadBuiltinChecker from pylint.lint import fix_import_path +from pylint.lint.pylinter import PyLinter EXPECTED = [ "Used builtin function 'map'. Using a list comprehension can be clearer.", @@ -34,7 +35,7 @@ def disable(): return ["I"] -def test_types_redefined(linter): +def test_types_redefined(linter: PyLinter) -> None: elif_test = osp.join(osp.dirname(osp.abspath(__file__)), "data", "bad_builtin.py") with fix_import_path([elif_test]): linter.check([elif_test]) diff --git a/tests/extensions/test_broad_try_clause.py b/tests/extensions/test_broad_try_clause.py index 9ec3f0f50..21c79fed0 100644 --- a/tests/extensions/test_broad_try_clause.py +++ b/tests/extensions/test_broad_try_clause.py @@ -21,7 +21,7 @@ from pylint.reporters import BaseReporter class BroadTryClauseTestReporter(BaseReporter): - def on_set_current_module(self, module, filepath): + def on_set_current_module(self, module: str, filepath: str) -> None: self.messages = [] def _display(self, layout): @@ -29,15 +29,16 @@ class BroadTryClauseTestReporter(BaseReporter): class BroadTryClauseTC(unittest.TestCase): + _linter = PyLinter() + @classmethod def setUpClass(cls): - cls._linter = PyLinter() cls._linter.set_reporter(BroadTryClauseTestReporter()) checkers.initialize(cls._linter) cls._linter.register_checker(BroadTryClauseChecker(cls._linter)) cls._linter.disable("I") - def test_broad_try_clause_message(self): + def test_broad_try_clause_message(self) -> None: broad_try_clause_test = osp.join( osp.dirname(osp.abspath(__file__)), "data", "broad_try_clause.py" ) diff --git a/tests/extensions/test_check_docs.py b/tests/extensions/test_check_docs.py index f462ea3d1..2e7004622 100644 --- a/tests/extensions/test_check_docs.py +++ b/tests/extensions/test_check_docs.py @@ -42,7 +42,7 @@ class TestParamDocChecker(CheckerTestCase): "docstring_min_length": -1, } - def test_missing_func_params_in_sphinx_docstring(self): + def test_missing_func_params_in_sphinx_docstring(self) -> None: """Example of a function with missing Sphinx parameter documentation in the docstring """ @@ -64,7 +64,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_missing_func_params_in_google_docstring(self): + def test_missing_func_params_in_google_docstring(self) -> None: """Example of a function with missing Google style parameter documentation in the docstring """ @@ -88,7 +88,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_missing_type_doc_google_docstring_exempt_kwonly_args(self): + def test_missing_type_doc_google_docstring_exempt_kwonly_args(self) -> None: node = astroid.extract_node( """ def identifier_kwarg_method(arg1: int, arg2: int, *, value1: str, value2: str): @@ -106,7 +106,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_missing_func_params_with_annotations_in_google_docstring(self): + def test_missing_func_params_with_annotations_in_google_docstring(self) -> None: """Example of a function with missing Google style parameter documentation in the docstring. """ @@ -128,7 +128,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_default_arg_with_annotations_in_google_docstring(self): + def test_default_arg_with_annotations_in_google_docstring(self) -> None: """Example of a function with missing Google style parameter documentation in the docstring. """ @@ -150,7 +150,9 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_missing_func_params_with_partial_annotations_in_google_docstring(self): + def test_missing_func_params_with_partial_annotations_in_google_docstring( + self, + ) -> None: """Example of a function with missing Google style parameter documentation in the docstring. """ @@ -174,7 +176,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_non_builtin_annotations_in_google_docstring(self): + def test_non_builtin_annotations_in_google_docstring(self) -> None: """Example of a function with missing Google style parameter documentation in the docstring. """ @@ -192,7 +194,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_non_builtin_annotations_for_returntype_in_google_docstring(self): + def test_non_builtin_annotations_for_returntype_in_google_docstring(self) -> None: """Example of a function with missing Google style parameter documentation in the docstring. """ @@ -210,7 +212,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_func_params_and_keyword_params_in_google_docstring(self): + def test_func_params_and_keyword_params_in_google_docstring(self) -> None: """Example of a function with Google style parameter splitted in Args and Keyword Args in the docstring """ @@ -232,7 +234,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_func_params_and_wrong_keyword_params_in_google_docstring(self): + def test_func_params_and_wrong_keyword_params_in_google_docstring(self) -> None: """Example of a function with Google style parameter splitted in Args and Keyword Args in the docstring but with wrong keyword args """ @@ -259,7 +261,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_missing_func_params_in_numpy_docstring(self): + def test_missing_func_params_in_numpy_docstring(self) -> None: """Example of a function with missing NumPy style parameter documentation in the docstring """ @@ -287,7 +289,7 @@ class TestParamDocChecker(CheckerTestCase): self.checker.visit_functiondef(node) @set_config(accept_no_param_doc=True) - def test_tolerate_no_param_documentation_at_all(self): + def test_tolerate_no_param_documentation_at_all(self) -> None: """Example of a function with no parameter documentation at all No error message is emitted. @@ -304,7 +306,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_don_t_tolerate_no_param_documentation_at_all(self): + def test_don_t_tolerate_no_param_documentation_at_all(self) -> None: """Example of a function with no parameter documentation at all Missing documentation error message is emitted. @@ -324,7 +326,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_see_tolerate_no_param_documentation_at_all(self): + def test_see_tolerate_no_param_documentation_at_all(self) -> None: """Example for the usage of "For the parameters, see" to suppress missing-param warnings. """ @@ -351,7 +353,7 @@ class TestParamDocChecker(CheckerTestCase): if isinstance(body_item, nodes.FunctionDef) and hasattr(body_item, "name"): self.checker.visit_functiondef(body_item) - def test_missing_method_params_in_sphinx_docstring(self): + def test_missing_method_params_in_sphinx_docstring(self) -> None: """Example of a class method with missing parameter documentation in the Sphinx style docstring """ @@ -375,7 +377,7 @@ class TestParamDocChecker(CheckerTestCase): ): self._visit_methods_of_class(node) - def test_missing_method_params_in_google_docstring(self): + def test_missing_method_params_in_google_docstring(self) -> None: """Example of a class method with missing parameter documentation in the Google style docstring """ @@ -400,7 +402,7 @@ class TestParamDocChecker(CheckerTestCase): ): self._visit_methods_of_class(node) - def test_missing_method_params_in_numpy_docstring(self): + def test_missing_method_params_in_numpy_docstring(self) -> None: """Example of a class method with missing parameter documentation in the Numpy style docstring """ @@ -427,7 +429,7 @@ class TestParamDocChecker(CheckerTestCase): ): self._visit_methods_of_class(node) - def test_existing_func_params_in_sphinx_docstring(self): + def test_existing_func_params_in_sphinx_docstring(self) -> None: """Example of a function with correctly documented parameters and return values (Sphinx style) """ @@ -455,7 +457,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_existing_func_params_in_google_docstring(self): + def test_existing_func_params_in_google_docstring(self) -> None: """Example of a function with correctly documented parameters and return values (Google style) """ @@ -481,7 +483,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_existing_func_params_in_numpy_docstring(self): + def test_existing_func_params_in_numpy_docstring(self) -> None: """Example of a function with correctly documented parameters and return values (Numpy style) """ @@ -513,7 +515,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_wrong_name_of_func_params_in_sphinx_docstring(self): + def test_wrong_name_of_func_params_in_sphinx_docstring(self) -> None: """Example of functions with inconsistent parameter names in the signature and in the Sphinx style documentation """ @@ -560,7 +562,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_wrong_name_of_func_params_in_google_docstring(self): + def test_wrong_name_of_func_params_in_google_docstring(self) -> None: """Example of functions with inconsistent parameter names in the signature and in the Google style documentation """ @@ -605,7 +607,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_wrong_name_of_func_params_in_numpy_docstring(self): + def test_wrong_name_of_func_params_in_numpy_docstring(self) -> None: """Example of functions with inconsistent parameter names in the signature and in the Numpy style documentation """ @@ -656,7 +658,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_see_sentence_for_func_params_in_sphinx_docstring(self): + def test_see_sentence_for_func_params_in_sphinx_docstring(self) -> None: """Example for the usage of "For the other parameters, see" to avoid too many repetitions, e.g. in functions or methods adhering to a given interface (Sphinx style) @@ -677,7 +679,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_see_sentence_for_func_params_in_google_docstring(self): + def test_see_sentence_for_func_params_in_google_docstring(self) -> None: """Example for the usage of "For the other parameters, see" to avoid too many repetitions, e.g. in functions or methods adhering to a given interface (Google style) @@ -698,7 +700,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_see_sentence_for_func_params_in_numpy_docstring(self): + def test_see_sentence_for_func_params_in_numpy_docstring(self) -> None: """Example for the usage of "For the other parameters, see" to avoid too many repetitions, e.g. in functions or methods adhering to a given interface (Numpy style) @@ -721,7 +723,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_constr_params_in_class_sphinx(self): + def test_constr_params_in_class_sphinx(self) -> None: """Example of a class with missing constructor parameter documentation (Sphinx style) @@ -748,7 +750,7 @@ class TestParamDocChecker(CheckerTestCase): ): self._visit_methods_of_class(node) - def test_constr_params_in_class_google(self): + def test_constr_params_in_class_google(self) -> None: """Example of a class with missing constructor parameter documentation (Google style) @@ -776,7 +778,7 @@ class TestParamDocChecker(CheckerTestCase): ): self._visit_methods_of_class(node) - def test_constr_params_in_class_numpy(self): + def test_constr_params_in_class_numpy(self) -> None: """Example of a class with missing constructor parameter documentation (Numpy style) @@ -806,7 +808,7 @@ class TestParamDocChecker(CheckerTestCase): ): self._visit_methods_of_class(node) - def test_constr_params_and_attributes_in_class_numpy(self): + def test_constr_params_and_attributes_in_class_numpy(self) -> None: """Example of a class with correct constructor parameter documentation and an attributes section (Numpy style) """ @@ -831,7 +833,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self._visit_methods_of_class(node) - def test_constr_params_in_init_sphinx(self): + def test_constr_params_in_init_sphinx(self) -> None: """Example of a class with missing constructor parameter documentation (Sphinx style) @@ -859,7 +861,7 @@ class TestParamDocChecker(CheckerTestCase): ): self._visit_methods_of_class(node) - def test_constr_params_in_init_google(self): + def test_constr_params_in_init_google(self) -> None: """Example of a class with missing constructor parameter documentation (Google style) @@ -887,7 +889,7 @@ class TestParamDocChecker(CheckerTestCase): ): self._visit_methods_of_class(node) - def test_constr_params_in_init_numpy(self): + def test_constr_params_in_init_numpy(self) -> None: """Example of a class with missing constructor parameter documentation (Numpy style) @@ -917,7 +919,7 @@ class TestParamDocChecker(CheckerTestCase): ): self._visit_methods_of_class(node) - def test_see_sentence_for_constr_params_in_class(self): + def test_see_sentence_for_constr_params_in_class(self) -> None: """Example usage of "For the parameters, see" in class docstring""" node = astroid.extract_node( """ @@ -936,7 +938,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self._visit_methods_of_class(node) - def test_see_sentence_for_constr_params_in_init(self): + def test_see_sentence_for_constr_params_in_init(self) -> None: """Example usage of "For the parameters, see" in init docstring""" node = astroid.extract_node( """ @@ -955,7 +957,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self._visit_methods_of_class(node) - def test_constr_params_in_class_and_init_sphinx(self): + def test_constr_params_in_class_and_init_sphinx(self) -> None: """Example of a class with missing constructor parameter documentation in both the init docstring and the class docstring (Sphinx style) @@ -993,7 +995,7 @@ class TestParamDocChecker(CheckerTestCase): ): self._visit_methods_of_class(node) - def test_constr_params_in_class_and_init_google(self): + def test_constr_params_in_class_and_init_google(self) -> None: """Example of a class with missing constructor parameter documentation in both the init docstring and the class docstring (Google style) @@ -1033,7 +1035,7 @@ class TestParamDocChecker(CheckerTestCase): ): self._visit_methods_of_class(node) - def test_constr_params_in_class_and_init_numpy(self): + def test_constr_params_in_class_and_init_numpy(self) -> None: """Example of a class with missing constructor parameter documentation in both the init docstring and the class docstring (Numpy style) @@ -1077,7 +1079,7 @@ class TestParamDocChecker(CheckerTestCase): ): self._visit_methods_of_class(node) - def test_kwonlyargs_are_taken_in_account(self): + def test_kwonlyargs_are_taken_in_account(self) -> None: node = astroid.extract_node( ''' def my_func(arg, *, kwonly, missing_kwonly): @@ -1094,7 +1096,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_warns_missing_args_sphinx(self): + def test_warns_missing_args_sphinx(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, *args): @@ -1114,7 +1116,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_warns_missing_kwargs_sphinx(self): + def test_warns_missing_kwargs_sphinx(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, **kwargs): @@ -1134,7 +1136,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_warns_missing_args_google(self): + def test_warns_missing_args_google(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, *args): @@ -1155,7 +1157,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_warns_missing_kwargs_google(self): + def test_warns_missing_kwargs_google(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, **kwargs): @@ -1176,7 +1178,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_warns_missing_args_numpy(self): + def test_warns_missing_args_numpy(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, *args): @@ -1201,7 +1203,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_warns_missing_kwargs_numpy(self): + def test_warns_missing_kwargs_numpy(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, **kwargs): @@ -1226,7 +1228,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_finds_args_without_type_sphinx(self): + def test_finds_args_without_type_sphinx(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, *args): @@ -1245,7 +1247,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_finds_kwargs_without_type_sphinx(self): + def test_finds_kwargs_without_type_sphinx(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, **kwargs): @@ -1264,7 +1266,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_finds_args_without_type_google(self): + def test_finds_args_without_type_google(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, *args): @@ -1284,7 +1286,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_finds_kwargs_without_type_google(self): + def test_finds_kwargs_without_type_google(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, **kwargs): @@ -1304,7 +1306,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_finds_args_without_type_numpy(self): + def test_finds_args_without_type_numpy(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, *args): @@ -1329,7 +1331,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_finds_args_with_xref_type_google(self): + def test_finds_args_with_xref_type_google(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, **kwargs): @@ -1349,7 +1351,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_finds_args_with_xref_type_numpy(self): + def test_finds_args_with_xref_type_numpy(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, *args): @@ -1374,7 +1376,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_finds_kwargs_without_type_numpy(self): + def test_finds_kwargs_without_type_numpy(self) -> None: node = astroid.extract_node( ''' def my_func(named_arg, **kwargs): @@ -1494,7 +1496,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignores_optional_specifier_google(self): + def test_ignores_optional_specifier_google(self) -> None: node = astroid.extract_node( ''' def do_something(param1, param2, param3=(), param4=[], param5=[], param6=True): @@ -1517,7 +1519,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignores_optional_specifier_numpy(self): + def test_ignores_optional_specifier_numpy(self) -> None: node = astroid.extract_node( ''' def do_something(param, param2='all'): @@ -1541,7 +1543,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_finds_short_name_exception(self): + def test_finds_short_name_exception(self) -> None: node = astroid.extract_node( ''' from fake_package import BadError @@ -1558,7 +1560,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_finds_missing_raises_from_setter_sphinx(self): + def test_finds_missing_raises_from_setter_sphinx(self) -> None: """Example of a setter having missing raises documentation in the Sphinx style docstring of the property """ @@ -1587,7 +1589,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_raise(node) - def test_finds_missing_raises_from_setter_google(self): + def test_finds_missing_raises_from_setter_google(self) -> None: """Example of a setter having missing raises documentation in the Google style docstring of the property """ @@ -1621,7 +1623,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_raise(node) - def test_finds_missing_raises_from_setter_numpy(self): + def test_finds_missing_raises_from_setter_numpy(self) -> None: """Example of a setter having missing raises documentation in the Numpy style docstring of the property """ @@ -1657,7 +1659,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_raise(node) - def test_finds_missing_raises_in_setter_sphinx(self): + def test_finds_missing_raises_in_setter_sphinx(self) -> None: """Example of a setter having missing raises documentation in its own Sphinx style docstring """ @@ -1690,7 +1692,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_raise(node) - def test_finds_missing_raises_from_setter_google_2(self): + def test_finds_missing_raises_from_setter_google_2(self) -> None: """Example of a setter having missing raises documentation in its own Google style docstring of the property """ @@ -1726,7 +1728,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_raise(node) - def test_finds_missing_raises_from_setter_numpy_2(self): + def test_finds_missing_raises_from_setter_numpy_2(self) -> None: """Example of a setter having missing raises documentation in its own Numpy style docstring of the property """ @@ -1766,7 +1768,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_raise(node) - def test_finds_property_return_type_sphinx(self): + def test_finds_property_return_type_sphinx(self) -> None: """Example of a property having return documentation in a Sphinx style docstring """ @@ -1785,7 +1787,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_finds_property_return_type_google(self): + def test_finds_property_return_type_google(self) -> None: """Example of a property having return documentation in a Google style docstring """ @@ -1806,7 +1808,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_finds_property_return_type_numpy(self): + def test_finds_property_return_type_numpy(self) -> None: """Example of a property having return documentation in a numpy style docstring """ @@ -1829,7 +1831,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_finds_annotation_property_return_type_sphinx(self): + def test_finds_annotation_property_return_type_sphinx(self) -> None: """Example of a property having missing return documentation in a Sphinx style docstring """ @@ -1849,7 +1851,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(node) - def test_finds_missing_property_return_type_sphinx(self): + def test_finds_missing_property_return_type_sphinx(self) -> None: """Example of a property having missing return documentation in a Sphinx style docstring """ @@ -1871,7 +1873,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_return(node) - def test_finds_annotation_property_return_type_google(self): + def test_finds_annotation_property_return_type_google(self) -> None: """Example of a property having return documentation in a Google style docstring """ @@ -1892,7 +1894,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(node) - def test_finds_missing_property_return_type_google(self): + def test_finds_missing_property_return_type_google(self) -> None: """Example of a property having return documentation in a Google style docstring """ @@ -1915,7 +1917,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_return(node) - def test_finds_missing_property_return_type_numpy(self): + def test_finds_missing_property_return_type_numpy(self) -> None: """Example of a property having return documentation in a numpy style docstring """ @@ -1940,7 +1942,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_return(node) - def test_ignores_non_property_return_type_sphinx(self): + def test_ignores_non_property_return_type_sphinx(self) -> None: """Example of a class function trying to use `type` as return documentation in a Sphinx style docstring """ @@ -1961,7 +1963,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_return(node) - def test_ignores_non_property_return_type_google(self): + def test_ignores_non_property_return_type_google(self) -> None: """Example of a class function trying to use `type` as return documentation in a Google style docstring """ @@ -1984,7 +1986,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_return(node) - def test_ignores_non_property_return_type_numpy(self): + def test_ignores_non_property_return_type_numpy(self) -> None: """Example of a class function trying to use `type` as return documentation in a numpy style docstring """ @@ -2009,7 +2011,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_return(node) - def test_non_property_annotation_return_type_numpy(self): + def test_non_property_annotation_return_type_numpy(self) -> None: """Example of a class function trying to use `type` as return documentation in a numpy style docstring """ @@ -2033,7 +2035,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_return(node) - def test_ignores_return_in_abstract_method_sphinx(self): + def test_ignores_return_in_abstract_method_sphinx(self) -> None: """Example of an abstract method documenting the return type that an implementation should return. """ @@ -2054,7 +2056,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignores_return_in_abstract_method_google(self): + def test_ignores_return_in_abstract_method_google(self) -> None: """Example of an abstract method documenting the return type that an implementation should return. """ @@ -2075,7 +2077,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignores_return_in_abstract_method_numpy(self): + def test_ignores_return_in_abstract_method_numpy(self) -> None: """Example of an abstract method documenting the return type that an implementation should return. """ @@ -2098,7 +2100,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignores_raise_notimplementederror_sphinx(self): + def test_ignores_raise_notimplementederror_sphinx(self) -> None: """Example of an abstract""" node = astroid.extract_node( """ @@ -2115,7 +2117,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignores_return_in_abstract_method_google_2(self): + def test_ignores_return_in_abstract_method_google_2(self) -> None: """Example of a method documenting the return type that an implementation should return. """ @@ -2134,7 +2136,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignores_return_in_abstract_method_numpy_2(self): + def test_ignores_return_in_abstract_method_numpy_2(self) -> None: """Example of a method documenting the return type that an implementation should return. """ @@ -2155,7 +2157,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignores_ignored_argument_names_sphinx(self): + def test_ignores_ignored_argument_names_sphinx(self) -> None: """Example of a method documenting the return type that an implementation should return. """ @@ -2174,7 +2176,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignores_ignored_argument_names_google(self): + def test_ignores_ignored_argument_names_google(self) -> None: """Example of a method documenting the return type that an implementation should return. """ @@ -2193,7 +2195,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignores_ignored_argument_names_numpy(self): + def test_ignores_ignored_argument_names_numpy(self) -> None: """Example of a method documenting the return type that an implementation should return. """ @@ -2214,7 +2216,7 @@ class TestParamDocChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_useless_docs_ignored_argument_names_sphinx(self): + def test_useless_docs_ignored_argument_names_sphinx(self) -> None: """Example of a method documenting the return type that an implementation should return. """ @@ -2241,7 +2243,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_useless_docs_ignored_argument_names_google(self): + def test_useless_docs_ignored_argument_names_google(self) -> None: """Example of a method documenting the return type that an implementation should return. """ @@ -2265,7 +2267,7 @@ class TestParamDocChecker(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_useless_docs_ignored_argument_names_numpy(self): + def test_useless_docs_ignored_argument_names_numpy(self) -> None: """Example of a method documenting the return type that an implementation should return. """ @@ -2296,7 +2298,7 @@ class TestParamDocChecker(CheckerTestCase): self.checker.visit_functiondef(node) @set_config(no_docstring_rgx=r"^_(?!_).*$") - def test_skip_no_docstring_rgx(self): + def test_skip_no_docstring_rgx(self) -> None: """Example of a function that matches the default 'no-docstring-rgx' config option No error message is emitted. @@ -2314,7 +2316,7 @@ class TestParamDocChecker(CheckerTestCase): self.checker.visit_functiondef(node) @set_config(docstring_min_length=3) - def test_skip_docstring_min_length(self): + def test_skip_docstring_min_length(self) -> None: """Example of a function that is less than 'docstring-min-length' config option No error message is emitted. diff --git a/tests/extensions/test_check_docs_utils.py b/tests/extensions/test_check_docs_utils.py index 11c292cc8..5df613131 100644 --- a/tests/extensions/test_check_docs_utils.py +++ b/tests/extensions/test_check_docs_utils.py @@ -24,7 +24,7 @@ from pylint.extensions import _check_docs_utils as utils "string,count", [("abc", 0), ("", 0), (" abc", 2), ("\n abc", 0), (" \n abc", 3)], ) -def test_space_indentation(string, count): +def test_space_indentation(string: str, count: int) -> None: """Test for pylint_plugin.ParamDocChecker""" assert utils.space_indentation(string) == count diff --git a/tests/extensions/test_check_mccabe.py b/tests/extensions/test_check_mccabe.py index 5cce6bff9..508f62b52 100644 --- a/tests/extensions/test_check_mccabe.py +++ b/tests/extensions/test_check_mccabe.py @@ -14,10 +14,12 @@ # pylint: disable=redefined-outer-name from os import path as osp +from typing import List import pytest from pylint.extensions import mccabe +from pylint.lint.pylinter import PyLinter EXPECTED_MSGS = [ "'f1' is too complex. The McCabe rating is 1", @@ -53,14 +55,16 @@ def register(): @pytest.fixture -def fname_mccabe_example(): +def fname_mccabe_example() -> str: return osp.join(osp.dirname(osp.abspath(__file__)), "data", "mccabe.py") @pytest.mark.parametrize( "complexity, expected", [(0, EXPECTED_MSGS), (9, EXPECTED_MSGS[-2:])] ) -def test_max_mccabe_rate(linter, fname_mccabe_example, complexity, expected): +def test_max_mccabe_rate( + linter: PyLinter, fname_mccabe_example: str, complexity: int, expected: List[str] +) -> None: linter.global_set_option("max-complexity", complexity) linter.check([fname_mccabe_example]) real_msgs = [message.msg for message in linter.reporter.messages] diff --git a/tests/extensions/test_check_raise_docs.py b/tests/extensions/test_check_raise_docs.py index 19fda4bb0..f6103ec0e 100644 --- a/tests/extensions/test_check_raise_docs.py +++ b/tests/extensions/test_check_raise_docs.py @@ -30,7 +30,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): CHECKER_CLASS = DocstringParameterChecker - def test_ignores_no_docstring(self): + def test_ignores_no_docstring(self) -> None: raise_node = astroid.extract_node( """ def my_func(self): @@ -40,7 +40,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_ignores_unknown_style(self): + def test_ignores_unknown_style(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -53,7 +53,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): self.checker.visit_raise(raise_node) @set_config(accept_no_raise_doc=False) - def test_warns_unknown_style(self): + def test_warns_unknown_style(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -67,7 +67,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_find_missing_sphinx_raises(self): + def test_find_missing_sphinx_raises(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -85,7 +85,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_find_missing_google_raises(self): + def test_find_missing_google_raises(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -104,7 +104,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_find_google_attr_raises_exact_exc(self): + def test_find_google_attr_raises_exact_exc(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -120,7 +120,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_google_attr_raises_substr_exc(self): + def test_find_google_attr_raises_substr_exc(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -136,7 +136,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_valid_missing_google_attr_raises(self): + def test_find_valid_missing_google_attr_raises(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -155,7 +155,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_find_invalid_missing_google_attr_raises(self): + def test_find_invalid_missing_google_attr_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -173,7 +173,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_google_raises_local_reference(self): + def test_google_raises_local_reference(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -192,7 +192,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): self.checker.visit_raise(raise_node) @set_config(accept_no_raise_doc=False) - def test_google_raises_with_prefix(self): + def test_google_raises_with_prefix(self) -> None: code_snippet = ''' def my_func(self): """This is a google docstring. @@ -208,7 +208,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_missing_numpy_raises(self): + def test_find_missing_numpy_raises(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -229,7 +229,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_ignore_spurious_sphinx_raises(self): + def test_ignore_spurious_sphinx_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -246,7 +246,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_all_sphinx_raises(self): + def test_find_all_sphinx_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -266,7 +266,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_all_google_raises(self): + def test_find_all_google_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -283,7 +283,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_all_numpy_raises(self): + def test_find_all_numpy_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -303,7 +303,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_multiple_sphinx_raises(self): + def test_find_multiple_sphinx_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -321,7 +321,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_multiple_google_raises(self): + def test_find_multiple_google_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -340,7 +340,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_finds_rethrown_sphinx_raises(self): + def test_finds_rethrown_sphinx_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -362,7 +362,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_find_rethrown_google_raises(self): + def test_find_rethrown_google_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -385,7 +385,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_find_rethrown_numpy_raises(self): + def test_find_rethrown_numpy_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -410,7 +410,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_finds_rethrown_sphinx_multiple_raises(self): + def test_finds_rethrown_sphinx_multiple_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -436,7 +436,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_find_rethrown_google_multiple_raises(self): + def test_find_rethrown_google_multiple_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -463,7 +463,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_find_rethrown_numpy_multiple_raises(self): + def test_find_rethrown_numpy_multiple_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -492,7 +492,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_ignores_caught_sphinx_raises(self): + def test_ignores_caught_sphinx_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -511,7 +511,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_ignores_caught_google_raises(self): + def test_ignores_caught_google_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -531,7 +531,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_ignores_caught_numpy_raises(self): + def test_ignores_caught_numpy_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -553,7 +553,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_numpy_attr_raises_exact_exc(self): + def test_find_numpy_attr_raises_exact_exc(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -571,7 +571,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_numpy_attr_raises_substr_exc(self): + def test_find_numpy_attr_raises_substr_exc(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -589,7 +589,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_valid_missing_numpy_attr_raises(self): + def test_find_valid_missing_numpy_attr_raises(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -610,7 +610,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_find_invalid_missing_numpy_attr_raises(self): + def test_find_invalid_missing_numpy_attr_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -631,7 +631,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): self.checker.visit_raise(raise_node) @set_config(accept_no_raise_doc=False) - def test_numpy_raises_with_prefix(self): + def test_numpy_raises_with_prefix(self) -> None: code_snippet = ''' def my_func(self): """This is a numpy docstring. @@ -649,7 +649,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_missing_sphinx_raises_infer_from_instance(self): + def test_find_missing_sphinx_raises_infer_from_instance(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -668,7 +668,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_find_missing_sphinx_raises_infer_from_function(self): + def test_find_missing_sphinx_raises_infer_from_function(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -688,7 +688,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_find_sphinx_attr_raises_exact_exc(self): + def test_find_sphinx_attr_raises_exact_exc(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -703,7 +703,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_sphinx_attr_raises_substr_exc(self): + def test_find_sphinx_attr_raises_substr_exc(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -718,7 +718,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_find_valid_missing_sphinx_attr_raises(self): + def test_find_valid_missing_sphinx_attr_raises(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -736,7 +736,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): ): self.checker.visit_raise(raise_node) - def test_find_invalid_missing_sphinx_attr_raises(self): + def test_find_invalid_missing_sphinx_attr_raises(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -754,7 +754,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): self.checker.visit_raise(raise_node) @set_config(accept_no_raise_doc=False) - def test_sphinx_raises_with_prefix(self): + def test_sphinx_raises_with_prefix(self) -> None: code_snippet = ''' def my_func(self): """This is a sphinx docstring. @@ -772,7 +772,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_ignores_raise_uninferable(self): + def test_ignores_raise_uninferable(self) -> None: raise_node = astroid.extract_node( ''' from unknown import Unknown @@ -789,7 +789,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_ignores_returns_from_inner_functions(self): + def test_ignores_returns_from_inner_functions(self) -> None: raise_node = astroid.extract_node( ''' def my_func(self): @@ -812,7 +812,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): # we do NOT expect a warning about the OSError in inner_func! self.checker.visit_raise(raise_node) - def test_ignores_returns_use_only_names(self): + def test_ignores_returns_use_only_names(self) -> None: raise_node = astroid.extract_node( ''' def myfunc(): @@ -829,7 +829,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_ignores_returns_use_only_exception_instances(self): + def test_ignores_returns_use_only_exception_instances(self) -> None: raise_node = astroid.extract_node( ''' def myfunc(): @@ -848,7 +848,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_no_crash_when_inferring_handlers(self): + def test_no_crash_when_inferring_handlers(self) -> None: raise_node = astroid.extract_node( ''' import collections @@ -867,7 +867,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_no_crash_when_cant_find_exception(self): + def test_no_crash_when_cant_find_exception(self) -> None: raise_node = astroid.extract_node( ''' import collections @@ -886,7 +886,7 @@ class TestDocstringCheckerRaise(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_raise(raise_node) - def test_no_error_notimplemented_documented(self): + def test_no_error_notimplemented_documented(self) -> None: raise_node = astroid.extract_node( ''' def my_func(): diff --git a/tests/extensions/test_check_return_docs.py b/tests/extensions/test_check_return_docs.py index 6f3baa92a..3e165561e 100644 --- a/tests/extensions/test_check_return_docs.py +++ b/tests/extensions/test_check_return_docs.py @@ -31,7 +31,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): CHECKER_CLASS = DocstringParameterChecker - def test_ignores_no_docstring(self): + def test_ignores_no_docstring(self) -> None: return_node = astroid.extract_node( """ def my_func(self): @@ -42,7 +42,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): self.checker.visit_return(return_node) @set_config(accept_no_return_doc=False) - def test_warns_no_docstring(self): + def test_warns_no_docstring(self) -> None: node = astroid.extract_node( """ def my_func(self): @@ -56,7 +56,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): ): self.checker.visit_return(return_node) - def test_ignores_unknown_style(self): + def test_ignores_unknown_style(self) -> None: return_node = astroid.extract_node( ''' def my_func(self): @@ -67,7 +67,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_warn_partial_sphinx_returns(self): + def test_warn_partial_sphinx_returns(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -84,7 +84,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): ): self.checker.visit_return(return_node) - def test_sphinx_missing_return_type_with_annotations(self): + def test_sphinx_missing_return_type_with_annotations(self) -> None: node = astroid.extract_node( ''' def my_func(self) -> bool: @@ -99,7 +99,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_warn_partial_sphinx_returns_type(self): + def test_warn_partial_sphinx_returns_type(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -114,7 +114,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertAddsMessages(Message(msg_id="missing-return-doc", node=node)): self.checker.visit_return(return_node) - def test_warn_missing_sphinx_returns(self): + def test_warn_missing_sphinx_returns(self) -> None: node = astroid.extract_node( ''' def my_func(self, doc_type): @@ -133,7 +133,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): ): self.checker.visit_return(return_node) - def test_warn_partial_google_returns(self): + def test_warn_partial_google_returns(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -151,7 +151,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): ): self.checker.visit_return(return_node) - def test_warn_partial_google_returns_type(self): + def test_warn_partial_google_returns_type(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -167,7 +167,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertAddsMessages(Message(msg_id="missing-return-doc", node=node)): self.checker.visit_return(return_node) - def test_warn_missing_google_returns(self): + def test_warn_missing_google_returns(self) -> None: node = astroid.extract_node( ''' def my_func(self, doc_type): @@ -186,7 +186,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): ): self.checker.visit_return(return_node) - def test_warn_partial_numpy_returns_type(self): + def test_warn_partial_numpy_returns_type(self) -> None: node = astroid.extract_node( ''' def my_func(self, doc_type): @@ -208,7 +208,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertAddsMessages(Message(msg_id="missing-return-doc", node=node)): self.checker.visit_return(return_node) - def test_warn_missing_numpy_returns(self): + def test_warn_missing_numpy_returns(self) -> None: node = astroid.extract_node( ''' def my_func(self, doc_type): @@ -229,7 +229,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): ): self.checker.visit_return(return_node) - def test_find_sphinx_returns(self): + def test_find_sphinx_returns(self) -> None: return_node = astroid.extract_node( ''' def my_func(self): @@ -244,7 +244,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_find_google_returns(self): + def test_find_google_returns(self) -> None: return_node = astroid.extract_node( ''' def my_func(self): @@ -259,7 +259,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_find_numpy_returns(self): + def test_find_numpy_returns(self) -> None: return_node = astroid.extract_node( ''' def my_func(self): @@ -276,7 +276,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_find_numpy_returns_with_of(self): + def test_find_numpy_returns_with_of(self) -> None: return_node = astroid.extract_node( ''' def my_func(self): @@ -293,7 +293,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_ignores_sphinx_return_none(self): + def test_ignores_sphinx_return_none(self) -> None: return_node = astroid.extract_node( ''' def my_func(self, doc_type): @@ -308,7 +308,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_ignores_google_return_none(self): + def test_ignores_google_return_none(self) -> None: return_node = astroid.extract_node( ''' def my_func(self, doc_type): @@ -323,7 +323,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_ignores_numpy_return_none(self): + def test_ignores_numpy_return_none(self) -> None: return_node = astroid.extract_node( ''' def my_func(self, doc_type): @@ -340,7 +340,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_finds_sphinx_return_custom_class(self): + def test_finds_sphinx_return_custom_class(self) -> None: return_node = astroid.extract_node( ''' def my_func(self): @@ -355,7 +355,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_finds_google_return_custom_class(self): + def test_finds_google_return_custom_class(self) -> None: return_node = astroid.extract_node( ''' def my_func(self): @@ -370,7 +370,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_finds_numpy_return_custom_class(self): + def test_finds_numpy_return_custom_class(self) -> None: return_node = astroid.extract_node( ''' def my_func(self): @@ -387,7 +387,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_finds_sphinx_return_list_of_custom_class(self): + def test_finds_sphinx_return_list_of_custom_class(self) -> None: return_node = astroid.extract_node( ''' def my_func(self): @@ -402,7 +402,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_finds_google_return_list_of_custom_class(self): + def test_finds_google_return_list_of_custom_class(self) -> None: return_node = astroid.extract_node( ''' def my_func(self): @@ -417,7 +417,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_finds_numpy_return_list_of_custom_class(self): + def test_finds_numpy_return_list_of_custom_class(self) -> None: return_node = astroid.extract_node( ''' def my_func(self): @@ -434,7 +434,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_return(return_node) - def test_warns_sphinx_return_list_of_custom_class_without_description(self): + def test_warns_sphinx_return_list_of_custom_class_without_description(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -449,7 +449,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertAddsMessages(Message(msg_id="missing-return-doc", node=node)): self.checker.visit_return(return_node) - def test_warns_google_return_list_of_custom_class_without_description(self): + def test_warns_google_return_list_of_custom_class_without_description(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -465,7 +465,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertAddsMessages(Message(msg_id="missing-return-doc", node=node)): self.checker.visit_return(return_node) - def test_warns_numpy_return_list_of_custom_class_without_description(self): + def test_warns_numpy_return_list_of_custom_class_without_description(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -482,7 +482,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertAddsMessages(Message(msg_id="missing-return-doc", node=node)): self.checker.visit_return(return_node) - def test_warns_sphinx_redundant_return_doc(self): + def test_warns_sphinx_redundant_return_doc(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -498,7 +498,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_warns_sphinx_redundant_rtype_doc(self): + def test_warns_sphinx_redundant_rtype_doc(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -514,7 +514,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_warns_google_redundant_return_doc(self): + def test_warns_google_redundant_return_doc(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -531,7 +531,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_warns_google_redundant_rtype_doc(self): + def test_warns_google_redundant_rtype_doc(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -548,7 +548,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_warns_numpy_redundant_return_doc(self): + def test_warns_numpy_redundant_return_doc(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -567,7 +567,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_warns_numpy_redundant_rtype_doc(self): + def test_warns_numpy_redundant_rtype_doc(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -585,7 +585,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_ignores_sphinx_redundant_return_doc_multiple_returns(self): + def test_ignores_sphinx_redundant_return_doc_multiple_returns(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -605,7 +605,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignores_google_redundant_return_doc_multiple_returns(self): + def test_ignores_google_redundant_return_doc_multiple_returns(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -622,7 +622,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignores_numpy_redundant_return_doc_multiple_returns(self): + def test_ignores_numpy_redundant_return_doc_multiple_returns(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -643,7 +643,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignore_sphinx_redundant_return_doc_yield(self): + def test_ignore_sphinx_redundant_return_doc_yield(self) -> None: node = astroid.extract_node( ''' def my_func_with_yield(self): @@ -659,7 +659,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_warns_google_redundant_return_doc_yield(self): + def test_warns_google_redundant_return_doc_yield(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -676,7 +676,7 @@ class TestDocstringCheckerReturn(CheckerTestCase): ): self.checker.visit_functiondef(node) - def test_warns_numpy_redundant_return_doc_yield(self): + def test_warns_numpy_redundant_return_doc_yield(self) -> None: node = astroid.extract_node( ''' def my_func(self): diff --git a/tests/extensions/test_check_yields_docs.py b/tests/extensions/test_check_yields_docs.py index 9cdee9e74..a0b9c0d70 100644 --- a/tests/extensions/test_check_yields_docs.py +++ b/tests/extensions/test_check_yields_docs.py @@ -27,7 +27,7 @@ class TestDocstringCheckerYield(CheckerTestCase): CHECKER_CLASS = DocstringParameterChecker - def test_ignores_no_docstring(self): + def test_ignores_no_docstring(self) -> None: yield_node = astroid.extract_node( """ def my_func(self): @@ -38,7 +38,7 @@ class TestDocstringCheckerYield(CheckerTestCase): self.checker.visit_yield(yield_node) @set_config(accept_no_yields_doc=False) - def test_warns_no_docstring(self): + def test_warns_no_docstring(self) -> None: node = astroid.extract_node( """ def my_func(self): @@ -52,7 +52,7 @@ class TestDocstringCheckerYield(CheckerTestCase): ): self.checker.visit_yield(yield_node) - def test_ignores_unknown_style(self): + def test_ignores_unknown_style(self) -> None: yield_node = astroid.extract_node( ''' def my_func(self): @@ -63,7 +63,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_yield(yield_node) - def test_warn_partial_sphinx_yields(self): + def test_warn_partial_sphinx_yields(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -80,7 +80,7 @@ class TestDocstringCheckerYield(CheckerTestCase): ): self.checker.visit_yield(yield_node) - def test_warn_partial_sphinx_yields_type(self): + def test_warn_partial_sphinx_yields_type(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -95,7 +95,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertAddsMessages(Message(msg_id="missing-yield-doc", node=node)): self.checker.visit_yield(yield_node) - def test_warn_missing_sphinx_yields(self): + def test_warn_missing_sphinx_yields(self) -> None: node = astroid.extract_node( ''' def my_func(self, doc_type): @@ -114,7 +114,7 @@ class TestDocstringCheckerYield(CheckerTestCase): ): self.checker.visit_yield(yield_node) - def test_warn_partial_google_yields(self): + def test_warn_partial_google_yields(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -132,7 +132,7 @@ class TestDocstringCheckerYield(CheckerTestCase): ): self.checker.visit_yield(yield_node) - def test_warn_partial_google_yields_type(self): + def test_warn_partial_google_yields_type(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -148,7 +148,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertAddsMessages(Message(msg_id="missing-yield-doc", node=node)): self.checker.visit_yield(yield_node) - def test_warn_missing_google_yields(self): + def test_warn_missing_google_yields(self) -> None: node = astroid.extract_node( ''' def my_func(self, doc_type): @@ -167,7 +167,7 @@ class TestDocstringCheckerYield(CheckerTestCase): ): self.checker.visit_yield(yield_node) - def test_warn_missing_numpy_yields(self): + def test_warn_missing_numpy_yields(self) -> None: node = astroid.extract_node( ''' def my_func(self, doc_type): @@ -188,7 +188,7 @@ class TestDocstringCheckerYield(CheckerTestCase): ): self.checker.visit_yield(yield_node) - def test_find_sphinx_yields(self): + def test_find_sphinx_yields(self) -> None: yield_node = astroid.extract_node( ''' def my_func(self): @@ -203,7 +203,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_yield(yield_node) - def test_find_google_yields(self): + def test_find_google_yields(self) -> None: yield_node = astroid.extract_node( ''' def my_func(self): @@ -218,7 +218,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_yield(yield_node) - def test_find_numpy_yields(self): + def test_find_numpy_yields(self) -> None: yield_node = astroid.extract_node( ''' def my_func(self): @@ -235,7 +235,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_yield(yield_node) - def test_finds_sphinx_yield_custom_class(self): + def test_finds_sphinx_yield_custom_class(self) -> None: yield_node = astroid.extract_node( ''' def my_func(self): @@ -250,7 +250,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_yield(yield_node) - def test_finds_google_yield_custom_class(self): + def test_finds_google_yield_custom_class(self) -> None: yield_node = astroid.extract_node( ''' def my_func(self): @@ -265,7 +265,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_yield(yield_node) - def test_finds_numpy_yield_custom_class(self): + def test_finds_numpy_yield_custom_class(self) -> None: yield_node = astroid.extract_node( ''' def my_func(self): @@ -282,7 +282,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_yield(yield_node) - def test_finds_sphinx_yield_list_of_custom_class(self): + def test_finds_sphinx_yield_list_of_custom_class(self) -> None: yield_node = astroid.extract_node( ''' def my_func(self): @@ -297,7 +297,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_yield(yield_node) - def test_finds_google_yield_list_of_custom_class(self): + def test_finds_google_yield_list_of_custom_class(self) -> None: yield_node = astroid.extract_node( ''' def my_func(self): @@ -312,7 +312,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_yield(yield_node) - def test_finds_numpy_yield_list_of_custom_class(self): + def test_finds_numpy_yield_list_of_custom_class(self) -> None: yield_node = astroid.extract_node( ''' def my_func(self): @@ -329,7 +329,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_yield(yield_node) - def test_warns_sphinx_yield_list_of_custom_class_without_description(self): + def test_warns_sphinx_yield_list_of_custom_class_without_description(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -344,7 +344,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertAddsMessages(Message(msg_id="missing-yield-doc", node=node)): self.checker.visit_yield(yield_node) - def test_warns_google_yield_list_of_custom_class_without_description(self): + def test_warns_google_yield_list_of_custom_class_without_description(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -360,7 +360,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertAddsMessages(Message(msg_id="missing-yield-doc", node=node)): self.checker.visit_yield(yield_node) - def test_warns_numpy_yield_list_of_custom_class_without_description(self): + def test_warns_numpy_yield_list_of_custom_class_without_description(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -380,7 +380,7 @@ class TestDocstringCheckerYield(CheckerTestCase): # No such thing as redundant yield documentation for sphinx because it # doesn't support yield documentation - def test_ignores_google_redundant_yield_doc_multiple_yields(self): + def test_ignores_google_redundant_yield_doc_multiple_yields(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -397,7 +397,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_functiondef(node) - def test_ignores_numpy_redundant_yield_doc_multiple_yields(self): + def test_ignores_numpy_redundant_yield_doc_multiple_yields(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -421,7 +421,7 @@ class TestDocstringCheckerYield(CheckerTestCase): # No such thing as redundant yield documentation for sphinx because it # doesn't support yield documentation - def test_warns_google_redundant_yield_doc_return(self): + def test_warns_google_redundant_yield_doc_return(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -436,7 +436,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertAddsMessages(Message(msg_id="redundant-yields-doc", node=node)): self.checker.visit_functiondef(node) - def test_warns_numpy_redundant_yield_doc_return(self): + def test_warns_numpy_redundant_yield_doc_return(self) -> None: node = astroid.extract_node( ''' def my_func(self): @@ -453,7 +453,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertAddsMessages(Message(msg_id="redundant-yields-doc", node=node)): self.checker.visit_functiondef(node) - def test_sphinx_missing_yield_type_with_annotations(self): + def test_sphinx_missing_yield_type_with_annotations(self) -> None: node = astroid.extract_node( ''' import typing @@ -470,7 +470,7 @@ class TestDocstringCheckerYield(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_yield(yield_node) - def test_google_missing_yield_type_with_annotations(self): + def test_google_missing_yield_type_with_annotations(self) -> None: node = astroid.extract_node( ''' import typing diff --git a/tests/extensions/test_comparetozero.py b/tests/extensions/test_comparetozero.py index 89b18a4f4..167a615ef 100644 --- a/tests/extensions/test_comparetozero.py +++ b/tests/extensions/test_comparetozero.py @@ -22,7 +22,7 @@ from pylint.reporters import BaseReporter class CompareToZeroTestReporter(BaseReporter): - def on_set_current_module(self, module, filepath): + def on_set_current_module(self, module: str, filepath: str) -> None: self.messages = [] def _display(self, layout): @@ -30,15 +30,16 @@ class CompareToZeroTestReporter(BaseReporter): class CompareToZeroUsedTC(unittest.TestCase): + _linter = PyLinter() + @classmethod - def setUpClass(cls): - cls._linter = PyLinter() + def setUpClass(cls) -> None: cls._linter.set_reporter(CompareToZeroTestReporter()) checkers.initialize(cls._linter) cls._linter.register_checker(CompareToZeroChecker(cls._linter)) cls._linter.disable("I") - def test_comparetozero_message(self): + def test_comparetozero_message(self) -> None: elif_test = os.path.join( os.path.dirname(os.path.abspath(__file__)), "data", "compare_to_zero.py" ) diff --git a/tests/extensions/test_confusing_elif.py b/tests/extensions/test_confusing_elif.py index a8d7096c5..65fd9badd 100644 --- a/tests/extensions/test_confusing_elif.py +++ b/tests/extensions/test_confusing_elif.py @@ -21,7 +21,7 @@ class TestConfusingConsecutiveElifChecker(CheckerTestCase): CHECKER_CLASS = ConfusingConsecutiveElifChecker - def test_triggered_if_if_block_ends_with_elif(self): + def test_triggered_if_if_block_ends_with_elif(self) -> None: """ Given an if-elif construct When the body of the if ends with an elif @@ -43,7 +43,7 @@ class TestConfusingConsecutiveElifChecker(CheckerTestCase): ): self.checker.visit_if(if_node_to_test) - def test_triggered_if_elif_block_ends_with_elif(self): + def test_triggered_if_elif_block_ends_with_elif(self) -> None: """ Given an if-elif-elif construct When the body of the first elif ends with an elif @@ -67,7 +67,7 @@ class TestConfusingConsecutiveElifChecker(CheckerTestCase): ): self.checker.visit_if(if_node_to_test) - def test_triggered_if_block_ends_with_if(self): + def test_triggered_if_block_ends_with_if(self) -> None: """ Given an if-elif construct When the body of the if ends with an if @@ -87,7 +87,7 @@ class TestConfusingConsecutiveElifChecker(CheckerTestCase): ): self.checker.visit_if(if_node_to_test) - def test_not_triggered_if_indented_block_ends_with_else(self): + def test_not_triggered_if_indented_block_ends_with_else(self) -> None: """ Given an if-elif construct When the body of the if ends with an else @@ -107,7 +107,7 @@ class TestConfusingConsecutiveElifChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_if(if_node_to_test) - def test_not_triggered_if_indentend_block_ends_with_call(self): + def test_not_triggered_if_indentend_block_ends_with_call(self) -> None: """ Given an if-elif construct When the body of the if ends with a function call @@ -131,7 +131,7 @@ class TestConfusingConsecutiveElifChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_if(if_node_to_test) - def test_not_triggered_if_indented_block_ends_with_ifexp(self): + def test_not_triggered_if_indented_block_ends_with_ifexp(self) -> None: """ Given an if-elif construct When the body of the if ends with an if expression @@ -152,7 +152,7 @@ class TestConfusingConsecutiveElifChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_if(if_node_to_test) - def test_not_triggered_if_outer_block_does_not_have_elif(self): + def test_not_triggered_if_outer_block_does_not_have_elif(self) -> None: """ Given an if construct without an elif When the body of the if ends with an if @@ -174,7 +174,7 @@ class TestConfusingConsecutiveElifChecker(CheckerTestCase): with self.assertNoMessages(): self.checker.visit_if(if_node_to_test) - def test_not_triggered_if_outer_block_continues_with_if(self): + def test_not_triggered_if_outer_block_continues_with_if(self) -> None: """ Given an if construct which continues with a new if construct When the body of the first if ends with an if expression diff --git a/tests/extensions/test_docstyle.py b/tests/extensions/test_docstyle.py index 8e002ead8..5155783e2 100644 --- a/tests/extensions/test_docstyle.py +++ b/tests/extensions/test_docstyle.py @@ -17,6 +17,7 @@ from os.path import abspath, dirname, join import pytest from pylint.extensions.docstyle import DocStringStyleChecker +from pylint.lint.pylinter import PyLinter EXPECTED_MSGS = [ "First line empty in function docstring", @@ -44,7 +45,7 @@ def checker(): return DocStringStyleChecker -def test_docstring_message(linter): +def test_docstring_message(linter: PyLinter) -> None: docstring_test = join(dirname(abspath(__file__)), "data", "docstring.py") linter.check([docstring_test]) msgs = linter.reporter.messages diff --git a/tests/extensions/test_elseif_used.py b/tests/extensions/test_elseif_used.py index 21e006eb1..0fbfa73fb 100644 --- a/tests/extensions/test_elseif_used.py +++ b/tests/extensions/test_elseif_used.py @@ -17,6 +17,7 @@ from os import path as osp import pytest from pylint.extensions.check_elif import ElseifUsedChecker +from pylint.lint.pylinter import PyLinter @pytest.fixture(scope="module") @@ -24,7 +25,7 @@ def checker(): return ElseifUsedChecker -def test_elseif_message(linter): +def test_elseif_message(linter: PyLinter) -> None: elif_test = osp.join(osp.dirname(osp.abspath(__file__)), "data", "elif.py") linter.check([elif_test]) msgs = linter.reporter.messages diff --git a/tests/extensions/test_empty_comment.py b/tests/extensions/test_empty_comment.py index b53f31d2f..42d1b51f2 100644 --- a/tests/extensions/test_empty_comment.py +++ b/tests/extensions/test_empty_comment.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest from pylint.extensions import empty_comment +from pylint.lint.pylinter import PyLinter @pytest.fixture(scope="module") @@ -20,7 +21,7 @@ def disable(): return ["all"] -def test_comment_base_case(linter): +def test_comment_base_case(linter: PyLinter) -> None: comment_test = str(Path(__file__).parent.joinpath("data", "empty_comment.py")) linter.check([comment_test]) msgs = linter.reporter.messages diff --git a/tests/extensions/test_emptystring.py b/tests/extensions/test_emptystring.py index 3b84129d8..95143c9ad 100644 --- a/tests/extensions/test_emptystring.py +++ b/tests/extensions/test_emptystring.py @@ -19,6 +19,7 @@ from os import path as osp import pytest from pylint.extensions.emptystring import CompareToEmptyStringChecker +from pylint.lint.pylinter import PyLinter @pytest.fixture(scope="module") @@ -31,7 +32,7 @@ def disable(): return ["I"] -def test_emptystring_message(linter): +def test_emptystring_message(linter: PyLinter) -> None: elif_test = osp.join( osp.dirname(osp.abspath(__file__)), "data", "empty_string_comparison.py" ) diff --git a/tests/extensions/test_overlapping_exceptions.py b/tests/extensions/test_overlapping_exceptions.py index 34a5be99a..005e0bcf9 100644 --- a/tests/extensions/test_overlapping_exceptions.py +++ b/tests/extensions/test_overlapping_exceptions.py @@ -9,6 +9,7 @@ from os.path import dirname, join import pytest from pylint.extensions.overlapping_exceptions import OverlappingExceptionsChecker +from pylint.lint.pylinter import PyLinter @pytest.fixture(scope="module") @@ -21,7 +22,7 @@ def disable(): return ["I"] -def test_overlapping_exceptions(linter): +def test_overlapping_exceptions(linter: PyLinter) -> None: test = join(dirname(__file__), "data", "overlapping_exceptions.py") linter.check([test]) msgs = linter.reporter.messages @@ -64,7 +65,7 @@ def test_overlapping_exceptions(linter): assert (msg.line, msg.msg) == exp -def test_overlapping_exceptions_py33(linter): +def test_overlapping_exceptions_py33(linter: PyLinter) -> None: """From Python 3.3 both IOError and socket.error are aliases for OSError.""" test = join(dirname(__file__), "data", "overlapping_exceptions_py33.py") linter.check([test]) diff --git a/tests/extensions/test_redefined.py b/tests/extensions/test_redefined.py index 91f1ae7ad..ad95d45e6 100644 --- a/tests/extensions/test_redefined.py +++ b/tests/extensions/test_redefined.py @@ -16,6 +16,7 @@ import pytest from pylint.extensions.redefined_variable_type import MultipleTypesChecker from pylint.lint import fix_import_path +from pylint.lint.pylinter import PyLinter EXPECTED = [ "Redefinition of self.var1 type from int to float", @@ -41,7 +42,7 @@ def disable(): return ["I"] -def test_types_redefined(linter): +def test_types_redefined(linter: PyLinter) -> None: elif_test = osp.join(osp.dirname(osp.abspath(__file__)), "data", "redefined.py") with fix_import_path([elif_test]): linter.check([elif_test]) diff --git a/tests/extensions/test_while_used.py b/tests/extensions/test_while_used.py index 23fe95f07..3bf081a29 100644 --- a/tests/extensions/test_while_used.py +++ b/tests/extensions/test_while_used.py @@ -11,7 +11,7 @@ class TestWhileUsed(CheckerTestCase): CHECKER_CLASS = WhileChecker - def test_while_used(self): + def test_while_used(self) -> None: node = astroid.extract_node( """ def f(): diff --git a/tests/lint/test_pylinter.py b/tests/lint/test_pylinter.py index f07531430..a1ea5351a 100644 --- a/tests/lint/test_pylinter.py +++ b/tests/lint/test_pylinter.py @@ -1,16 +1,23 @@ +from typing import Any from unittest.mock import patch +from _pytest.capture import CaptureFixture from astroid import AstroidBuildingError +from mypy_extensions import NoReturn +from py._path.local import LocalPath # type: ignore +from pylint.lint.pylinter import PyLinter from pylint.utils import FileState -def raise_exception(*args, **kwargs): +def raise_exception(*args: Any, **kwargs: Any) -> NoReturn: raise AstroidBuildingError(modname="spam") @patch.object(FileState, "iter_spurious_suppression_messages", raise_exception) -def test_crash_in_file(linter, capsys, tmpdir): +def test_crash_in_file( + linter: PyLinter, capsys: CaptureFixture, tmpdir: LocalPath +) -> None: args = linter.load_command_line_configuration([__file__]) linter.crash_file_path = str(tmpdir / "pylint-crash-%Y") linter.check(args) diff --git a/tests/lint/test_utils.py b/tests/lint/test_utils.py index 7fcdc5dec..80e7287f0 100644 --- a/tests/lint/test_utils.py +++ b/tests/lint/test_utils.py @@ -1,7 +1,9 @@ +from pathlib import PosixPath + from pylint.lint.utils import get_fatal_error_message, prepare_crash_report -def test_prepare_crash_report(tmp_path): +def test_prepare_crash_report(tmp_path: PosixPath) -> None: exception_content = "Exmessage" python_file = tmp_path / "myfile.py" python_content = "from shadok import MagicFaucet" @@ -22,7 +24,7 @@ def test_prepare_crash_report(tmp_path): assert "raise Exception(exception_content)" in template_content -def test_get_fatal_error_message(): +def test_get_fatal_error_message() -> None: python_path = "mypath.py" crash_path = "crash.txt" msg = get_fatal_error_message(python_path, crash_path) diff --git a/tests/lint/unittest_expand_modules.py b/tests/lint/unittest_expand_modules.py index f3ec8364f..ef98cf575 100644 --- a/tests/lint/unittest_expand_modules.py +++ b/tests/lint/unittest_expand_modules.py @@ -10,7 +10,7 @@ import pytest from pylint.lint.expand_modules import _is_in_ignore_list_re, expand_modules -def test__is_in_ignore_list_re_match(): +def test__is_in_ignore_list_re_match() -> None: patterns = [ re.compile(".*enchilada.*"), re.compile("unittest_.*"), @@ -21,7 +21,7 @@ def test__is_in_ignore_list_re_match(): assert _is_in_ignore_list_re("src/tests/whatever.xml", patterns) -def test__is_in_ignore_list_re_nomatch(): +def test__is_in_ignore_list_re_nomatch() -> None: patterns = [ re.compile(".*enchilada.*"), re.compile("unittest_.*"), diff --git a/tests/lint/unittest_lint.py b/tests/lint/unittest_lint.py index 110a2061c..18656ad74 100644 --- a/tests/lint/unittest_lint.py +++ b/tests/lint/unittest_lint.py @@ -48,9 +48,11 @@ from io import StringIO from os import chdir, getcwd from os.path import abspath, basename, dirname, isdir, join, sep from shutil import rmtree +from typing import Iterable, Iterator, List, Optional, Tuple import platformdirs import pytest +from _pytest.capture import CaptureFixture from pylint import checkers, config, exceptions, interfaces, lint, testutils from pylint.checkers.utils import check_messages @@ -78,7 +80,7 @@ else: @contextmanager -def fake_home(): +def fake_home() -> Iterator: folder = tempfile.mkdtemp("fake-home") old_home = os.environ.get(HOME) try: @@ -107,7 +109,7 @@ DATA_DIR = join(HERE, "..", "data") @contextmanager -def tempdir(): +def tempdir() -> Iterator[str]: """Create a temp directory and change the current location to it. This is supposed to be used with a *with* statement. @@ -126,7 +128,7 @@ def tempdir(): rmtree(abs_tmp) -def create_files(paths, chroot="."): +def create_files(paths: List[str], chroot: str = ".") -> None: """Creates directories and files found in <path>. :param list paths: list of relative paths to files or directories @@ -165,15 +167,15 @@ def create_files(paths, chroot="."): @pytest.fixture -def fake_path(): +def fake_path() -> Iterator[Iterable[str]]: orig = list(sys.path) - fake = [1, 2, 3] + fake: Iterable[str] = ["1", "2", "3"] sys.path[:] = fake yield fake sys.path[:] = orig -def test_no_args(fake_path): +def test_no_args(fake_path: List[int]) -> None: with lint.fix_import_path([]): assert sys.path == fake_path assert sys.path == fake_path @@ -182,7 +184,7 @@ def test_no_args(fake_path): @pytest.mark.parametrize( "case", [["a/b/"], ["a/b"], ["a/b/__init__.py"], ["a/"], ["a"]] ) -def test_one_arg(fake_path, case): +def test_one_arg(fake_path: List[str], case: List[str]) -> None: with tempdir() as chroot: create_files(["a/b/__init__.py"]) expected = [join(chroot, "a")] + fake_path @@ -246,14 +248,14 @@ def reporter(): @pytest.fixture -def init_linter(linter): +def init_linter(linter: PyLinter) -> PyLinter: linter.open() linter.set_current_module("toto") linter.file_state = FileState("toto") return linter -def test_pylint_visit_method_taken_in_account(linter): +def test_pylint_visit_method_taken_in_account(linter: PyLinter) -> None: class CustomChecker(checkers.BaseChecker): __implements__ = interfaces.IAstroidChecker name = "custom" @@ -270,7 +272,7 @@ def test_pylint_visit_method_taken_in_account(linter): linter.check("abc") -def test_enable_message(init_linter): +def test_enable_message(init_linter: PyLinter) -> None: linter = init_linter assert linter.is_message_enabled("W0101") assert linter.is_message_enabled("W0102") @@ -287,7 +289,7 @@ def test_enable_message(init_linter): assert linter.is_message_enabled("W0102", 1) -def test_enable_message_category(init_linter): +def test_enable_message_category(init_linter: PyLinter) -> None: linter = init_linter assert linter.is_message_enabled("W0101") assert linter.is_message_enabled("C0202") @@ -306,7 +308,7 @@ def test_enable_message_category(init_linter): assert linter.is_message_enabled("C0202", line=1) -def test_message_state_scope(init_linter): +def test_message_state_scope(init_linter: PyLinter) -> None: class FakeConfig: confidence = ["HIGH"] @@ -324,7 +326,7 @@ def test_message_state_scope(init_linter): ) -def test_enable_message_block(init_linter): +def test_enable_message_block(init_linter: PyLinter) -> None: linter = init_linter linter.open() filepath = join(REGRTEST_DATA_DIR, "func_block_disable_msg.py") @@ -382,7 +384,7 @@ def test_enable_message_block(init_linter): assert fs._suppression_mapping["E1101", 110] == 109 -def test_enable_by_symbol(init_linter): +def test_enable_by_symbol(init_linter: PyLinter) -> None: """messages can be controlled by symbolic names. The state is consistent across symbols and numbers. @@ -411,7 +413,7 @@ def test_enable_by_symbol(init_linter): assert linter.is_message_enabled("dangerous-default-value", 1) -def test_enable_report(linter): +def test_enable_report(linter: PyLinter) -> None: assert linter.report_is_enabled("RP0001") linter.disable("RP0001") assert not linter.report_is_enabled("RP0001") @@ -419,19 +421,19 @@ def test_enable_report(linter): assert linter.report_is_enabled("RP0001") -def test_report_output_format_aliased(linter): +def test_report_output_format_aliased(linter: PyLinter) -> None: text.register(linter) linter.set_option("output-format", "text") assert linter.reporter.__class__.__name__ == "TextReporter" -def test_set_unsupported_reporter(linter): +def test_set_unsupported_reporter(linter: PyLinter) -> None: text.register(linter) with pytest.raises(exceptions.InvalidReporterError): linter.set_option("output-format", "missing.module.Class") -def test_set_option_1(linter): +def test_set_option_1(linter: PyLinter) -> None: linter.set_option("disable", "C0111,W0234") assert not linter.is_message_enabled("C0111") assert not linter.is_message_enabled("W0234") @@ -440,7 +442,7 @@ def test_set_option_1(linter): assert not linter.is_message_enabled("non-iterator-returned") -def test_set_option_2(linter): +def test_set_option_2(linter: PyLinter) -> None: linter.set_option("disable", ("C0111", "W0234")) assert not linter.is_message_enabled("C0111") assert not linter.is_message_enabled("W0234") @@ -449,14 +451,14 @@ def test_set_option_2(linter): assert not linter.is_message_enabled("non-iterator-returned") -def test_enable_checkers(linter): +def test_enable_checkers(linter: PyLinter) -> None: linter.disable("design") assert not ("design" in [c.name for c in linter.prepare_checkers()]) linter.enable("design") assert "design" in [c.name for c in linter.prepare_checkers()] -def test_errors_only(linter): +def test_errors_only(linter: PyLinter) -> None: linter.error_mode() checkers = linter.prepare_checkers() checker_names = {c.name for c in checkers} @@ -464,13 +466,13 @@ def test_errors_only(linter): assert set() == should_not & checker_names -def test_disable_similar(linter): +def test_disable_similar(linter: PyLinter) -> None: linter.set_option("disable", "RP0801") linter.set_option("disable", "R0801") assert not ("similarities" in [c.name for c in linter.prepare_checkers()]) -def test_disable_alot(linter): +def test_disable_alot(linter: PyLinter) -> None: """check that we disabled a lot of checkers""" linter.set_option("reports", False) linter.set_option("disable", "R,C,W") @@ -479,7 +481,7 @@ def test_disable_alot(linter): assert not (cname in checker_names), cname -def test_addmessage(linter): +def test_addmessage(linter: PyLinter) -> None: linter.set_reporter(testutils.GenericTestReporter()) linter.open() linter.set_current_module("0123") @@ -491,7 +493,7 @@ def test_addmessage(linter): ] == linter.reporter.messages -def test_addmessage_invalid(linter): +def test_addmessage_invalid(linter: PyLinter) -> None: linter.set_reporter(testutils.GenericTestReporter()) linter.open() linter.set_current_module("0123") @@ -512,7 +514,7 @@ def test_addmessage_invalid(linter): assert str(cm.value) == "Message C0321 must provide Node, got None" -def test_load_plugin_command_line(): +def test_load_plugin_command_line() -> None: dummy_plugin_path = join(REGRTEST_DATA_DIR, "dummy_plugin") sys.path.append(dummy_plugin_path) @@ -528,7 +530,7 @@ def test_load_plugin_command_line(): sys.path.remove(dummy_plugin_path) -def test_load_plugin_config_file(): +def test_load_plugin_config_file() -> None: dummy_plugin_path = join(REGRTEST_DATA_DIR, "dummy_plugin") sys.path.append(dummy_plugin_path) config_path = join(REGRTEST_DATA_DIR, "dummy_plugin.rc") @@ -545,7 +547,7 @@ def test_load_plugin_config_file(): sys.path.remove(dummy_plugin_path) -def test_load_plugin_configuration(): +def test_load_plugin_configuration() -> None: dummy_plugin_path = join(REGRTEST_DATA_DIR, "dummy_plugin") sys.path.append(dummy_plugin_path) @@ -562,20 +564,20 @@ def test_load_plugin_configuration(): assert run.linter.config.black_list == ["foo", "bar", "bin"] -def test_init_hooks_called_before_load_plugins(): +def test_init_hooks_called_before_load_plugins() -> None: with pytest.raises(RuntimeError): Run(["--load-plugins", "unexistant", "--init-hook", "raise RuntimeError"]) with pytest.raises(RuntimeError): Run(["--init-hook", "raise RuntimeError", "--load-plugins", "unexistant"]) -def test_analyze_explicit_script(linter): +def test_analyze_explicit_script(linter: PyLinter) -> None: linter.set_reporter(testutils.GenericTestReporter()) linter.check(os.path.join(DATA_DIR, "ascript")) assert ["C: 2: Line too long (175/100)"] == linter.reporter.messages -def test_full_documentation(linter): +def test_full_documentation(linter: PyLinter) -> None: out = StringIO() linter.print_full_documentation(out) output = out.getvalue() @@ -593,7 +595,7 @@ def test_full_documentation(linter): assert re.search(regexp, output) -def test_list_msgs_enabled(init_linter, capsys): +def test_list_msgs_enabled(init_linter: PyLinter, capsys: CaptureFixture) -> None: linter = init_linter linter.enable("W0101", scope="package") linter.disable("W0102", scope="package") @@ -616,12 +618,12 @@ def test_list_msgs_enabled(init_linter, capsys): @pytest.fixture -def pop_pylintrc(): +def pop_pylintrc() -> None: os.environ.pop("PYLINTRC", None) @pytest.mark.usefixtures("pop_pylintrc") -def test_pylint_home(): +def test_pylint_home() -> None: uhome = os.path.expanduser("~") if uhome == "~": expected = ".pylint.d" @@ -645,7 +647,7 @@ def test_pylint_home(): @pytest.mark.usefixtures("pop_pylintrc") -def test_pylintrc(): +def test_pylintrc() -> None: with fake_home(): current_dir = getcwd() chdir(os.path.dirname(os.path.abspath(sys.executable))) @@ -661,7 +663,7 @@ def test_pylintrc(): @pytest.mark.usefixtures("pop_pylintrc") -def test_pylintrc_parentdir(): +def test_pylintrc_parentdir() -> None: with tempdir() as chroot: create_files( @@ -689,7 +691,7 @@ def test_pylintrc_parentdir(): @pytest.mark.usefixtures("pop_pylintrc") -def test_pylintrc_parentdir_no_package(): +def test_pylintrc_parentdir_no_package() -> None: with tempdir() as chroot: with fake_home(): create_files(["a/pylintrc", "a/b/pylintrc", "a/b/c/d/__init__.py"]) @@ -706,31 +708,31 @@ def test_pylintrc_parentdir_no_package(): class TestPreprocessOptions: - def _callback(self, name, value): + def _callback(self, name: str, value: Optional[str]) -> None: self.args.append((name, value)) - def test_value_equal(self): - self.args = [] + def test_value_equal(self) -> None: + self.args: List[Tuple[str, Optional[str]]] = [] preprocess_options( ["--foo", "--bar=baz", "--qu=ux"], {"foo": (self._callback, False), "qu": (self._callback, True)}, ) assert [("foo", None), ("qu", "ux")] == self.args - def test_value_space(self): + def test_value_space(self) -> None: self.args = [] preprocess_options(["--qu", "ux"], {"qu": (self._callback, True)}) assert [("qu", "ux")] == self.args @staticmethod - def test_error_missing_expected_value(): + def test_error_missing_expected_value() -> None: with pytest.raises(ArgumentPreprocessingError): preprocess_options(["--foo", "--bar", "--qu=ux"], {"bar": (None, True)}) with pytest.raises(ArgumentPreprocessingError): preprocess_options(["--foo", "--bar"], {"bar": (None, True)}) @staticmethod - def test_error_unexpected_value(): + def test_error_unexpected_value() -> None: with pytest.raises(ArgumentPreprocessingError): preprocess_options( ["--foo", "--bar=spam", "--qu=ux"], {"bar": (None, False)} @@ -739,14 +741,17 @@ class TestPreprocessOptions: class _CustomPyLinter(PyLinter): # pylint: disable=too-many-ancestors - def should_analyze_file(self, modname, path, is_argument=False): + @staticmethod + def should_analyze_file(modname: str, path: str, is_argument: bool = False) -> bool: if os.path.basename(path) == "wrong.py": return False - return super().should_analyze_file(modname, path, is_argument=is_argument) + return super(_CustomPyLinter, _CustomPyLinter).should_analyze_file( + modname, path, is_argument=is_argument + ) -def test_custom_should_analyze_file(): +def test_custom_should_analyze_file() -> None: """Check that we can write custom should_analyze_file that work even for arguments. """ @@ -775,7 +780,7 @@ def test_custom_should_analyze_file(): # we do the check with jobs=1 as well, so that we are sure that the duplicates # are created by the multiprocessing problem. @pytest.mark.parametrize("jobs", [1, 2]) -def test_multiprocessing(jobs): +def test_multiprocessing(jobs: int) -> None: """Check that multiprocessing does not create duplicates.""" # For the bug (#3584) to show up we need more than one file with issues # per process @@ -804,7 +809,7 @@ def test_multiprocessing(jobs): assert len(messages) == len(set(messages)) -def test_filename_with__init__(init_linter): +def test_filename_with__init__(init_linter: PyLinter) -> None: # This tracks a regression where a file whose name ends in __init__.py, # such as flycheck__init__.py, would accidentally lead to linting the # entire containing directory. @@ -818,7 +823,7 @@ def test_filename_with__init__(init_linter): assert len(messages) == 0 -def test_by_module_statement_value(init_linter): +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")) diff --git a/tests/message/conftest.py b/tests/message/conftest.py index 942119076..e30dbb535 100644 --- a/tests/message/conftest.py +++ b/tests/message/conftest.py @@ -3,10 +3,12 @@ # pylint: disable=redefined-outer-name +from typing import Dict, ValuesView + import pytest from pylint.checkers import BaseChecker -from pylint.message import MessageDefinitionStore, MessageIdStore +from pylint.message import MessageDefinition, MessageDefinitionStore, MessageIdStore @pytest.fixture @@ -20,12 +22,12 @@ def symbol(): @pytest.fixture -def empty_store(): +def empty_store() -> MessageDefinitionStore: return MessageDefinitionStore() @pytest.fixture -def store(): +def store() -> MessageDefinitionStore: store_ = MessageDefinitionStore() class Checker(BaseChecker): @@ -50,12 +52,12 @@ def store(): @pytest.fixture -def message_definitions(store): +def message_definitions(store: MessageDefinitionStore) -> ValuesView[MessageDefinition]: return store.messages @pytest.fixture -def msgids(): +def msgids() -> Dict[str, str]: return { "W1234": "warning-symbol", "W1235": "warning-symbol-two", @@ -65,12 +67,12 @@ def msgids(): @pytest.fixture -def empty_msgid_store(): +def empty_msgid_store() -> MessageIdStore: return MessageIdStore() @pytest.fixture -def msgid_store(msgids): +def msgid_store(msgids: Dict[str, str]) -> MessageIdStore: msgid_store = MessageIdStore() for msgid, symbol in msgids.items(): msgid_store.add_msgid_and_symbol(msgid, symbol) diff --git a/tests/message/unittest_message.py b/tests/message/unittest_message.py index 5a02c26a0..6f8b4aa01 100644 --- a/tests/message/unittest_message.py +++ b/tests/message/unittest_message.py @@ -1,11 +1,16 @@ # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html # For details: https://github.com/PyCQA/pylint/blob/main/LICENSE +from typing import Dict, ValuesView + from pylint.message import Message +from pylint.message.message_definition import MessageDefinition -def test_new_message(message_definitions): - def build_message(message_definition, location_value): +def test_new_message(message_definitions: ValuesView[MessageDefinition]) -> None: + def build_message( + message_definition: MessageDefinition, location_value: Dict[str, str] + ) -> Message: return Message( symbol=message_definition.symbol, msg_id=message_definition.msgid, diff --git a/tests/message/unittest_message_definition.py b/tests/message/unittest_message_definition.py index 743499424..2015c2154 100644 --- a/tests/message/unittest_message_definition.py +++ b/tests/message/unittest_message_definition.py @@ -46,7 +46,7 @@ class FalseChecker(BaseChecker): class TestMessagesDefinition: @staticmethod - def assert_with_fail_msg(msg, expected=True): + def assert_with_fail_msg(msg: MessageDefinition, expected: bool = True) -> None: fail_msg = ( f"With minversion='{msg.minversion}' and maxversion='{msg.maxversion}'," f" and the python interpreter being {sys.version_info} " @@ -58,19 +58,19 @@ class TestMessagesDefinition: assert not msg.may_be_emitted(), fail_msg.format(" not ") @staticmethod - def get_message_definition(): - args = [ + def get_message_definition() -> MessageDefinition: + kwargs = {"minversion": None, "maxversion": None} + return MessageDefinition( FalseChecker(), "W1234", "message", "description", "msg-symbol", WarningScope.NODE, - ] - kwargs = {"minversion": None, "maxversion": None} - return MessageDefinition(*args, **kwargs) + **kwargs, + ) - def test_may_be_emitted(self): + def test_may_be_emitted(self) -> None: major = sys.version_info.major minor = sys.version_info.minor msg = self.get_message_definition() @@ -85,7 +85,7 @@ class TestMessagesDefinition: msg.maxversion = (major, minor - 1) self.assert_with_fail_msg(msg, expected=False) - def test_repr(self): + def test_repr(self) -> None: msg = self.get_message_definition() repr_str = str([msg, msg]) assert "W1234" in repr_str @@ -93,7 +93,7 @@ class TestMessagesDefinition: expected = "[MessageDefinition:msg-symbol-one (W1234), MessageDefinition:msg-symbol-two (W1235)]" assert str(FalseChecker().messages) == expected - def test_str(self): + def test_str(self) -> None: msg = self.get_message_definition() str_msg = str(msg) assert "W1234" in str_msg @@ -102,7 +102,7 @@ class TestMessagesDefinition: message one msg description""" assert str(FalseChecker().messages[0]) == expected - def test_format_help(self): + def test_format_help(self) -> None: msg = self.get_message_definition() major = sys.version_info.major minor = sys.version_info.minor diff --git a/tests/message/unittest_message_definition_store.py b/tests/message/unittest_message_definition_store.py index a08ca7c86..4d108489e 100644 --- a/tests/message/unittest_message_definition_store.py +++ b/tests/message/unittest_message_definition_store.py @@ -5,10 +5,12 @@ from contextlib import redirect_stdout from io import StringIO import pytest +from _pytest.capture import CaptureFixture from pylint.checkers import BaseChecker from pylint.exceptions import InvalidMessageError, UnknownMessageError from pylint.message import MessageDefinition +from pylint.message.message_definition_store import MessageDefinitionStore @pytest.mark.parametrize( @@ -126,7 +128,9 @@ def test_register_error(empty_store, messages, expected): assert str(cm.value) == expected -def test_register_error_new_id_duplicate_of_new(empty_store): +def test_register_error_new_id_duplicate_of_new( + empty_store: MessageDefinitionStore, +) -> None: class CheckerOne(BaseChecker): name = "checker_one" msgs = {"W1234": ("message one", "msg-symbol-one", "msg description.")} @@ -143,7 +147,7 @@ def test_register_error_new_id_duplicate_of_new(empty_store): ) -def test_format_help(capsys, store): +def test_format_help(capsys: CaptureFixture, store: MessageDefinitionStore) -> None: store.help_message([]) captured = capsys.readouterr() assert captured.out == "" @@ -165,12 +169,12 @@ No such message id or symbol 'C1234'. ) -def test_get_msg_display_string(store): +def test_get_msg_display_string(store: MessageDefinitionStore) -> None: assert store.get_msg_display_string("W1234") == "'msg-symbol'" assert store.get_msg_display_string("E1234") == "'duplicate-keyword-arg'" -def test_check_message_id(store): +def test_check_message_id(store: MessageDefinitionStore) -> None: w1234 = store.get_message_definitions("W1234")[0] w0001 = store.get_message_definitions("W0001")[0] e1234 = store.get_message_definitions("E1234")[0] @@ -185,10 +189,12 @@ def test_check_message_id(store): class TestMessageDefinitionStore: @staticmethod - def _compare_messages(desc, msg, checkerref=False): + def _compare_messages( + desc: str, msg: MessageDefinition, checkerref: bool = False + ) -> None: assert desc == msg.format_help(checkerref=checkerref) - def test_message_help(self, store): + def test_message_help(self, store: MessageDefinitionStore) -> None: message_definition = store.get_message_definitions("W1234")[0] self._compare_messages( """:msg-symbol (W1234): *message* @@ -203,7 +209,7 @@ class TestMessageDefinitionStore: checkerref=False, ) - def test_message_help_minmax(self, store): + def test_message_help_minmax(self, store: MessageDefinitionStore) -> None: # build the message manually to be python version independent message_definition = store.get_message_definitions("E1234")[0] self._compare_messages( @@ -223,7 +229,7 @@ class TestMessageDefinitionStore: ) -def test_list_messages(store): +def test_list_messages(store: MessageDefinitionStore) -> None: output = StringIO() with redirect_stdout(output): store.list_messages() @@ -231,12 +237,12 @@ def test_list_messages(store): assert ":msg-symbol (W1234): *message*" in output.getvalue() -def test_renamed_message_register(store): +def test_renamed_message_register(store: MessageDefinitionStore) -> None: assert store.get_message_definitions("W0001")[0].symbol == "msg-symbol" assert store.get_message_definitions("old-symbol")[0].symbol == "msg-symbol" -def test_multiple_child_of_old_name(store): +def test_multiple_child_of_old_name(store: MessageDefinitionStore) -> None: """We can define multiple name with the same old name.""" class FamillyChecker(BaseChecker): @@ -263,7 +269,5 @@ def test_multiple_child_of_old_name(store): assert len(mother) == 2 assert len(child) == 1 assert len(other_child) == 1 - child = child[0] - other_child = other_child[0] - assert child in mother - assert other_child in mother + assert child[0] in mother + assert other_child[0] in mother diff --git a/tests/message/unittest_message_id_store.py b/tests/message/unittest_message_id_store.py index e61aba66b..340b23d32 100644 --- a/tests/message/unittest_message_id_store.py +++ b/tests/message/unittest_message_id_store.py @@ -1,12 +1,16 @@ # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html # For details: https://github.com/PyCQA/pylint/blob/main/LICENSE +from typing import Dict, ValuesView + import pytest from pylint.exceptions import InvalidMessageError, UnknownMessageError +from pylint.message.message_definition import MessageDefinition +from pylint.message.message_id_store import MessageIdStore -def test_len_str(msgid_store, msgids): +def test_len_str(msgid_store: MessageIdStore, msgids: Dict[str, str]) -> None: assert len(msgid_store) == len(msgids) str_result = str(msgid_store) assert "MessageIdStore: [" in str_result @@ -17,7 +21,7 @@ def test_len_str(msgid_store, msgids): assert "]" in str_result -def test_get_message_ids(msgid_store, msgids): +def test_get_message_ids(msgid_store: MessageIdStore, msgids: Dict[str, str]) -> None: """We can get message id even with capitalization problem.""" msgid = list(msgids.keys())[0] msgids_result = msgid_store.get_active_msgids(msgid.lower()) @@ -25,14 +29,17 @@ def test_get_message_ids(msgid_store, msgids): assert msgid == msgids_result[0] -def test_get_message_ids_not_existing(empty_msgid_store): +def test_get_message_ids_not_existing(empty_msgid_store: MessageIdStore) -> None: with pytest.raises(UnknownMessageError) as error: w9876 = "W9876" empty_msgid_store.get_active_msgids(w9876) assert w9876 in str(error.value) -def test_register_message_definitions(empty_msgid_store, message_definitions): +def test_register_message_definitions( + empty_msgid_store: MessageIdStore, + message_definitions: ValuesView[MessageDefinition], +) -> None: number_of_msgid = len(message_definitions) for message_definition in message_definitions: empty_msgid_store.register_message_definition( @@ -45,7 +52,7 @@ def test_register_message_definitions(empty_msgid_store, message_definitions): assert len(empty_msgid_store) == number_of_msgid -def test_add_msgid_and_symbol(empty_msgid_store): +def test_add_msgid_and_symbol(empty_msgid_store: MessageIdStore) -> None: empty_msgid_store.add_msgid_and_symbol("E1235", "new-sckiil") empty_msgid_store.add_legacy_msgid_and_symbol("C1235", "old-sckiil", "E1235") assert len(empty_msgid_store) == 2 @@ -65,7 +72,7 @@ def test_add_msgid_and_symbol(empty_msgid_store): empty_msgid_store.get_msgid("not-exist") -def test_duplicate_symbol(empty_msgid_store): +def test_duplicate_symbol(empty_msgid_store: MessageIdStore) -> None: empty_msgid_store.add_msgid_and_symbol("W1234", "warning-symbol") with pytest.raises(InvalidMessageError) as error: empty_msgid_store.check_msgid_and_symbol("W1234", "other-symbol") @@ -75,7 +82,7 @@ def test_duplicate_symbol(empty_msgid_store): ) -def test_duplicate_msgid(msgid_store): +def test_duplicate_msgid(msgid_store: MessageIdStore) -> None: msgid_store.add_msgid_and_symbol("W1234", "warning-symbol") with pytest.raises(InvalidMessageError) as error: msgid_store.check_msgid_and_symbol("W1235", "warning-symbol") diff --git a/tests/pyreverse/conftest.py b/tests/pyreverse/conftest.py index 982980101..3a037840f 100644 --- a/tests/pyreverse/conftest.py +++ b/tests/pyreverse/conftest.py @@ -1,6 +1,7 @@ -from typing import Callable, Optional, Tuple +from typing import Callable, List, Optional, Tuple import pytest +from astroid.nodes.scoped_nodes import Module from pylint.pyreverse.inspector import Project, project_from_files @@ -14,7 +15,7 @@ class PyreverseConfig: # pylint: disable=too-many-instance-attributes, too-many def __init__( self, mode: str = "PUB_ONLY", - classes: Tuple = tuple(), + classes: Optional[List[str]] = None, show_ancestors: Optional[int] = None, all_ancestors: Optional[bool] = None, show_associated: Optional[int] = None, @@ -30,7 +31,10 @@ class PyreverseConfig: # pylint: disable=too-many-instance-attributes, too-many output_directory: str = "", ): self.mode = mode - self.classes = classes + if classes: + self.classes = classes + else: + self.classes = [] self.show_ancestors = show_ancestors self.all_ancestors = all_ancestors self.show_associated = show_associated @@ -86,7 +90,7 @@ def get_project() -> Callable: def _get_project(module: str, name: Optional[str] = "No Name") -> Project: """return an astroid project representation""" - def _astroid_wrapper(func, modname): + def _astroid_wrapper(func: Callable, modname: str) -> Module: return func(modname) return project_from_files([module], _astroid_wrapper, project_name=name) diff --git a/tests/pyreverse/test_diadefs.py b/tests/pyreverse/test_diadefs.py index 497e1eebe..3c2ab7fda 100644 --- a/tests/pyreverse/test_diadefs.py +++ b/tests/pyreverse/test_diadefs.py @@ -22,9 +22,11 @@ # pylint: disable=redefined-outer-name import sys from pathlib import Path +from typing import Callable, Dict, List, Tuple import pytest from astroid import nodes +from conftest import PyreverseConfig # type: ignore #pylint: disable=no-name-in-module from pylint.pyreverse.diadefslib import ( ClassDiadefGenerator, @@ -32,15 +34,18 @@ from pylint.pyreverse.diadefslib import ( DiaDefGenerator, DiadefsHandler, ) -from pylint.pyreverse.inspector import Linker +from pylint.pyreverse.diagrams import DiagramEntity, Relationship +from pylint.pyreverse.inspector import Linker, Project -def _process_classes(classes): +def _process_classes(classes: List[DiagramEntity]) -> List[Tuple[bool, str]]: """extract class names of a list""" return sorted((isinstance(c.node, nodes.ClassDef), c.title) for c in classes) -def _process_relations(relations): +def _process_relations( + relations: Dict[str, List[Relationship]] +) -> List[Tuple[str, str, str]]: """extract relation indices from a relation list""" result = [] for rel_type, rels in relations.items(): @@ -51,7 +56,7 @@ def _process_relations(relations): @pytest.fixture -def HANDLER(default_config): +def HANDLER(default_config: PyreverseConfig) -> DiadefsHandler: return DiadefsHandler(default_config) @@ -60,7 +65,9 @@ def PROJECT(get_project): return get_project("data") -def test_option_values(default_config, HANDLER, PROJECT): +def test_option_values( + default_config: PyreverseConfig, HANDLER: DiadefsHandler, PROJECT: Project +) -> None: """test for ancestor, associated and module options""" df_h = DiaDefGenerator(Linker(PROJECT), HANDLER) cl_config = default_config @@ -91,7 +98,7 @@ def test_option_values(default_config, HANDLER, PROJECT): assert not hndl.module_names -def test_default_values(): +def test_default_values() -> None: """test default values for package or class diagrams""" # TODO : should test difference between default values for package or class diagrams pylint: disable=fixme @@ -105,14 +112,18 @@ class TestDefaultDiadefGenerator: ("specialization", "Specialization", "Ancestor"), ] - def test_exctract_relations(self, HANDLER, PROJECT): + def test_exctract_relations( + self, HANDLER: DiadefsHandler, PROJECT: Project + ) -> None: """test extract_relations between classes""" cd = DefaultDiadefGenerator(Linker(PROJECT), HANDLER).visit(PROJECT)[1] cd.extract_relationships() relations = _process_relations(cd.relationships) assert relations == self._should_rels - def test_functional_relation_extraction(self, default_config, get_project): + def test_functional_relation_extraction( + self, default_config: PyreverseConfig, get_project: Callable + ) -> None: """functional test of relations extraction; different classes possibly in different modules""" # XXX should be catching pyreverse environnement problem but doesn't @@ -125,7 +136,7 @@ class TestDefaultDiadefGenerator: assert relations == self._should_rels -def test_known_values1(HANDLER, PROJECT): +def test_known_values1(HANDLER: DiadefsHandler, PROJECT: Project) -> None: dd = DefaultDiadefGenerator(Linker(PROJECT), HANDLER).visit(PROJECT) assert len(dd) == 2 keys = [d.TYPE for d in dd] @@ -152,7 +163,7 @@ def test_known_values1(HANDLER, PROJECT): ] -def test_known_values2(HANDLER, get_project): +def test_known_values2(HANDLER: DiadefsHandler, get_project: Callable) -> None: project = get_project("data.clientmodule_test") dd = DefaultDiadefGenerator(Linker(project), HANDLER).visit(project) assert len(dd) == 1 @@ -164,7 +175,7 @@ def test_known_values2(HANDLER, get_project): assert classes == [(True, "Ancestor"), (True, "Specialization")] -def test_known_values3(HANDLER, PROJECT): +def test_known_values3(HANDLER: DiadefsHandler, PROJECT: Project) -> None: HANDLER.config.classes = ["Specialization"] cdg = ClassDiadefGenerator(Linker(PROJECT), HANDLER) special = "data.clientmodule_test.Specialization" @@ -179,7 +190,7 @@ def test_known_values3(HANDLER, PROJECT): ] -def test_known_values4(HANDLER, PROJECT): +def test_known_values4(HANDLER: DiadefsHandler, PROJECT: Project) -> None: HANDLER.config.classes = ["Specialization"] HANDLER.config.module_names = False cd = ClassDiadefGenerator(Linker(PROJECT), HANDLER).class_diagram( @@ -196,7 +207,9 @@ def test_known_values4(HANDLER, PROJECT): @pytest.mark.skipif(sys.version_info < (3, 8), reason="Requires dataclasses") -def test_regression_dataclasses_inference(HANDLER, get_project): +def test_regression_dataclasses_inference( + HANDLER: DiadefsHandler, get_project: Callable +) -> None: project_path = Path("regrtest_data") / "dataclasses_pyreverse" path = get_project(str(project_path)) diff --git a/tests/pyreverse/test_inspector.py b/tests/pyreverse/test_inspector.py index 0c8873f97..014838564 100644 --- a/tests/pyreverse/test_inspector.py +++ b/tests/pyreverse/test_inspector.py @@ -17,23 +17,25 @@ # pylint: disable=redefined-outer-name import os +from typing import Callable import astroid import pytest from astroid import nodes from pylint.pyreverse import inspector +from pylint.pyreverse.inspector import Project @pytest.fixture -def project(get_project): +def project(get_project: Callable) -> Project: project = get_project("data", "data") linker = inspector.Linker(project) linker.visit(project) return project -def test_class_implements(project): +def test_class_implements(project: Project) -> None: klass = project.get_module("data.clientmodule_test")["Ancestor"] assert hasattr(klass, "implements") assert len(klass.implements) == 1 @@ -41,13 +43,13 @@ def test_class_implements(project): assert klass.implements[0].name == "Interface" -def test_class_implements_specialization(project): +def test_class_implements_specialization(project: Project) -> None: klass = project.get_module("data.clientmodule_test")["Specialization"] assert hasattr(klass, "implements") assert len(klass.implements) == 0 -def test_locals_assignment_resolution(project): +def test_locals_assignment_resolution(project: Project) -> None: klass = project.get_module("data.clientmodule_test")["Specialization"] assert hasattr(klass, "locals_type") type_dict = klass.locals_type @@ -60,7 +62,7 @@ def test_locals_assignment_resolution(project): assert type_dict["top"][0].value == "class" -def test_instance_attrs_resolution(project): +def test_instance_attrs_resolution(project: Project) -> None: klass = project.get_module("data.clientmodule_test")["Specialization"] assert hasattr(klass, "instance_attrs_type") type_dict = klass.instance_attrs_type @@ -74,7 +76,7 @@ def test_instance_attrs_resolution(project): assert type_dict["_id"][0] is astroid.Uninferable -def test_concat_interfaces(): +def test_concat_interfaces() -> None: cls = astroid.extract_node( ''' class IMachin: pass @@ -96,7 +98,7 @@ def test_concat_interfaces(): assert [i.name for i in interfaces] == ["IMachin"] -def test_interfaces(): +def test_interfaces() -> None: module = astroid.parse( """ class Interface(object): pass @@ -122,12 +124,12 @@ def test_interfaces(): assert [i.name for i in inspector.interfaces(klass)] == interfaces -def test_from_directory(project): +def test_from_directory(project: Project) -> None: expected = os.path.join("tests", "data", "__init__.py") assert project.name == "data" assert project.path.endswith(expected) -def test_project_node(project): +def test_project_node(project: Project) -> None: expected = ["data", "data.clientmodule_test", "data.suppliermodule_test"] assert sorted(project.keys()) == expected diff --git a/tests/pyreverse/test_printer.py b/tests/pyreverse/test_printer.py index 77d12f630..b5606e37b 100644 --- a/tests/pyreverse/test_printer.py +++ b/tests/pyreverse/test_printer.py @@ -47,6 +47,6 @@ def test_unsupported_layout(layout: Layout, printer_class: Type[Printer]): class TestPlantUmlPrinter: printer = PlantUmlPrinter(title="unittest", layout=Layout.TOP_TO_BOTTOM) - def test_node_without_properties(self): + def test_node_without_properties(self) -> None: self.printer.emit_node(name="test", type_=NodeType.CLASS) assert self.printer.lines[-2:] == ['class "test" as test {\n', "}\n"] diff --git a/tests/pyreverse/test_utils.py b/tests/pyreverse/test_utils.py index 1d231eafa..5abd0126c 100644 --- a/tests/pyreverse/test_utils.py +++ b/tests/pyreverse/test_utils.py @@ -9,6 +9,7 @@ """Tests for pylint.pyreverse.utils""" +from typing import Any from unittest.mock import patch import astroid @@ -80,8 +81,8 @@ def test_get_annotation_assignattr(init_method, label): @patch("pylint.pyreverse.utils.get_annotation") -@patch("astroid.nodes.NodeNG.infer", side_effect=astroid.InferenceError) -def test_infer_node_1(mock_infer, mock_get_annotation): +@patch("astroid.node_classes.NodeNG.infer", side_effect=astroid.InferenceError) +def test_infer_node_1(mock_infer: Any, mock_get_annotation: Any) -> None: """Return set() when astroid.InferenceError is raised and an annotation has not been returned """ @@ -93,8 +94,8 @@ def test_infer_node_1(mock_infer, mock_get_annotation): @patch("pylint.pyreverse.utils.get_annotation") -@patch("astroid.nodes.NodeNG.infer") -def test_infer_node_2(mock_infer, mock_get_annotation): +@patch("astroid.node_classes.NodeNG.infer") +def test_infer_node_2(mock_infer: Any, mock_get_annotation: Any) -> None: """Return set(node.infer()) when InferenceError is not raised and an annotation has not been returned """ @@ -105,7 +106,7 @@ def test_infer_node_2(mock_infer, mock_get_annotation): assert mock_infer.called -def test_infer_node_3(): +def test_infer_node_3() -> None: """Return a set containing a nodes.ClassDef object when the attribute has a type annotation""" node = astroid.extract_node( @@ -123,7 +124,7 @@ def test_infer_node_3(): assert isinstance(infer_node(instance_attr).pop(), nodes.ClassDef) -def test_infer_node_4(): +def test_infer_node_4() -> None: """Verify the label for an argument with a typehint of the type nodes.Subscript """ diff --git a/tests/pyreverse/test_writer.py b/tests/pyreverse/test_writer.py index 66a150bbc..28ed16046 100644 --- a/tests/pyreverse/test_writer.py +++ b/tests/pyreverse/test_writer.py @@ -24,12 +24,14 @@ Unit test for ``DiagramWriter`` import codecs import os from difflib import unified_diff +from typing import Callable, Iterator, List from unittest.mock import Mock import pytest +from conftest import PyreverseConfig # type: ignore from pylint.pyreverse.diadefslib import DefaultDiadefGenerator, DiadefsHandler -from pylint.pyreverse.inspector import Linker +from pylint.pyreverse.inspector import Linker, Project from pylint.pyreverse.writer import DiagramWriter _DEFAULTS = { @@ -57,7 +59,7 @@ class Config: setattr(self, attr, value) -def _file_lines(path): +def _file_lines(path: str) -> List[str]: # we don't care about the actual encoding, but python3 forces us to pick one with codecs.open(path, encoding="latin1") as stream: lines = [ @@ -79,14 +81,16 @@ COLORIZED_PUML_FILES = ["packages_colorized.puml", "classes_colorized.puml"] @pytest.fixture() -def setup_dot(default_config, get_project): +def setup_dot(default_config: PyreverseConfig, get_project: Callable) -> Iterator: writer = DiagramWriter(default_config) project = get_project(os.path.join(os.path.dirname(__file__), "..", "data")) yield from _setup(project, default_config, writer) @pytest.fixture() -def setup_colorized_dot(colorized_dot_config, get_project): +def setup_colorized_dot( + colorized_dot_config: PyreverseConfig, get_project: Callable +) -> Iterator: writer = DiagramWriter(colorized_dot_config) project = get_project( os.path.join(os.path.dirname(__file__), "..", "data"), name="colorized" @@ -95,21 +99,23 @@ def setup_colorized_dot(colorized_dot_config, get_project): @pytest.fixture() -def setup_vcg(vcg_config, get_project): +def setup_vcg(vcg_config: PyreverseConfig, get_project: Callable) -> Iterator: writer = DiagramWriter(vcg_config) project = get_project(os.path.join(os.path.dirname(__file__), "..", "data")) yield from _setup(project, vcg_config, writer) @pytest.fixture() -def setup_puml(puml_config, get_project): +def setup_puml(puml_config: PyreverseConfig, get_project: Callable) -> Iterator: writer = DiagramWriter(puml_config) project = get_project(os.path.join(os.path.dirname(__file__), "..", "data")) yield from _setup(project, puml_config, writer) @pytest.fixture() -def setup_colorized_puml(colorized_puml_config, get_project): +def setup_colorized_puml( + colorized_puml_config: PyreverseConfig, get_project: Callable +) -> Iterator: writer = DiagramWriter(colorized_puml_config) project = get_project( os.path.join(os.path.dirname(__file__), "..", "data"), name="colorized" @@ -117,7 +123,9 @@ def setup_colorized_puml(colorized_puml_config, get_project): yield from _setup(project, colorized_puml_config, writer) -def _setup(project, config, writer): +def _setup( + project: Project, config: PyreverseConfig, writer: DiagramWriter +) -> Iterator: linker = Linker(project) handler = DiadefsHandler(config) dd = DefaultDiadefGenerator(linker, handler).visit(project) @@ -136,48 +144,51 @@ def _setup(project, config, writer): @pytest.mark.usefixtures("setup_dot") @pytest.mark.parametrize("generated_file", DOT_FILES) -def test_dot_files(generated_file): +def test_dot_files(generated_file: str) -> None: _assert_files_are_equal(generated_file) @pytest.mark.usefixtures("setup_colorized_dot") @pytest.mark.parametrize("generated_file", COLORIZED_DOT_FILES) -def test_colorized_dot_files(generated_file): +def test_colorized_dot_files(generated_file: str) -> None: _assert_files_are_equal(generated_file) @pytest.mark.usefixtures("setup_vcg") @pytest.mark.parametrize("generated_file", VCG_FILES) -def test_vcg_files(generated_file): +def test_vcg_files(generated_file: str) -> None: _assert_files_are_equal(generated_file) @pytest.mark.usefixtures("setup_puml") @pytest.mark.parametrize("generated_file", PUML_FILES) -def test_puml_files(generated_file): +def test_puml_files(generated_file: str) -> None: _assert_files_are_equal(generated_file) @pytest.mark.usefixtures("setup_colorized_puml") @pytest.mark.parametrize("generated_file", COLORIZED_PUML_FILES) -def test_colorized_puml_files(generated_file): +def test_colorized_puml_files(generated_file: str) -> None: _assert_files_are_equal(generated_file) -def _assert_files_are_equal(generated_file): +def _assert_files_are_equal(generated_file: str) -> None: expected_file = os.path.join(os.path.dirname(__file__), "data", generated_file) generated = _file_lines(generated_file) expected = _file_lines(expected_file) - generated = "\n".join(generated) - expected = "\n".join(expected) + joined_generated = "\n".join(generated) + joined_expected = "\n".join(expected) files = f"\n *** expected : {expected_file}, generated : {generated_file} \n" diff = "\n".join( - line for line in unified_diff(expected.splitlines(), generated.splitlines()) + line + for line in unified_diff( + joined_expected.splitlines(), joined_generated.splitlines() + ) ) - assert expected == generated, f"{files}{diff}" + assert joined_expected == joined_generated, f"{files}{diff}" -def test_color_for_stdlib_module(default_config): +def test_color_for_stdlib_module(default_config: PyreverseConfig) -> None: writer = DiagramWriter(default_config) obj = Mock() obj.node = Mock() diff --git a/tests/regrtest_data/dummy_plugin/dummy_plugin.py b/tests/regrtest_data/dummy_plugin/dummy_plugin.py index 95b0b9305..dd0554f7e 100644 --- a/tests/regrtest_data/dummy_plugin/dummy_plugin.py +++ b/tests/regrtest_data/dummy_plugin/dummy_plugin.py @@ -1,4 +1,5 @@ from pylint.checkers import BaseChecker +from pylint.lint.pylinter import PyLinter class DummyPlugin1(BaseChecker): @@ -25,6 +26,6 @@ class DummyPlugin2(BaseChecker): ) -def register(linter): +def register(linter: PyLinter) -> None: linter.register_checker(DummyPlugin1(linter)) linter.register_checker(DummyPlugin2(linter)) diff --git a/tests/test_check_parallel.py b/tests/test_check_parallel.py index 6e94ed74c..f87f81845 100644 --- a/tests/test_check_parallel.py +++ b/tests/test_check_parallel.py @@ -11,8 +11,10 @@ import collections import os +from typing import List, Tuple import pytest +from astroid.nodes.scoped_nodes import Module import pylint.interfaces import pylint.lint.parallel @@ -24,7 +26,7 @@ from pylint.lint.parallel import check_parallel from pylint.testutils import GenericTestReporter as Reporter -def _gen_file_data(idx=0): +def _gen_file_data(idx: int = 0) -> Tuple[str, str, str]: """Generates a file to use as a stream""" filepath = os.path.abspath( os.path.join(os.path.dirname(__file__), "input", "similar1") @@ -37,7 +39,7 @@ def _gen_file_data(idx=0): return file_data -def _gen_file_datas(count=1): +def _gen_file_datas(count: int = 1) -> List[Tuple[str, str, str]]: return [_gen_file_data(idx) for idx in range(count)] @@ -56,12 +58,12 @@ class SequentialTestChecker(BaseChecker): ) } - def __init__(self, linter, *args, **kwargs): - super().__init__(linter, *args, **kwargs) - self.data = [] + def __init__(self, linter: PyLinter) -> None: + super().__init__(linter) + self.data: List[str] = [] self.linter = linter - def process_module(self, _astroid): + def process_module(self, _astroid: Module) -> None: """Called once per stream/file/astroid object""" # record the number of invocations with the data object record = self.test_data + str(len(self.data)) @@ -95,25 +97,25 @@ class ParallelTestChecker(BaseChecker): ) } - def __init__(self, linter, *args, **kwargs): - super().__init__(linter, *args, **kwargs) - self.data = [] + def __init__(self, linter: PyLinter) -> None: + super().__init__(linter) + self.data: List[str] = [] self.linter = linter self.stats = None - def open(self): + def open(self) -> None: """init the checkers: reset statistics information""" self.stats = self.linter.add_stats() self.data = [] - def close(self): + def close(self) -> None: for _ in self.data[1::2]: # Work on pairs of files, see class docstring. self.add_message("R9999", args=("From process_module, two files seen.",)) def get_map_data(self): return self.data - def reduce_map_data(self, linter, data): + def reduce_map_data(self, linter: PyLinter, data: List[List[str]]) -> None: recombined = type(self)(linter) recombined.open() aggregated = [] @@ -123,7 +125,7 @@ class ParallelTestChecker(BaseChecker): self.add_message("R9999", args=("From reduce_map_data",)) recombined.close() - def process_module(self, _astroid): + def process_module(self, _astroid: Module) -> None: """Called once per stream/file/astroid object""" # record the number of invocations with the data object record = self.test_data + str(len(self.data)) @@ -167,19 +169,19 @@ class TestCheckParallelFramework: def teardown_class(self): pylint.lint.parallel._worker_linter = self._prev_global_linter - def test_worker_initialize(self): + def test_worker_initialize(self) -> None: linter = PyLinter(reporter=Reporter()) worker_initialize(linter=linter) assert pylint.lint.parallel._worker_linter == linter - def test_worker_check_single_file_uninitialised(self): + 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'" ): worker_check_single_file(_gen_file_data()) - def test_worker_check_single_file_no_checkers(self): + def test_worker_check_single_file_no_checkers(self) -> None: linter = PyLinter(reporter=Reporter()) worker_initialize(linter=linter) @@ -219,7 +221,7 @@ class TestCheckParallelFramework: "warning": 0, } == stats - def test_worker_check_sequential_checker(self): + def test_worker_check_sequential_checker(self) -> None: """Same as test_worker_check_single_file_no_checkers with SequentialTestChecker""" linter = PyLinter(reporter=Reporter()) worker_initialize(linter=linter) @@ -269,7 +271,7 @@ class TestCheckParallelFramework: class TestCheckParallel: """Tests the check_parallel() function""" - def test_sequential_checkers_work(self): + def test_sequential_checkers_work(self) -> None: """Tests original basic types of checker works as expected in -jN This means that a sequential checker should return the same data for a given @@ -340,7 +342,7 @@ class TestCheckParallel: "warning": 0, } == linter.stats - def test_invoke_single_job(self): + def test_invoke_single_job(self) -> None: """Tests basic checkers functionality using just a single workderdo This is *not* the same -j1 and does not happen under normal operation""" diff --git a/tests/test_config.py b/tests/test_config.py index 1c33ef039..7a4b09639 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,14 +1,16 @@ # pylint: disable=missing-module-docstring, missing-function-docstring, protected-access import os import unittest.mock +from pathlib import PosixPath import pytest import pylint.lint from pylint.config import OptionsManagerMixIn +from pylint.lint.run import Run -def check_configuration_file_reader(config_file): +def check_configuration_file_reader(config_file: PosixPath) -> Run: """Initialize pylint with the given configuration file and check that what we initialized the linter with what was expected. """ @@ -34,7 +36,7 @@ def check_configuration_file_reader(config_file): return runner -def test_can_read_ini(tmp_path): +def test_can_read_ini(tmp_path: PosixPath) -> None: # Check that we can read the "regular" INI .pylintrc file config_file = tmp_path / ".pylintrc" config_file.write_text( @@ -48,7 +50,7 @@ reports = yes check_configuration_file_reader(config_file) -def test_can_read_setup_cfg(tmp_path): +def test_can_read_setup_cfg(tmp_path: PosixPath) -> None: # Check that we can read a setup.cfg (which is an INI file where # section names are prefixed with "pylint." config_file = tmp_path / "setup.cfg" @@ -63,7 +65,7 @@ reports = yes check_configuration_file_reader(config_file) -def test_can_read_toml(tmp_path): +def test_can_read_toml(tmp_path: PosixPath) -> None: # Check that we can read a TOML file where lists and integers are # expressed as strings. config_file = tmp_path / "pyproject.toml" @@ -78,7 +80,7 @@ reports = "yes" check_configuration_file_reader(config_file) -def test_can_read_toml_rich_types(tmp_path): +def test_can_read_toml_rich_types(tmp_path: PosixPath) -> None: # Check that we can read a TOML file where lists, integers and # booleans are expressed as such (and not as strings), using TOML # type system. @@ -97,7 +99,7 @@ reports = true check_configuration_file_reader(config_file) -def test_can_read_env_variable(tmp_path): +def test_can_read_env_variable(tmp_path: PosixPath) -> None: # Check that we can read the "regular" INI .pylintrc file # if it has an environment variable. config_file = tmp_path / "pyproject.toml" @@ -113,7 +115,7 @@ reports = "yes" options_manager_mix_in = OptionsManagerMixIn("", "${tmp_path_env}") options_manager_mix_in.read_config_file("${tmp_path_env}") - def test_read_config_file(): + def test_read_config_file() -> None: with pytest.raises(OSError): options_manager_mix_in.read_config_file("${tmp_path_en}") diff --git a/tests/test_epylint.py b/tests/test_epylint.py index 796b1ca87..4f2d2aad0 100644 --- a/tests/test_epylint.py +++ b/tests/test_epylint.py @@ -1,12 +1,14 @@ """Test for issue https://github.com/PyCQA/pylint/issues/4286""" # pylint: disable=redefined-outer-name +from pathlib import PosixPath + import pytest from pylint import epylint as lint @pytest.fixture() -def example_path(tmp_path): +def example_path(tmp_path: PosixPath) -> PosixPath: content = """class IvrAudioApp: def run(self): @@ -18,7 +20,7 @@ def example_path(tmp_path): return path -def test_epylint_good_command(example_path): +def test_epylint_good_command(example_path: PosixPath) -> None: out, err = lint.py_run( # pylint: disable-next=consider-using-f-string "%s -E --disable=E1111 --msg-template '{category} {module} {obj} {line} {column} {msg}'" @@ -36,7 +38,7 @@ def test_epylint_good_command(example_path): assert err.read() == "" -def test_epylint_strange_command(example_path): +def test_epylint_strange_command(example_path: PosixPath) -> None: out, err = lint.py_run( # pylint: disable-next=consider-using-f-string "%s -E --disable=E1111 --msg-template={category} {module} {obj} {line} {column} {msg}" diff --git a/tests/test_func.py b/tests/test_func.py index b57dc7d18..98bdf184a 100644 --- a/tests/test_func.py +++ b/tests/test_func.py @@ -23,6 +23,7 @@ import re import sys from os.path import abspath, dirname, join +from typing import List, Optional, Tuple import pytest @@ -36,22 +37,24 @@ FILTER_RGX = None INFO_TEST_RGX = re.compile(r"^func_i\d\d\d\d$") -def exception_str(self, ex): # pylint: disable=unused-argument - """function used to replace default __str__ method of exception instances""" +def exception_str(self, ex) -> str: # pylint: disable=unused-argument + """function used to replace default __str__ method of exception instances + This function is not typed because it is legacy code""" return f"in {ex.file}\n:: {', '.join(ex.args)}" class LintTestUsingModule: - INPUT_DIR = None + INPUT_DIR: Optional[str] = None DEFAULT_PACKAGE = "input" package = DEFAULT_PACKAGE linter = linter - module = None - depends = None - output = None + module: Optional[str] = None + depends: Optional[List[Tuple[str, str]]] = None + output: Optional[str] = None - def _test_functionality(self): - tocheck = [self.package + "." + self.module] + def _test_functionality(self) -> None: + if self.module: + tocheck = [self.package + "." + self.module] # pylint: disable=not-an-iterable; can't handle boolean checks for now if self.depends: tocheck += [ @@ -59,7 +62,7 @@ class LintTestUsingModule: ] self._test(tocheck) - def _check_result(self, got): + def _check_result(self, got: str) -> None: error_msg = ( f"Wrong output for '{self.output}':\n" "You can update the expected output automatically with: '" @@ -67,26 +70,27 @@ class LintTestUsingModule: ) assert self._get_expected() == got, error_msg - def _test(self, tocheck): - if INFO_TEST_RGX.match(self.module): + def _test(self, tocheck: List[str]) -> None: + if self.module and INFO_TEST_RGX.match(self.module): self.linter.enable("I") else: self.linter.disable("I") try: self.linter.check(tocheck) except Exception as ex: - # need finalization to restore a correct state - self.linter.reporter.finalize() - ex.file = tocheck + print(f"Exception: {ex} in {tocheck}:: {'‚ '.join(ex.args)}") + ex.file = tocheck # type: ignore # This is legacy code we're trying to remove, not worth it to type correctly print(ex) - ex.__str__ = exception_str + ex.__str__ = exception_str # type: ignore # This is legacy code we're trying to remove, impossible to type correctly raise self._check_result(self.linter.reporter.finalize()) - def _has_output(self): - return not self.module.startswith("func_noerror_") + def _has_output(self) -> bool: + return isinstance(self.module, str) and not self.module.startswith( + "func_noerror_" + ) - def _get_expected(self): + def _get_expected(self) -> str: if self._has_output() and self.output: with open(self.output, encoding="utf-8") as fobj: return fobj.read().strip() + "\n" @@ -150,7 +154,9 @@ def test_functionality(module_file, messages_file, dependencies, recwarn): assert "invalid escape sequence" in str(warning.message) -def __test_functionality(module_file, messages_file, dependencies): +def __test_functionality( + module_file: str, messages_file: str, dependencies: List[Tuple[str, str]] +) -> None: lint_test = LintTestUpdate() if UPDATE_FILE.exists() else LintTestUsingModule() lint_test.module = module_file.replace(".py", "") lint_test.output = messages_file diff --git a/tests/test_functional.py b/tests/test_functional.py index 5924af270..513823a05 100644 --- a/tests/test_functional.py +++ b/tests/test_functional.py @@ -25,11 +25,15 @@ import csv import os import sys +from typing import Union import pytest +from _pytest.config import Config +from _pytest.recwarn import WarningsRecorder from pylint import testutils from pylint.testutils import UPDATE_FILE, UPDATE_OPTION +from pylint.testutils.functional_test_file import FunctionalTestFile from pylint.utils import HAS_ISORT_5 # Notes: @@ -96,10 +100,14 @@ TEST_WITH_EXPECTED_DEPRECATION = [ @pytest.mark.parametrize("test_file", TESTS, ids=TESTS_NAMES) -def test_functional(test_file, recwarn, pytestconfig): +def test_functional( + test_file: FunctionalTestFile, recwarn: WarningsRecorder, pytestconfig: Config +) -> None: __tracebackhide__ = True # pylint: disable=unused-variable if UPDATE_FILE.exists(): - lint_test = LintModuleOutputUpdate(test_file, pytestconfig) + lint_test: Union[ + LintModuleOutputUpdate, testutils.LintModuleTest + ] = LintModuleOutputUpdate(test_file, pytestconfig) else: lint_test = testutils.LintModuleTest(test_file, pytestconfig) lint_test.setUp() diff --git a/tests/test_import_graph.py b/tests/test_import_graph.py index b2061c006..802970718 100644 --- a/tests/test_import_graph.py +++ b/tests/test_import_graph.py @@ -21,8 +21,10 @@ import os import shutil from os.path import exists +from typing import Iterator, Union import pytest +from _pytest.fixtures import SubRequest from pylint import testutils from pylint.checkers import imports, initialize @@ -30,7 +32,7 @@ from pylint.lint import PyLinter @pytest.fixture -def dest(request): +def dest(request: SubRequest) -> Iterator[Union[Iterator, Iterator[str]]]: dest = request.param yield dest try: @@ -44,7 +46,7 @@ POSSIBLE_DOT_FILENAMES = ["foo.dot", "foo.gv", "tests/regrtest_data/foo.dot"] @pytest.mark.parametrize("dest", POSSIBLE_DOT_FILENAMES, indirect=True) -def test_dependencies_graph(dest): +def test_dependencies_graph(dest: str) -> None: """DOC files are correctly generated, and the graphname is the basename""" imports._dependencies_graph(dest, {"labas": ["hoho", "yep"], "hoho": ["yep"]}) with open(dest, encoding="utf-8") as stream: @@ -70,21 +72,21 @@ URL="." node[shape="box"] @pytest.mark.skipif( any(shutil.which(x) for x in ("dot", "gv")), reason="dot or gv is installed" ) -def test_missing_graphviz(filename): +def test_missing_graphviz(filename: str) -> None: """Raises if graphviz is not installed, and defaults to png if no extension given""" with pytest.raises(RuntimeError, match=r"Cannot generate `graph\.png`.*"): imports._dependencies_graph(filename, {"a": ["b", "c"], "b": ["c"]}) @pytest.fixture -def linter(): +def linter() -> PyLinter: pylinter = PyLinter(reporter=testutils.GenericTestReporter()) initialize(pylinter) return pylinter @pytest.fixture -def remove_files(): +def remove_files() -> Iterator: yield for fname in ("import.dot", "ext_import.dot", "int_import.dot"): try: @@ -94,7 +96,7 @@ def remove_files(): @pytest.mark.usefixtures("remove_files") -def test_checker_dep_graphs(linter): +def test_checker_dep_graphs(linter: PyLinter) -> None: linter.global_set_option("persistent", False) linter.global_set_option("reports", True) linter.global_set_option("enable", "imports") diff --git a/tests/test_pragma_parser.py b/tests/test_pragma_parser.py index 0dec8ac88..473f2048b 100644 --- a/tests/test_pragma_parser.py +++ b/tests/test_pragma_parser.py @@ -8,41 +8,46 @@ from pylint.utils.pragma_parser import ( ) -def test_simple_pragma(): +def test_simple_pragma() -> None: comment = "#pylint: disable = missing-docstring" match = OPTION_PO.search(comment) + assert match for pragma_repr in parse_pragma(match.group(2)): assert pragma_repr.action == "disable" assert pragma_repr.messages == ["missing-docstring"] -def test_disable_checker_with_number_in_name(): +def test_disable_checker_with_number_in_name() -> None: comment = "#pylint: disable = j3-custom-checker" match = OPTION_PO.search(comment) + assert match for pragma_repr in parse_pragma(match.group(2)): assert pragma_repr.action == "disable" assert pragma_repr.messages == ["j3-custom-checker"] -def test_simple_pragma_no_messages(): +def test_simple_pragma_no_messages() -> None: comment = "#pylint: skip-file" match = OPTION_PO.search(comment) + assert match for pragma_repr in parse_pragma(match.group(2)): assert pragma_repr.action == "skip-file" assert pragma_repr.messages == [] -def test_simple_pragma_multiple_messages(): +def test_simple_pragma_multiple_messages() -> None: comment = "#pylint: disable = missing-docstring, invalid-name" match = OPTION_PO.search(comment) + assert match for pragma_repr in parse_pragma(match.group(2)): assert pragma_repr.action == "disable" assert pragma_repr.messages == ["missing-docstring", "invalid-name"] -def test_multiple_pragma_multiple_messages(): +def test_multiple_pragma_multiple_messages() -> None: comment = "#pylint: disable = missing-docstring, invalid-name, enable = R0202, no-self-use" match = OPTION_PO.search(comment) + assert match res = list(parse_pragma(match.group(2))) assert res[0].action == "disable" assert res[0].messages == ["missing-docstring", "invalid-name"] @@ -50,51 +55,58 @@ def test_multiple_pragma_multiple_messages(): assert res[1].messages == ["R0202", "no-self-use"] -def test_missing_assignment(): +def test_missing_assignment() -> None: comment = "#pylint: disable missing-docstring" match = OPTION_PO.search(comment) + assert match with pytest.raises(InvalidPragmaError): list(parse_pragma(match.group(2))) -def test_missing_keyword(): +def test_missing_keyword() -> None: comment = "#pylint: = missing-docstring" match = OPTION_PO.search(comment) + assert match with pytest.raises(InvalidPragmaError): list(parse_pragma(match.group(2))) -def test_unsupported_assignment(): +def test_unsupported_assignment() -> None: comment = "#pylint: disable-all = missing-docstring" match = OPTION_PO.search(comment) + assert match with pytest.raises(UnRecognizedOptionError): list(parse_pragma(match.group(2))) -def test_unknown_keyword_with_messages(): +def test_unknown_keyword_with_messages() -> None: comment = "#pylint: unknown-keyword = missing-docstring" match = OPTION_PO.search(comment) + assert match with pytest.raises(UnRecognizedOptionError): list(parse_pragma(match.group(2))) -def test_unknown_keyword_without_messages(): +def test_unknown_keyword_without_messages() -> None: comment = "#pylint: unknown-keyword" match = OPTION_PO.search(comment) + assert match with pytest.raises(UnRecognizedOptionError): list(parse_pragma(match.group(2))) -def test_missing_message(): +def test_missing_message() -> None: comment = "#pylint: disable = " match = OPTION_PO.search(comment) + assert match with pytest.raises(InvalidPragmaError): list(parse_pragma(match.group(2))) -def test_parse_message_with_dash(): +def test_parse_message_with_dash() -> None: comment = "#pylint: disable = raw_input-builtin" match = OPTION_PO.search(comment) + assert match res = list(parse_pragma(match.group(2))) assert res[0].action == "disable" assert res[0].messages == ["raw_input-builtin"] diff --git a/tests/test_pylint_runners.py b/tests/test_pylint_runners.py index d3d84fb79..84ac05c31 100644 --- a/tests/test_pylint_runners.py +++ b/tests/test_pylint_runners.py @@ -1,9 +1,11 @@ # pylint: disable=missing-module-docstring, missing-function-docstring import os import sys +from typing import Callable from unittest.mock import patch import pytest +from py._path.local import LocalPath # type: ignore from pylint import run_epylint, run_pylint, run_pyreverse, run_symilar @@ -11,7 +13,7 @@ from pylint import run_epylint, run_pylint, run_pyreverse, run_symilar @pytest.mark.parametrize( "runner", [run_epylint, run_pylint, run_pyreverse, run_symilar] ) -def test_runner(runner, tmpdir): +def test_runner(runner: Callable, tmpdir: LocalPath) -> None: filepath = os.path.abspath(__file__) testargs = ["", filepath] with tmpdir.as_cwd(): diff --git a/tests/test_regr.py b/tests/test_regr.py index 22d5bdfb2..793a19612 100644 --- a/tests/test_regr.py +++ b/tests/test_regr.py @@ -23,11 +23,13 @@ to be incorporated in the automatic functional test framework import os import sys from os.path import abspath, dirname, join +from typing import Iterator import astroid import pytest from pylint import testutils +from pylint.lint.pylinter import PyLinter REGR_DATA = join(dirname(abspath(__file__)), "regrtest_data") sys.path.insert(1, REGR_DATA) @@ -44,7 +46,7 @@ def disable(): @pytest.fixture -def finalize_linter(linter): +def finalize_linter(linter: PyLinter) -> Iterator[PyLinter]: """call reporter.finalize() to cleanup pending messages if a test finished badly """ @@ -91,13 +93,13 @@ def test_crash(finalize_linter, file_name): @pytest.mark.parametrize( "fname", [x for x in os.listdir(REGR_DATA) if x.endswith("_crash.py")] ) -def test_descriptor_crash(fname, finalize_linter): +def test_descriptor_crash(fname: str, finalize_linter: PyLinter) -> None: finalize_linter.check(join(REGR_DATA, fname)) finalize_linter.reporter.finalize().strip() @pytest.fixture -def modify_path(): +def modify_path() -> Iterator: cwd = os.getcwd() sys.path.insert(0, "") yield @@ -106,7 +108,7 @@ def modify_path(): @pytest.mark.usefixtures("modify_path") -def test_check_package___init__(finalize_linter): +def test_check_package___init__(finalize_linter: PyLinter) -> None: filename = "package.__init__" finalize_linter.check(filename) checked = list(finalize_linter.stats["by_module"].keys()) @@ -118,7 +120,7 @@ def test_check_package___init__(finalize_linter): assert checked == ["__init__"] -def test_pylint_config_attr(): +def test_pylint_config_attr() -> None: mod = astroid.MANAGER.ast_from_module_name("pylint.lint.pylinter") pylinter = mod["PyLinter"] expect = [ diff --git a/tests/test_self.py b/tests/test_self.py index 2bf635176..9c0444150 100644 --- a/tests/test_self.py +++ b/tests/test_self.py @@ -51,18 +51,22 @@ from copy import copy from io import StringIO from os.path import abspath, dirname, join from pathlib import Path -from typing import Generator, Optional +from typing import Any, Generator, Iterator, List, Optional, Union from unittest import mock from unittest.mock import patch import pytest +from _pytest.capture import EncodedFile +from py._path.local import LocalPath # type: ignore from pylint import modify_sys_path from pylint.constants import MAIN_CHECKER_NAME, MSG_TYPES_STATUS from pylint.lint import Run +from pylint.lint.pylinter import PyLinter from pylint.message import Message from pylint.reporters import JSONReporter from pylint.reporters.text import BaseReporter, ColorizedTextReporter, TextReporter +from pylint.reporters.ureports.nodes import EvaluationSection from pylint.utils import utils HERE = abspath(dirname(__file__)) @@ -73,7 +77,7 @@ UNNECESSARY_LAMBDA = join( @contextlib.contextmanager -def _patch_streams(out): +def _patch_streams(out: Union[StringIO, EncodedFile]) -> Iterator: sys.stderr = sys.stdout = out try: yield @@ -83,7 +87,7 @@ def _patch_streams(out): @contextlib.contextmanager -def _configure_lc_ctype(lc_ctype): +def _configure_lc_ctype(lc_ctype: str) -> Iterator: lc_ctype_env = "LC_CTYPE" original_lctype = os.environ.get(lc_ctype_env) os.environ[lc_ctype_env] = lc_ctype @@ -96,7 +100,7 @@ def _configure_lc_ctype(lc_ctype): class MultiReporter(BaseReporter): - def __init__(self, reporters): + def __init__(self, reporters: List[BaseReporter]) -> None: # pylint: disable=super-init-not-called # We don't call it because there is an attribute "linter" that is set inside the base class # and we have another setter here using yet undefined attribute. @@ -104,7 +108,7 @@ class MultiReporter(BaseReporter): self._reporters = reporters self.path_strip_prefix = os.getcwd() + os.sep - def on_set_current_module(self, *args, **kwargs): + def on_set_current_module(self, *args: str, **kwargs: Any) -> None: for rep in self._reporters: rep.on_set_current_module(*args, **kwargs) @@ -112,26 +116,32 @@ class MultiReporter(BaseReporter): for rep in self._reporters: rep.handle_message(msg) - def _display(self, layout): + def _display(self, layout: EvaluationSection) -> None: pass @property - def out(self): + def out(self) -> StringIO: return self._reporters[0].out @property - def linter(self): + def linter(self) -> Optional[Any]: return self._linter @linter.setter - def linter(self, value): + def linter(self, value: PyLinter) -> None: self._linter = value for rep in self._reporters: rep.linter = value class TestRunTC: - def _runtest(self, args, reporter=None, out=None, code=None): + def _runtest( + self, + args: List[str], + reporter: Any = None, + out: Optional[StringIO] = None, + code: int = None, + ) -> None: if out is None: out = StringIO() pylint_code = self._run_pylint(args, reporter=reporter, out=out) @@ -147,7 +157,9 @@ class TestRunTC: assert pylint_code == code, msg @staticmethod - def _run_pylint(args, out, reporter=None): + def _run_pylint( + args: List[str], out: Union[StringIO, EncodedFile], reporter: Any = None + ) -> int: args = args + ["--persistent=no"] with _patch_streams(out): with pytest.raises(SystemExit) as cm: @@ -157,19 +169,21 @@ class TestRunTC: return cm.value.code @staticmethod - def _clean_paths(output): + def _clean_paths(output: str) -> str: """Normalize path to the tests directory.""" output = re.sub(CLEAN_PATH, "", output, flags=re.MULTILINE) return output.replace("\\", "/") - def _test_output(self, args, expected_output): + def _test_output(self, args: List[str], expected_output: str) -> None: out = StringIO() self._run_pylint(args, out=out) actual_output = self._clean_paths(out.getvalue()) expected_output = self._clean_paths(expected_output) assert expected_output.strip() in actual_output.strip() - def _test_output_file(self, args, filename, expected_output): + def _test_output_file( + self, args: List[str], filename: LocalPath, expected_output: str + ) -> None: """ Run Pylint with the ``output`` option set (must be included in the ``args`` passed to this method!) and check the file content afterwards. @@ -184,11 +198,11 @@ class TestRunTC: ), "Unexpected output to stdout/stderr while output option was set" assert expected_output.strip() in file_output.strip() - def test_pkginfo(self): + def test_pkginfo(self) -> None: """Make pylint check itself.""" self._runtest(["pylint.__pkginfo__"], reporter=TextReporter(StringIO()), code=0) - def test_all(self): + def test_all(self) -> None: """Make pylint check itself.""" reporters = [ TextReporter(StringIO()), @@ -201,21 +215,21 @@ class TestRunTC: code=2, ) - def test_no_ext_file(self): + def test_no_ext_file(self) -> None: self._runtest([join(HERE, "input", "noext")], code=0) - def test_w0704_ignored(self): + def test_w0704_ignored(self) -> None: self._runtest([join(HERE, "input", "ignore_except_pass_by_default.py")], code=0) - def test_exit_zero(self): + def test_exit_zero(self) -> None: self._runtest( ["--exit-zero", join(HERE, "regrtest_data", "syntax_error.py")], code=0 ) - def test_generate_config_option(self): + def test_generate_config_option(self) -> None: self._runtest(["--generate-rcfile"], code=0) - def test_generate_config_option_order(self): + def test_generate_config_option_order(self) -> None: out1 = StringIO() out2 = StringIO() self._runtest(["--generate-rcfile"], code=0, out=out1) @@ -224,7 +238,7 @@ class TestRunTC: output2 = out2.getvalue() assert output1 == output2 - def test_generate_config_disable_symbolic_names(self): + def test_generate_config_disable_symbolic_names(self) -> None: # Test that --generate-rcfile puts symbolic names in the --disable # option. @@ -243,25 +257,25 @@ class TestRunTC: messages = utils._splitstrip(parser.get("MESSAGES CONTROL", "disable")) assert "suppressed-message" in messages - def test_generate_rcfile_no_obsolete_methods(self): + def test_generate_rcfile_no_obsolete_methods(self) -> None: out = StringIO() self._run_pylint(["--generate-rcfile"], out=out) output = out.getvalue() assert "profile" not in output - def test_nonexistent_config_file(self): + def test_nonexistent_config_file(self) -> None: self._runtest(["--rcfile=/tmp/this_file_does_not_exist"], code=32) - def test_help_message_option(self): + def test_help_message_option(self) -> None: self._runtest(["--help-msg", "W0101"], code=0) - def test_error_help_message_option(self): + def test_error_help_message_option(self) -> None: self._runtest(["--help-msg", "WX101"], code=0) - def test_error_missing_arguments(self): + def test_error_missing_arguments(self) -> None: self._runtest([], code=32) - def test_no_out_encoding(self): + def test_no_out_encoding(self) -> None: """test redirection of stdout with non ascii caracters""" # This test reproduces bug #48066 ; it happens when stdout is redirected # through '>' : the sys.stdout.encoding becomes then None, and if the @@ -274,7 +288,7 @@ class TestRunTC: code=28, ) - def test_parallel_execution(self): + def test_parallel_execution(self) -> None: out = StringIO() self._runtest( [ @@ -290,14 +304,14 @@ class TestRunTC: in out.getvalue().strip() ) - def test_parallel_execution_missing_arguments(self): + def test_parallel_execution_missing_arguments(self) -> None: self._runtest(["-j 2", "not_here", "not_here_too"], code=1) - def test_abbreviations_are_not_supported(self): + def test_abbreviations_are_not_supported(self) -> None: expected = "no such option: --load-plugin" self._test_output([".", "--load-plugin"], expected_output=expected) - def test_enable_all_works(self): + def test_enable_all_works(self) -> None: module = join(HERE, "data", "clientmodule_test.py") expected = textwrap.dedent( f""" @@ -311,7 +325,7 @@ class TestRunTC: [module, "--disable=all", "--enable=all", "-rn"], expected_output=expected ) - def test_wrong_import_position_when_others_disabled(self): + def test_wrong_import_position_when_others_disabled(self) -> None: module1 = join(HERE, "regrtest_data", "import_something.py") module2 = join(HERE, "regrtest_data", "wrong_import_position.py") expected_output = textwrap.dedent( @@ -341,19 +355,19 @@ class TestRunTC: actual_output = actual_output[actual_output.find("\n") :] assert self._clean_paths(expected_output.strip()) == actual_output.strip() - def test_import_itself_not_accounted_for_relative_imports(self): + def test_import_itself_not_accounted_for_relative_imports(self) -> None: expected = "Your code has been rated at 10.00/10" package = join(HERE, "regrtest_data", "dummy") self._test_output( [package, "--disable=locally-disabled", "-rn"], expected_output=expected ) - def test_reject_empty_indent_strings(self): + def test_reject_empty_indent_strings(self) -> None: expected = "indent string can't be empty" module = join(HERE, "data", "clientmodule_test.py") self._test_output([module, "--indent-string="], expected_output=expected) - def test_json_report_when_file_has_syntax_error(self): + def test_json_report_when_file_has_syntax_error(self) -> None: out = StringIO() module = join(HERE, "regrtest_data", "syntax_error.py") self._runtest([module], code=2, reporter=JSONReporter(out)) @@ -385,7 +399,7 @@ class TestRunTC: assert "<unknown>" in msg assert "line 1" in msg - def test_json_report_when_file_is_missing(self): + def test_json_report_when_file_is_missing(self) -> None: out = StringIO() module = join(HERE, "regrtest_data", "totally_missing.py") self._runtest([module], code=1, reporter=JSONReporter(out)) @@ -407,7 +421,7 @@ class TestRunTC: assert message[key] == value assert message["message"].startswith("No module named") - def test_json_report_does_not_escape_quotes(self): + def test_json_report_does_not_escape_quotes(self) -> None: out = StringIO() module = join(HERE, "regrtest_data", "unused_variable.py") self._runtest([module], code=4, reporter=JSONReporter(out)) @@ -429,12 +443,12 @@ class TestRunTC: assert key in message assert message[key] == value - def test_information_category_disabled_by_default(self): + def test_information_category_disabled_by_default(self) -> None: expected = "Your code has been rated at 10.00/10" path = join(HERE, "regrtest_data", "meta.py") self._test_output([path], expected_output=expected) - def test_error_mode_shows_no_score(self): + def test_error_mode_shows_no_score(self) -> None: module = join(HERE, "regrtest_data", "application_crash.py") expected_output = textwrap.dedent( f""" @@ -444,19 +458,19 @@ class TestRunTC: ) self._test_output([module, "-E"], expected_output=expected_output) - def test_evaluation_score_shown_by_default(self): + def test_evaluation_score_shown_by_default(self) -> None: expected_output = "Your code has been rated at " module = join(HERE, "regrtest_data", "application_crash.py") self._test_output([module], expected_output=expected_output) - def test_confidence_levels(self): + def test_confidence_levels(self) -> None: expected = "Your code has been rated at" path = join(HERE, "regrtest_data", "meta.py") self._test_output( [path, "--confidence=HIGH,INFERENCE"], expected_output=expected ) - def test_bom_marker(self): + def test_bom_marker(self) -> None: path = join(HERE, "regrtest_data", "meta.py") config_path = join(HERE, "regrtest_data", ".pylintrc") expected = "Your code has been rated at 10.00/10" @@ -464,7 +478,7 @@ class TestRunTC: [path, f"--rcfile={config_path}", "-rn"], expected_output=expected ) - def test_pylintrc_plugin_duplicate_options(self): + def test_pylintrc_plugin_duplicate_options(self) -> None: dummy_plugin_path = join(HERE, "regrtest_data", "dummy_plugin") # Enable --load-plugins=dummy_plugin sys.path.append(dummy_plugin_path) @@ -491,7 +505,7 @@ class TestRunTC: ) sys.path.remove(dummy_plugin_path) - def test_pylintrc_comments_in_values(self): + def test_pylintrc_comments_in_values(self) -> None: path = join(HERE, "regrtest_data", "test_pylintrc_comments.py") config_path = join(HERE, "regrtest_data", "comments_pylintrc") expected = textwrap.dedent( @@ -506,12 +520,12 @@ class TestRunTC: [path, f"--rcfile={config_path}", "-rn"], expected_output=expected ) - def test_no_crash_with_formatting_regex_defaults(self): + def test_no_crash_with_formatting_regex_defaults(self) -> None: self._runtest( ["--ignore-patterns=a"], reporter=TextReporter(StringIO()), code=32 ) - def test_getdefaultencoding_crashes_with_lc_ctype_utf8(self): + def test_getdefaultencoding_crashes_with_lc_ctype_utf8(self) -> None: module = join(HERE, "regrtest_data", "application_crash.py") expected_output = textwrap.dedent( f""" @@ -563,7 +577,7 @@ class TestRunTC: ) assert mock_stdin.call_count == 1 - def test_stdin_missing_modulename(self): + def test_stdin_missing_modulename(self) -> None: self._runtest(["--from-stdin"], code=32) @pytest.mark.parametrize("write_bpy_to_disk", [False, True]) @@ -620,7 +634,7 @@ class TestRunTC: expected_output=expected, ) - def test_stdin_syntaxerror(self): + def test_stdin_syntaxerror(self) -> None: expected_output = ( "************* Module a\n" "a.py:1:4: E0001: invalid syntax (<unknown>, line 1) (syntax-error)" @@ -635,8 +649,8 @@ class TestRunTC: ) assert mock_stdin.call_count == 1 - def test_version(self): - def check(lines): + def test_version(self) -> None: + def check(lines: List[str]) -> None: assert lines[0].startswith("pylint ") assert lines[1].startswith("astroid ") assert lines[2].startswith("Python ") @@ -646,10 +660,10 @@ class TestRunTC: check(out.getvalue().splitlines()) result = subprocess.check_output([sys.executable, "-m", "pylint", "--version"]) - result = result.decode("utf-8") - check(result.splitlines()) + result_str = result.decode("utf-8") + check(result_str.splitlines()) - def test_fail_under(self): + def test_fail_under(self) -> None: self._runtest( [ "--fail-under", @@ -923,7 +937,7 @@ class TestRunTC: assert sys.path == paths[1:] @staticmethod - def test_do_not_import_files_from_local_directory(tmpdir): + def test_do_not_import_files_from_local_directory(tmpdir: LocalPath) -> None: p_astroid = tmpdir / "astroid.py" p_astroid.write("'Docstring'\nimport completely_unknown\n") p_hmac = tmpdir / "hmac.py" @@ -971,7 +985,9 @@ class TestRunTC: ) @staticmethod - def test_do_not_import_files_from_local_directory_with_pythonpath(tmpdir): + def test_do_not_import_files_from_local_directory_with_pythonpath( + tmpdir: LocalPath, + ) -> None: p_astroid = tmpdir / "astroid.py" p_astroid.write("'Docstring'\nimport completely_unknown\n") p_hmac = tmpdir / "hmac.py" @@ -998,7 +1014,9 @@ class TestRunTC: del os.environ["PYTHONPATH"] @staticmethod - def test_import_plugin_from_local_directory_if_pythonpath_cwd(tmpdir): + def test_import_plugin_from_local_directory_if_pythonpath_cwd( + tmpdir: LocalPath, + ) -> None: p_plugin = tmpdir / "plugin.py" p_plugin.write("# Some plugin content") @@ -1029,7 +1047,9 @@ class TestRunTC: else: del os.environ["PYTHONPATH"] - def test_allow_import_of_files_found_in_modules_during_parallel_check(self, tmpdir): + def test_allow_import_of_files_found_in_modules_during_parallel_check( + self, tmpdir: LocalPath + ) -> None: test_directory = tmpdir / "test_directory" test_directory.mkdir() spam_module = test_directory / "spam.py" @@ -1061,7 +1081,7 @@ class TestRunTC: ) @staticmethod - def test_can_list_directories_without_dunder_init(tmpdir): + def test_can_list_directories_without_dunder_init(tmpdir: LocalPath) -> None: test_directory = tmpdir / "test_directory" test_directory.mkdir() spam_module = test_directory / "spam.py" @@ -1079,12 +1099,12 @@ class TestRunTC: stderr=subprocess.PIPE, ) - def test_jobs_score(self): + def test_jobs_score(self) -> None: path = join(HERE, "regrtest_data", "unused_variable.py") expected = "Your code has been rated at 7.50/10" self._test_output([path, "--jobs=2", "-ry"], expected_output=expected) - def test_duplicate_code_raw_strings(self): + def test_duplicate_code_raw_strings(self) -> None: path = join(HERE, "regrtest_data", "duplicate_data_raw_strings") expected_output = "Similar lines in 2 files" self._test_output( @@ -1092,7 +1112,7 @@ class TestRunTC: expected_output=expected_output, ) - def test_regression_parallel_mode_without_filepath(self): + def test_regression_parallel_mode_without_filepath(self) -> None: # Test that parallel mode properly passes filepath # https://github.com/PyCQA/pylint/issues/3564 path = join( @@ -1100,7 +1120,7 @@ class TestRunTC: ) self._test_output([path, "-j2"], expected_output="No such file or directory") - def test_output_file_valid_path(self, tmpdir): + def test_output_file_valid_path(self, tmpdir: LocalPath) -> None: path = join(HERE, "regrtest_data", "unused_variable.py") output_file = tmpdir / "output.txt" expected = "Your code has been rated at 7.50/10" @@ -1110,7 +1130,7 @@ class TestRunTC: expected_output=expected, ) - def test_output_file_invalid_path_exits_with_code_32(self): + def test_output_file_invalid_path_exits_with_code_32(self) -> None: path = join(HERE, "regrtest_data", "unused_variable.py") output_file = "thisdirectorydoesnotexit/output.txt" self._runtest([path, f"--output={output_file}"], code=32) @@ -1186,7 +1206,9 @@ class TestRunTC: expected_output, ) - def test_output_file_can_be_combined_with_custom_reporter(self, tmpdir): + def test_output_file_can_be_combined_with_custom_reporter( + self, tmpdir: LocalPath + ) -> None: path = join(HERE, "regrtest_data", "unused_variable.py") output_file = tmpdir / "output.txt" # It does not really have to be a truly custom reporter. @@ -1199,7 +1221,7 @@ class TestRunTC: ) assert output_file.exists() - def test_output_file_specified_in_rcfile(self, tmpdir): + def test_output_file_specified_in_rcfile(self, tmpdir: LocalPath) -> None: output_file = tmpdir / "output.txt" rcfile = tmpdir / "pylintrc" rcfile_contents = textwrap.dedent( diff --git a/tests/testutils/test_output_line.py b/tests/testutils/test_output_line.py index 18689f432..cd8bc7e9b 100644 --- a/tests/testutils/test_output_line.py +++ b/tests/testutils/test_output_line.py @@ -3,17 +3,19 @@ # pylint: disable=redefined-outer-name +from typing import Callable, List, Optional + import pytest from pylint.constants import PY38_PLUS -from pylint.interfaces import HIGH, INFERENCE +from pylint.interfaces import HIGH, INFERENCE, Confidence from pylint.message import Message from pylint.testutils.output_line import MalformedOutputLineException, OutputLine @pytest.fixture() -def message(): - def inner(confidence=HIGH): +def message() -> Callable: + def inner(confidence: Confidence = HIGH) -> Message: return Message( symbol="missing-docstring", msg_id="C0123", @@ -32,11 +34,11 @@ def message(): return inner -def test_output_line(): +def test_output_line() -> None: output_line = OutputLine( symbol="missing-docstring", lineno=0, - column=0, + column="0", object="", msg="Missing docstring's bad.", confidence=HIGH, @@ -44,14 +46,14 @@ def test_output_line(): assert output_line.symbol == "missing-docstring" -def test_output_line_from_message(message): +def test_output_line_from_message(message: Callable) -> None: output_line = OutputLine.from_msg(message()) assert output_line.symbol == "missing-docstring" assert output_line.msg == "msg" @pytest.mark.parametrize("confidence", [HIGH, INFERENCE]) -def test_output_line_to_csv(confidence, message): +def test_output_line_to_csv(confidence: Confidence, message: Callable) -> None: output_line = OutputLine.from_msg(message(confidence)) csv = output_line.to_csv() expected_column = "column" if PY38_PLUS else "" @@ -65,7 +67,7 @@ def test_output_line_to_csv(confidence, message): ) -def test_output_line_from_csv_error(): +def test_output_line_from_csv_error() -> None: with pytest.raises( MalformedOutputLineException, match="msg-symbolic-name:42:27:MyClass.my_function:The message", @@ -81,16 +83,20 @@ def test_output_line_from_csv_error(): @pytest.mark.parametrize( "confidence,expected_confidence", [[None, "HIGH"], ["INFERENCE", "INFERENCE"]] ) -def test_output_line_from_csv(confidence, expected_confidence): - proper_csv = ( - "missing-docstring", - "1", - "2", - "obj", - "msg", - ) - if confidence is not None: - proper_csv += (confidence,) +def test_output_line_from_csv( + confidence: Optional[str], expected_confidence: Confidence +) -> None: + if confidence: + proper_csv: List[str] = [ + "missing-docstring", + "1", + "2", + "obj", + "msg", + confidence, + ] + else: + proper_csv = ["missing-docstring", "1", "2", "obj", "msg"] output_line = OutputLine.from_csv(proper_csv) expected_column = "2" if PY38_PLUS else "" assert output_line == OutputLine( diff --git a/tests/unittest_config.py b/tests/unittest_config.py index 8a14117b2..d6d62e492 100644 --- a/tests/unittest_config.py +++ b/tests/unittest_config.py @@ -23,18 +23,18 @@ from pylint import config RE_PATTERN_TYPE = getattr(re, "Pattern", getattr(re, "_pattern_type", None)) -def test__regexp_validator_valid(): +def test__regexp_validator_valid() -> None: result = config.option._regexp_validator(None, None, "test_.*") assert isinstance(result, RE_PATTERN_TYPE) assert result.pattern == "test_.*" -def test__regexp_validator_invalid(): +def test__regexp_validator_invalid() -> None: with pytest.raises(sre_constants.error): config.option._regexp_validator(None, None, "test_)") -def test__csv_validator_no_spaces(): +def test__csv_validator_no_spaces() -> None: values = ["One", "Two", "Three"] result = config.option._csv_validator(None, None, ",".join(values)) assert isinstance(result, list) @@ -43,7 +43,7 @@ def test__csv_validator_no_spaces(): assert result[i] == value -def test__csv_validator_spaces(): +def test__csv_validator_spaces() -> None: values = ["One", "Two", "Three"] result = config.option._csv_validator(None, None, ", ".join(values)) assert isinstance(result, list) @@ -52,7 +52,7 @@ def test__csv_validator_spaces(): assert result[i] == value -def test__regexp_csv_validator_valid(): +def test__regexp_csv_validator_valid() -> None: pattern_strings = ["test_.*", "foo\\.bar", "^baz$"] result = config.option._regexp_csv_validator(None, None, ",".join(pattern_strings)) for i, regex in enumerate(result): @@ -60,7 +60,7 @@ def test__regexp_csv_validator_valid(): assert regex.pattern == pattern_strings[i] -def test__regexp_csv_validator_invalid(): +def test__regexp_csv_validator_invalid() -> None: pattern_strings = ["test_.*", "foo\\.bar", "^baz)$"] with pytest.raises(sre_constants.error): config.option._regexp_csv_validator(None, None, ",".join(pattern_strings)) diff --git a/tests/unittest_reporters_json.py b/tests/unittest_reporters_json.py index a9de3c748..c5748ef31 100644 --- a/tests/unittest_reporters_json.py +++ b/tests/unittest_reporters_json.py @@ -16,6 +16,7 @@ import json from io import StringIO +from typing import Any, Dict, List from pylint import checkers from pylint.lint import PyLinter @@ -38,14 +39,14 @@ expected_result = [ ] -def test_simple_json_output_no_score(): +def test_simple_json_output_no_score() -> None: report = get_linter_result(score=False) assert len(report) == 1 report_result = [sorted(report[0].items(), key=lambda item: item[0])] assert report_result == expected_result -def get_linter_result(score): +def get_linter_result(score: bool) -> List[Dict[str, Any]]: output = StringIO() reporter = JSONReporter(output) linter = PyLinter(reporter=reporter) diff --git a/tests/utils/unittest_ast_walker.py b/tests/utils/unittest_ast_walker.py index 364b35a35..9d350830a 100644 --- a/tests/utils/unittest_ast_walker.py +++ b/tests/utils/unittest_ast_walker.py @@ -2,6 +2,7 @@ # For details: https://github.com/PyCQA/pylint/blob/main/LICENSE import warnings +from typing import Dict, Set import astroid @@ -11,15 +12,15 @@ from pylint.utils import ASTWalker class TestASTWalker: class MockLinter: - def __init__(self, msgs): + def __init__(self, msgs: Dict[str, bool]) -> None: self._msgs = msgs - def is_message_enabled(self, msgid): + def is_message_enabled(self, msgid: str) -> bool: return self._msgs.get(msgid, True) class Checker: - def __init__(self): - self.called = set() + def __init__(self) -> None: + self.called: Set[str] = set() @check_messages("first-message") def visit_module(self, module): # pylint: disable=unused-argument @@ -37,7 +38,7 @@ class TestASTWalker: def leave_assignname(self, module): raise NotImplementedError - def test_check_messages(self): + def test_check_messages(self) -> None: linter = self.MockLinter( {"first-message": True, "second-message": False, "third-message": True} ) @@ -47,9 +48,9 @@ class TestASTWalker: walker.walk(astroid.parse("x = func()")) assert {"module", "assignname"} == checker.called - def test_deprecated_methods(self): + def test_deprecated_methods(self) -> None: class Checker: - def __init__(self): + def __init__(self) -> None: self.called = False @check_messages("first-message") diff --git a/tests/utils/unittest_utils.py b/tests/utils/unittest_utils.py index a07a70c79..77853b234 100644 --- a/tests/utils/unittest_utils.py +++ b/tests/utils/unittest_utils.py @@ -23,7 +23,7 @@ import io from pylint.utils import utils -def test_decoding_stream_unknown_encoding(): +def test_decoding_stream_unknown_encoding() -> None: """decoding_stream should fall back to *some* decoding when given an unknown encoding. """ @@ -34,7 +34,7 @@ def test_decoding_stream_unknown_encoding(): assert ret == ["foo\n", "bar"] -def test_decoding_stream_known_encoding(): +def test_decoding_stream_known_encoding() -> None: binary_io = io.BytesIO("€".encode("cp1252")) stream = utils.decoding_stream(binary_io, "cp1252") assert stream.read() == "€" |