From 61b9f38fb4c6d834065172b96118c643fd31cedf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Fri, 1 Apr 2022 23:50:21 +0200 Subject: [PATCH 1/2] Use the ``argparse`` config handler in ``class_checker.py`` --- pylint/checkers/classes/class_checker.py | 19 ++++++++++--------- pylint/config/argument.py | 24 +++++++++++++++++++++--- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/pylint/checkers/classes/class_checker.py b/pylint/checkers/classes/class_checker.py index db5d6dbb1f..deddbb8356 100644 --- a/pylint/checkers/classes/class_checker.py +++ b/pylint/checkers/classes/class_checker.py @@ -760,7 +760,7 @@ class ClassChecker(BaseChecker): ) def __init__(self, linter=None): - super().__init__(linter) + super().__init__(linter, future_option_parsing=True) self._accessed = ScopeAccessMap() self._first_attrs = [] self._meth_could_be_func = None @@ -1019,7 +1019,7 @@ def _check_attribute_defined_outside_init(self, cnode: nodes.ClassDef) -> None: # checks attributes are defined in an allowed method such as __init__ if not self.linter.is_message_enabled("attribute-defined-outside-init"): return - defining_methods = self.config.defining_attr_methods + defining_methods = self.linter.namespace.defining_attr_methods current_module = cnode.root() for attr, nodes_lst in cnode.instance_attrs.items(): # Exclude `__dict__` as it is already defined. @@ -1629,7 +1629,7 @@ def _check_protected_attribute_access(self, node: nodes.Attribute): if ( is_attr_protected(attrname) - and attrname not in self.config.exclude_protected + and attrname not in self.linter.namespace.exclude_protected ): klass = node_frame_class(node) @@ -1700,7 +1700,7 @@ def _check_protected_attribute_access(self, node: nodes.Attribute): licit_protected_member = not attrname.startswith("__") if ( - not self.config.check_protected_access_in_special_methods + not self.linter.namespace.check_protected_access_in_special_methods and licit_protected_member and self._is_called_inside_special_method(node) ): @@ -1855,8 +1855,9 @@ def _check_first_arg_for_type(self, node, metaclass=0): if node.type == "staticmethod": if ( first_arg == "self" - or first_arg in self.config.valid_classmethod_first_arg - or first_arg in self.config.valid_metaclass_classmethod_first_arg + or first_arg in self.linter.namespace.valid_classmethod_first_arg + or first_arg + in self.linter.namespace.valid_metaclass_classmethod_first_arg ): self.add_message("bad-staticmethod-argument", args=first, node=node) return @@ -1870,7 +1871,7 @@ def _check_first_arg_for_type(self, node, metaclass=0): if node.type == "classmethod": self._check_first_arg_config( first, - self.config.valid_metaclass_classmethod_first_arg, + self.linter.namespace.valid_metaclass_classmethod_first_arg, node, "bad-mcs-classmethod-argument", node.name, @@ -1879,7 +1880,7 @@ def _check_first_arg_for_type(self, node, metaclass=0): else: self._check_first_arg_config( first, - self.config.valid_classmethod_first_arg, + self.linter.namespace.valid_classmethod_first_arg, node, "bad-mcs-method-argument", node.name, @@ -1888,7 +1889,7 @@ def _check_first_arg_for_type(self, node, metaclass=0): elif node.type == "classmethod" or node.name == "__class_getitem__": self._check_first_arg_config( first, - self.config.valid_classmethod_first_arg, + self.linter.namespace.valid_classmethod_first_arg, node, "bad-classmethod-argument", node.name, diff --git a/pylint/config/argument.py b/pylint/config/argument.py index 3b9f46336b..6c32c930a1 100644 --- a/pylint/config/argument.py +++ b/pylint/config/argument.py @@ -8,22 +8,40 @@ """ -from typing import Callable, Dict, List, Optional, Union +import argparse +from typing import Callable, Dict, List, Optional, Sequence, Union from pylint import utils as pylint_utils -_ArgumentTypes = Union[str, List[str]] +_ArgumentTypes = Union[str, Sequence[str], bool] """List of possible argument types.""" -def _csv_transformer(value: str) -> List[str]: +def _csv_transformer(value: str) -> Sequence[str]: """Transforms a comma separated string.""" return pylint_utils._check_csv(value) +YES_VALUES = {"y", "yes", "true"} +NO_VALUES = {"n", "no", "false"} + + +def _yn_transformer(value: str) -> bool: + """Transforms a yes/no or stringified bool into a bool.""" + value = value.lower() + if value in YES_VALUES: + return True + if value in NO_VALUES: + return False + raise argparse.ArgumentError( + None, f"Invalid yn value '{value}', should be in (y, yes, true, n, no, false)" + ) + + _TYPE_TRANSFORMERS: Dict[str, Callable[[str], _ArgumentTypes]] = { "choice": str, "csv": _csv_transformer, + "yn": _yn_transformer, } """Type transformers for all argument types. From d5f1b995975fc2bda7ccad677ec0e115915a901b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Fri, 1 Apr 2022 23:59:24 +0200 Subject: [PATCH 2/2] Fix --- pylint/config/argument.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pylint/config/argument.py b/pylint/config/argument.py index 4dc6ff96e3..ea2f7bc8bd 100644 --- a/pylint/config/argument.py +++ b/pylint/config/argument.py @@ -14,7 +14,7 @@ from pylint import utils as pylint_utils -_ArgumentTypes = Union[str, List[str], int, Pattern[str], bool] +_ArgumentTypes = Union[str, Sequence[str], int, Pattern[str], bool] """List of possible argument types.""" @@ -35,7 +35,7 @@ def _yn_transformer(value: str) -> bool: if value in NO_VALUES: return False raise argparse.ArgumentError( - None, f"Invalid yn value '{value}', should be in (y, yes, true, n, no, false)" + None, f"Invalid yn value '{value}', should be in {*YES_VALUES, *NO_VALUES}" )