Skip to content

Commit

Permalink
Update lint rules
Browse files Browse the repository at this point in the history
  • Loading branch information
MrThearMan committed Sep 22, 2024
1 parent 3c6aa2d commit 43c31a5
Show file tree
Hide file tree
Showing 15 changed files with 481 additions and 371 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ repos:
]

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.4
rev: v0.6.7
hooks:
- id: ruff
- id: ruff-format
523 changes: 276 additions & 247 deletions poetry.lock

Large diffs are not rendered by default.

154 changes: 124 additions & 30 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Framework :: Django :: 3.2",
"Framework :: Django :: 4.0",
"Framework :: Django :: 4.1",
"Framework :: Django :: 4.2",
"Framework :: Django :: 5.0",
"Framework :: Django :: 5.1",
"Operating System :: OS Independent",
"Intended Audience :: Developers",
"Natural Language :: English",
Expand All @@ -48,29 +47,29 @@ exclude = [

[tool.poetry.dependencies]
python = ">=3.9,<4"
Django = ">=3.2"
Django = ">=4.2"
asgiref = ">=3.5.0"
httpx = ">=0.23.0"
cryptography = ">=36.0.0"
django-settings-holder = ">=0.1.0"
django-settings-holder = ">=0.1.2"
djangorestframework = { version = ">=3.14.0", optional = true}

[tool.poetry.group.test.dependencies]
pytest = "8.3.3"
coverage = "7.6.1"
freezegun = "^1.2.2"
freezegun = "1.5.1"
pytest-django = "4.9.0"
pre-commit = "3.8.0"
tox = "4.18.1"
tox = "4.20.0"
tox-gh-actions = "3.2.0"

[tool.poetry.group.docs.dependencies]
mkdocs = "1.6.1"
pymdown-extensions = "10.9"
pymdown-extensions = "10.10"
mkdocs-mermaid2-plugin = "1.1.1"

[tool.poetry.group.lint.dependencies]
mypy = "1.11.2"
pre-commit = "3.8.0"
django-stubs = "5.0.4"
djangorestframework-stubs = "3.15.1"

Expand All @@ -79,11 +78,17 @@ drf = ["djangorestframework"]

[tool.ruff]
fix = true
unsafe-fixes = true
line-length = 120
exclude = [
"tests/*",
extend-exclude = [
"tests*",
]
select = [
lint.typing-modules = [
"signal_webhooks.typing",
]
lint.explicit-preview-rules = true
lint.preview = true
lint.select = [
"A", # flake8-builtins
"ANN", # flake8-annotations
"ARG", # flake8-unused-arguments
Expand All @@ -97,14 +102,21 @@ select = [
"D202", # pydocstyle: No blank lines allowed after function docstring (found {num_lines})
"D209", # pydocstyle: Multi-line docstring closing quotes should be on a separate line
"D213", # pydocstyle: Multi-line docstring summary should start at the second line
"DJ", # flake8-django
"DTZ", # flake8-datetimez
"E", # pycodestyle errors
"EM", # flake8-errmsg
"F", # pyflakes
"FA", # flake8-future-annotations
"FBT", # flake8-boolean-trap
"FLY", # flynt
"G", # flake8-logging-format
"I", # isort
"ICN", # flake8-import-conventions
"INP", # flake8-no-pep420
"INT", # flake8-gettext
"ISC", # flake8-implicit-str-concat
"LOG", # flake8-logging
"N", # pep8-naming
"PERF", # perflint
"PGH", # pygrep-hooks
Expand All @@ -114,26 +126,55 @@ select = [
"PTH", # flake8-use-pathlib
"PYI", # flake8-pyi
"Q", # flake8-quotes
"R", # Refactor
"RET", # flake8-return
"RSE", # flake8-raise
"RUF", # ruff-specific rules
"S", # flake8-bandit
"SIM", # flake8-simplify
"SLF", # flake8-self
"T20", # flake8-print
"TCH", # flake8-type-checking
"TID", # flake8-tidy-imports
"TRY", # tryceratops
"UP", # pyupgrade
"W", # pycodestyle warnings
]
ignore = [
"S101", # assert is OK
"S105", # no hardcoded passwords
"S311", # random-module is OK.
"ARG001", # Anused function argument
# Preview rules
lint.extend-select = [
"B909", # loop-iterator-mutation
"FURB110", # if-exp-instead-of-or-operator
"FURB142", # for-loop-set-mutations
"FURB145", # slice-copy
"FURB171", # single-item-membership-test
"FURB187", # list-reverse-copy
"PLE0307", # invalid-str-return-type
"PLR0916", # too-many-boolean-expressions
"PLR1730", # if-stmt-min-max
"PLR1733", # unnecessary-dict-index-lookup
"PLR1736", # unnecessary-list-index-lookup
"PLR6104", # non-augmented-assignment
"PLW0211", # bad-staticmethod-argument
"PLW0642", # self-or-cls-assignment
"RUF021", # parenthesize-chained-operators
"RUF022", # unsorted-dunder-all
"UP042", # replace-str-enum
]
lint.ignore = [
"ANN101", # Missing type annotation for `self` in method
"ANN102", # Missing type annotation for `cls` in classmethod
"ANN401", # Any is allowed
"ANN102", # Missing type annotation for `cls` in method
"ANN401", # Any-typing allowed
"RUF012", # No ClassVar required
"ARG002", # Unused method argument
"ARG003", # Unused class method argument
"N805", # First argument of a method should be named `self`
"SLF001", # Accessing private members is allowed
"UP007", # Use `X | Y` for union type annotations
"G004", # Logging statement uses f-string
"S602", # Broken: https://github.com/astral-sh/ruff/issues/4045
"S603", # Broken: https://github.com/astral-sh/ruff/issues/4045
"RUF012", # Mutable class attributes
"DJ001", # Avoid using `django.db.models.Model.objects.create`
#
# Conflicting with ruff-format
#
Expand All @@ -153,18 +194,68 @@ ignore = [
"W191", # tab-indentation
]

[tool.ruff.per-file-ignores]
"__init__.py" = ["F401"]
"signal_webhooks/admin.py" = ["S105"]
[tool.ruff.lint.extend-per-file-ignores]
"test_*.py" = [
"ANN", # No need to annotate tests
"N801", # Allow whatever class names in tests
"N802", # Allow whatever function names in tests
"N815", # Allow whatever variable names in tests
"PLR0915", # Can have as many statements as needed
"PLR2004", # Magic value comparisons are allowed in tests
"S101", # Assert is fine
"S105", # Hardcoded passwords are fine in tests
"S106", # Hardcoded passwords are fine in tests
"S108", # No need to care about insecure temp file usages in tests
"S311", # Pseudo-random generators are fine here
"SLF", # Allow accessing private members in tests
"UP", # No upgrade rules
]
"conftest.py" = [
"ARG", # Fixtures can be unused
"ANN", # No need to annotate tests
"UP", # No upgrade rules
]

[tool.ruff.isort]
[tool.ruff.lint.isort]
combine-as-imports = false
split-on-trailing-comma = false
known-third-party = [
"django",
"asgiref",
"httpx",
"cryptography",
"django-settings-holder",
]
known-first-party = [
"signal_webhooks",
]

[tool.ruff.lint.flake8-import-conventions]
banned-from = [
"base64",
"csv",
"datetime",
"hashlib",
"hmac",
"json",
"logging",
"math",
"os",
"pickle",
"random",
"re",
"shutil",
"subprocess",
"sys",
"tempfile",
"time",
"uuid",
"xml",
"yaml",
]

[tool.ruff.lint.pylint]
max-args = 7

[tool.mypy]
python_version = "3.12"
Expand Down Expand Up @@ -192,7 +283,7 @@ exclude_lines = [
]

[tool.pytest.ini_options]
addopts = "-vv -s --log-cli-level=INFO"
addopts = "-vv -s --disable-warnings"
markers = [
"e2e: Marks tests as e2e.",
]
Expand All @@ -203,7 +294,7 @@ django_settings_module = "tests.project.settings"
[tool.tox]
legacy_tox_ini = """
[tox]
envlist = py{39, 310, 311, 312}-django{32, 40, 41, 42}
envlist = py{39, 310, 311, 312}-django{42, 50, 51}
isolated_build = true
[gh-actions]
Expand All @@ -219,23 +310,26 @@ allowlist_externals =
setenv =
PYTHONPATH = {toxinidir}
deps =
django32: Django>=3.2,<4.0
django40: Django>=4.0,<4.1
django41: Django>=4.1,<4.2
django42: Django>=4.2,<4.3
py39-django50: Django>=4.2,<4.3
py{310, 311, 312}-django50: Django>=5.0,<5.1
py39-django51: Django>=4.2,<4.3
py{310, 311, 312}-django51: Django>=5.1,<5.2
asgiref>=3.5.0
httpx>=0.23.0
cryptography>=36.0.0
django-settings-holder>=0.1.0
django-settings-holder>=0.1.2
djangorestframework>=3.13.0
pytest
coverage
pytest-django
freezegun
commands =
coverage run -m pytest -m "not e2e"
coverage run -m pytest -m "not e2e" -vv -s --disable-warnings
"""

[build-system]
Expand Down
4 changes: 2 additions & 2 deletions signal_webhooks/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
from .typing import Any, Dict, Optional, Union

__all__ = [
"WebhookModelForm",
"WebhookAdmin",
"WebhookModelForm",
]


Expand All @@ -27,7 +27,7 @@
class WebhookModelForm(forms.ModelForm):
class Meta:
model = WebhookModel
fields = "__all__"
fields = "__all__" # noqa: DJ007
widgets = {
"auth_token": forms.Textarea,
}
Expand Down
4 changes: 2 additions & 2 deletions signal_webhooks/api/serializers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from rest_framework.exceptions import ValidationError
from rest_framework.serializers import ModelSerializer

from ..typing import Any, Dict
from ..utils import get_webhook_model
from signal_webhooks.typing import Any, Dict
from signal_webhooks.utils import get_webhook_model

__all__ = [
"WebhookSerializer",
Expand Down
3 changes: 2 additions & 1 deletion signal_webhooks/api/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from rest_framework.viewsets import ModelViewSet

from ..utils import get_webhook_model
from signal_webhooks.utils import get_webhook_model

from .serializers import WebhookSerializer

__all__ = [
Expand Down
2 changes: 2 additions & 0 deletions signal_webhooks/apps.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from django.apps import AppConfig

__all__ = [
Expand Down
2 changes: 2 additions & 0 deletions signal_webhooks/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

__all__ = [
"WebhookCancelled",
]
Expand Down
14 changes: 7 additions & 7 deletions signal_webhooks/fields.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from __future__ import annotations

import base64
import logging
from base64 import b64decode, b64encode
from os import urandom
import os
from typing import TYPE_CHECKING

from cryptography.exceptions import InvalidTag
Expand All @@ -26,13 +26,13 @@
class TokenField(models.CharField):
"""Encrypt token with a cipher before saving it."""

def from_db_value(self, value: str, *args: Any, **kwargs: Any) -> str: # noqa: ARG002
def from_db_value(self, value: str, *args: Any, **kwargs: Any) -> str:
if not value:
return value

key = decode_cipher_key()

string = b64decode(value)
string = base64.b64decode(value)
nonce = string[:12]
data = string[12:]
cipher = AESGCM(key=key)
Expand All @@ -45,13 +45,13 @@ def from_db_value(self, value: str, *args: Any, **kwargs: Any) -> str: # noqa:

return decrypted_token.decode()

def get_prep_value(self, value: str, *args: Any, **kwargs: Any) -> str: # noqa: ARG002
def get_prep_value(self, value: str, *args: Any, **kwargs: Any) -> str:
if not value:
return value

key = decode_cipher_key()

nonce = urandom(12)
nonce = os.urandom(12)
cipher = AESGCM(key)
encrypted_token = cipher.encrypt(nonce, value.encode(encoding="utf-8"), None)
return b64encode(nonce + encrypted_token).decode()
return base64.b64encode(nonce + encrypted_token).decode()
Loading

0 comments on commit 43c31a5

Please sign in to comment.