Skip to content

Commit

Permalink
Tighten Ruff rules and fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
bartTC committed Dec 15, 2023
1 parent 9e80dbb commit 12b7dba
Show file tree
Hide file tree
Showing 18 changed files with 196 additions and 172 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
Changelog:
==========

v1.4 (2023-12-15):

- Added support for Django 5.0.
- Added support for Python 3.12
- Type Annotations

v1.3 (2022-04-30):

- Added support for Django 3.2 to 4.2.
Expand Down
2 changes: 1 addition & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ pytest-django = "*"

[scripts]
tests = "pytest"
cleanup = "sh -c \"ruff --fix wakawaka && black wakawaka\""
cleanup = "sh -c \"ruff --fix wakawaka && ruff format wakawaka\""
runserver = "sh -c \"django-admin migrate --noinput && django-admin runserver\""

34 changes: 15 additions & 19 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,28 @@
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta:__legacy__"

[tool.black]
target-version = ['py311']
include = '\.pyi?$'
exclude = "migrations"

[tool.ruff]
target-version = "py38"
exclude = ["migrations"]
select = ["ALL"]
ignore = [
"A", # Variable/Argument/Class attribute ... is shadowing a python builtin
"C90" , # Method is too complex
"ANN101", # Missing Type Annotation for "self"
"ANN401", # Dynamically typed expressions (typing.Any) are disallowed in `**kwargs`"
"ARG001", # Unused function argument (request, ...)
"ARG002", # Unused method argument (*args, **kwargs)
"D", # Missing or badly formatted docstrings
"E501", # Line too long (>88)
"EM", # Exception must not use <string format>
"ERA001", # Found commented-out code
"FBT", # Flake Boolean Trap (don't use arg=True in functions)
"N8", # Invalid class/method/function naming
"PLR09", # Too many branches, arguments, statements
"PT009", # Use a regular `assert` instead of unittest-style `assertEqual`
"RUF005", # Consider `(list, *list) instead of concatenation
"S101", # Use of `assert` detected
"S308", # Use of `mark_safe` may expose cross-site scripting vulnerabilities
"SLF001", # Private member accessed"
"TID252", # Relative imports from parent modules are banned (from ..foo import bar)"
"TRY003", # Avoid specifying long messages outside the exception class
"RUF012", # Mutable class attributes https://github.com/astral-sh/ruff/issues/5243

"COM812", # (ruff format) Checks for the absence of trailing commas
"ISC001", # (ruff format) Checks for implicitly concatenated strings on a single line
]

[tool.ruff.extend-per-file-ignores]
# Also ignore `E402` in all `__init__.py` files.
"test_*.py" = [
"S101", # S101 Use of `assert` detected
"PLR2004", # Magic value used in comparison,
]

[tool.pytest.ini_options]
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ classifiers =
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Framework :: Django

[options]
Expand Down
2 changes: 1 addition & 1 deletion wakawaka/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class RevisionInlines(admin.TabularInline):

@admin.register(WikiPage)
class WikiPageAdmin(admin.ModelAdmin):
inlines = [RevisionInlines]
inlines = (RevisionInlines,)


@admin.register(Revision)
Expand Down
26 changes: 17 additions & 9 deletions wakawaka/forms.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
from __future__ import annotations

from typing import Any

from django import forms
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.http import HttpRequest, HttpResponseRedirect
from django.urls import reverse
from django.utils.translation import gettext
from django.utils.translation import gettext_lazy as _

from wakawaka.models import Revision
from wakawaka.models import Revision, WikiPage


class WikiPageForm(forms.Form):
Expand All @@ -19,7 +23,9 @@ class WikiPageForm(forms.Form):
required=False,
)

