Lint galore. Also use python 3.12.

This commit is contained in:
Víðir Valberg Guðmundsson 2024-02-29 21:25:59 +01:00
parent 4112069cac
commit 1b65558608
18 changed files with 68 additions and 105 deletions

View file

@ -1,5 +1,5 @@
default_language_version: default_language_version:
python: python3.11 python: python3.12
exclude: ^.*\b(migrations)\b.*$ exclude: ^.*\b(migrations)\b.*$
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
@ -16,45 +16,22 @@ repos:
- id: end-of-file-fixer - id: end-of-file-fixer
- id: trailing-whitespace - id: trailing-whitespace
- repo: https://github.com/charliermarsh/ruff-pre-commit - repo: https://github.com/charliermarsh/ruff-pre-commit
rev: 'v0.1.11' rev: 'v0.3.0'
hooks: hooks:
- id: ruff - id: ruff
args: args:
- --fix - --fix
- repo: https://github.com/asottile/reorder_python_imports - id: ruff-format
rev: v3.12.0
hooks:
- id: reorder-python-imports
args:
- --py310-plus
- --application-directories=.:src
exclude: migrations/
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/asottile/pyupgrade
rev: v3.15.0 rev: v3.15.1
hooks: hooks:
- id: pyupgrade - id: pyupgrade
args: args:
- --py311-plus - --py311-plus
exclude: migrations/ exclude: migrations/
- repo: https://github.com/adamchainz/django-upgrade - repo: https://github.com/adamchainz/django-upgrade
rev: 1.15.0 rev: 1.16.0
hooks: hooks:
- id: django-upgrade - id: django-upgrade
args: args:
- --target-version=4.1 - --target-version=5.0
- repo: https://github.com/asottile/yesqa
rev: v1.5.0
hooks:
- id: yesqa
- repo: https://github.com/asottile/add-trailing-comma
rev: v3.1.0
hooks:
- id: add-trailing-comma
- repo: https://github.com/hadialqattan/pycln
rev: v2.4.0
hooks:
- id: pycln
- repo: https://github.com/psf/black
rev: 23.12.1
hooks:
- id: black

View file

@ -1,4 +1,4 @@
FROM python:3.11-slim-bullseye FROM python:3.12-slim-bullseye
ENV PYTHONFAULTHANDLER=1 \ ENV PYTHONFAULTHANDLER=1 \
PYTHONUNBUFFERED=1 \ PYTHONUNBUFFERED=1 \

View file

@ -104,3 +104,26 @@ follow_imports = "normal"
[[tool.mypy.overrides]] [[tool.mypy.overrides]]
module = "tests.*" module = "tests.*"
allow_untyped_defs = true allow_untyped_defs = true
[tool.ruff]
target-version = "py312"
extend-exclude = [
".git",
"__pycache__",
]
line-length = 120
[tool.ruff.lint]
select = ["ALL"]
ignore = [
"G004", # Logging statement uses f-string
"ANN101", # Missing type annotation for `self` in method
"ANN102", # Missing type annotation for `cls` in classmethod
"EM101", # Exception must not use a string literal, assign to variable first
"EM102", # Exception must not use a f-string literal, assign to variable first
"COM812", # missing-trailing-comma (https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules)
"ISC001", # single-line-implicit-string-concatenation (https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules)
]
[tool.ruff.lint.isort]
force-single-line = true

View file

