Skip to content

Commit

Permalink
Use ruff instead of flake8 and black (#96)
Browse files Browse the repository at this point in the history
* Use `ruff` instead of flake8 and black

* Ignore ruff cache

* Enable Pytest lint

* Enable eradicable code lint

* Enable Ruff lint
  • Loading branch information
leplatrem committed Feb 29, 2024
1 parent 4bad625 commit 6b9e191
Show file tree
Hide file tree
Showing 15 changed files with 87 additions and 86 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ build
dist
*.pyc
.pytest_cache/
.ruff_cache/
# dump.rdb is created by redis-server, needed to run tests
dump.rdb
6 changes: 0 additions & 6 deletions .isort.cfg

This file was deleted.

2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
recursive-include docs *
recursive-include tests *
include pytest.ini AUTHORS.rst CODE_OF_CONDUCT.md pyproject.toml LICENSE README.rst tox.ini .coveragerc .isort.cfg .readthedocs.yaml
include pytest.ini AUTHORS.rst CODE_OF_CONDUCT.md pyproject.toml LICENSE README.rst tox.ini .coveragerc .readthedocs.yaml
prune docs/_build
global-exclude *.pyc
prune __pycache__
44 changes: 27 additions & 17 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
[tool.black]
line-length = 88
target-version = ['py37', 'py38', 'py39', 'py310', 'py311']
include = '\.pyi?$'
exclude = '''
/(
\.eggs
| \.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| build
| dist
)/
'''
[tool.ruff]
extend-exclude = [
"__pycache__",
]

[tool.ruff.lint]
select = [
# pycodestyle
"E", "W",
# flake8
"F",
# isort
"I",
# pytest style
"PT",
# eradicate commented code
"ERA",
# ruff lint
"RUF",
]
ignore = [
# `format` will wrap lines.
"E501",
]

[tool.ruff.lint.isort]
known-first-party = ["dockerflow"]
3 changes: 2 additions & 1 deletion src/dockerflow/django/middleware.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import re
import time
import typing
import urllib
import uuid

Expand All @@ -16,7 +17,7 @@ class DockerflowMiddleware(MiddlewareMixin):
https://github.com/mozilla-services/Dockerflow/blob/main/docs/mozlog.md
"""

viewpatterns = [
viewpatterns: typing.ClassVar = [
(re.compile(r"/__version__/?$"), views.version),
(re.compile(r"/__heartbeat__/?$"), views.heartbeat),
(re.compile(r"/__lbheartbeat__/?$"), views.lbheartbeat),
Expand Down
5 changes: 3 additions & 2 deletions src/dockerflow/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import socket
import sys
import traceback
import typing


class SafeJSONEncoder(json.JSONEncoder):
Expand All @@ -32,7 +33,7 @@ class JsonLogFormatter(logging.Formatter):
LOGGING_FORMAT_VERSION = "2.0"

# Map from Python logging to Syslog severity levels
SYSLOG_LEVEL_MAP = {
SYSLOG_LEVEL_MAP: typing.ClassVar = {
50: 2, # CRITICAL
40: 3, # ERROR
30: 4, # WARNING
Expand All @@ -43,7 +44,7 @@ class JsonLogFormatter(logging.Formatter):
# Syslog level to use when/if python level isn't found in map
DEFAULT_SYSLOG_LEVEL = 7

EXCLUDED_LOGRECORD_ATTRS = set(
EXCLUDED_LOGRECORD_ATTRS: typing.ClassVar = set(
(
"args",
"asctime",
Expand Down
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import dockerflow.checks.registry


@pytest.fixture
@pytest.fixture()
def version_content():
"""
as documented on https://github.com/mozilla-services/Dockerflow/blob/main/docs/version_object.md
Expand All @@ -20,6 +20,6 @@ def version_content():


@pytest.fixture(autouse=True)
def clear_checks():
def _clear_checks():
yield
dockerflow.checks.registry.clear_checks()
9 changes: 4 additions & 5 deletions tests/core/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


@pytest.fixture()
def reset_logging():
def _reset_logging():
logging.shutdown()
reload(logging)

Expand All @@ -31,7 +31,8 @@ def assert_records(records):
return details


def test_initialization_from_ini(reset_logging, caplog, tmpdir):
@pytest.mark.usefixtures("_reset_logging")
def test_initialization_from_ini(caplog, tmpdir):
ini_content = textwrap.dedent(
"""
[loggers]
Expand Down Expand Up @@ -229,7 +230,5 @@ def test_ignore_json_message(caplog):
}
}
}
""".replace(
"\\", "\\\\"
)
""".replace("\\", "\\\\")
) # HACK: Fix escaping for easy copy/paste
31 changes: 16 additions & 15 deletions tests/django/test_django.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@


@pytest.fixture(autouse=True)
def reset_checks():
def _reset_checks():
yield
registry.registered_checks = set()
registry.deployment_checks = set()


@pytest.fixture(autouse=True)
def setup_request_summary_logger(dockerflow_middleware):
def _setup_request_summary_logger(dockerflow_middleware):
dockerflow_middleware.summary_logger.addHandler(logging.NullHandler())
dockerflow_middleware.summary_logger.setLevel(logging.INFO)


@pytest.fixture
@pytest.fixture()
def dockerflow_middleware():
return DockerflowMiddleware(get_response=HttpResponse())

Expand All @@ -55,7 +55,7 @@ def test_version_missing(dockerflow_middleware, mocker, rf):
assert response.status_code == 404


@pytest.mark.django_db
@pytest.mark.django_db()
def test_heartbeat(client, settings):
response = client.get("/__heartbeat__")
assert response.status_code == 200
Expand All @@ -73,7 +73,7 @@ def test_heartbeat(client, settings):
assert content.get("details") is None


@pytest.mark.django_db
@pytest.mark.django_db()
def test_heartbeat_debug(client, settings):
settings.DOCKERFLOW_CHECKS = [
"tests.django.django_checks.warning",
Expand All @@ -89,7 +89,7 @@ def test_heartbeat_debug(client, settings):
assert content["details"]


@pytest.mark.django_db
@pytest.mark.django_db()
def test_heartbeat_silenced(client, settings):
settings.DOCKERFLOW_CHECKS = [
"tests.django.django_checks.warning",
Expand All @@ -107,8 +107,9 @@ def test_heartbeat_silenced(client, settings):
assert "error" not in content["details"]


@pytest.mark.django_db
def test_heartbeat_logging(dockerflow_middleware, reset_checks, rf, settings, caplog):
@pytest.mark.django_db()
@pytest.mark.usefixtures("_reset_checks")
def test_heartbeat_logging(dockerflow_middleware, rf, settings, caplog):
request = rf.get("/__heartbeat__")
settings.DOCKERFLOW_CHECKS = [
"tests.django.django_checks.warning",
Expand All @@ -123,7 +124,7 @@ def test_heartbeat_logging(dockerflow_middleware, reset_checks, rf, settings, ca
assert ("WARNING", "tests.checks.W001: some warning") in logged


@pytest.mark.django_db
@pytest.mark.django_db()
def test_lbheartbeat_makes_no_db_queries(dockerflow_middleware, rf):
queries = CaptureQueriesContext(connection)
request = rf.get("/__lbheartbeat__")
Expand All @@ -133,7 +134,7 @@ def test_lbheartbeat_makes_no_db_queries(dockerflow_middleware, rf):
assert len(queries) == 0


@pytest.mark.django_db
@pytest.mark.django_db()
def test_redis_check(client, settings):
settings.DOCKERFLOW_CHECKS = ["dockerflow.django.checks.check_redis_connected"]
checks.register()
Expand All @@ -152,7 +153,7 @@ def assert_log_record(request, record, errno=0, level=logging.INFO):
assert isinstance(record.t, int)


@pytest.fixture
@pytest.fixture()
def dockerflow_request(rf):
return rf.get("/", HTTP_USER_AGENT="dockerflow/tests", HTTP_ACCEPT_LANGUAGE="tlh")

Expand Down Expand Up @@ -248,15 +249,15 @@ def test_check_database_connected_misconfigured(mocker):
assert errors[0].id == health.ERROR_MISCONFIGURED_DATABASE


@pytest.mark.django_db
@pytest.mark.django_db()
def test_check_database_connected_unsuable(mocker):
mocker.patch("django.db.connection.is_usable", return_value=False)
errors = checks.check_database_connected([])
assert len(errors) == 1
assert errors[0].id == health.ERROR_UNUSABLE_DATABASE


@pytest.mark.django_db
@pytest.mark.django_db()
def test_check_database_connected_success(mocker):
errors = checks.check_database_connected([])
assert errors == []
Expand All @@ -272,7 +273,7 @@ def test_check_migrations_applied_cannot_check_migrations(exception, mocker):
assert errors[0].id == health.INFO_CANT_CHECK_MIGRATIONS


@pytest.mark.django_db
@pytest.mark.django_db()
def test_check_migrations_applied_unapplied_migrations(mocker):
mock_loader = mocker.patch("django.db.migrations.loader.MigrationLoader")
mock_loader.return_value.applied_migrations = ["spam", "eggs"]
Expand Down Expand Up @@ -306,7 +307,7 @@ def test_check_migrations_applied_unapplied_migrations(mocker):


@pytest.mark.parametrize(
"exception,error",
("exception", "error"),
[
(redis.ConnectionError, health.ERROR_CANNOT_CONNECT_REDIS),
(NotImplementedError, health.ERROR_MISSING_REDIS_CLIENT),
Expand Down
6 changes: 3 additions & 3 deletions tests/fastapi/test_fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ def create_app():
return app


@pytest.fixture
@pytest.fixture()
def app():
return create_app()


@pytest.fixture
@pytest.fixture()
def client(app):
return TestClient(app)

Expand Down Expand Up @@ -120,7 +120,7 @@ def test_mozlog_failure(client, mocker, caplog):
"dockerflow.fastapi.views.get_version", side_effect=ValueError("crash")
)

with pytest.raises(ValueError):
with pytest.raises(expected_exception=ValueError):
client.get("/__version__")

record = caplog.records[0]
Expand Down
4 changes: 2 additions & 2 deletions tests/flask/migrations/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from logging.config import fileConfig

from alembic import context # no:qa
from flask import current_app # noqa
from flask import current_app
from sqlalchemy import engine_from_config, pool

# this is the Alembic Config object, which provides
Expand All @@ -24,7 +24,7 @@

# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# my_important_option = config.get_main_option("my_important_option") # noqa
# ... etc.


Expand Down
Loading

0 comments on commit 6b9e191

Please sign in to comment.