def save(self, request, page, *args, **kwargs):
def save(
self, request: HttpRequest, page: WikiPage, *args: Any, **kwargs: Any
) -> None:
Revision.objects.create(
page=page,
creator=request.user,
Expand All @@ -32,7 +38,7 @@ def save(self, request, page, *args, **kwargs):
class DeleteWikiPageForm(forms.Form):
delete = forms.ChoiceField(label=_("Delete"), choices=())

def __init__(self, request, *args, **kwargs) -> None:
def __init__(self, request: HttpRequest, *args: Any, **kwargs: Any) -> None:
"""
Override the __init__ to display only delete choices the user has
permission for.
Expand All @@ -52,13 +58,15 @@ def __init__(self, request, *args, **kwargs) -> None:

super().__init__(*args, **kwargs)

def _delete_page(self, page):
def _delete_page(self, page: WikiPage) -> None:
page.delete()

def _delete_revision(self, rev):
def _delete_revision(self, rev: Revision) -> None:
rev.delete()

def delete_wiki(self, request, page, rev):
def delete_wiki(
self, request: HttpRequest, page: WikiPage, rev: Revision
) -> HttpResponseRedirect | None:
"""
Deletes the page with all revisions or the revision, based on the
users choice.
Expand Down Expand Up @@ -120,10 +128,10 @@ def delete_wiki(self, request, page, rev):
messages.success(
request,
gettext(
"The page for %s was deleted because you deleted the only revision",
"The page for %s was deleted because "
"you deleted the only revision",
)
% page.slug,
)
return HttpResponseRedirect(reverse("wakawaka_index"))
return None
return None
8 changes: 5 additions & 3 deletions wakawaka/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from django.conf import settings
from django.db import models
from django.utils.translation import gettext
Expand All @@ -12,13 +14,13 @@ class WikiPage(models.Model):
class Meta:
verbose_name = _("Wiki page")
verbose_name_plural = _("Wiki pages")
ordering = ["slug"]
ordering = ("slug",)

def __str__(self) -> str:
return self.slug

@property
def current(self):
def current(self) -> WikiPage:
return self.revisions.latest()


Expand All @@ -44,7 +46,7 @@ class Revision(models.Model):
class Meta:
verbose_name = _("Revision")
verbose_name_plural = _("Revisions")
ordering = ["-modified"]
ordering = ("-modified",)
get_latest_by = "modified"

def __str__(self) -> str:
Expand Down
13 changes: 7 additions & 6 deletions wakawaka/templatetags/wakawaka_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.core.exceptions import ObjectDoesNotExist
from django.template import Library
from django.urls import reverse
from django.utils.safestring import mark_safe
from django.utils.safestring import SafeString, mark_safe

from wakawaka.models import WikiPage
from wakawaka.urls import WIKI_SLUG
Expand All @@ -13,21 +13,22 @@
WIKI_WORDS_REGEX = re.compile(r"\b%s\b" % WIKI_SLUG, re.UNICODE)


def replace_wikiwords(value):
def replace_wikiword(m):
def replace_wikiwords(value: str) -> SafeString:
def replace_wikiword(m: re.Match) -> str:
slug = m.group(1)
try:
page = WikiPage.objects.get(slug=slug)
url = reverse("wakawaka_page", kwargs={"slug": slug})
return rf'<a href="{url}">{page.slug}</a>'
except ObjectDoesNotExist:
url = reverse("wakawaka_edit", kwargs={"slug": slug})
return rf'<a class="doesnotexist" href="{url}">{slug}</a>'
else:
return rf'<a href="{url}">{page.slug}</a>'

return mark_safe(WIKI_WORDS_REGEX.sub(replace_wikiword, value))
return mark_safe(WIKI_WORDS_REGEX.sub(replace_wikiword, value)) # noqa: S308


@register.filter
def wikify(value):
def wikify(value: str) -> SafeString:
"""Makes WikiWords"""
return replace_wikiwords(value)
9 changes: 5 additions & 4 deletions wakawaka/tests/base.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from typing import Any

from django import get_version
from django.contrib.auth.models import User
Expand All @@ -13,7 +14,7 @@ class BaseTestCase(testcases.TestCase):
General integrity tests around the project.
"""

def _create_user(self, username, password):
def _create_user(self, username: str, password: str) -> User:
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
Expand All @@ -24,7 +25,7 @@ def _create_user(self, username, password):
user.set_password(password)
return user

def login_superuser(self, create=True):
def login_superuser(self) -> User:
username, password = "superuser", "foobar"
user = self._create_user(username, password)
user.is_superuser = True
Expand All @@ -33,15 +34,15 @@ def login_superuser(self, create=True):
self.client.login(username=username, password=password)
return user

def login_staffuser_noperm(self, create=True):
def login_staffuser_noperm(self) -> User:
username, password = "staffuser", "foobar"
user = self._create_user(username, password)
user.is_staff = True
user.save()
self.client.login(username=username, password=password)
return user

def create_wikipage(self, slug, *args):
def create_wikipage(self, slug: str, *args: Any) -> WikiPage:
"""
Creates a WikiPage using the given slug. Creates a Revision with the
content of each additional argument. Example::
Expand Down
18 changes: 9 additions & 9 deletions wakawaka/tests/test_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,28 @@ class ChangesTestCase(BaseTestCase):
The Changes view displays the actual diff of two revisons.
"""

def setUp(self):
def setUp(self) -> None:
super().setUp()

# Create one page with two revisions
self.page = self.create_wikipage("WikiIndex", "First Content", "Second Content")
self.page_url = reverse("wakawaka_changes", kwargs={"slug": "WikiIndex"})

def test_no_rev_ids_given(self):
def test_no_rev_ids_given(self) -> None:
response = self.client.get(self.page_url)
self.assertEqual(response.status_code, 400)
assert response.status_code == 400

def test_nonexisting_rev_ids_given(self):
def test_nonexisting_rev_ids_given(self) -> None:
url = f"{self.page_url}?a=3&b=4"
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
assert response.status_code == 404

def test_compare_rev_ids(self):
def test_compare_rev_ids(self) -> None:
url = f"{self.page_url}?a=1&b=2"
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200

def test_compare_same_rev_ids(self):
def test_compare_same_rev_ids(self) -> None:
url = f"{self.page_url}?a=1&b=1"
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
12 changes: 6 additions & 6 deletions wakawaka/tests/test_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ class IndexTestCase(BaseTestCase):
Index and WikiIndex tests.
"""

def test_calling_home_redircts_to_wikiindex(self):
def test_calling_home_redircts_to_wikiindex(self) -> None:
"""
Calling the homepage `/` will automatically redirect to the
`WikiIndex` index page.
"""
response = self.client.get(reverse("wakawaka_index"))
self.assertEqual(response.status_code, 302)
self.assertEqual(response["Location"], "/WikiIndex/")
assert response.status_code == 302
assert response["Location"] == "/WikiIndex/"

def test_wikiindex_is_a_setting(self):
def test_wikiindex_is_a_setting(self) -> None:
"""
This Homepage name `WikiIndex` can be set by a setting.
"""
with self.settings(WAKAWAKA_DEFAULT_INDEX="WikiWukuIndex"):
response = self.client.get(reverse("wakawaka_index"))
self.assertEqual(response.status_code, 302)
self.assertEqual(response["Location"], "/WikiWukuIndex/")
assert response.status_code == 302
assert response["Location"] == "/WikiWukuIndex/"
Loading

0 comments on commit 12b7dba

Please sign in to comment.