Skip to content

Commit 4b52dd4

Browse files
chore: enable core Ruff rule groups (#286)
1 parent d260533 commit 4b52dd4

11 files changed

Lines changed: 55 additions & 34 deletions

File tree

noxfile.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,8 @@ def should_skip(python: str, django: str) -> bool:
4747
# Django 5.2 requires Python 3.10+
4848
return True
4949

50-
if django == DJ51 and version(python) < version(PY310):
51-
# Django 5.1 requires Python 3.10+
52-
return True
53-
54-
return False
50+
# Django 5.1 requires Python 3.10+
51+
return django == DJ51 and version(python) < version(PY310)
5552

5653

5754
@nox.session

pyproject.toml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ extend-include = ["*.pyi?"]
174174
indent-width = 4
175175
# Same as Black.
176176
line-length = 88
177-
# Assume Python >3.8
178-
target-version = "py38"
177+
# Same as requires-python.
178+
target-version = "py39"
179179

180180
[tool.ruff.format]
181181
# Like Black, indent with spaces, rather than tabs.
@@ -192,10 +192,23 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
192192
fixable = ["A", "B", "C", "D", "E", "F", "I"]
193193
ignore = ["E501", "E741"] # temporary
194194
select = [
195+
"A", # flake8-builtins
195196
"B", # flake8-bugbear
196-
"E", # Pycodestyle
197+
"C4", # flake8-comprehensions
198+
"DJ", # flake8-django
199+
"DTZ", # flake8-datetimez
200+
"E", # pycodestyle
197201
"F", # Pyflakes
202+
"G", # flake8-logging-format
198203
"I", # isort
204+
"LOG", # flake8-logging
205+
"PIE", # flake8-pie
206+
"PT", # flake8-pytest-style
207+
"RET", # flake8-return
208+
"RUF100", # unused noqa
209+
"S", # flake8-bandit
210+
"SIM", # flake8-simplify
211+
"T20", # flake8-print
199212
"UP" # pyupgrade
200213
]
201214
unfixable = []
@@ -206,6 +219,10 @@ known-first-party = ["email_relay"]
206219
required-imports = ["from __future__ import annotations"]
207220

208221
[tool.ruff.lint.per-file-ignores]
222+
# Release helper intentionally shells out to Git/GitHub CLI and prints progress.
223+
".bin/bump.py" = ["PIE810", "S110", "S602", "T201"]
224+
# Sphinx uses this conventional variable name.
225+
"docs/conf.py" = ["A001"]
209226
# Tests can use magic values, assertions, and relative imports
210227
"tests/**/*" = ["PLR2004", "S101", "TID252"]
211228

src/email_relay/management/commands/runrelay.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def delete_old_messages(self) -> None:
5858
seconds=app_settings.MESSAGES_RETENTION_SECONDS
5959
)
6060
)
61-
logger.debug(f"deleted {deleted_messages} messages")
61+
logger.debug("deleted %s messages", deleted_messages)
6262

6363
def ping_healthcheck(self) -> None:
6464
if app_settings.RELAY_HEALTHCHECK_URL is not None:
@@ -77,12 +77,14 @@ def ping_healthcheck(self) -> None:
7777
timeout=app_settings.RELAY_HEALTHCHECK_TIMEOUT,
7878
)
7979
except requests.exceptions.RequestException as e:
80-
logger.warning(f"healthcheck failed, got exception: {e}")
80+
logger.warning("healthcheck failed, got exception: %s", e)
8181
return
8282

8383
if response.status_code == app_settings.RELAY_HEALTHCHECK_STATUS_CODE:
8484
logger.debug("healthcheck ping successful")
8585
else:
8686
logger.warning(
87-
f"healthcheck failed, got {response.status_code}, expected {app_settings.RELAY_HEALTHCHECK_STATUS_CODE}"
87+
"healthcheck failed, got %s, expected %s",
88+
response.status_code,
89+
app_settings.RELAY_HEALTHCHECK_STATUS_CODE,
8890
)

src/email_relay/models.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def get_message_batch(self) -> list[Message]:
3636
self.deferred().prioritized(), # type: ignore[attr-defined]
3737
)
3838
)
39-
logger.debug(f"found {len(message_batch)} messages to send")
39+
logger.debug("found %s messages to send", len(message_batch))
4040
if app_settings.EMAIL_MAX_BATCH is not None:
4141
msg = f"max batch size is {app_settings.EMAIL_MAX_BATCH}"
4242
if len(message_batch) > app_settings.EMAIL_MAX_BATCH:
@@ -45,8 +45,8 @@ def get_message_batch(self) -> list[Message]:
4545
message_batch = message_batch[: app_settings.EMAIL_MAX_BATCH]
4646
return message_batch
4747

48-
def get_message_for_sending(self, id: int) -> Message:
49-
return self.filter(id=id).select_for_update(skip_locked=True).get()
48+
def get_message_for_sending(self, message_id: int) -> Message:
49+
return self.filter(id=message_id).select_for_update(skip_locked=True).get()
5050

5151
def messages_available_to_send(self) -> bool:
5252
return self.queued().exists() or self.deferred().exists() # type: ignore[attr-defined]
@@ -124,7 +124,7 @@ def save(self, *args, **kwargs):
124124
# Overriding the save method in order to make sure that
125125
# modified field is updated even if it is not given as
126126
# a parameter to the update field argument.
127-
update_fields = kwargs.get("update_fields", None)
127+
update_fields = kwargs.get("update_fields")
128128
if update_fields:
129129
kwargs["update_fields"] = set(update_fields).union({"updated_at"})
130130