@ -7,7 +7,6 @@ from django.db import models
class Migration(migrations.Migration): class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
@ -99,9 +98,7 @@ class Migration(migrations.Migration):
), ),
( (
"vat", "vat",
djmoney.models.fields.MoneyField( djmoney.models.fields.MoneyField(decimal_places=2, max_digits=16, verbose_name="VAT"),
decimal_places=2, max_digits=16, verbose_name="VAT"
),
), ),
("is_paid", models.BooleanField(default=False, verbose_name="is paid")), ("is_paid", models.BooleanField(default=False, verbose_name="is paid")),
( (

View file

@ -17,8 +17,7 @@ class CreatedModifiedAbstract(models.Model):
class Account(CreatedModifiedAbstract): class Account(CreatedModifiedAbstract):
""" """This is the model where we can give access to several users, such that they
This is the model where we can give access to several users, such that they
can decide which account to use to pay for something. can decide which account to use to pay for something.
""" """
@ -30,8 +29,7 @@ class Account(CreatedModifiedAbstract):
class Transaction(CreatedModifiedAbstract): class Transaction(CreatedModifiedAbstract):
""" """Tracks in and outgoing events of an account. When an order is received, an
Tracks in and outgoing events of an account. When an order is received, an
amount is subtracted, when a payment is received, an amount is added. amount is subtracted, when a payment is received, an amount is added.
""" """
@ -50,8 +48,7 @@ class Transaction(CreatedModifiedAbstract):
class Order(CreatedModifiedAbstract): class Order(CreatedModifiedAbstract):
""" """Scoped out: Contents of invoices will have to be tracked either here or in
Scoped out: Contents of invoices will have to be tracked either here or in
a separate Invoice model. This is undecided because we are not generating a separate Invoice model. This is undecided because we are not generating
invoices at the moment. invoices at the moment.
""" """

View file

@ -8,7 +8,7 @@ from . import models
# do stuff # do stuff
@pytest.mark.django_db @pytest.mark.django_db()
def test_balance(): def test_balance():
user = User.objects.create_user("test", "lala@adas.com", "1234") user = User.objects.create_user("test", "lala@adas.com", "1234")
account = models.Account.objects.create(owner=user) account = models.Account.objects.create(owner=user)

View file

@ -1,5 +1,4 @@
""" """Membership application
Membership application
====================== ======================
This application's domain relate to organizational structures and This application's domain relate to organizational structures and

View file

@ -7,7 +7,6 @@ from django.db import models
class Migration(migrations.Migration): class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [

View file

@ -2,11 +2,11 @@
import django.contrib.postgres.constraints import django.contrib.postgres.constraints
import django.contrib.postgres.fields.ranges import django.contrib.postgres.fields.ranges
from django.db import migrations, models from django.db import migrations
from django.db import models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("membership", "0001_initial"), ("membership", "0001_initial"),
] ]
@ -34,9 +34,7 @@ class Migration(migrations.Migration):
), ),
( (
"period", "period",
django.contrib.postgres.fields.ranges.DateRangeField( django.contrib.postgres.fields.ranges.DateRangeField(verbose_name="period"),
verbose_name="period"
),
), ),
], ],
), ),

View file

@ -1,11 +1,11 @@
# Generated by Django 4.1 on 2023-01-02 21:05 # Generated by Django 4.1 on 2023-01-02 21:05
from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
from django.db import migrations
from django.db import models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("membership", "0002_subscriptionperiod_remove_membership_period_and_more"), ("membership", "0002_subscriptionperiod_remove_membership_period_and_more"),
] ]

View file

@ -1,11 +1,11 @@
# Generated by Django 4.1 on 2023-01-02 21:06 # Generated by Django 4.1 on 2023-01-02 21:06
from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
from django.db import migrations
from django.db import models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("membership", "0003_membership_period"), ("membership", "0003_membership_period"),
] ]

View file

@ -4,22 +4,20 @@ from django.db import migrations
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('auth', '0012_alter_user_first_name_max_length'), ("auth", "0012_alter_user_first_name_max_length"),
('membership', '0004_alter_membership_period'), ("membership", "0004_alter_membership_period"),
] ]
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='Member', name="Member",
fields=[ fields=[],
],
options={ options={
'proxy': True, "proxy": True,
'indexes': [], "indexes": [],
'constraints': [], "constraints": [],
}, },
bases=('auth.user',), bases=("auth.user",),
), ),
] ]

View file

@ -5,7 +5,6 @@ from django.contrib.postgres.fields import RangeOperators
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from utils.mixins import CreatedModifiedAbstract from utils.mixins import CreatedModifiedAbstract
@ -35,9 +34,7 @@ class Member(User):
class SubscriptionPeriod(CreatedModifiedAbstract): class SubscriptionPeriod(CreatedModifiedAbstract):
""" """Denotes a period for which members should pay their membership fee for."""
Denotes a period for which members should pay their membership fee for.
"""
period = DateRangeField(verbose_name=_("period")) period = DateRangeField(verbose_name=_("period"))
@ -52,15 +49,11 @@ class SubscriptionPeriod(CreatedModifiedAbstract):
] ]
def __str__(self): def __str__(self):
return ( return f"{self.period.lower} - {self.period.upper or _('next general assembly')}"
f"{self.period.lower} - {self.period.upper or _('next general assembly')}"
)
class Membership(CreatedModifiedAbstract): class Membership(CreatedModifiedAbstract):
""" """Tracks that a user has membership of a given type for a given period."""
Tracks that a user has membership of a given type for a given period.
"""
class QuerySet(models.QuerySet): class QuerySet(models.QuerySet):
def for_member(self, member: Member): def for_member(self, member: Member):
@ -106,8 +99,7 @@ class Membership(CreatedModifiedAbstract):
class MembershipType(CreatedModifiedAbstract): class MembershipType(CreatedModifiedAbstract):
""" """Models membership types. Currently only a name, but will in the future
Models membership types. Currently only a name, but will in the future
possibly contain more information like fees. possibly contain more information like fees.
""" """

