diff options
author | Joris Roovers <joris.roovers@gmail.com> | 2023-01-09 12:07:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-09 12:07:50 +0100 |
commit | 56ea2963b3135a811f9869effdc7009ea43998ed (patch) | |
tree | 2edec807eb5d1c416e7e1716b60a8da285a78a7d | |
parent | 5dc7a586a9dcb1700ad9bc056737c04a15b7716b (diff) |
Ruff: additional style enforcement (#407)
Enable additional styling rules for ruff and fix related violations.
-rw-r--r-- | docs/index.md | 3 | ||||
-rw-r--r-- | gitlint-core/gitlint/cli.py | 36 | ||||
-rw-r--r-- | gitlint-core/gitlint/config.py | 4 | ||||
-rw-r--r-- | gitlint-core/gitlint/exception.py | 2 | ||||
-rw-r--r-- | gitlint-core/gitlint/git.py | 2 | ||||
-rw-r--r-- | gitlint-core/gitlint/options.py | 1 | ||||
-rw-r--r-- | gitlint-core/gitlint/rule_finder.py | 6 | ||||
-rw-r--r-- | gitlint-core/gitlint/rules.py | 16 | ||||
-rw-r--r-- | gitlint-core/gitlint/shell.py | 4 | ||||
-rw-r--r-- | gitlint-core/gitlint/tests/base.py | 4 | ||||
-rw-r--r-- | gitlint-core/gitlint/tests/cli/test_cli.py | 3 | ||||
-rw-r--r-- | gitlint-core/gitlint/tests/cli/test_cli_hooks.py | 114 | ||||
-rw-r--r-- | gitlint-core/gitlint/tests/config/test_config.py | 2 | ||||
-rw-r--r-- | gitlint-core/gitlint/tests/config/test_config_builder.py | 3 | ||||
-rw-r--r-- | gitlint-core/gitlint/tests/git/test_git_commit.py | 8 | ||||
-rw-r--r-- | gitlint-core/gitlint/utils.py | 5 | ||||
-rw-r--r-- | pyproject.toml | 30 | ||||
-rw-r--r-- | qa/base.py | 6 | ||||
-rw-r--r-- | qa/shell.py | 11 | ||||
-rw-r--r-- | qa/test_stdin.py | 2 |
20 files changed, 118 insertions, 144 deletions
diff --git a/docs/index.md b/docs/index.md index 91daea5..521242f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,7 +30,8 @@ useful throughout the years. - **User-defined rules:** Want to do more then what gitlint offers out of the box? Write your own [user defined rules](user_defined_rules.md). - **Full unicode support:** Lint your Russian, Chinese or Emoji commit messages with ease! - **Production-ready:** Gitlint checks a lot of the boxes you're looking for: actively maintained, high unit test coverage, integration tests, - python code standards (pep8, pylint), good documentation, widely used, proven track record. + python code standards ([black](https://github.com/psf/black), [ruff](https://github.com/charliermarsh/ruff)), + good documentation, widely used, proven track record. ## Getting Started ### Installation diff --git a/gitlint-core/gitlint/cli.py b/gitlint-core/gitlint/cli.py index d10512a..4433ec3 100644 --- a/gitlint-core/gitlint/cli.py +++ b/gitlint-core/gitlint/cli.py @@ -42,8 +42,6 @@ LOG = logging.getLogger("gitlint.cli") class GitLintUsageError(GitlintError): """Exception indicating there is an issue with how gitlint is used.""" - pass - def setup_logging(): """Setup gitlint logging""" @@ -247,40 +245,40 @@ class ContextObj: # fmt: off -@click.group(invoke_without_command=True, context_settings={'max_content_width': 120}, +@click.group(invoke_without_command=True, context_settings={"max_content_width": 120}, epilog="When no COMMAND is specified, gitlint defaults to 'gitlint lint'.") -@click.option('--target', envvar='GITLINT_TARGET', +@click.option("--target", envvar="GITLINT_TARGET", type=click.Path(exists=True, resolve_path=True, file_okay=False, readable=True), help="Path of the target git repository. [default: current working directory]") -@click.option('-C', '--config', envvar='GITLINT_CONFIG', +@click.option("-C", "--config", envvar="GITLINT_CONFIG", type=click.Path(exists=True, dir_okay=False, readable=True, resolve_path=True), help=f"Config file location [default: {DEFAULT_CONFIG_FILE}]") -@click.option('-c', multiple=True, +@click.option("-c", multiple=True, help="Config flags in format <rule>.<option>=<value> (e.g.: -c T1.line-length=80). " + "Flag can be used multiple times to set multiple config values.") # pylint: disable=bad-continuation -@click.option('--commit', envvar='GITLINT_COMMIT', default=None, help="Hash (SHA) of specific commit to lint.") -@click.option('--commits', envvar='GITLINT_COMMITS', default=None, +@click.option("--commit", envvar="GITLINT_COMMIT", default=None, help="Hash (SHA) of specific commit to lint.") +@click.option("--commits", envvar="GITLINT_COMMITS", default=None, help="The range of commits (refspec or comma-separated hashes) to lint. [default: HEAD]") -@click.option('-e', '--extra-path', envvar='GITLINT_EXTRA_PATH', +@click.option("-e", "--extra-path", envvar="GITLINT_EXTRA_PATH", help="Path to a directory or python module with extra user-defined rules", type=click.Path(exists=True, resolve_path=True, readable=True)) -@click.option('--ignore', envvar='GITLINT_IGNORE', default="", help="Ignore rules (comma-separated by id or name).") -@click.option('--contrib', envvar='GITLINT_CONTRIB', default="", +@click.option("--ignore", envvar="GITLINT_IGNORE", default="", help="Ignore rules (comma-separated by id or name).") +@click.option("--contrib", envvar="GITLINT_CONTRIB", default="", help="Contrib rules to enable (comma-separated by id or name).") -@click.option('--msg-filename', type=click.File(encoding=gitlint.utils.DEFAULT_ENCODING), +@click.option("--msg-filename", type=click.File(encoding=gitlint.utils.DEFAULT_ENCODING), help="Path to a file containing a commit-msg.") -@click.option('--ignore-stdin', envvar='GITLINT_IGNORE_STDIN', is_flag=True, +@click.option("--ignore-stdin", envvar="GITLINT_IGNORE_STDIN", is_flag=True, help="Ignore any stdin data. Useful for running in CI server.") -@click.option('--staged', envvar='GITLINT_STAGED', is_flag=True, +@click.option("--staged", envvar="GITLINT_STAGED", is_flag=True, help="Attempt smart guesses about meta info (like author name, email, branch, changed files, etc) " + "for staged commits.") -@click.option('--fail-without-commits', envvar='GITLINT_FAIL_WITHOUT_COMMITS', is_flag=True, +@click.option("--fail-without-commits", envvar="GITLINT_FAIL_WITHOUT_COMMITS", is_flag=True, help="Hard fail when the target commit range is empty.") -@click.option('-v', '--verbose', envvar='GITLINT_VERBOSITY', count=True, default=0, - help="Verbosity, more v's for more verbose output (e.g.: -v, -vv, -vvv). [default: -vvv]", ) -@click.option('-s', '--silent', envvar='GITLINT_SILENT', is_flag=True, +@click.option("-v", "--verbose", envvar="GITLINT_VERBOSITY", count=True, default=0, + help="Verbosity, use multiple times for more verbose output (e.g.: -v, -vv, -vvv). [default: -vvv]", ) +@click.option("-s", "--silent", envvar="GITLINT_SILENT", is_flag=True, help="Silent mode (no output). Takes precedence over -v, -vv, -vvv.") -@click.option('-d', '--debug', envvar='GITLINT_DEBUG', help="Enable debugging output.", is_flag=True) +@click.option("-d", "--debug", envvar="GITLINT_DEBUG", help="Enable debugging output.", is_flag=True) @click.version_option(version=gitlint.__version__) @click.pass_context def cli( # pylint: disable=too-many-arguments diff --git a/gitlint-core/gitlint/config.py b/gitlint-core/gitlint/config.py index 600cbba..f06192e 100644 --- a/gitlint-core/gitlint/config.py +++ b/gitlint-core/gitlint/config.py @@ -296,7 +296,7 @@ class LintConfig: # pylint: disable=too-many-instance-attributes if not hasattr(self, attr_name) or attr_name[0] == "_": raise LintConfigError(f"'{option_name}' is not a valid gitlint option") - # else: + # else setattr(self, attr_name, option_value) def __eq__(self, other): @@ -386,7 +386,7 @@ class RuleCollection: """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()]: # pylint: disable=unnecessary-comprehension + for rule in list(self._rules.values()): if hasattr(rule, attr_name) and (getattr(rule, attr_name) == attr_val): del self._rules[rule.id] diff --git a/gitlint-core/gitlint/exception.py b/gitlint-core/gitlint/exception.py index bcba54e..d1e8c9c 100644 --- a/gitlint-core/gitlint/exception.py +++ b/gitlint-core/gitlint/exception.py @@ -1,4 +1,2 @@ class GitlintError(Exception): """Based Exception class for all gitlint exceptions""" - - pass diff --git a/gitlint-core/gitlint/git.py b/gitlint-core/gitlint/git.py index b6c3b21..4750171 100644 --- a/gitlint-core/gitlint/git.py +++ b/gitlint-core/gitlint/git.py @@ -21,8 +21,6 @@ LOG = logging.getLogger(__name__) class GitContextError(GitlintError): """Exception indicating there is an issue with the git context""" - pass - class GitNotInstalledError(GitContextError): def __init__(self): diff --git a/gitlint-core/gitlint/options.py b/gitlint-core/gitlint/options.py index c634ad9..ff7d9f1 100644 --- a/gitlint-core/gitlint/options.py +++ b/gitlint-core/gitlint/options.py @@ -37,7 +37,6 @@ class RuleOption: @abstractmethod def set(self, value): """Validates and sets the option's value""" - pass # pragma: no cover def __str__(self): return f"({self.name}: {self.value} ({self.description}))" diff --git a/gitlint-core/gitlint/rule_finder.py b/gitlint-core/gitlint/rule_finder.py index a3a6d17..fdc9f22 100644 --- a/gitlint-core/gitlint/rule_finder.py +++ b/gitlint-core/gitlint/rule_finder.py @@ -55,7 +55,7 @@ def find_rule_classes(extra_path): importlib.import_module(module) except Exception as e: - raise rules.UserRuleError(f"Error while importing extra-path module '{module}': {e}") + raise rules.UserRuleError(f"Error while importing extra-path module '{module}': {e}") from e # Find all rule classes in the module. We do this my inspecting all members of the module and checking # 1) is it a class, if not, skip @@ -138,13 +138,13 @@ def assert_valid_rule_class(clazz, rule_type="User-defined"): # pylint: disable if not hasattr(clazz, "validate") or not inspect.isroutine(clazz.validate): raise rules.UserRuleError(f"{rule_type} rule class '{clazz.__name__}' must have a 'validate' method") # Configuration rules must have an `apply` method - elif issubclass(clazz, rules.ConfigurationRule): + elif issubclass(clazz, rules.ConfigurationRule): # noqa: SIM102 if not hasattr(clazz, "apply") or not inspect.isroutine(clazz.apply): msg = f"{rule_type} Configuration rule class '{clazz.__name__}' must have an 'apply' method" raise rules.UserRuleError(msg) # LineRules must have a valid target: rules.CommitMessageTitle or rules.CommitMessageBody - if issubclass(clazz, rules.LineRule): + if issubclass(clazz, rules.LineRule): # noqa: SIM102 if clazz.target not in [rules.CommitMessageTitle, rules.CommitMessageBody]: msg = ( f"The target attribute of the {rule_type.lower()} LineRule class '{clazz.__name__}' " diff --git a/gitlint-core/gitlint/rules.py b/gitlint-core/gitlint/rules.py index 9cf8166..cea4645 100644 --- a/gitlint-core/gitlint/rules.py +++ b/gitlint-core/gitlint/rules.py @@ -50,40 +50,28 @@ class Rule: class ConfigurationRule(Rule): """Class representing rules that can dynamically change the configuration of gitlint during runtime.""" - pass - class CommitRule(Rule): """Class representing rules that act on an entire commit at once""" - pass - class LineRule(Rule): """Class representing rules that act on a line by line basis""" - pass - class LineRuleTarget: """Base class for LineRule targets. A LineRuleTarget specifies where a given rule will be applied (e.g. commit message title, commit message body). Each LineRule MUST have a target specified.""" - pass - class CommitMessageTitle(LineRuleTarget): """Target class used for rules that apply to a commit message title""" - pass - class CommitMessageBody(LineRuleTarget): """Target class used for rules that apply to a commit message body""" - pass - class RuleViolation: """Class representing a violation of a rule. I.e.: When a rule is broken, the rule will instantiate this class @@ -107,8 +95,6 @@ class RuleViolation: class UserRuleError(GitlintError): """Error used to indicate that an error occurred while trying to load a user rule""" - pass - class MaxLineLength(LineRule): name = "max-line-length" @@ -319,7 +305,7 @@ class BodyChangedFileMention(CommitRule): for needs_mentioned_file in self.options["files"].value: # if a file that we need to look out for is actually changed, then check whether it occurs # in the commit msg body - if needs_mentioned_file in commit.changed_files: + if needs_mentioned_file in commit.changed_files: # noqa: SIM102 if needs_mentioned_file not in " ".join(commit.message.body): violation_message = f"Body does not mention changed file '{needs_mentioned_file}'" violations.append(RuleViolation(self.id, violation_message, None, len(commit.message.body) + 1)) diff --git a/gitlint-core/gitlint/shell.py b/gitlint-core/gitlint/shell.py index 2f66f30..21dfaba 100644 --- a/gitlint-core/gitlint/shell.py +++ b/gitlint-core/gitlint/shell.py @@ -27,8 +27,6 @@ else: class CommandNotFound(Exception): """Exception indicating a command was not found during execution""" - pass - class ShResult: """Result wrapper class. We use this to more easily migrate from using https://amoffat.github.io/sh/ to using the builtin subprocess module""" @@ -45,8 +43,6 @@ else: class ErrorReturnCode(ShResult, Exception): """ShResult subclass for unexpected results (acts as an exception).""" - pass - def git(*command_parts, **kwargs): """Git shell wrapper. Implemented as separate function here, so we can do a 'sh' style imports: diff --git a/gitlint-core/gitlint/tests/base.py b/gitlint-core/gitlint/tests/base.py index 0ac51e7..7c91963 100644 --- a/gitlint-core/gitlint/tests/base.py +++ b/gitlint-core/gitlint/tests/base.py @@ -173,11 +173,11 @@ class BaseTestCase(unittest.TestCase): exception_msg = str(exc) if exception_msg != expected_msg: error = f"Right exception, wrong message:\n got: {exception_msg}\n expected: {expected_msg}" - raise self.fail(error) + raise self.fail(error) from exc # else: everything is fine, just return return except Exception as exc: - raise self.fail(f"Expected '{expected_exception.__name__}' got '{exc.__class__.__name__}'") + raise self.fail(f"Expected '{expected_exception.__name__}' got '{exc.__class__.__name__}'") from exc # No exception raised while we expected one raise self.fail(f"Expected to raise {expected_exception.__name__}, didn't get an exception at all") diff --git a/gitlint-core/gitlint/tests/cli/test_cli.py b/gitlint-core/gitlint/tests/cli/test_cli.py index 7bf3b4f..b4577c8 100644 --- a/gitlint-core/gitlint/tests/cli/test_cli.py +++ b/gitlint-core/gitlint/tests/cli/test_cli.py @@ -218,8 +218,7 @@ class CLITests(BaseTestCase): self.assertEqual(result.exit_code, 2) @patch("gitlint.cli.get_stdin_data", return_value=False) - @patch("gitlint.git.sh") - def test_lint_commit_negative(self, sh, _): + def test_lint_commit_negative(self, _): """Negative test for --commit option""" # Try using --commit and --commits at the same time (not allowed) diff --git a/gitlint-core/gitlint/tests/cli/test_cli_hooks.py b/gitlint-core/gitlint/tests/cli/test_cli_hooks.py index 641961d..cf8298a 100644 --- a/gitlint-core/gitlint/tests/cli/test_cli_hooks.py +++ b/gitlint-core/gitlint/tests/cli/test_cli_hooks.py @@ -128,68 +128,65 @@ class CLIHookTests(BaseTestCase): # When set_editors[i] == None, ensure we don't fallback to EDITOR set in shell invocating the tests os.environ.pop("EDITOR", None) - with self.patch_input(["e", "e", "n"]): - with self.tempdir() as tmpdir: - msg_filename = os.path.realpath(os.path.join(tmpdir, "hür")) - with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: - f.write(commit_messages[i] + "\n") - - with patch("gitlint.display.stderr", new=StringIO()) as stderr: - result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) - self.assertEqual( - result.output, - self.get_expected( - "cli/test_cli_hooks/test_hook_edit_1_stdout", {"commit_msg": commit_messages[i]} - ), - ) - expected = self.get_expected( - "cli/test_cli_hooks/test_hook_edit_1_stderr", {"commit_msg": commit_messages[i]} - ) - self.assertEqual(stderr.getvalue(), expected) - - # exit code = number of violations - self.assertEqual(result.exit_code, 2) - - shell.assert_called_with(expected_editors[i] + " " + msg_filename) - self.assert_log_contains("DEBUG: gitlint.cli run-hook: editing commit message") - self.assert_log_contains(f"DEBUG: gitlint.cli run-hook: {expected_editors[i]} {msg_filename}") + with self.patch_input(["e", "e", "n"]), self.tempdir() as tmpdir: + msg_filename = os.path.realpath(os.path.join(tmpdir, "hür")) + with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: + f.write(commit_messages[i] + "\n") + + with patch("gitlint.display.stderr", new=StringIO()) as stderr: + result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) + self.assertEqual( + result.output, + self.get_expected( + "cli/test_cli_hooks/test_hook_edit_1_stdout", {"commit_msg": commit_messages[i]} + ), + ) + expected = self.get_expected( + "cli/test_cli_hooks/test_hook_edit_1_stderr", {"commit_msg": commit_messages[i]} + ) + self.assertEqual(stderr.getvalue(), expected) + + # exit code = number of violations + self.assertEqual(result.exit_code, 2) + + shell.assert_called_with(expected_editors[i] + " " + msg_filename) + self.assert_log_contains("DEBUG: gitlint.cli run-hook: editing commit message") + self.assert_log_contains(f"DEBUG: gitlint.cli run-hook: {expected_editors[i]} {msg_filename}") def test_run_hook_no(self): """Test for run-hook subcommand, answering 'n(o)' after commit-hook""" - with self.patch_input(["n"]): - with self.tempdir() as tmpdir: - msg_filename = os.path.join(tmpdir, "hür") - with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: - f.write("WIP: höok no\n") + with self.patch_input(["n"]), self.tempdir() as tmpdir: + msg_filename = os.path.join(tmpdir, "hür") + with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: + f.write("WIP: höok no\n") - with patch("gitlint.display.stderr", new=StringIO()) as stderr: - result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) - self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_no_1_stdout")) - self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli_hooks/test_hook_no_1_stderr")) + with patch("gitlint.display.stderr", new=StringIO()) as stderr: + result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) + self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_no_1_stdout")) + self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli_hooks/test_hook_no_1_stderr")) - # We decided not to keep the commit message: hook returns number of violations (>0) - # This will cause git to abort the commit - self.assertEqual(result.exit_code, 2) - self.assert_log_contains("DEBUG: gitlint.cli run-hook: commit message declined") + # We decided not to keep the commit message: hook returns number of violations (>0) + # This will cause git to abort the commit + self.assertEqual(result.exit_code, 2) + self.assert_log_contains("DEBUG: gitlint.cli run-hook: commit message declined") def test_run_hook_yes(self): """Test for run-hook subcommand, answering 'y(es)' after commit-hook""" - with self.patch_input(["y"]): - with self.tempdir() as tmpdir: - msg_filename = os.path.join(tmpdir, "hür") - with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: - f.write("WIP: höok yes\n") + with self.patch_input(["y"]), self.tempdir() as tmpdir: + msg_filename = os.path.join(tmpdir, "hür") + with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: + f.write("WIP: höok yes\n") - with patch("gitlint.display.stderr", new=StringIO()) as stderr: - result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) - self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_yes_1_stdout")) - self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli_hooks/test_hook_yes_1_stderr")) + with patch("gitlint.display.stderr", new=StringIO()) as stderr: + result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) + self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_yes_1_stdout")) + self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli_hooks/test_hook_yes_1_stderr")) - # Exit code is 0 because we decide to keep the commit message - # This will cause git to keep the commit - self.assertEqual(result.exit_code, 0) - self.assert_log_contains("DEBUG: gitlint.cli run-hook: commit message accepted") + # Exit code is 0 because we decide to keep the commit message + # This will cause git to keep the commit + self.assertEqual(result.exit_code, 0) + self.assert_log_contains("DEBUG: gitlint.cli run-hook: commit message accepted") @patch("gitlint.cli.get_stdin_data", return_value=False) @patch("gitlint.git.sh") @@ -271,11 +268,10 @@ class CLIHookTests(BaseTestCase): "commit-1-branch-1\ncommit-1-branch-2\n", ] - with self.patch_input(["e"]): - with patch("gitlint.display.stderr", new=StringIO()) as stderr: - result = self.cli.invoke(cli.cli, ["run-hook"]) - expected = self.get_expected("cli/test_cli_hooks/test_hook_local_commit_1_stderr") - self.assertEqual(stderr.getvalue(), expected) - self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_local_commit_1_stdout")) - # If we can't edit the message, run-hook follows regular gitlint behavior and exit code = # violations - self.assertEqual(result.exit_code, 2) + with self.patch_input(["e"]), patch("gitlint.display.stderr", new=StringIO()) as stderr: + result = self.cli.invoke(cli.cli, ["run-hook"]) + expected = self.get_expected("cli/test_cli_hooks/test_hook_local_commit_1_stderr") + self.assertEqual(stderr.getvalue(), expected) + self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_local_commit_1_stdout")) + # If we can't edit the message, run-hook follows regular gitlint behavior and exit code = # violations + self.assertEqual(result.exit_code, 2) diff --git a/gitlint-core/gitlint/tests/config/test_config.py b/gitlint-core/gitlint/tests/config/test_config.py index e70bebe..439fd93 100644 --- a/gitlint-core/gitlint/tests/config/test_config.py +++ b/gitlint-core/gitlint/tests/config/test_config.py @@ -170,7 +170,7 @@ class LintConfigTests(BaseTestCase): # UserRuleError, RuleOptionError should be re-raised as LintConfigErrors side_effects = [rules.UserRuleError("üser-rule"), options.RuleOptionError("rüle-option")] for side_effect in side_effects: - with patch("gitlint.config.rule_finder.find_rule_classes", side_effect=side_effect): + with patch("gitlint.config.rule_finder.find_rule_classes", side_effect=side_effect): # noqa: SIM117 with self.assertRaisesMessage(LintConfigError, str(side_effect)): config.contrib = "contrib-title-conventional-commits" diff --git a/gitlint-core/gitlint/tests/config/test_config_builder.py b/gitlint-core/gitlint/tests/config/test_config_builder.py index eee4afa..ac2a896 100644 --- a/gitlint-core/gitlint/tests/config/test_config_builder.py +++ b/gitlint-core/gitlint/tests/config/test_config_builder.py @@ -254,8 +254,7 @@ class LintConfigBuilderTests(BaseTestCase): my_rule.options["regex"].set("wrong") def test_named_rules_negative(self): - # T7 = title-match-regex - # Invalid rule name + # Invalid rule name (T7 = title-match-regex) for invalid_name in ["", " ", " ", "\t", "\n", "å b", "å:b", "åb:", ":åb"]: config_builder = LintConfigBuilder() config_builder.set_option(f"T7:{invalid_name}", "regex", "tëst") diff --git a/gitlint-core/gitlint/tests/git/test_git_commit.py b/gitlint-core/gitlint/tests/git/test_git_commit.py index 4e2439c..e6b0b2c 100644 --- a/gitlint-core/gitlint/tests/git/test_git_commit.py +++ b/gitlint-core/gitlint/tests/git/test_git_commit.py @@ -379,7 +379,7 @@ class GitCommitTests(BaseTestCase): @patch("gitlint.git.sh") def test_get_latest_commit_fixup_squash_commit(self, sh): commit_prefixes = {"fixup": "is_fixup_commit", "squash": "is_squash_commit", "amend": "is_fixup_amend_commit"} - for commit_type in commit_prefixes.keys(): + for commit_type in commit_prefixes: sample_sha = "d8ac47e9f2923c7f22d8668e3a1ed04eb4cdbca9" sh.git.side_effect = [ @@ -612,7 +612,7 @@ class GitCommitTests(BaseTestCase): # mapping between cleanup commit prefixes and the commit object attribute commit_prefixes = {"fixup": "is_fixup_commit", "squash": "is_squash_commit", "amend": "is_fixup_amend_commit"} - for commit_type in commit_prefixes.keys(): + for commit_type in commit_prefixes: commit_msg = f"{commit_type}! Test message" gitcontext = GitContext.from_commit_msg(commit_msg) commit = gitcontext.commits[-1] @@ -638,7 +638,7 @@ class GitCommitTests(BaseTestCase): @patch("gitlint.git.sh") @patch("arrow.now") def test_staged_commit(self, now, sh): - # StagedLocalGitCommit() + """Test for StagedLocalGitCommit()""" sh.git.side_effect = [ "#", # git config --get core.commentchar @@ -740,7 +740,7 @@ class GitCommitTests(BaseTestCase): git.return_value = "foöbar" # Test simple equality case - now = datetime.datetime.utcnow() + now = datetime.datetime.now(datetime.timezone.utc) context1 = GitContext() commit_message1 = GitCommitMessage(context1, "tëst\n\nfoo", "tëst\n\nfoo", "tēst", ["", "föo"]) commit1 = GitCommit( diff --git a/gitlint-core/gitlint/utils.py b/gitlint-core/gitlint/utils.py index e94b2f7..20368b7 100644 --- a/gitlint-core/gitlint/utils.py +++ b/gitlint-core/gitlint/utils.py @@ -59,10 +59,7 @@ def getpreferredencoding(): # Support dotted (C.UTF-8) and non-dotted (C or UTF-8) charsets: # If encoding contains a dot: split and use second part, otherwise use everything dot_index = encoding.find(".") - if dot_index != -1: - default_encoding = encoding[dot_index + 1 :] - else: - default_encoding = encoding + default_encoding = encoding[dot_index + 1 :] if dot_index != -1 else encoding break # We've determined what encoding the user *wants*, let's now check if it's actually a valid encoding on the diff --git a/pyproject.toml b/pyproject.toml index a219f4a..3633c53 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -88,7 +88,7 @@ dependencies = [ "pytest-cov==4.0.0", "python-coveralls==2.9.3", "pylint==2.15.3", - "ruff==0.0.211", + "ruff==0.0.215", "radon==5.1.0", "pdbr==0.7.5; sys_platform != \"win32\"" ] @@ -101,10 +101,11 @@ u = "unit-tests" unit-tests-no-cov = "pytest -rw -s {args:gitlint-core}" format = "black --check --diff ." plint = "pylint gitlint-core/gitlint qa" -lint = "ruff gitlint-core/gitlint qa" +lint = "ruff {args:gitlint-core/gitlint qa}" +autoformat = "black ." autofix = [ "ruff --fix gitlint-core/gitlint qa", - "black .", + "autoformat", ] all = [ @@ -165,20 +166,33 @@ target-version = "py37" extend-exclude = ["gitlint-core/gitlint/tests/samples/user_rules/import_exception/invalid_python.py"] ignore = [ - "E501", # Never enforce `E501` (line length violations) - taken care of by black + "E501", # Never enforce `E501` (line length violations) - taken care of by black + "SIM108" # Use ternary operator instead of if-else-block ] select = [ - "E", # Pycodestyle "F", # PyFlakes - "T20", # no print statements - "UP", # pyupgrade + "E", # Pycodestyle + "W", # Pycodestyle + "I", # isort (import order) + "YTT", # flake8-2020 (misuse of sys.version) + "S", # flake8-bandit (security) + "B", # flake8-bugbear + "C4", # flake8-comprehensions (correct use of comprehensions) + "T10", # flake8-debugger (no debug statements) + "T20", # flake8-print (no print statements) + "SIM", # flake8-simplify (use simple code) + "TID", # flake8-tidy-imports (correct import syntax) + "ARG", # flake8-unused-arguments (no unused function arguments) + "DTZ", # flake8-datetimez (correct datetime usage) + "ERA", # eradicate (no commented out code) + "UP", # pyupgrade (modern python syntax) "PLC", # pylint "PLE", # pylint "PLR", # pylint "PLW", # pylint + "PIE", # flake8-pie "RUF", # ruff specific - "I", # isort ] [tool.coverage.run] @@ -6,7 +6,7 @@ import platform import shutil import sys import tempfile -from datetime import datetime |