src/email_relay/relay.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def send_all():
4545
if email is not None:
4646
email.connection = connection
4747
email.send()
48-
logger.debug(f"sent message {message.id}")
48+
logger.debug("sent message %s", message.id)
4949
message.mark_sent()
5050
counts["sent"] += 1
5151
else:
@@ -65,23 +65,23 @@ def send_all():
6565
and message.retry_count >= app_settings.EMAIL_MAX_RETRIES
6666
):
6767
logger.warning(
68-
f"max retries reached, marking message {message.id} as failed"
68+
"max retries reached, marking message %s as failed", message.id
6969
)
7070
message.fail(log=str(err))
7171
connection = None
7272
counts["failed"] += 1
7373
continue
7474

7575
logger.debug(
76-
f"deferring message {message.id} due to {err}", exc_info=True
76+
"deferring message %s due to %s", message.id, err, exc_info=True
7777
)
7878
message.defer(log=str(err))
7979
connection = None
8080
counts["deferred"] += 1
8181
except Exception as err:
82-
logger.error(
83-
f"unexpected error processing message {message.id}, marking as failed.",
84-
exc_info=True,
82+
logger.exception(
83+
"unexpected error processing message %s, marking as failed.",
84+
message.id,
8585
)
8686
message.fail(log=str(err))
8787
connection = None
@@ -92,16 +92,21 @@ def send_all():
9292
and counts["deferred"] >= app_settings.EMAIL_MAX_DEFERRED
9393
):
9494
logger.debug(
95-
f"max deferred emails reached ({app_settings.EMAIL_MAX_DEFERRED}), stopping"
95+
"max deferred emails reached (%s), stopping",
96+
app_settings.EMAIL_MAX_DEFERRED,
9697
)
9798
break
9899

99100
if app_settings.EMAIL_THROTTLE > 0:
100101
logger.debug(
101-
f"throttling enabled, sleeping for {app_settings.EMAIL_THROTTLE} seconds"
102+
"throttling enabled, sleeping for %s seconds",
103+
app_settings.EMAIL_THROTTLE,
102104
)
103105
time.sleep(app_settings.EMAIL_THROTTLE)
104106

105107
logger.info(
106-
f"sent {counts['sent']} emails, deferred {counts['deferred']} emails, failed {counts['failed']} emails"
108+
"sent %s emails, deferred %s emails, failed %s emails",
109+
counts["sent"],
110+
counts["deferred"],
111+
counts["failed"],
107112
)

src/email_relay/service.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def get_user_settings_from_env() -> dict[str, Any]:
2626
>>> get_user_settings_from_env()
2727
{'DEBUG': False}
2828
"""
29-
all_env_vars = {k: v for k, v in os.environ.items()}
29+
all_env_vars = dict(os.environ)
3030
env_vars_dict = env_vars_to_nested_dict(all_env_vars)
3131
valid_settings = filter_valid_django_settings(env_vars_dict)
3232
return coerce_dict_values(valid_settings)
@@ -176,7 +176,7 @@ def run_relay_service() -> int:
176176
settings.configure(**SETTINGS)
177177
django.setup()
178178
call_command("migrate")
179-
print("Starting email relay service...")
179+
print("Starting email relay service...") # noqa: T201
180180
call_command("runrelay")
181181
# should never get here, `runrelay` is an infinite loop
182182
# but if it does, exit with 0

tests/test_conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99

1010
@pytest.mark.parametrize(
11-
"setting,default_setting",
11+
("setting", "default_setting"),
1212
[
1313
("DATABASE_ALIAS", "email_relay_db"),
1414
("EMAIL_MAX_BATCH", None),
@@ -32,7 +32,7 @@ def test_default_settings(setting, default_setting):
3232

3333

3434
@pytest.mark.parametrize(
35-
"setting,user_setting",
35+
("setting", "user_setting"),
3636
[
3737
("DATABASE_ALIAS", "custom_db_name"),
3838
("EMAIL_MAX_BATCH", 10),

tests/test_email.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def test_to_dict():
7878
email_dict = RelayEmailData.from_email_message(email_message).to_dict()
7979

8080
assert email_dict == IsPartialDict(
81-
**{
81+
{
8282
"subject": email_message.subject,
8383
"body": email_message.body,
8484
"from_email": email_message.from_email,
@@ -111,7 +111,7 @@ def test_to_dict_multi_alternatives():
111111
email_dict = RelayEmailData.from_email_message(email_multi_alternatives).to_dict()
112112

113113
assert email_dict == IsPartialDict(
114-
**{
114+
{
115115
"subject": email_multi_alternatives.subject,
116116
"body": email_multi_alternatives.body,
117117
"from_email": email_multi_alternatives.from_email,
@@ -147,7 +147,7 @@ def test_to_dict_with_attachment():
147147
email_dict = RelayEmailData.from_email_message(email).to_dict()
148148

149149
assert email_dict == IsPartialDict(
150-
**{
150+
{
151151
"subject": email.subject,
152152
"body": email.body,
153153
"from_email": email.from_email,

tests/test_models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def test_get_message_for_sending(self):
5353
assert message_for_sending == message
5454

5555
@pytest.mark.parametrize(
56-
"status, expected",
56+
("status", "expected"),
5757
[
5858
(Status.QUEUED, True),
5959
(Status.DEFERRED, True),

tests/test_runrelay.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def test_command_with_empty_queue(runrelay, mailoutbox):
4040

4141

4242
@pytest.mark.parametrize(
43-
"status,quantity,expected_sent",
43+
("status", "quantity", "expected_sent"),
4444
[
4545
(Status.QUEUED, 10, 10),
4646
(Status.DEFERRED, 10, 10),

0 commit comments

Comments
 (0)