View file

@ -1,15 +1,14 @@
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django_view_decorator import namespaced_decorator_factory from django_view_decorator import namespaced_decorator_factory
from utils.view_utils import RowAction
from utils.view_utils import render
from utils.view_utils import render_list
from .permissions import ADMINISTRATE_MEMBERS from .permissions import ADMINISTRATE_MEMBERS
from .selectors import get_member from .selectors import get_member
from .selectors import get_members from .selectors import get_members
from .selectors import get_memberships from .selectors import get_memberships
from .selectors import get_subscription_periods from .selectors import get_subscription_periods
from utils.view_utils import render
from utils.view_utils import render_list
from utils.view_utils import RowAction
member_view = namespaced_decorator_factory(namespace="member", base_path="membership") member_view = namespaced_decorator_factory(namespace="member", base_path="membership")

View file

@ -1,5 +1,4 @@
from django_view_decorator import view from django_view_decorator import view
from utils.view_utils import render from utils.view_utils import render

View file

@ -1,5 +1,4 @@
""" """WSGI config for membersystem project.
WSGI config for membersystem project.
It exposes the WSGI callable as a module-level variable named ``application``. It exposes the WSGI callable as a module-level variable named ``application``.

View file

@ -7,7 +7,6 @@ register = template.Library()
@register.simple_tag(takes_context=True) @register.simple_tag(takes_context=True)
def active_path(context, path_name, class_name) -> str | None: def active_path(context, path_name, class_name) -> str | None:
"""Return the given class name if the current path matches the given path name.""" """Return the given class name if the current path matches the given path name."""
path = reverse(path_name) path = reverse(path_name)
request_path = context.get("request").path request_path = context.get("request").path

View file

@ -15,9 +15,7 @@ from zen_queries import render as zen_queries_render
@dataclass @dataclass
class Row: class Row:
""" """A row in a table."""
A row in a table.
"""
data: dict[str, str] data: dict[str, str]
actions: list[dict[str, str]] actions: list[dict[str, str]]
@ -25,18 +23,14 @@ class Row:
@dataclass @dataclass
class RowAction: class RowAction:
""" """An action that can be performed on a row in a table."""
An action that can be performed on a row in a table.
"""
label: str label: str
url_name: str url_name: str
url_kwargs: dict[str, str] url_kwargs: dict[str, str]
def render(self, obj) -> dict[str, str]: def render(self, obj) -> dict[str, str]:
""" """Render the action as a dictionary for the given object."""
Render the action as a dictionary for the given object.
"""
url = reverse( url = reverse(
self.url_name, self.url_name,
kwargs={key: getattr(obj, value) for key, value in self.url_kwargs.items()}, kwargs={key: getattr(obj, value) for key, value in self.url_kwargs.items()},
@ -50,14 +44,11 @@ def render_list(
entity_name_plural: str, entity_name_plural: str,
objects: list["Model"], objects: list["Model"],
columns: list[tuple[str, str]], columns: list[tuple[str, str]],
row_actions: list[RowAction] = None, row_actions: list[RowAction] | None = None,
list_actions: list[tuple[str, str]] = None, list_actions: list[tuple[str, str]] | None = None,
paginate_by: int = None, paginate_by: int | None = None,
) -> HttpResponse: ) -> HttpResponse:
""" """Render a list of objects with a table."""
Render a list of objects with a table.
"""
# TODO: List actions # TODO: List actions
total_count = len(objects) total_count = len(objects)
@ -107,16 +98,12 @@ def render_list(
def base_context(request: HttpRequest) -> dict[str, Any]: def base_context(request: HttpRequest) -> dict[str, Any]:
""" """Return a base context for all views."""
Return a base context for all views.
"""
return {"site": get_current_site(request)} return {"site": get_current_site(request)}
def render(request, template_name, context=None): def render(request, template_name, context=None):
""" """Render a template with a base context."""
Render a template with a base context.
"""
if context is None: if context is None:
context = {} context = {}
context = base_context(request) | context context = base_context(request) | context