From 6af3373e67577db991d6c10d3a6ce3cbfc10760b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Sun, 2 Jan 2022 23:21:15 +0100 Subject: [PATCH 1/2] Add ``pydocstringformatter`` to pre-commit config --- .pre-commit-config.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0857eaa500..37600cc60c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -95,3 +95,8 @@ repos: - id: prettier args: [--prose-wrap=always, --print-width=88] exclude: tests(/.*)*/data + - repo: https://github.com/DanielNoord/pydocstringformatter + rev: v0.2.0 + hooks: + - id: pydocstringformatter + exclude: *fixtures From 2db086031fda62567dc7561efd1c81499f321257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Sun, 2 Jan 2022 23:21:23 +0100 Subject: [PATCH 2/2] Format docstrings with ``pydocstringformatter`` --- examples/custom.py | 3 +- examples/deprecation_checker.py | 3 +- pylint/checkers/base.py | 15 ++++---- pylint/checkers/base_checker.py | 9 +++-- pylint/checkers/classes/class_checker.py | 10 ++--- .../classes/special_methods_checker.py | 3 +- pylint/checkers/ellipsis_checker.py | 3 +- pylint/checkers/exceptions.py | 3 +- pylint/checkers/format.py | 29 +++++--------- pylint/checkers/logging.py | 7 +--- pylint/checkers/newstyle.py | 3 +- .../implicit_booleaness_checker.py | 3 +- .../refactoring/recommendation_checker.py | 3 +- .../refactoring/refactoring_checker.py | 28 +++++++------- pylint/checkers/similar.py | 38 +++++++------------ pylint/checkers/spelling.py | 10 ++--- pylint/checkers/strings.py | 9 ++--- pylint/checkers/typecheck.py | 17 +++------ pylint/checkers/unsupported_version.py | 3 +- pylint/checkers/utils.py | 30 ++++++--------- pylint/checkers/variables.py | 29 +++++--------- pylint/config/configuration_mixin.py | 3 +- pylint/config/option_manager_mixin.py | 3 +- pylint/epylint.py | 3 +- pylint/extensions/_check_docs_utils.py | 6 +-- pylint/extensions/comparison_placement.py | 3 +- pylint/extensions/docparams.py | 6 +-- pylint/extensions/mccabe.py | 3 +- pylint/extensions/overlapping_exceptions.py | 3 +- pylint/lint/expand_modules.py | 3 +- pylint/lint/pylinter.py | 12 ++++-- pylint/message/message_id_store.py | 6 ++- pylint/pyreverse/__init__.py | 4 +- pylint/pyreverse/diadefslib.py | 3 +- pylint/pyreverse/dot_printer.py | 4 +- pylint/pyreverse/inspector.py | 3 +- pylint/pyreverse/main.py | 3 +- pylint/pyreverse/mermaidjs_printer.py | 4 +- pylint/pyreverse/plantuml_printer.py | 4 +- pylint/pyreverse/printer.py | 4 +- pylint/pyreverse/utils.py | 6 ++- pylint/reporters/multi_reporter.py | 3 +- pylint/reporters/text.py | 3 +- pylint/testutils/lint_module_test.py | 3 +- pylint/testutils/output_line.py | 3 +- pylint/testutils/pyreverse.py | 3 +- pylint/utils/pragma_parser.py | 15 ++------ script/bump_changelog.py | 4 +- tests/benchmark/test_baseline_benchmarks.py | 33 ++++++++++------ tests/checkers/unittest_design.py | 3 +- tests/checkers/unittest_format.py | 6 +-- tests/checkers/unittest_stdlib.py | 3 +- tests/checkers/unittest_variables.py | 3 +- .../config/test_functional_config_loading.py | 3 +- tests/config/unittest_config.py | 6 ++- tests/pyreverse/test_diadefs.py | 3 +- tests/pyreverse/test_inspector.py | 4 +- tests/pyreverse/test_printer_factory.py | 4 +- tests/pyreverse/test_utils.py | 3 +- tests/pyreverse/test_writer.py | 4 +- tests/test_check_parallel.py | 6 ++- tests/test_func.py | 3 +- tests/test_self.py | 7 +--- tests/unittest_reporting.py | 3 +- 64 files changed, 208 insertions(+), 264 deletions(-) diff --git a/examples/custom.py b/examples/custom.py index 695f77d20d..d4376fc4e3 100644 --- a/examples/custom.py +++ b/examples/custom.py @@ -52,7 +52,8 @@ class MyAstroidChecker(BaseChecker): def visit_call(self, node: nodes.Call) -> None: """Called when a :class:`.nodes.Call` node is visited. - See :mod:`astroid` for the description of available nodes.""" + See :mod:`astroid` for the description of available nodes. + """ if not ( isinstance(node.func, nodes.Attribute) and isinstance(node.func.expr, nodes.Name) diff --git a/examples/deprecation_checker.py b/examples/deprecation_checker.py index d3dca4e07d..79a7285379 100644 --- a/examples/deprecation_checker.py +++ b/examples/deprecation_checker.py @@ -1,5 +1,4 @@ -""" -Example checker detecting deprecated functions/methods. Following example searches for usages of +"""Example checker detecting deprecated functions/methods. Following example searches for usages of deprecated function `deprecated_function` and deprecated method `MyClass.deprecated_method` from module mymodule: diff --git a/pylint/checkers/base.py b/pylint/checkers/base.py index 39ab5d673b..c1eefab921 100644 --- a/pylint/checkers/base.py +++ b/pylint/checkers/base.py @@ -103,7 +103,8 @@ class NamingStyle: """It may seem counterintuitive that single naming style has multiple "accepted" forms of regular expressions, but we need to special-case stuff like dunder names - in method names.""" + in method names. + """ ANY: Pattern[str] = re.compile(".*") CLASS_NAME_RGX: Pattern[str] = ANY @@ -278,8 +279,7 @@ def in_nested_list(nested_list, obj): def _get_break_loop_node(break_node): - """ - Returns the loop node that holds the break node in arguments. + """Returns the loop node that holds the break node in arguments. Args: break_node (astroid.Break): the break node of interest. @@ -300,8 +300,7 @@ def _get_break_loop_node(break_node): def _loop_exits_early(loop): - """ - Returns true if a loop may end with a break statement. + """Returns true if a loop may end with a break statement. Args: loop (astroid.For, astroid.While): the loop node inspected. @@ -389,8 +388,7 @@ def _determine_function_name_type(node: nodes.FunctionDef, config=None): def _has_abstract_methods(node): - """ - Determine if the given `node` has abstract methods. + """Determine if the given `node` has abstract methods. The methods should be made abstract by decorating them with `abc` decorators. @@ -1496,7 +1494,8 @@ def _check_not_in_finally(self, node, node_name, breaker_classes=()): """check that a node is not inside a 'finally' clause of a 'try...finally' statement. If we find a parent which type is in breaker_classes before - a 'try...finally' block we skip the whole check.""" + a 'try...finally' block we skip the whole check. + """ # if self._tryfinallys is empty, we're not an in try...finally block if not self._tryfinallys: return diff --git a/pylint/checkers/base_checker.py b/pylint/checkers/base_checker.py index 8fe44a2e23..5a6efd20c2 100644 --- a/pylint/checkers/base_checker.py +++ b/pylint/checkers/base_checker.py @@ -50,7 +50,8 @@ class BaseChecker(OptionsProviderMixIn): def __init__(self, linter=None): """checker instances should have the linter as argument - :param ILinter linter: is an object implementing ILinter.""" + :param ILinter linter: is an object implementing ILinter. + """ if self.name is not None: self.name = self.name.lower() super().__init__() @@ -67,7 +68,8 @@ def __repr__(self): def __str__(self): """This might be incomplete because multiple class inheriting BaseChecker - can have the same name. Cf MessageHandlerMixIn.get_full_documentation()""" + can have the same name. Cf MessageHandlerMixIn.get_full_documentation() + """ return self.get_full_documentation( msgs=self.msgs, options=self.options_and_values(), reports=self.reports ) @@ -132,7 +134,8 @@ def check_consistency(self): checker. :raises InvalidMessageError: If the checker id in the messages are not - always the same.""" + always the same. + """ checker_id = None existing_ids = [] for message in self.messages: diff --git a/pylint/checkers/classes/class_checker.py b/pylint/checkers/classes/class_checker.py index b76e10e43a..fce2f7025f 100644 --- a/pylint/checkers/classes/class_checker.py +++ b/pylint/checkers/classes/class_checker.py @@ -186,8 +186,7 @@ class _DefaultMissing: def _has_different_parameters_default_value(original, overridden): - """ - Check if original and overridden methods arguments have different default values + """Check if original and overridden methods arguments have different default values Return True if one of the overridden arguments has a default value different from the default value of the original argument @@ -821,8 +820,7 @@ def _check_consistent_mro(self, node): pass def _check_proper_bases(self, node): - """ - Detect that a class inherits something which is not + """Detect that a class inherits something which is not a class or a type. """ for base in node.bases: @@ -1655,9 +1653,7 @@ def _check_protected_attribute_access(self, node: nodes.Attribute): @staticmethod def _is_called_inside_special_method(node: nodes.NodeNG) -> bool: - """ - Returns true if the node is located inside a special (aka dunder) method - """ + """Returns true if the node is located inside a special (aka dunder) method""" try: frame_name = node.frame().name except AttributeError: diff --git a/pylint/checkers/classes/special_methods_checker.py b/pylint/checkers/classes/special_methods_checker.py index 51c52b3ae4..f268230072 100644 --- a/pylint/checkers/classes/special_methods_checker.py +++ b/pylint/checkers/classes/special_methods_checker.py @@ -21,8 +21,7 @@ def _safe_infer_call_result(node, caller, context=None): - """ - Safely infer the return value of a function. + """Safely infer the return value of a function. Returns None if inference failed or if there is some ambiguity (more than one node has been inferred). Otherwise, returns inferred value. diff --git a/pylint/checkers/ellipsis_checker.py b/pylint/checkers/ellipsis_checker.py index e5d4c4ecd9..af8715ed55 100644 --- a/pylint/checkers/ellipsis_checker.py +++ b/pylint/checkers/ellipsis_checker.py @@ -1,5 +1,4 @@ -"""Ellipsis checker for Python code -""" +"""Ellipsis checker for Python code""" from typing import TYPE_CHECKING from astroid import nodes diff --git a/pylint/checkers/exceptions.py b/pylint/checkers/exceptions.py index 0d60b0a395..eafbafa2b9 100644 --- a/pylint/checkers/exceptions.py +++ b/pylint/checkers/exceptions.py @@ -57,8 +57,7 @@ def predicate(obj): def _annotated_unpack_infer(stmt, context=None): - """ - Recursively generate nodes inferred by the given statement. + """Recursively generate nodes inferred by the given statement. If the inferred value is a list or a tuple, recurse on the elements. Returns an iterator which yields tuples in the format ('original node', 'inferred node'). diff --git a/pylint/checkers/format.py b/pylint/checkers/format.py index 17a50911cf..f38944ded0 100644 --- a/pylint/checkers/format.py +++ b/pylint/checkers/format.py @@ -669,9 +669,7 @@ def _check_multi_statement_line(self, node, line): self._visited_lines[line] = 2 def check_line_ending(self, line: str, i: int) -> None: - """ - Check that the final newline is not missing and that there is no trailing whitespace. - """ + """Check that the final newline is not missing and that there is no trailing whitespace.""" if not line.endswith("\n"): self.add_message("missing-final-newline", line=i) return @@ -683,9 +681,7 @@ def check_line_ending(self, line: str, i: int) -> None: ) def check_line_length(self, line: str, i: int, checker_off: bool) -> None: - """ - Check that the line length is less than the authorized value - """ + """Check that the line length is less than the authorized value""" max_chars = self.config.max_line_length ignore_long_line = self.config.ignore_long_lines line = line.rstrip() @@ -697,9 +693,7 @@ def check_line_length(self, line: str, i: int, checker_off: bool) -> None: @staticmethod def remove_pylint_option_from_lines(options_pattern_obj) -> str: - """ - Remove the `# pylint ...` pattern from lines - """ + """Remove the `# pylint ...` pattern from lines""" lines = options_pattern_obj.string purged_lines = ( lines[: options_pattern_obj.start(1)].rstrip() @@ -709,9 +703,7 @@ def remove_pylint_option_from_lines(options_pattern_obj) -> str: @staticmethod def is_line_length_check_activated(pylint_pattern_match_object) -> bool: - """ - Return true if the line length check is activated - """ + """Return true if the line length check is activated""" try: for pragma in parse_pragma(pylint_pattern_match_object.group(2)): if pragma.action == "disable" and "line-too-long" in pragma.messages: @@ -723,9 +715,7 @@ def is_line_length_check_activated(pylint_pattern_match_object) -> bool: @staticmethod def specific_splitlines(lines: str) -> List[str]: - """ - Split lines according to universal newlines except those in a specific sets - """ + """Split lines according to universal newlines except those in a specific sets""" unsplit_ends = { "\v", "\x0b", @@ -749,11 +739,10 @@ def specific_splitlines(lines: str) -> List[str]: return res def check_lines(self, lines: str, lineno: int) -> None: - """ - Check lines have : - - a final newline - - no trailing whitespace - - less than a maximum number of characters + """Check lines have : + - a final newline + - no trailing whitespace + - less than a maximum number of characters """ # we're first going to do a rough check whether any lines in this set # go over the line limit. If none of them do, then we don't need to diff --git a/pylint/checkers/logging.py b/pylint/checkers/logging.py index 19e04c7d1b..4c44017419 100644 --- a/pylint/checkers/logging.py +++ b/pylint/checkers/logging.py @@ -23,8 +23,7 @@ # 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 -"""checker for use of Python logging -""" +"""checker for use of Python logging""" import string from typing import TYPE_CHECKING, Set @@ -295,9 +294,7 @@ def _helper_string(self, node): @staticmethod def _is_operand_literal_str(operand): - """ - Return True if the operand in argument is a literal string - """ + """Return True if the operand in argument is a literal string""" return isinstance(operand, nodes.Const) and operand.name == "str" def _check_call_func(self, node: nodes.Call): diff --git a/pylint/checkers/newstyle.py b/pylint/checkers/newstyle.py index b19a5c7ef5..45b4409d87 100644 --- a/pylint/checkers/newstyle.py +++ b/pylint/checkers/newstyle.py @@ -20,8 +20,7 @@ # 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 -"""check for new / old style related problems -""" +"""check for new / old style related problems""" from typing import TYPE_CHECKING import astroid diff --git a/pylint/checkers/refactoring/implicit_booleaness_checker.py b/pylint/checkers/refactoring/implicit_booleaness_checker.py index 29277e3a23..6167e3e88f 100644 --- a/pylint/checkers/refactoring/implicit_booleaness_checker.py +++ b/pylint/checkers/refactoring/implicit_booleaness_checker.py @@ -129,7 +129,8 @@ def instance_has_bool(class_def: nodes.ClassDef) -> bool: def visit_unaryop(self, node: nodes.UnaryOp) -> None: """`not len(S)` must become `not S` regardless if the parent block is a test condition or something else (boolean expression) - e.g. `if not len(S):`""" + e.g. `if not len(S):` + """ if ( isinstance(node, nodes.UnaryOp) and node.op == "not" diff --git a/pylint/checkers/refactoring/recommendation_checker.py b/pylint/checkers/refactoring/recommendation_checker.py index 3094ffd07e..785e37fddf 100644 --- a/pylint/checkers/refactoring/recommendation_checker.py +++ b/pylint/checkers/refactoring/recommendation_checker.py @@ -337,7 +337,8 @@ def visit_const(self, node: nodes.Const) -> None: def _detect_replacable_format_call(self, node: nodes.Const) -> None: """Check whether a string is used in a call to format() or '%' and whether it - can be replaced by an f-string""" + can be replaced by an f-string + """ if ( isinstance(node.parent, nodes.Attribute) and node.parent.attrname == "format" diff --git a/pylint/checkers/refactoring/refactoring_checker.py b/pylint/checkers/refactoring/refactoring_checker.py index 40a72a53f3..a182574561 100644 --- a/pylint/checkers/refactoring/refactoring_checker.py +++ b/pylint/checkers/refactoring/refactoring_checker.py @@ -118,8 +118,7 @@ def _is_a_return_statement(node: nodes.Call) -> bool: def _is_part_of_with_items(node: nodes.Call) -> bool: - """ - Checks if one of the node's parents is a ``nodes.With`` node and that the node itself is located + """Checks if one of the node's parents is a ``nodes.With`` node and that the node itself is located somewhere under its ``items``. """ frame = node.frame() @@ -135,7 +134,8 @@ def _is_part_of_with_items(node: nodes.Call) -> bool: def _will_be_released_automatically(node: nodes.Call) -> bool: """Checks if a call that could be used in a ``with`` statement is used in an alternative - construct which would ensure that its __exit__ method is called.""" + construct which would ensure that its __exit__ method is called. + """ callables_taking_care_of_exit = frozenset( ( "contextlib._BaseExitStack.enter_context", @@ -152,7 +152,8 @@ def _will_be_released_automatically(node: nodes.Call) -> bool: class ConsiderUsingWithStack(NamedTuple): """Stack for objects that may potentially trigger a R1732 message - if they are not used in a ``with`` block later on.""" + if they are not used in a ``with`` block later on. + """ module_scope: Dict[str, nodes.NodeNG] = {} class_scope: Dict[str, nodes.NodeNG] = {} @@ -1278,7 +1279,8 @@ def _apply_boolean_simplification_rules(operator, values): reverse for AND 2) False values in OR expressions are only relevant if all values are - false, and the reverse for AND""" + false, and the reverse for AND + """ simplified_values = [] for subnode in values: @@ -1299,7 +1301,8 @@ def _simplify_boolean_operation(self, bool_op): """Attempts to simplify a boolean operation Recursively applies simplification on the operator terms, - and keeps track of whether reductions have been made.""" + and keeps track of whether reductions have been made. + """ children = list(bool_op.get_children()) intermediate = [ self._simplify_boolean_operation(child) @@ -1320,7 +1323,8 @@ def _check_simplifiable_condition(self, node): """Check if a boolean condition can be simplified. Variables will not be simplified, even in the value can be inferred, - and expressions like '3 + 4' will remain expanded.""" + and expressions like '3 + 4' will remain expanded. + """ if not utils.is_test_condition(node): return @@ -1506,8 +1510,7 @@ def _check_use_list_or_dict_literal(self, node: nodes.Call) -> None: self.add_message("use-dict-literal", node=node) def _check_consider_using_join(self, aug_assign): - """ - We start with the augmented assignment and work our way upwards. + """We start with the augmented assignment and work our way upwards. Names of variables for nodes if match successful: result = '' # assign for number in ['1', '2', '3'] # for_loop @@ -1630,8 +1633,7 @@ def _check_unnecessary_comprehension(self, node: nodes.Comprehension) -> None: @staticmethod def _is_and_or_ternary(node): - """ - Returns true if node is 'condition and true_value or false_value' form. + """Returns true if node is 'condition and true_value or false_value' form. All of: condition, true_value and false_value should not be a complex boolean expression """ @@ -1793,9 +1795,7 @@ def _is_node_return_ended(self, node: nodes.NodeNG) -> bool: @staticmethod def _has_return_in_siblings(node: nodes.NodeNG) -> bool: - """ - Returns True if there is at least one return in the node's siblings - """ + """Returns True if there is at least one return in the node's siblings""" next_sibling = node.next_sibling() while next_sibling: if isinstance(next_sibling, nodes.Return): diff --git a/pylint/checkers/similar.py b/pylint/checkers/similar.py index 51ec27c0bb..ab72631355 100644 --- a/pylint/checkers/similar.py +++ b/pylint/checkers/similar.py @@ -108,8 +108,7 @@ class LineSpecifs(NamedTuple): class CplSuccessiveLinesLimits: - """ - This class holds a couple of SuccessiveLinesLimits objects, one for each file compared, + """This class holds a couple of SuccessiveLinesLimits objects, one for each file compared, and a counter on the number of common lines between both stripped lines collections extracted from both files """ @@ -133,9 +132,7 @@ def __init__( class LinesChunk: - """ - The LinesChunk object computes and stores the hash of some consecutive stripped lines of a lineset. - """ + """The LinesChunk object computes and stores the hash of some consecutive stripped lines of a lineset.""" __slots__ = ("_fileid", "_index", "_hash") @@ -170,8 +167,7 @@ def __str__(self) -> str: class SuccessiveLinesLimits: - """ - A class to handle the numbering of begin and end of successive lines. + """A class to handle the numbering of begin and end of successive lines. :note: Only the end line number can be updated. """ @@ -199,9 +195,7 @@ def __repr__(self) -> str: class LineSetStartCouple(NamedTuple): - """ - Indices in both linesets that mark the beginning of successive lines - """ + """Indices in both linesets that mark the beginning of successive lines""" fst_lineset_index: Index snd_lineset_index: Index @@ -235,8 +229,7 @@ def increment(self, value: Index) -> "LineSetStartCouple": def hash_lineset( lineset: "LineSet", min_common_lines: int = DEFAULT_MIN_SIMILARITY_LINE ) -> Tuple[HashToIndex_T, IndexToLines_T]: - """ - Return two dicts. The first associates the hash of successive stripped lines of a lineset + """Return two dicts. The first associates the hash of successive stripped lines of a lineset to the indices of the starting lines. The second dict, associates the index of the starting line in the lineset's stripped lines to the couple [start, end] lines number in the corresponding file. @@ -275,8 +268,7 @@ def hash_lineset( def remove_successives(all_couples: CplIndexToCplLines_T) -> None: - """ - Removes all successive entries in the dictionary in argument + """Removes all successive entries in the dictionary in argument :param all_couples: collection that has to be cleaned up from successives entries. The keys are couples of indices that mark the beginning of common entries @@ -325,8 +317,7 @@ def filter_noncode_lines( stindex_2: Index, common_lines_nb: int, ) -> int: - """ - Return the effective number of common lines between lineset1 and lineset2 filtered from non code lines, that is to say the number of + """Return the effective number of common lines between lineset1 and lineset2 filtered from non code lines, that is to say the number of common successive stripped lines except those that do not contain code (for example a ligne with only an ending parathensis) @@ -477,8 +468,7 @@ def _get_similarity_report( def _find_common( self, lineset1: "LineSet", lineset2: "LineSet" ) -> Generator[Commonality, None, None]: - """ - Find similarities in the two given linesets. + """Find similarities in the two given linesets. This the core of the algorithm. The idea is to compute the hashes of a minimal number of successive lines of each lineset and then compare the hashes. @@ -562,7 +552,8 @@ def get_map_data(self): def combine_mapreduce_data(self, linesets_collection): """Reduces and recombines data into a format that we can report on - The partner function of get_map_data()""" + The partner function of get_map_data() + """ self.linesets = [line for lineset in linesets_collection for line in lineset] @@ -573,8 +564,7 @@ def stripped_lines( ignore_imports: bool, ignore_signatures: bool, ) -> List[LineSpecifs]: - """ - Return tuples of line/line number/line type with leading/trailing whitespace and any ignored code features removed + """Return tuples of line/line number/line type with leading/trailing whitespace and any ignored code features removed :param lines: a collection of lines :param ignore_comments: if true, any comment in the lines collection is removed from the result @@ -664,8 +654,7 @@ def _get_functions( @functools.total_ordering class LineSet: - """ - Holds and indexes all the lines of a single source file. + """Holds and indexes all the lines of a single source file. Allows for correspondence between real lines of the source file and stripped ones, which are the real ones from which undesired patterns have been removed. """ @@ -871,7 +860,8 @@ def get_map_data(self): def reduce_map_data(self, linter, data): """Reduces and recombines data into a format that we can report on - The partner function of get_map_data()""" + The partner function of get_map_data() + """ recombined = SimilarChecker(linter) recombined.min_lines = self.min_lines recombined.ignore_comments = self.ignore_comments diff --git a/pylint/checkers/spelling.py b/pylint/checkers/spelling.py index 012c396ded..752eb83e3c 100644 --- a/pylint/checkers/spelling.py +++ b/pylint/checkers/spelling.py @@ -28,8 +28,7 @@ # 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 -"""Checker for spelling errors in comments and docstrings. -""" +"""Checker for spelling errors in comments and docstrings.""" import os import re import tokenize @@ -147,9 +146,7 @@ class SphinxDirectives(RegExFilter): class ForwardSlashChunker(Chunker): - """ - This chunker allows splitting words like 'before/after' into 'before' and 'after' - """ + """This chunker allows splitting words like 'before/after' into 'before' and 'after'""" def next(self): while True: @@ -194,7 +191,8 @@ def _strip_code_flanked_in_backticks(line: str) -> str: """Alter line so code flanked in backticks is ignored. Pyenchant automatically strips backticks when parsing tokens, - so this cannot be done at the individual filter level.""" + so this cannot be done at the individual filter level. + """ def replace_code_but_leave_surrounding_characters(match_obj) -> str: return match_obj.group(1) + match_obj.group(5) diff --git a/pylint/checkers/strings.py b/pylint/checkers/strings.py index e4dcfc8316..458c96fe64 100644 --- a/pylint/checkers/strings.py +++ b/pylint/checkers/strings.py @@ -34,8 +34,7 @@ # 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 -"""Checker for string formatting operations. -""" +"""Checker for string formatting operations.""" import collections import numbers @@ -540,8 +539,7 @@ def _check_new_format(self, node, func): self._check_new_format_specifiers(node, fields, named_arguments) def _check_new_format_specifiers(self, node, fields, named): - """ - Check attribute and index access in the format + """Check attribute and index access in the format string ("{0.a}" and "{0[a]}"). """ for key, specifiers in fields: @@ -934,8 +932,7 @@ def register(linter: "PyLinter") -> None: def str_eval(token): - """ - Mostly replicate `ast.literal_eval(token)` manually to avoid any performance hit. + """Mostly replicate `ast.literal_eval(token)` manually to avoid any performance hit. This supports f-strings, contrary to `ast.literal_eval`. We have to support all string literal notations: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py index a2239469a3..c0a7725f93 100644 --- a/pylint/checkers/typecheck.py +++ b/pylint/checkers/typecheck.py @@ -55,8 +55,7 @@ # 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 -"""try to find more bugs in the code using astroid inference capabilities -""" +"""try to find more bugs in the code using astroid inference capabilities""" import fnmatch import heapq @@ -1137,9 +1136,7 @@ def _get_nomember_msgid_hint(self, node, owner): "non-str-assignment-to-dunder-name", ) def visit_assign(self, node: nodes.Assign) -> None: - """ - Process assignments in the AST. - """ + """Process assignments in the AST.""" self._check_assignment_from_function_call(node) self._check_dundername_is_string(node) @@ -1193,9 +1190,7 @@ def _check_assignment_from_function_call(self, node): self.add_message("assignment-from-none", node=node) def _check_dundername_is_string(self, node): - """ - Check a string is assigned to self.__name__ - """ + """Check a string is assigned to self.__name__""" # Check the left-hand side of the assignment is .__name__ lhs = node.targets[0] @@ -1216,8 +1211,7 @@ def _check_dundername_is_string(self, node): self.add_message("non-str-assignment-to-dunder-name", node=node) def _check_uninferable_call(self, node): - """ - Check that the given uninferable Call node does not + """Check that the given uninferable Call node does not call an actual function. """ if not isinstance(node.func, nodes.Attribute): @@ -1979,8 +1973,7 @@ def visit_for(self, node: nodes.For) -> None: class IterableChecker(BaseChecker): - """ - Checks for non-iterables used in an iterable context. + """Checks for non-iterables used in an iterable context. Contexts include: - for-statement - starargs in function call diff --git a/pylint/checkers/unsupported_version.py b/pylint/checkers/unsupported_version.py index 64078aa689..ada104ab90 100644 --- a/pylint/checkers/unsupported_version.py +++ b/pylint/checkers/unsupported_version.py @@ -68,7 +68,8 @@ def visit_decorators(self, node: nodes.Decorators) -> None: def _check_typing_final(self, node: nodes.Decorators) -> None: """Add a message when the `typing.final` decorator is used and the - py-version is lower than 3.8""" + py-version is lower than 3.8 + """ if self._py38_plus: return diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index cd72e38ee3..c20342c82e 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -57,8 +57,7 @@ # 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 -"""some functions that may be useful for various checkers -""" +"""some functions that may be useful for various checkers""" import builtins import itertools import numbers @@ -476,7 +475,8 @@ def assign_parent(node: nodes.NodeNG) -> nodes.NodeNG: def overrides_a_method(class_node: nodes.ClassDef, name: str) -> bool: """return True if is a method overridden from an ancestor - which is not the base object class""" + which is not the base object class + """ for ancestor in class_node.ancestors(): if ancestor.name == "object": continue @@ -501,7 +501,8 @@ class IncompleteFormatString(Exception): class UnsupportedFormatCharacter(Exception): """A format character in a format string is not one of the supported - format characters.""" + format characters. + """ def __init__(self, index): super().__init__(index) @@ -625,8 +626,7 @@ def collect_string_fields(format_string) -> Iterable[Optional[str]]: def parse_format_method_string( format_string: str, ) -> Tuple[List[Tuple[str, List[Tuple[bool, str]]]], int, int]: - """ - Parses a PEP 3101 format string, returning a tuple of + """Parses a PEP 3101 format string, returning a tuple of (keyword_arguments, implicit_pos_args_cnt, explicit_pos_args), where keyword_arguments is the set of mapping keys in the format string, implicit_pos_args_cnt is the number of arguments required by the format string and @@ -733,8 +733,7 @@ def get_argument_from_call( def inherit_from_std_ex(node: nodes.NodeNG) -> bool: - """ - Return whether the given class node is subclass of + """Return whether the given class node is subclass of exceptions.Exception. """ ancestors = node.ancestors() if hasattr(node, "ancestors") else [] @@ -746,8 +745,7 @@ def inherit_from_std_ex(node: nodes.NodeNG) -> bool: def error_of_type(handler: nodes.ExceptHandler, error_type) -> bool: - """ - Check if the given exception handler catches + """Check if the given exception handler catches the given error_type. The *handler* parameter is a node, representing an ExceptHandler node. @@ -908,8 +906,7 @@ def uninferable_final_decorators( def unimplemented_abstract_methods( node: nodes.ClassDef, is_abstract_cb: nodes.FunctionDef = None ) -> Dict[str, nodes.NodeNG]: - """ - Get the unimplemented abstract methods for the given *node*. + """Get the unimplemented abstract methods for the given *node*. A method can be considered abstract if the callback *is_abstract_cb* returns a ``True`` value. The check defaults to verifying that @@ -1368,8 +1365,7 @@ def is_registered_in_singledispatch_function(node: nodes.FunctionDef) -> bool: def get_node_last_lineno(node: nodes.NodeNG) -> int: - """ - Get the last lineno of the given node. For a simple statement this will just be node.lineno, + """Get the last lineno of the given node. For a simple statement this will just be node.lineno, but for a node that has child statements (e.g. a method) this will be the lineno of the last child statement recursively. """ @@ -1440,8 +1436,7 @@ def is_node_in_type_annotation_context(node: nodes.NodeNG) -> bool: def is_subclass_of(child: nodes.ClassDef, parent: nodes.ClassDef) -> bool: - """ - Check if first node is a subclass of second node. + """Check if first node is a subclass of second node. :param child: Node to check for subclass. :param parent: Node to check for superclass. :returns: True if child is derived from parent. False otherwise. @@ -1588,8 +1583,7 @@ def get_iterating_dictionary_name( def get_subscript_const_value(node: nodes.Subscript) -> nodes.Const: - """ - Returns the value 'subscript.slice' of a Subscript node. + """Returns the value 'subscript.slice' of a Subscript node. :param node: Subscript Node to extract value from :returns: Const Node containing subscript value diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index 8bfdc197e6..44d54cfd27 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -333,8 +333,7 @@ def _fix_dot_imports(not_consumed): def _find_frame_imports(name, frame): - """ - Detect imports in the frame, with the required + """Detect imports in the frame, with the required *name*. Such imports can be considered assignments. Returns True if an import for the given name was found. """ @@ -369,9 +368,7 @@ def _flattened_scope_names(iterator): def _assigned_locally(name_node): - """ - Checks if name_node has corresponding assign statement in same scope - """ + """Checks if name_node has corresponding assign statement in same scope""" assign_stmts = name_node.scope().nodes_of_class(nodes.AssignName) return any(a.name == name_node.name for a in assign_stmts) @@ -545,9 +542,7 @@ def _has_locals_call_after_node(stmt, scope): class NamesConsumer: - """ - A simple class to handle consumed, to consume and scope type info of node locals - """ + """A simple class to handle consumed, to consume and scope type info of node locals""" def __init__(self, node, scope_type): self._atomic = ScopeConsumer( @@ -584,8 +579,7 @@ def consumed(self): @property def consumed_uncertain(self) -> DefaultDict[str, List[nodes.NodeNG]]: - """ - Retrieves nodes filtered out by get_next_to_consume() that may not + """Retrieves nodes filtered out by get_next_to_consume() that may not have executed, such as statements in except blocks, or statements in try blocks (when evaluating their corresponding except and finally blocks). Checkers that want to treat the statements as executed @@ -598,8 +592,7 @@ def scope_type(self): return self._atomic.scope_type def mark_as_consumed(self, name, consumed_nodes): - """ - Mark the given nodes as consumed for the name. + """Mark the given nodes as consumed for the name. If all of the nodes for the name were consumed, delete the name from the to_consume dictionary """ @@ -612,8 +605,7 @@ def mark_as_consumed(self, name, consumed_nodes): del self.to_consume[name] def get_next_to_consume(self, node): - """ - Return a list of the nodes that define `node` from this scope. If it is + """Return a list of the nodes that define `node` from this scope. If it is uncertain whether a node will be consumed, such as for statements in except blocks, add it to self.consumed_uncertain instead of returning it. Return None to indicate a special case that needs to be handled by the caller. @@ -700,8 +692,7 @@ def get_next_to_consume(self, node): @staticmethod def _uncertain_nodes_in_except_blocks(found_nodes, node, node_statement): - """ - Return any nodes in ``found_nodes`` that should be treated as uncertain + """Return any nodes in ``found_nodes`` that should be treated as uncertain because they are in an except block. """ uncertain_nodes = [] @@ -1846,8 +1837,7 @@ def _is_never_evaluated( return False def _ignore_class_scope(self, node): - """ - Return True if the node is in a local class scope, as an assignment. + """Return True if the node is in a local class scope, as an assignment. :param node: Node considered :type node: astroid.Node @@ -2169,8 +2159,7 @@ def _allowed_redefined_builtin(self, name): def _has_homonym_in_upper_function_scope( self, node: nodes.Name, index: int ) -> bool: - """ - Return whether there is a node with the same name in the + """Return whether there is a node with the same name in the to_consume dict of an upper scope and if that scope is a function diff --git a/pylint/config/configuration_mixin.py b/pylint/config/configuration_mixin.py index 2d34933f08..a2abcb7528 100644 --- a/pylint/config/configuration_mixin.py +++ b/pylint/config/configuration_mixin.py @@ -7,7 +7,8 @@ class ConfigurationMixIn(OptionsManagerMixIn, OptionsProviderMixIn): """Basic mixin for simple configurations which don't need the - manager / providers model""" + manager / providers model + """ def __init__(self, *args, **kwargs): if not args: diff --git a/pylint/config/option_manager_mixin.py b/pylint/config/option_manager_mixin.py index e6e031e7df..67740d3342 100644 --- a/pylint/config/option_manager_mixin.py +++ b/pylint/config/option_manager_mixin.py @@ -332,7 +332,8 @@ def _parse_toml( def load_config_file(self): """Dispatch values previously read from a configuration file to each - option's provider""" + option's provider + """ parser = self.cfgfile_parser for section in parser.sections(): for option, value in parser.items(section): diff --git a/pylint/epylint.py b/pylint/epylint.py index a7eec3302d..5517543a4d 100755 --- a/pylint/epylint.py +++ b/pylint/epylint.py @@ -69,7 +69,8 @@ def _get_env(): """Extracts the environment PYTHONPATH and appends the current 'sys.path' - to it.""" + to it. + """ env = dict(os.environ) env["PYTHONPATH"] = os.pathsep.join(sys.path) return env diff --git a/pylint/extensions/_check_docs_utils.py b/pylint/extensions/_check_docs_utils.py index 611a04aa25..2ff86b00b8 100644 --- a/pylint/extensions/_check_docs_utils.py +++ b/pylint/extensions/_check_docs_utils.py @@ -121,8 +121,7 @@ def _split_multiple_exc_types(target: str) -> List[str]: def possible_exc_types(node: nodes.NodeNG) -> Set[nodes.ClassDef]: - """ - Gets all the possible raised exception types for the given raise node. + """Gets all the possible raised exception types for the given raise node. .. note:: @@ -401,8 +400,7 @@ def match_param_docs(self): class EpytextDocstring(SphinxDocstring): - """ - Epytext is similar to Sphinx. See the docs: + """Epytext is similar to Sphinx. See the docs: http://epydoc.sourceforge.net/epytext.html http://epydoc.sourceforge.net/fields.html#fields diff --git a/pylint/extensions/comparison_placement.py b/pylint/extensions/comparison_placement.py index c4a5cffcb0..e045ebdd01 100644 --- a/pylint/extensions/comparison_placement.py +++ b/pylint/extensions/comparison_placement.py @@ -1,8 +1,7 @@ # 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 -""" -Checks for yoda comparisons (variable before constant) +"""Checks for yoda comparisons (variable before constant) See https://en.wikipedia.org/wiki/Yoda_conditions """ diff --git a/pylint/extensions/docparams.py b/pylint/extensions/docparams.py index 8a29a947dc..8d9472fbfa 100644 --- a/pylint/extensions/docparams.py +++ b/pylint/extensions/docparams.py @@ -24,8 +24,7 @@ # 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 -"""Pylint plugin for checking in Sphinx, Google, or Numpy style docstrings -""" +"""Pylint plugin for checking in Sphinx, Google, or Numpy style docstrings""" import re from typing import TYPE_CHECKING, Optional @@ -642,8 +641,7 @@ def _handle_no_raise_doc(self, excs, node): self._add_raise_message(excs, node) def _add_raise_message(self, missing_excs, node): - """ - Adds a message on :param:`node` for the missing exception type. + """Adds a message on :param:`node` for the missing exception type. :param missing_excs: A list of missing exception types. :type missing_excs: set(str) diff --git a/pylint/extensions/mccabe.py b/pylint/extensions/mccabe.py index d4e752f48c..d675087fe1 100644 --- a/pylint/extensions/mccabe.py +++ b/pylint/extensions/mccabe.py @@ -181,7 +181,8 @@ class McCabeMethodChecker(checkers.BaseChecker): @check_messages("too-complex") def visit_module(self, node: nodes.Module) -> None: """visit an astroid.Module node to check too complex rating and - add message if is greater than max_complexity stored from options""" + add message if is greater than max_complexity stored from options + """ visitor = PathGraphingAstVisitor() for child in node.body: visitor.preorder(child, visitor) diff --git a/pylint/extensions/overlapping_exceptions.py b/pylint/extensions/overlapping_exceptions.py index ef6afefea0..9729fd112e 100644 --- a/pylint/extensions/overlapping_exceptions.py +++ b/pylint/extensions/overlapping_exceptions.py @@ -19,7 +19,8 @@ class OverlappingExceptionsChecker(checkers.BaseChecker): """Checks for two or more exceptions in the same exception handler clause that are identical or parts of the same inheritance hierarchy - (i.e. overlapping).""" + (i.e. overlapping). + """ __implements__ = interfaces.IAstroidChecker diff --git a/pylint/lint/expand_modules.py b/pylint/lint/expand_modules.py index 7a0dc7004f..4d3600a000 100644 --- a/pylint/lint/expand_modules.py +++ b/pylint/lint/expand_modules.py @@ -18,7 +18,8 @@ def _is_package_cb(inner_path, parts): def get_python_path(filepath: str) -> str: """TODO This get the python path with the (bad) assumption that there is always - an __init__.py. This is not true since python 3.3 and is causing problem.""" + an __init__.py. This is not true since python 3.3 and is causing problem. + """ dirname = os.path.realpath(os.path.expanduser(filepath)) if not os.path.isdir(dirname): dirname = os.path.dirname(dirname) diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py index 49ddb29ad9..8b1993b4ea 100644 --- a/pylint/lint/pylinter.py +++ b/pylint/lint/pylinter.py @@ -542,7 +542,8 @@ def __init__( pylintrc=None, ): """Some stuff has to be done before ancestors initialization... - messages store / checkers / reporter / astroid manager""" + messages store / checkers / reporter / astroid manager + """ # Attributes for reporters self.reporter: Union[reporters.BaseReporter, reporters.MultiReporter] if reporter: @@ -851,7 +852,8 @@ def list_messages_enabled(self): def process_tokens(self, tokens): """Process tokens from the current module to search for module/block level - options.""" + options. + """ control_pragmas = {"disable", "disable-next", "enable"} prev_line = None saw_newline = True @@ -1464,7 +1466,8 @@ def _add_one_message( end_col_offset: Optional[int], ) -> None: """After various checks have passed a single Message is - passed to the reporter and added to stats""" + passed to the reporter and added to stats + """ message_definition.check_message_definition(line, node) # Look up "location" data of node if not yet supplied @@ -1698,7 +1701,8 @@ def _register_by_id_managed_msg( self, msgid_or_symbol: str, line: Optional[int], is_disabled: bool = True ) -> None: """If the msgid is a numeric one, then register it to inform the user - it could furnish instead a symbolic msgid.""" + it could furnish instead a symbolic msgid. + """ if msgid_or_symbol[1:].isdigit(): try: symbol = self.msgs_store.message_id_store.get_symbol( diff --git a/pylint/message/message_id_store.py b/pylint/message/message_id_store.py index a16d12bfed..c4d1f4e8f7 100644 --- a/pylint/message/message_id_store.py +++ b/pylint/message/message_id_store.py @@ -52,7 +52,8 @@ def add_msgid_and_symbol(self, msgid: str, symbol: str) -> None: """Add valid message id. There is a little duplication with add_legacy_msgid_and_symbol to avoid a function call, - this is called a lot at initialization.""" + this is called a lot at initialization. + """ self.__msgid_to_symbol[msgid] = symbol self.__symbol_to_msgid[symbol] = msgid @@ -62,7 +63,8 @@ def add_legacy_msgid_and_symbol( """Add valid legacy message id. There is a little duplication with add_msgid_and_symbol to avoid a function call, - this is called a lot at initialization.""" + this is called a lot at initialization. + """ self.__msgid_to_symbol[msgid] = symbol self.__symbol_to_msgid[symbol] = msgid existing_old_names = self.__old_names.get(msgid, []) diff --git a/pylint/pyreverse/__init__.py b/pylint/pyreverse/__init__.py index fdbbe1e832..3902445224 100644 --- a/pylint/pyreverse/__init__.py +++ b/pylint/pyreverse/__init__.py @@ -1,8 +1,6 @@ # 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 -""" -pyreverse.extensions -""" +"""pyreverse.extensions""" __revision__ = "$Id $" diff --git a/pylint/pyreverse/diadefslib.py b/pylint/pyreverse/diadefslib.py index aee686da52..1e059dea31 100644 --- a/pylint/pyreverse/diadefslib.py +++ b/pylint/pyreverse/diadefslib.py @@ -19,8 +19,7 @@ # 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 -"""handle diagram generation options for class diagram or default diagrams -""" +"""handle diagram generation options for class diagram or default diagrams""" from typing import Any, Optional diff --git a/pylint/pyreverse/dot_printer.py b/pylint/pyreverse/dot_printer.py index c2fd62fb9b..fb7f3d8bc2 100644 --- a/pylint/pyreverse/dot_printer.py +++ b/pylint/pyreverse/dot_printer.py @@ -8,9 +8,7 @@ # 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 -""" -Class to generate files in dot format and image formats supported by Graphviz. -""" +"""Class to generate files in dot format and image formats supported by Graphviz.""" import os import subprocess import sys diff --git a/pylint/pyreverse/inspector.py b/pylint/pyreverse/inspector.py index 25819f5aa4..2c7162d7c1 100644 --- a/pylint/pyreverse/inspector.py +++ b/pylint/pyreverse/inspector.py @@ -14,8 +14,7 @@ # 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 -""" -Visitor doing some postprocessing on the astroid tree. +"""Visitor doing some postprocessing on the astroid tree. Try to resolve definitions (namespace) dictionary, relationship... """ import collections diff --git a/pylint/pyreverse/main.py b/pylint/pyreverse/main.py index c48b9f3c30..f96c07a596 100644 --- a/pylint/pyreverse/main.py +++ b/pylint/pyreverse/main.py @@ -20,8 +20,7 @@ # 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 -""" - %prog [options] +"""%prog [options] create UML diagrams for classes and modules in """ diff --git a/pylint/pyreverse/mermaidjs_printer.py b/pylint/pyreverse/mermaidjs_printer.py index d215b559d1..bf12fa2ec3 100644 --- a/pylint/pyreverse/mermaidjs_printer.py +++ b/pylint/pyreverse/mermaidjs_printer.py @@ -3,9 +3,7 @@ # 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 -""" -Class to generate files in mermaidjs format -""" +"""Class to generate files in mermaidjs format""" from typing import Dict, Optional from pylint.pyreverse.printer import EdgeType, NodeProperties, NodeType, Printer diff --git a/pylint/pyreverse/plantuml_printer.py b/pylint/pyreverse/plantuml_printer.py index c73cddd5e1..be49c51eba 100644 --- a/pylint/pyreverse/plantuml_printer.py +++ b/pylint/pyreverse/plantuml_printer.py @@ -3,9 +3,7 @@ # 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 -""" -Class to generate files in dot format and image formats supported by Graphviz. -""" +"""Class to generate files in dot format and image formats supported by Graphviz.""" from typing import Dict, Optional from pylint.pyreverse.printer import EdgeType, Layout, NodeProperties, NodeType, Printer diff --git a/pylint/pyreverse/printer.py b/pylint/pyreverse/printer.py index 0a8715011e..0fdee79fd4 100644 --- a/pylint/pyreverse/printer.py +++ b/pylint/pyreverse/printer.py @@ -7,9 +7,7 @@ # 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 -""" -Base class defining the interface for a printer. -""" +"""Base class defining the interface for a printer.""" from abc import ABC, abstractmethod from enum import Enum from typing import List, NamedTuple, Optional diff --git a/pylint/pyreverse/utils.py b/pylint/pyreverse/utils.py index e220617816..454b9dfc9e 100644 --- a/pylint/pyreverse/utils.py +++ b/pylint/pyreverse/utils.py @@ -270,7 +270,8 @@ def get_annotation( def infer_node(node: Union[nodes.AssignAttr, nodes.AssignName]) -> set: """Return a set containing the node annotation if it exists - otherwise return a set of the inferred types using the NodeNG.infer method""" + otherwise return a set of the inferred types using the NodeNG.infer method + """ ann = get_annotation(node) try: @@ -286,7 +287,8 @@ def infer_node(node: Union[nodes.AssignAttr, nodes.AssignName]) -> set: def check_graphviz_availability(): """Check if the ``dot`` command is available on the machine. This is needed if image output is desired and ``dot`` is used to convert - from *.dot or *.gv into the final output format.""" + from *.dot or *.gv into the final output format. + """ if shutil.which("dot") is None: print( "The requested output format is currently not available.\n" diff --git a/pylint/reporters/multi_reporter.py b/pylint/reporters/multi_reporter.py index 3eb75181e9..61740908dd 100644 --- a/pylint/reporters/multi_reporter.py +++ b/pylint/reporters/multi_reporter.py @@ -49,8 +49,7 @@ def out(self): @out.setter def out(self, output: Optional[AnyFile] = None): - """ - MultiReporter doesn't have its own output. This method is only + """MultiReporter doesn't have its own output. This method is only provided for API parity with BaseReporter and should not be called with non-None values for 'output'. """ diff --git a/pylint/reporters/text.py b/pylint/reporters/text.py index b69a3a139d..b0db63f11a 100644 --- a/pylint/reporters/text.py +++ b/pylint/reporters/text.py @@ -60,8 +60,7 @@ class MessageStyle(NamedTuple): or the color number when 256 colors are available """ style: Tuple[str, ...] = () - """Tuple of style strings (see `ANSI_COLORS` for available values). - """ + """Tuple of style strings (see `ANSI_COLORS` for available values).""" ColorMappingDict = Dict[str, MessageStyle] diff --git a/pylint/testutils/lint_module_test.py b/pylint/testutils/lint_module_test.py index 8dbf5e60b4..9bbf00d2fa 100644 --- a/pylint/testutils/lint_module_test.py +++ b/pylint/testutils/lint_module_test.py @@ -142,7 +142,8 @@ def multiset_difference( ) -> Tuple[MessageCounter, Dict[Tuple[int, str], int]]: """Takes two multisets and compares them. - A multiset is a dict with the cardinality of the key as the value.""" + A multiset is a dict with the cardinality of the key as the value. + """ missing = expected_entries.copy() missing.subtract(actual_entries) unexpected = {} diff --git a/pylint/testutils/output_line.py b/pylint/testutils/output_line.py index 9c0c762395..fe80247957 100644 --- a/pylint/testutils/output_line.py +++ b/pylint/testutils/output_line.py @@ -104,7 +104,8 @@ def _get_column(column: str) -> int: @staticmethod def _get_py38_none_value(value: T, check_endline: bool) -> Optional[T]: """Used to make end_line and end_column None as indicated by our version compared to - `min_pyver_end_position`.""" + `min_pyver_end_position`. + """ if not check_endline: return None # pragma: no cover return value diff --git a/pylint/testutils/pyreverse.py b/pylint/testutils/pyreverse.py index f70fe540f7..ac72def41c 100644 --- a/pylint/testutils/pyreverse.py +++ b/pylint/testutils/pyreverse.py @@ -8,7 +8,8 @@ # A NamedTuple is not possible as some tests need to modify attributes during the test. class PyreverseConfig: # pylint: disable=too-many-instance-attributes, too-many-arguments """Holds the configuration options for Pyreverse. - The default values correspond to the defaults of the options' parser.""" + The default values correspond to the defaults of the options' parser. + """ def __init__( self, diff --git a/pylint/utils/pragma_parser.py b/pylint/utils/pragma_parser.py index 1cd1213a7b..df506465db 100644 --- a/pylint/utils/pragma_parser.py +++ b/pylint/utils/pragma_parser.py @@ -61,13 +61,10 @@ def emit_pragma_representer(action: str, messages: List[str]) -> PragmaRepresent class PragmaParserError(Exception): - """ - A class for exceptions thrown by pragma_parser module - """ + """A class for exceptions thrown by pragma_parser module""" def __init__(self, message: str, token: str) -> None: - """ - :args message: explain the reason why the exception has been thrown + """:args message: explain the reason why the exception has been thrown :args token: token concerned by the exception """ self.message = message @@ -76,15 +73,11 @@ def __init__(self, message: str, token: str) -> None: class UnRecognizedOptionError(PragmaParserError): - """ - Thrown in case the of a valid but unrecognized option - """ + """Thrown in case the of a valid but unrecognized option""" class InvalidPragmaError(PragmaParserError): - """ - Thrown in case the pragma is invalid - """ + """Thrown in case the pragma is invalid""" def parse_pragma(pylint_pragma: str) -> Generator[PragmaRepresenter, None, None]: diff --git a/script/bump_changelog.py b/script/bump_changelog.py index 6b8e4abbff..6e25719d4c 100644 --- a/script/bump_changelog.py +++ b/script/bump_changelog.py @@ -1,9 +1,7 @@ # ORIGINAL here: https://github.com/PyCQA/astroid/blob/main/script/bump_changelog.py # DO NOT MODIFY DIRECTLY -""" -This script permits to upgrade the changelog in astroid or pylint when releasing a version. -""" +"""This script permits to upgrade the changelog in astroid or pylint when releasing a version.""" # pylint: disable=logging-fstring-interpolation import argparse import enum diff --git a/tests/benchmark/test_baseline_benchmarks.py b/tests/benchmark/test_baseline_benchmarks.py index 58939fd4db..5227ca5ae1 100644 --- a/tests/benchmark/test_baseline_benchmarks.py +++ b/tests/benchmark/test_baseline_benchmarks.py @@ -40,7 +40,8 @@ class SleepingChecker(BaseChecker): """A checker that sleeps, the wall-clock time should reduce as we add workers As we apply a roughly constant amount of "work" in this checker any variance is - likely to be caused by the pylint system.""" + likely to be caused by the pylint system. + """ __implements__ = (pylint.interfaces.IRawChecker,) @@ -57,7 +58,8 @@ class SleepingChecker(BaseChecker): def process_module(self, _node: nodes.Module) -> None: """Sleeps for `sleep_duration` on each call - This effectively means each file costs ~`sleep_duration`+framework overhead""" + This effectively means each file costs ~`sleep_duration`+framework overhead + """ time.sleep(self.sleep_duration) @@ -65,7 +67,8 @@ class SleepingCheckerLong(BaseChecker): """A checker that sleeps, the wall-clock time should reduce as we add workers As we apply a roughly constant amount of "work" in this checker any variance is - likely to be caused by the pylint system.""" + likely to be caused by the pylint system. + """ __implements__ = (pylint.interfaces.IRawChecker,) @@ -82,7 +85,8 @@ class SleepingCheckerLong(BaseChecker): def process_module(self, _node: nodes.Module) -> None: """Sleeps for `sleep_duration` on each call - This effectively means each file costs ~`sleep_duration`+framework overhead""" + This effectively means each file costs ~`sleep_duration`+framework overhead + """ time.sleep(self.sleep_duration) @@ -111,7 +115,8 @@ class TestEstablishBaselineBenchmarks: """Naive benchmarks for the high-level pylint framework Because this benchmarks the fundamental and common parts and changes seen here will - impact everything else""" + impact everything else + """ empty_filepath = _empty_filepath() empty_file_info = FileItem( @@ -176,7 +181,8 @@ def test_baseline_lots_of_files_j1(self, benchmark): """Establish a baseline with only 'master' checker being run in -j1 We do not register any checkers except the default 'master', so the cost is just - that of the system with a lot of files registered""" + that of the system with a lot of files registered + """ if benchmark.disabled: benchmark(print, "skipping, only benchmark large file counts") return # _only_ run this test is profiling @@ -195,7 +201,8 @@ def test_baseline_lots_of_files_j10(self, benchmark): As with the -j1 variant above `test_baseline_lots_of_files_j1`, we do not register any checkers except the default 'master', so the cost is just that of - the check_parallel system across 10 workers, plus the overhead of PyLinter""" + the check_parallel system across 10 workers, plus the overhead of PyLinter + """ if benchmark.disabled: benchmark(print, "skipping, only benchmark large file counts") return # _only_ run this test is profiling @@ -213,7 +220,8 @@ def test_baseline_lots_of_files_j1_empty_checker(self, benchmark): """Baselines pylint for a single extra checker being run in -j1, for N-files We use a checker that does no work, so the cost is just that of the system at - scale""" + scale + """ if benchmark.disabled: benchmark(print, "skipping, only benchmark large file counts") return # _only_ run this test is profiling @@ -232,7 +240,8 @@ def test_baseline_lots_of_files_j10_empty_checker(self, benchmark): """Baselines pylint for a single extra checker being run in -j10, for N-files We use a checker that does no work, so the cost is just that of the system at - scale, across workers""" + scale, across workers + """ if benchmark.disabled: benchmark(print, "skipping, only benchmark large file counts") return # _only_ run this test is profiling @@ -254,7 +263,8 @@ def test_baseline_benchmark_j1_single_working_checker(self, benchmark): impact of running a simple system with -j1 against the same system with -j10. We expect this benchmark to take very close to - `numfiles*SleepingChecker.sleep_duration`""" + `numfiles*SleepingChecker.sleep_duration` + """ if benchmark.disabled: benchmark(print, "skipping, do not want to sleep in main tests") return # _only_ run this test is profiling @@ -279,7 +289,8 @@ def test_baseline_benchmark_j10_single_working_checker(self, benchmark): `error_margin*(1/J)*(numfiles*SleepingChecker.sleep_duration)` Because of the cost of the framework and system the performance difference will - *not* be 1/10 of -j1 versions.""" + *not* be 1/10 of -j1 versions. + """ if benchmark.disabled: benchmark(print, "skipping, do not want to sleep in main tests") return # _only_ run this test is profiling diff --git a/tests/checkers/unittest_design.py b/tests/checkers/unittest_design.py index fd9c78f0e2..faf8f6e9e0 100644 --- a/tests/checkers/unittest_design.py +++ b/tests/checkers/unittest_design.py @@ -56,7 +56,8 @@ def test_exclude_too_few_methods_with_value(self) -> None: def test_ignore_paths_with_no_value(self) -> None: """Test exclude-too-few-public-methods option with no value. - Compare against actual list to see if validator works.""" + Compare against actual list to see if validator works. + """ options = get_global_option(self.checker, "exclude-too-few-public-methods") assert options == [] diff --git a/tests/checkers/unittest_format.py b/tests/checkers/unittest_format.py index 1fdb0f8bce..8aa7ec0c78 100644 --- a/tests/checkers/unittest_format.py +++ b/tests/checkers/unittest_format.py @@ -109,7 +109,8 @@ def testCheckKeywordParensHandlesUnnecessaryParens(self) -> None: def testNoSuperfluousParensWalrusOperatorIf(self) -> None: """Parenthesis change the meaning of assignment in the walrus operator - and so are not always superfluous:""" + and so are not always superfluous: + """ cases = [ ("if (odd := is_odd(i))\n"), ("not (foo := 5)\n"), @@ -177,8 +178,7 @@ def test_encoding_token(self) -> None: def test_disable_global_option_end_of_line() -> None: - """ - Test for issue with disabling tokenizer messages + """Test for issue with disabling tokenizer messages that extend beyond the scope of the ast tokens """ file_ = tempfile.NamedTemporaryFile("w", delete=False) diff --git a/tests/checkers/unittest_stdlib.py b/tests/checkers/unittest_stdlib.py index 9529af3ada..88f5c79229 100644 --- a/tests/checkers/unittest_stdlib.py +++ b/tests/checkers/unittest_stdlib.py @@ -45,7 +45,8 @@ def test_deprecated_no_qname_on_unexpected_nodes(self) -> None: While this test might seem weird since it uses a transform, it's actually testing a crash that happened in production, but there was no way to retrieve the code for which this - occurred (how an AssignAttr got to be the result of a function inference beats me...)""" + occurred (how an AssignAttr got to be the result of a function inference beats me...) + """ def infer_func( node: Name, context: Optional[Any] = None diff --git a/tests/checkers/unittest_variables.py b/tests/checkers/unittest_variables.py index a59278bb99..f42c3fbae6 100644 --- a/tests/checkers/unittest_variables.py +++ b/tests/checkers/unittest_variables.py @@ -198,7 +198,8 @@ def test_nested_lambda(self) -> None: @set_config(ignored_argument_names=re.compile("arg")) def test_ignored_argument_names_no_message(self) -> None: """Make sure is_ignored_argument_names properly ignores - function arguments""" + function arguments + """ node = astroid.parse( """ def fooby(arg): diff --git a/tests/config/test_functional_config_loading.py b/tests/config/test_functional_config_loading.py index 0dacb69739..1937435f73 100644 --- a/tests/config/test_functional_config_loading.py +++ b/tests/config/test_functional_config_loading.py @@ -1,8 +1,7 @@ # 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 -""" -This launches the configuration functional tests. This permits to test configuration +"""This launches the configuration functional tests. This permits to test configuration files by providing a file with the appropriate extension in the ``tests/config/functional`` directory. diff --git a/tests/config/unittest_config.py b/tests/config/unittest_config.py index d98b2a7a1b..72474abe3f 100644 --- a/tests/config/unittest_config.py +++ b/tests/config/unittest_config.py @@ -77,7 +77,8 @@ def test__regexp_csv_validator_invalid() -> None: class TestPyLinterOptionSetters(CheckerTestCase): """Class to check the set_config decorator and get_global_option util - for options declared in PyLinter.""" + for options declared in PyLinter. + """ class Checker(BaseChecker): name = "checker" @@ -98,7 +99,8 @@ def test_ignore_paths_with_value(self) -> None: def test_ignore_paths_with_no_value(self) -> None: """Test ignore-paths option with no value. - Compare against actual list to see if validator works.""" + Compare against actual list to see if validator works. + """ options = get_global_option(self.checker, "ignore-paths") assert options == [] diff --git a/tests/pyreverse/test_diadefs.py b/tests/pyreverse/test_diadefs.py index b172792808..5fe73bf36f 100644 --- a/tests/pyreverse/test_diadefs.py +++ b/tests/pyreverse/test_diadefs.py @@ -128,7 +128,8 @@ def test_functional_relation_extraction( self, default_config: PyreverseConfig, get_project: Callable ) -> None: """functional test of relations extraction; - different classes possibly in different modules""" + different classes possibly in different modules + """ # XXX should be catching pyreverse environment problem but doesn't # pyreverse doesn't extract the relations but this test ok project = get_project("data") diff --git a/tests/pyreverse/test_inspector.py b/tests/pyreverse/test_inspector.py index dec38f541c..6fff4e5fc0 100644 --- a/tests/pyreverse/test_inspector.py +++ b/tests/pyreverse/test_inspector.py @@ -13,9 +13,7 @@ # 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 -""" - for the visitors.diadefs module -""" +"""for the visitors.diadefs module""" # pylint: disable=redefined-outer-name import os diff --git a/tests/pyreverse/test_printer_factory.py b/tests/pyreverse/test_printer_factory.py index f2ad7106aa..f39b90dade 100644 --- a/tests/pyreverse/test_printer_factory.py +++ b/tests/pyreverse/test_printer_factory.py @@ -3,9 +3,7 @@ # 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 -""" -Unit tests for pylint.pyreverse.printer_factory -""" +"""Unit tests for pylint.pyreverse.printer_factory""" import pytest diff --git a/tests/pyreverse/test_utils.py b/tests/pyreverse/test_utils.py index c631917d9e..94ee858e09 100644 --- a/tests/pyreverse/test_utils.py +++ b/tests/pyreverse/test_utils.py @@ -109,7 +109,8 @@ def test_infer_node_2(mock_infer: Any, mock_get_annotation: Any) -> None: def test_infer_node_3() -> None: """Return a set containing a nodes.ClassDef object when the attribute - has a type annotation""" + has a type annotation + """ node = astroid.extract_node( """ class Component: diff --git a/tests/pyreverse/test_writer.py b/tests/pyreverse/test_writer.py index b436b65e9b..426cef68e1 100644 --- a/tests/pyreverse/test_writer.py +++ b/tests/pyreverse/test_writer.py @@ -17,9 +17,7 @@ # 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 -""" -Unit test for ``DiagramWriter`` -""" +"""Unit test for ``DiagramWriter``""" import codecs diff --git a/tests/test_check_parallel.py b/tests/test_check_parallel.py index bc27530f3b..738b3061c2 100644 --- a/tests/test_check_parallel.py +++ b/tests/test_check_parallel.py @@ -359,7 +359,8 @@ def test_sequential_checkers_work(self) -> None: 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""" + This is *not* the same -j1 and does not happen under normal operation + """ linter = PyLinter(reporter=Reporter()) linter.register_checker(SequentialTestChecker(linter)) @@ -429,7 +430,8 @@ def test_compare_workers_to_single_proc(self, num_files, num_jobs, num_checkers) number of checkers applied. This test becomes more important if we want to change how we parametrise the - checkers, for example if we aim to batch the files across jobs.""" + checkers, for example if we aim to batch the files across jobs. + """ # define the stats we expect to get back from the runs, these should only vary # with the number of files. diff --git a/tests/test_func.py b/tests/test_func.py index 575773bb9d..3e6bf36ce1 100644 --- a/tests/test_func.py +++ b/tests/test_func.py @@ -39,7 +39,8 @@ 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""" + This function is not typed because it is legacy code + """ return f"in {ex.file}\n:: {', '.join(ex.args)}" diff --git a/tests/test_self.py b/tests/test_self.py index 9f33d745c9..99bf56280d 100644 --- a/tests/test_self.py +++ b/tests/test_self.py @@ -183,8 +183,7 @@ def _test_output(self, args: List[str], expected_output: str) -> None: 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 + """Run Pylint with the ``output`` option set (must be included in the ``args`` passed to this method!) and check the file content afterwards. """ out = StringIO() @@ -1164,9 +1163,7 @@ def test_fail_on_exit_code(self, args, expected): self._runtest([path, "--fail-under=-10"] + args, code=expected) def test_one_module_fatal_error(self): - """ - Fatal errors in one of several modules linted still exits non-zero. - """ + """Fatal errors in one of several modules linted still exits non-zero.""" valid_path = join(HERE, "conftest.py") invalid_path = join(HERE, "garbagePath.py") self._runtest([valid_path, invalid_path], code=1) diff --git a/tests/unittest_reporting.py b/tests/unittest_reporting.py index 29aac8640a..1ee9477593 100644 --- a/tests/unittest_reporting.py +++ b/tests/unittest_reporting.py @@ -94,7 +94,8 @@ def test_template_option_end_line(linter) -> None: def test_template_option_non_existing(linter) -> None: """Test the msg-template option with non-existent options. This makes sure that this option remains backwards compatible as new - parameters do not break on previous versions""" + parameters do not break on previous versions + """ output = StringIO() linter.reporter.out = output linter.set_option(