From 06b9243d68d9e7d2aa894769cb879b84714729f8 Mon Sep 17 00:00:00 2001 From: Paul Traylor Date: Fri, 19 May 2023 15:02:52 +0900 Subject: [PATCH 1/3] Initial ruff configuration To reduce some of the extra tools and configuration, we want to migrate to ruff as a replacement of isort and pyflakes. --- Makefile | 13 +++++++++++++ pyproject.toml | 22 ++++++++++++---------- setup.cfg | 9 --------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 1fc8b07d0..be0117b7b 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,8 @@ PIP_COMPILE := $(ENV_DIR)/bin/pip-compile APP_BIN := $(ENV_DIR)/bin/promgen CELERY_BIN := $(ENV_DIR)/bin/celery SPHINX := $(ENV_DIR)/bin/sphinx-build +RUFF_BIN := $(ENV_DIR)/bin/ruff +BLACK_BIN := $(ENV_DIR)/bin/black DOCKER_TAG := promgen:local SYSTEM_PYTHON ?= python3.9 @@ -136,6 +138,17 @@ $(SPHINX): $(PIP_BIN) docs: $(SPHINX) $(SPHINX) -avb html docs dist/html +$(RUFF_BIN): $(PIP_BIN) + $(PIP_BIN) install ruff + +$(BLACK_BIN): $(PIP_BIN) + $(PIP_BIN) install black + +.PHONY: format +format: $(RUFF_BIN) $(BLACK_BIN) + $(RUFF_BIN) check promgen --fix + $(BLACK_BIN) promgen + #### Other assorted commands diff --git a/pyproject.toml b/pyproject.toml index e30396f40..203657835 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.black] line-length = 100 -target-version = ['py36'] +target-version = ['py39'] extend-exclude = ''' ( promgen/migrations @@ -8,13 +8,15 @@ promgen/migrations ) ''' -[tool.isort] -forced_separate = "django,promgen" -known_django = "django" -known_first_party = "promgen" -sections = "FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRSTPARTY,LOCALFOLDER" -profile = "black" -float_to_top = true - [tool.ruff] -ignore = ['E501'] +ignore = [ + 'E741', # Ambiguous variable name + 'E501', # Let black handle line-length +] + +[tool.ruff.isort] +known-first-party = ["promgen"] +forced-separate = ["django"] + +[tool.codespell] +skip = '*.min.js,*.min.css,*.css.map,.venv,dist,.git' diff --git a/setup.cfg b/setup.cfg index 7d5f08141..db861f142 100644 --- a/setup.cfg +++ b/setup.cfg @@ -66,12 +66,3 @@ docs = Sphinx sphinxcontrib-httpdomain mysql = mysqlclient==1.4.2 - -[flake8] -max-line-length = 100 -extend-ignore = E203 -ignore = E501 -exclude = migrations - -[codespell] -skip = *.min.js,*.min.css,*.css.map,.venv,dist,.git From af2c352786f952d819e69b928bf6c99dcde5954b Mon Sep 17 00:00:00 2001 From: Paul Traylor Date: Fri, 4 Aug 2023 14:28:49 +0900 Subject: [PATCH 2/3] Ruff fixes --- promgen/apps.py | 4 +- promgen/discovery/__init__.py | 4 +- promgen/middleware.py | 2 +- promgen/migrations/0013_validation_fix.py | 1 - promgen/migrations/0014_exporter_scheme.py | 1 - promgen/notification/user.py | 2 +- promgen/prometheus.py | 1 - promgen/proxy.py | 3 -- promgen/signals.py | 2 +- promgen/tests/__init__.py | 2 +- promgen/views.py | 49 +++++++++++----------- 11 files changed, 33 insertions(+), 38 deletions(-) diff --git a/promgen/apps.py b/promgen/apps.py index 745913e76..bcd73eff6 100644 --- a/promgen/apps.py +++ b/promgen/apps.py @@ -2,10 +2,10 @@ # These sources are released under the terms of the MIT license: see LICENSE import logging +import warnings from django.apps import AppConfig from django.db.models.signals import post_migrate -import warnings logger = logging.getLogger(__name__) @@ -57,7 +57,7 @@ class PromgenConfig(AppConfig): default_auto_field = "django.db.models.AutoField" def ready(self): - from promgen import checks, signals # NOQA + from promgen import celery, checks, signals # NOQA post_migrate.connect(default_shard, sender=self) post_migrate.connect(default_admin, sender=self) diff --git a/promgen/discovery/__init__.py b/promgen/discovery/__init__.py index bc8cdf315..11db0248a 100644 --- a/promgen/discovery/__init__.py +++ b/promgen/discovery/__init__.py @@ -18,10 +18,10 @@ def fetch(self, farm): """ Return list of hosts for farm """ - raise NotImplemented() + raise NotImplementedError() def farms(self): """ Return a list of farm names """ - raise NotImplemented() + raise NotImplementedError() diff --git a/promgen/middleware.py b/promgen/middleware.py index 41c5ae640..3c7e4c1a7 100644 --- a/promgen/middleware.py +++ b/promgen/middleware.py @@ -59,7 +59,7 @@ def __call__(self, request): } for msg, func in triggers.items(): - for (receiver, status) in func(self, request=request, force=True): + for receiver, status in func(self, request=request, force=True): if status is False: messages.warning(request, "Error queueing %s " % msg) return response diff --git a/promgen/migrations/0013_validation_fix.py b/promgen/migrations/0013_validation_fix.py index 7349faabc..1cd4f8506 100644 --- a/promgen/migrations/0013_validation_fix.py +++ b/promgen/migrations/0013_validation_fix.py @@ -1,6 +1,5 @@ # Generated by Django 2.2.10 on 2020-02-14 05:41 -import re import django.core.validators import django.db.models.deletion diff --git a/promgen/migrations/0014_exporter_scheme.py b/promgen/migrations/0014_exporter_scheme.py index cf5f1c3a8..a311046cb 100644 --- a/promgen/migrations/0014_exporter_scheme.py +++ b/promgen/migrations/0014_exporter_scheme.py @@ -1,7 +1,6 @@ # Generated by Django 2.2.10 on 2020-02-18 09:28 from django.db import migrations, models -import django.db.models.deletion class Migration(migrations.Migration): diff --git a/promgen/notification/user.py b/promgen/notification/user.py index b7f28ee7d..eddae1fd4 100644 --- a/promgen/notification/user.py +++ b/promgen/notification/user.py @@ -49,6 +49,6 @@ def _send(self, address, data): for sender in models.Sender.objects.filter(obj=user, enabled=True): try: sender.driver._send(sender.value, data) - except: + except Exception: logger.exception("Error sending with %s", sender) return True diff --git a/promgen/prometheus.py b/promgen/prometheus.py index 7cd2eaa6e..c759b9869 100644 --- a/promgen/prometheus.py +++ b/promgen/prometheus.py @@ -160,7 +160,6 @@ def import_rules_v2(config, content_object=None): counters = collections.defaultdict(int) for group in config["groups"]: for r in group["rules"]: - defaults = { "clause": r["expr"], "duration": r["for"], diff --git a/promgen/proxy.py b/promgen/proxy.py index 086082917..b38f097b8 100644 --- a/promgen/proxy.py +++ b/promgen/proxy.py @@ -7,10 +7,7 @@ from urllib.parse import urljoin import requests -from dateutil import parser -from django.conf import settings from django.http import HttpResponse, JsonResponse -from django.template import defaultfilters from django.views.generic import View from django.views.generic.base import TemplateView from promgen import forms, models, prometheus, util diff --git a/promgen/signals.py b/promgen/signals.py index aaae64c57..aab5f2232 100644 --- a/promgen/signals.py +++ b/promgen/signals.py @@ -6,7 +6,7 @@ from django.conf import settings from django.contrib import messages -from django.contrib.auth.models import Group, User +from django.contrib.auth.models import Group from django.core.cache import cache from django.db.models.signals import post_delete, post_save, pre_delete, pre_save from django.dispatch import Signal, receiver diff --git a/promgen/tests/__init__.py b/promgen/tests/__init__.py index 4bb5cac43..a63fdc0b8 100644 --- a/promgen/tests/__init__.py +++ b/promgen/tests/__init__.py @@ -57,7 +57,7 @@ def assertMockCalls(self, mock_func, *args, **kwargs): # We split them here, instead of passing to assertEquals, so that we have # the arguments directly and not a call() object call_args, call_kwargs = mock_func.call_args - self.assertEquals((call_args, call_kwargs), (args, kwargs)) + self.assertEqual((call_args, call_kwargs), (args, kwargs)) def add_user_permissions(self, *args, user=None): codenames = [p.split(".")[1] for p in args] diff --git a/promgen/views.py b/promgen/views.py index a4be5db72..e3b77d317 100644 --- a/promgen/views.py +++ b/promgen/views.py @@ -14,24 +14,8 @@ import requests from prometheus_client.core import CounterMetricFamily, GaugeMetricFamily -from django.contrib import messages -from django.contrib.auth.mixins import LoginRequiredMixin -from django.contrib.contenttypes.models import ContentType -from django.db.models import Count, Q -from django.db.utils import IntegrityError -from django.http import HttpResponse, HttpResponseRedirect, JsonResponse -from django.shortcuts import get_object_or_404, redirect, render -from django.template.loader import render_to_string -from django.urls import reverse -from django.utils.translation import ugettext as _ -from django.views.generic import DetailView, ListView, UpdateView, View -from django.views.generic.base import RedirectView, TemplateView -from django.views.generic.detail import SingleObjectMixin -from django.views.generic.edit import CreateView, DeleteView, FormView - import promgen.templatetags.promgen as macro from promgen import ( - celery, discovery, forms, mixins, @@ -45,6 +29,21 @@ ) from promgen.shortcuts import resolve_domain +from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.contenttypes.models import ContentType +from django.db.models import Count, Q +from django.db.utils import IntegrityError +from django.http import HttpResponse, HttpResponseRedirect, JsonResponse +from django.shortcuts import get_object_or_404, redirect, render +from django.template.loader import render_to_string +from django.urls import reverse +from django.utils.translation import ugettext as _ +from django.views.generic import DetailView, ListView, UpdateView, View +from django.views.generic.base import RedirectView, TemplateView +from django.views.generic.detail import SingleObjectMixin +from django.views.generic.edit import CreateView, DeleteView, FormView + logger = logging.getLogger(__name__) @@ -763,7 +762,9 @@ def get_context_data(self, **kwargs): # We use setdefault here, because we may have received existing forms in the case of a POST # that has errors to be corrected context.setdefault("label_form", forms.LabelFormSet(initial=self.object.labels)) - context.setdefault("annotation_form", forms.AnnotationFormSet(initial=self.object.annotations)) + context.setdefault( + "annotation_form", forms.AnnotationFormSet(initial=self.object.annotations) + ) return context def form_invalid(self, **kwargs): @@ -1197,7 +1198,7 @@ def form_valid(self, form): counters = prometheus.import_rules_v2(rules) messages.info(self.request, "Imported %s" % counters) return redirect("rule-import") - except: + except Exception: messages.error(self.request, "Error importing rules") return self.form_invalid(form) @@ -1276,15 +1277,15 @@ def post(self, request, pk): # check our test query output for labels outside our expected match if rule.content_type.model == "service": # for a service rule, we expect the current service and all child projects as expected - expected_labels["service"] = set([rule.content_object.name]) - expected_labels["project"] = set( - [project.name for project in rule.content_object.project_set.all()] - ) + expected_labels["service"] = {rule.content_object.name} + expected_labels["project"] = { + project.name for project in rule.content_object.project_set.all() + } if rule.content_type.model == "project": # for a project rule we expect only the current project and the parent service - expected_labels["service"] = set([rule.content_object.service.name]) - expected_labels["project"] = set([rule.content_object.name]) + expected_labels["service"] = {rule.content_object.service.name} + expected_labels["project"] = {rule.content_object.name} query = macro.rulemacro(rule, request.POST["query"]) # Since our rules affect all servers we use Promgen's proxy-query to test our rule From 186b87ddf90336309801327fec063a65aa57677d Mon Sep 17 00:00:00 2001 From: Paul Traylor Date: Fri, 4 Aug 2023 16:38:27 +0900 Subject: [PATCH 3/3] Add ruff fixes to .git-blame-ignore-revs --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 743f468c3..9f62c2e5c 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -2,3 +2,5 @@ 4d53038426aedf2abf337a2876d0d6ceccefc09b # black a81731039c118543398c90869e608dde0acaf32c +# ruff +af2c352786f952d819e69b928bf6c99dcde5954b