From 4fee3e091a8d79a40f70ff9c1f87b29b9340049a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 25 Jan 2021 14:26:11 +0100 Subject: Merging upstream version 0.15.0. Signed-off-by: Daniel Baumann --- gitlint/config.py | 117 +++++++++++++++++++++++------------------------------- 1 file changed, 49 insertions(+), 68 deletions(-) (limited to 'gitlint/config.py') diff --git a/gitlint/config.py b/gitlint/config.py index 4dad707..1eeb35d 100644 --- a/gitlint/config.py +++ b/gitlint/config.py @@ -1,9 +1,4 @@ -try: - # python 2.x - from ConfigParser import ConfigParser, Error as ConfigParserError -except ImportError: # pragma: no cover - # python 3.x - from configparser import ConfigParser, Error as ConfigParserError # pragma: no cover, pylint: disable=import-error +from configparser import ConfigParser, Error as ConfigParserError import copy import io @@ -12,11 +7,12 @@ import os import shutil from collections import OrderedDict -from gitlint.utils import ustr, sstr, DEFAULT_ENCODING +from gitlint.utils import DEFAULT_ENCODING from gitlint import rules # For some weird reason pylint complains about this, pylint: disable=unused-import from gitlint import options from gitlint import rule_finder from gitlint.contrib import rules as contrib_rules +from gitlint.exception import GitlintError def handle_option_error(func): @@ -27,16 +23,16 @@ def handle_option_error(func): try: return func(*args) except options.RuleOptionError as e: - raise LintConfigError(ustr(e)) + raise LintConfigError(str(e)) from e return wrapped -class LintConfigError(Exception): +class LintConfigError(GitlintError): pass -class LintConfig(object): +class LintConfig: """ Class representing gitlint configuration. Contains active config as well as number of methods to easily get/set the config. """ @@ -198,7 +194,7 @@ class LintConfig(object): self.rules.add_rules(rule_classes, {'is_user_defined': True}) except (options.RuleOptionError, rules.UserRuleError) as e: - raise LintConfigError(ustr(e)) + raise LintConfigError(str(e)) from e @property def contrib(self): @@ -219,27 +215,25 @@ class LintConfig(object): # For each specified contrib rule, check whether it exists among the contrib classes for rule_id_or_name in self.contrib: rule_class = next((rc for rc in rule_classes if - rc.id == ustr(rule_id_or_name) or rc.name == ustr(rule_id_or_name)), False) + rule_id_or_name in (rc.id, rc.name)), False) # If contrib rule exists, instantiate it and add it to the rules list if rule_class: self.rules.add_rule(rule_class, rule_class.id, {'is_contrib': True}) else: - raise LintConfigError(u"No contrib rule with id or name '{0}' found.".format(ustr(rule_id_or_name))) + raise LintConfigError(f"No contrib rule with id or name '{rule_id_or_name}' found.") except (options.RuleOptionError, rules.UserRuleError) as e: - raise LintConfigError(ustr(e)) + raise LintConfigError(str(e)) from e def _get_option(self, rule_name_or_id, option_name): - rule_name_or_id = ustr(rule_name_or_id) # convert to unicode first - option_name = ustr(option_name) rule = self.rules.find_rule(rule_name_or_id) if not rule: - raise LintConfigError(u"No such rule '{0}'".format(rule_name_or_id)) + raise LintConfigError(f"No such rule '{rule_name_or_id}'") option = rule.options.get(option_name) if not option: - raise LintConfigError(u"Rule '{0}' has no option '{1}'".format(rule_name_or_id, option_name)) + raise LintConfigError(f"Rule '{rule_name_or_id}' has no option '{option_name}'") return option @@ -256,14 +250,14 @@ class LintConfig(object): try: option.set(option_value) except options.RuleOptionError as e: - msg = u"'{0}' is not a valid value for option '{1}.{2}'. {3}." - raise LintConfigError(msg.format(option_value, rule_name_or_id, option_name, ustr(e))) + msg = f"'{option_value}' is not a valid value for option '{rule_name_or_id}.{option_name}'. {e}." + raise LintConfigError(msg) from e def set_general_option(self, option_name, option_value): attr_name = option_name.replace("-", "_") # only allow setting general options that exist and don't start with an underscore if not hasattr(self, attr_name) or attr_name[0] == "_": - raise LintConfigError(u"'{0}' is not a valid gitlint option".format(option_name)) + raise LintConfigError(f"'{option_name}' is not a valid gitlint option") # else: setattr(self, attr_name, option_value) @@ -285,30 +279,26 @@ class LintConfig(object): self.ignore == other.ignore and \ self._config_path == other._config_path # noqa - def __ne__(self, other): - return not self.__eq__(other) # required for py2 - def __str__(self): # config-path is not a user exposed variable, so don't print it under the general section - return_str = u"config-path: {0}\n".format(self._config_path) - return_str += u"[GENERAL]\n" - return_str += u"extra-path: {0}\n".format(self.extra_path) - return_str += u"contrib: {0}\n".format(sstr(self.contrib)) - return_str += u"ignore: {0}\n".format(",".join(self.ignore)) - return_str += u"ignore-merge-commits: {0}\n".format(self.ignore_merge_commits) - return_str += u"ignore-fixup-commits: {0}\n".format(self.ignore_fixup_commits) - return_str += u"ignore-squash-commits: {0}\n".format(self.ignore_squash_commits) - return_str += u"ignore-revert-commits: {0}\n".format(self.ignore_revert_commits) - return_str += u"ignore-stdin: {0}\n".format(self.ignore_stdin) - return_str += u"staged: {0}\n".format(self.staged) - return_str += u"verbosity: {0}\n".format(self.verbosity) - return_str += u"debug: {0}\n".format(self.debug) - return_str += u"target: {0}\n".format(self.target) - return_str += u"[RULES]\n{0}".format(self.rules) - return return_str - - -class RuleCollection(object): + return (f"config-path: {self._config_path}\n" + f"[GENERAL]\n" + f"extra-path: {self.extra_path}\n" + f"contrib: {self.contrib}\n" + f"ignore: {','.join(self.ignore)}\n" + f"ignore-merge-commits: {self.ignore_merge_commits}\n" + f"ignore-fixup-commits: {self.ignore_fixup_commits}\n" + f"ignore-squash-commits: {self.ignore_squash_commits}\n" + f"ignore-revert-commits: {self.ignore_revert_commits}\n" + f"ignore-stdin: {self.ignore_stdin}\n" + f"staged: {self.staged}\n" + f"verbosity: {self.verbosity}\n" + f"debug: {self.debug}\n" + f"target: {self.target}\n" + f"[RULES]\n{self.rules}") + + +class RuleCollection: """ Class representing an ordered list of rules. Methods are provided to easily retrieve, add or delete rules. """ def __init__(self, rule_classes=None, rule_attrs=None): @@ -318,8 +308,6 @@ class RuleCollection(object): self.add_rules(rule_classes, rule_attrs) def find_rule(self, rule_id_or_name): - # try finding rule by id - rule_id_or_name = ustr(rule_id_or_name) # convert to unicode first rule = self._rules.get(rule_id_or_name) # if not found, try finding rule by name if not rule: @@ -351,7 +339,7 @@ class RuleCollection(object): """ Deletes all rules from the collection that match a given attribute name and value """ # Create a new list based on _rules.values() because in python 3, values() is a ValuesView as opposed to a list # This means you can't modify the ValueView while iterating over it. - for rule in [r for r in self._rules.values()]: + for rule in [r for r in self._rules.values()]: # pylint: disable=unnecessary-comprehension if hasattr(rule, attr_name) and (getattr(rule, attr_name) == attr_val): del self._rules[rule.id] @@ -362,19 +350,13 @@ class RuleCollection(object): def __eq__(self, other): return isinstance(other, RuleCollection) and self._rules == other._rules - def __ne__(self, other): - return not self.__eq__(other) # required for py2 - def __len__(self): return len(self._rules) - def __repr__(self): - return self.__unicode__() # pragma: no cover - - def __unicode__(self): + def __str__(self): return_str = "" for rule in self._rules.values(): - return_str += u" {0}: {1}\n".format(rule.id, rule.name) + return_str += f" {rule.id}: {rule.name}\n" for option_name, option_value in sorted(rule.options.items()): if option_value.value is None: option_val_repr = None @@ -384,11 +366,11 @@ class RuleCollection(object): option_val_repr = option_value.value.pattern else: option_val_repr = option_value.value - return_str += u" {0}={1}\n".format(option_name, option_val_repr) + return_str += f" {option_name}={option_val_repr}\n" return return_str -class LintConfigBuilder(object): +class LintConfigBuilder: """ Factory class that can build gitlint config. This is primarily useful to deal with complex configuration scenarios where configuration can be set and overridden from various sources (typically according to certain precedence rules) before the actual config should be @@ -427,28 +409,27 @@ class LintConfigBuilder(object): raise ValueError() rule_name, option_name = config_name.split(".", 1) self.set_option(rule_name, option_name, option_value) - except ValueError: # raised if the config string is invalid + except ValueError as e: # raised if the config string is invalid raise LintConfigError( - u"'{0}' is an invalid configuration option. Use '.