From 1afaafab726754026a3b7425c44b1b152c84525a Mon Sep 17 00:00:00 2001 From: Sean Mooney Date: Wed, 17 Sep 2025 08:14:08 +0100 Subject: [PATCH] adopt ruff check this change adds ruff check as a pre-commit hook and ignores a number of linit error many of these will be removed in future patches As is done in other repos https://codesearch.opendev.org/?q=--unsafe-fixes&i=nope&literal=nope&files=&excludeFiles=&repos= we enable the pre-commit hook with --fix --unsafe-fixes which allows it to modify code where the intent might change but typically wont https://docs.astral.sh/ruff/linter/#fix-safety as this will be human reviewed this is safe to use in our project and allow ruff to fix more linting issues it detects. formatting is still left to autopep8 Change-Id: I46c4d462414dfa8ec4ded0defe4c3028ef14f4dd Signed-off-by: Sean Mooney --- .pre-commit-config.yaml | 5 +++ pyproject.toml | 31 +++++++++++++++++++ releasenotes/source/conf.py | 2 -- watcher/api/app.wsgi | 1 - watcher/tests/common/test_utils.py | 2 +- .../model/faker_cluster_state.py | 2 +- .../notification/test_cinder_notifications.py | 2 +- 7 files changed, 39 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 41b10b7ec..bb527cad0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -39,6 +39,11 @@ repos: hooks: - id: bandit args: ['-x', 'tests', '-s', 'B101,B311,B320'] + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.12.1 + hooks: + - id: ruff-check + args: ['--fix', '--unsafe-fixes'] - repo: https://github.com/hhatto/autopep8 rev: v2.3.2 hooks: diff --git a/pyproject.toml b/pyproject.toml index 5e862a959..f2a7006bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,34 @@ [build-system] requires = ["pbr>=6.0.0", "setuptools>=64.0.0"] build-backend = "pbr.build" + +[tool.ruff] +line-length = 79 +target-version = "py310" + +[tool.ruff.lint] +select = ["E4", "E7", "E9", "F", "S", "U"] +ignore = [ + "UP031", # Use format specifiers instead of percent format + "UP032", # Use f-string instead of `format` call + # we only use asserts for type narrowing + "S101", + # we do not use random number geneerators for crypto + "S311", + # S104 Possible binding to all interfaces + "S104", + # S105 Possible hardcoded password assigned to variable" + "S105", + # S106 Possible hardcoded password assigned to argument + "S106", + # S110 `try`-`except`-`pass` detected, consider logging the exception + "S110", + # E741 Ambiguous variable name + "E741", + # E402 Module level import not at top of file + "E402", + # # UP031 Use format specifiers instead of percent format + # "UP031", +] +[tool.ruff.lint.per-file-ignores] +"watcher/tests/*" = ["S"] diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py index 4e94342cb..a8c15c7c3 100644 --- a/releasenotes/source/conf.py +++ b/releasenotes/source/conf.py @@ -22,8 +22,6 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import os -import sys # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the diff --git a/watcher/api/app.wsgi b/watcher/api/app.wsgi index 88d87d3aa..1d4bba357 100644 --- a/watcher/api/app.wsgi +++ b/watcher/api/app.wsgi @@ -1,5 +1,4 @@ # -*- mode: python -*- -# -*- encoding: utf-8 -*- # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain diff --git a/watcher/tests/common/test_utils.py b/watcher/tests/common/test_utils.py index aae20a38d..bcbb1bdc4 100644 --- a/watcher/tests/common/test_utils.py +++ b/watcher/tests/common/test_utils.py @@ -37,7 +37,7 @@ class TestCommonUtils(base.TestCase): IOError, utils.async_compat_call, self.test_coro, - raise_exc=IOError('fake error')) + raise_exc=OSError('fake error')) def test_async_compat_timeout(self): # Timeout not reached. diff --git a/watcher/tests/decision_engine/model/faker_cluster_state.py b/watcher/tests/decision_engine/model/faker_cluster_state.py index 8719f1acf..eacd57c90 100644 --- a/watcher/tests/decision_engine/model/faker_cluster_state.py +++ b/watcher/tests/decision_engine/model/faker_cluster_state.py @@ -371,7 +371,7 @@ class FakerEmptyModelCollector(base.BaseClusterDataModelCollector): def __init__(self, config=None, osc=None): if config is None: config = mock.Mock(period=777) - super(FakerEmptyModelCollector, self).__init__(config) + super().__init__(config) @property def notification_endpoints(self): diff --git a/watcher/tests/decision_engine/model/notification/test_cinder_notifications.py b/watcher/tests/decision_engine/model/notification/test_cinder_notifications.py index eeecc854f..2802162f8 100644 --- a/watcher/tests/decision_engine/model/notification/test_cinder_notifications.py +++ b/watcher/tests/decision_engine/model/notification/test_cinder_notifications.py @@ -611,7 +611,7 @@ class TestCinderNotificationsEmptyModel(NotificationTestCase): FAKE_METADATA = {'message_id': None, 'timestamp': None} def setUp(self): - super(TestCinderNotificationsEmptyModel, self).setUp() + super().setUp() self.fake_cdmc = faker_cluster_state.FakerEmptyModelCollector() @mock.patch.object(cnotification.CapacityNotificationEndpoint,