bump ruff to 0.16

This commit is contained in:
imperosol
2026-07-26 19:46:03 +02:00
parent 2d75a3e6c2
commit 3be4c583f1
11 changed files with 64 additions and 65 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
repos: repos:
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version. # Ruff version.
rev: v0.15.19 rev: v0.16.0
hooks: hooks:
- id: ruff-check # just check the code, and print the errors - id: ruff-check # just check the code, and print the errors
- id: ruff-check # actually fix the fixable errors, but print nothing - id: ruff-check # actually fix the fixable errors, but print nothing
+8 -4
View File
@@ -61,9 +61,8 @@ Un fichier de migration ressemble à ça :
```python ```python
from django.db import migrations from django.db import migrations
class Migration(migrations.Migration):
class Migration(migrations.Migration):
dependencies = [ dependencies = [
# liste des autres migrations à appliquer avant celle-ci # liste des autres migrations à appliquer avant celle-ci
] ]
@@ -117,14 +116,16 @@ Par exemple :
```python ```python
from django.db import migrations from django.db import migrations
def forwards_func(apps, schema_editor): def forwards_func(apps, schema_editor):
print("Appplication de la migration") print("Appplication de la migration")
def reverse_func(apps, schema_editor): def reverse_func(apps, schema_editor):
print("Annulation de la migration") print("Annulation de la migration")
class Migration(migrations.Migration):
class Migration(migrations.Migration):
dependencies = [] dependencies = []
operations = [ operations = [
@@ -164,6 +165,7 @@ On écrirait donc, dans l'application `pedagogy` :
from django.db import models from django.db import models
from core.models import User from core.models import User
class UserUe(models.Model): class UserUe(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE)
ue = models.CharField(max_length=10) ue = models.CharField(max_length=10)
@@ -174,6 +176,7 @@ Et nous aurions le fichier de migration suivant :
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
@@ -289,6 +292,7 @@ La commande vous donnera ceci :
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
replaces = [("pedagogy", "0004_userue"), ("pedagogy", "0005_alter_userue_ue")] replaces = [("pedagogy", "0004_userue"), ("pedagogy", "0005_alter_userue_ue")]
+1 -5
View File
@@ -191,7 +191,6 @@ for user in richest.annotate(amount=F("customer__amount"))[:100]:
On aurait même pu réorganiser ça : On aurait même pu réorganiser ça :
```python ```python
from core.models import User from core.models import User
from django.db.models import F from django.db.models import F
@@ -239,10 +238,7 @@ nous écrivons donc instinctivement :
from counter.models import Counter from counter.models import Counter
foyer = Counter.objects.get(name="Foyer") foyer = Counter.objects.get(name="Foyer")
total_amount = sum( total_amount = sum(sale.amount * sale.unit_price for sale in foyer.sellings.all())
sale.amount * sale.unit_price
for sale in foyer.sellings.all()
)
``` ```
On pourrait penser qu'il n'y a pas de problème. On pourrait penser qu'il n'y a pas de problème.
+1 -2
View File
@@ -27,12 +27,11 @@ SITH_SUBSCRIPTIONS = {
"cursus-alternant": {"name": _("Alternating cursus"), "price": 30, "duration": 6}, "cursus-alternant": {"name": _("Alternating cursus"), "price": 30, "duration": 6},
"membre-honoraire": {"name": _("Honorary member"), "price": 0, "duration": 666}, "membre-honoraire": {"name": _("Honorary member"), "price": 0, "duration": 666},
"un-jour": {"name": _("One day"), "price": 0, "duration": 0.00555333}, "un-jour": {"name": _("One day"), "price": 0, "duration": 0.00555333},
# On rajoute ici notre cotisation # On rajoute ici notre cotisation
# Elle se nomme "Un mois" # Elle se nomme "Un mois"
# Coûte 6€ # Coûte 6€
# Dure 1 mois (on raisonne en semestre, ici, c'est 1/6 de semestre) # Dure 1 mois (on raisonne en semestre, ici, c'est 1/6 de semestre)
"un-mois": {"name": _("One month"), "price": 6, "duration": 0.166} "un-mois": {"name": _("One month"), "price": 6, "duration": 0.166},
} }
``` ```
+1 -1
View File
@@ -15,7 +15,7 @@ Si le mot est dans le code Python :
```python ```python
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
help_text=_("Hello") help_text = _("Hello")
``` ```
Si le mot apparaît dans le template Jinja : Si le mot apparaît dans le template Jinja :
+1
View File
@@ -26,6 +26,7 @@ from django.templatetags.static import static
# Sélectionnez le fichier de bannière pour le weekmail de l'automne 2018 # Sélectionnez le fichier de bannière pour le weekmail de l'automne 2018
def get_banner(self): def get_banner(self):
return "http://" + settings.SITH_URL + static("com/img/weekmail_bannerA18.jpg") return "http://" + settings.SITH_URL + static("com/img/weekmail_bannerA18.jpg")
``` ```
+3 -2
View File
@@ -147,14 +147,15 @@ Voici quelques exemples :
env = Env() env = Env()
env.read_env() env.read_env()
async def main(): async def main():
async with aiohttp.ClientSession( async with aiohttp.ClientSession(
base_url="https://ae.utbm.fr/api/", base_url="https://ae.utbm.fr/api/", headers={"X-APIKey": env.str("API_KEY")}
headers={"X-APIKey": env.str("API_KEY")}
) as session: ) as session:
async with session.get("club/1") as res: async with session.get("club/1") as res:
print(await res.json()) print(await res.json())
asyncio.run(main()) asyncio.run(main())
``` ```
+7 -11
View File
@@ -161,8 +161,8 @@ qui seront alors injectés.
```python ```python
from django.views.generic import CreateView, UpdateView, TemplateView from django.views.generic import CreateView, UpdateView, TemplateView
from core.views.mixins import FragmentMixin from core.views.mixins import FragmentMixin
class FooCreateFragment(FragmentMixin, CreateView): class FooCreateFragment(FragmentMixin, CreateView):
model = Foo model = Foo
fields = ["foo", "bar"] fields = ["foo", "bar"]
@@ -182,7 +182,7 @@ qui seront alors injectés.
def get_context_data(**kwargs): def get_context_data(**kwargs):
return super().get_context_data(**kwargs) | { return super().get_context_data(**kwargs) | {
"create_fragment": FooCreateFragment.as_fragment()(), "create_fragment": FooCreateFragment.as_fragment()(),
"update_fragment": FooUpdateFragment.as_fragment()(foo_id=1) "update_fragment": FooUpdateFragment.as_fragment()(foo_id=1),
} }
``` ```
@@ -288,7 +288,7 @@ class FooCreateFragment(FragmentMixin, CreateView):
def render_fragment(self, request, **kwargs): def render_fragment(self, request, **kwargs):
if "foo" in kwargs: if "foo" in kwargs:
kwargs["foo"] += 2 kwargs["foo"] += 2
return super().render_fragment(request, **kwargs) return super().render_fragment(request, **kwargs)
``` ```
@@ -319,11 +319,9 @@ from core.views.mixins import UseFragmentsMixin
class FooCompositeFormView(UseFragmentsMixin, TemplateView): class FooCompositeFormView(UseFragmentsMixin, TemplateView):
fragments = { fragments = {
"create_fragment": FooCreateFragment, "create_fragment": FooCreateFragment,
"update_fragment": FooUpdateFragment "update_fragment": FooUpdateFragment,
}
fragment_data = {
"update_fragment": {"foo": 4}
} }
fragment_data = {"update_fragment": {"foo": 4}}
template_name = "app/foo.jinja" template_name = "app/foo.jinja"
``` ```
@@ -342,9 +340,7 @@ from core.views.mixins import UseFragmentsMixin
class FooCompositeFormView(UseFragmentsMixin, TemplateView): class FooCompositeFormView(UseFragmentsMixin, TemplateView):
fragments = { fragments = {"create_fragment": FooCreateFragment}
"create_fragment": FooCreateFragment
}
template_name = "app/foo.jinja" template_name = "app/foo.jinja"
def get_fragment_context_data(self): def get_fragment_context_data(self):
+14 -12
View File
@@ -123,6 +123,7 @@ Par exemple, prenons le modèle suivant :
```python ```python
from django.db import models from django.db import models
class News(models.Model): class News(models.Model):
# ... # ...
@@ -192,20 +193,21 @@ Pour les vues sous forme de fonction, il y a le décorateur
```python ```python
from com.models import News from com.models import News
from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin
from django.shortcuts import redirect from django.shortcuts import redirect
from django.urls import reverse from django.urls import reverse
from django.views import View from django.views import View
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
class NewsModerateView(PermissionRequiredMixin, SingleObjectMixin, View): class NewsModerateView(PermissionRequiredMixin, SingleObjectMixin, View):
model = News model = News
pk_url_kwarg = "news_id" pk_url_kwarg = "news_id"
permission_required = "com.moderate_news" permission_required = "com.moderate_news"
# On peut aussi fournir plusieurs permissions, par exemple : # On peut aussi fournir plusieurs permissions, par exemple :
# permission_required = ["com.moderate_news", "com.delete_news"] # permission_required = ["com.moderate_news", "com.delete_news"]
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
# Si nous sommes ici, nous pouvons être certains que l'utilisateur # Si nous sommes ici, nous pouvons être certains que l'utilisateur
# a la permission requise # a la permission requise
@@ -219,12 +221,13 @@ Pour les vues sous forme de fonction, il y a le décorateur
```python ```python
from com.models import News from com.models import News
from django.contrib.auth.decorators import permission_required from django.contrib.auth.decorators import permission_required
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse from django.urls import reverse
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
@permission_required("com.moderate_news") @permission_required("com.moderate_news")
@require_POST @require_POST
def moderate_news(request, news_id: int): def moderate_news(request, news_id: int):
@@ -263,6 +266,7 @@ from core.auth.mixins import PermissionOrAuthorRequiredMixin
from django.views.generic import UpdateView from django.views.generic import UpdateView
class NewsUpdateView(PermissionOrAuthorRequiredMixin, UpdateView): class NewsUpdateView(PermissionOrAuthorRequiredMixin, UpdateView):
model = News model = News
pk_url_kwarg = "news_id" pk_url_kwarg = "news_id"
@@ -324,8 +328,8 @@ Voici un exemple d'implémentation de ce système :
from core.models import User, Group from core.models import User, Group
class Article(models.Model):
class Article(models.Model):
title = models.CharField(_("title"), max_length=100) title = models.CharField(_("title"), max_length=100)
content = models.TextField(_("content")) content = models.TextField(_("content"))
@@ -370,6 +374,7 @@ Voici un exemple d'implémentation de ce système :
from core.models import User, Group from core.models import User, Group
class Article(models.Model): class Article(models.Model):
title = models.CharField(_("title"), max_length=100) title = models.CharField(_("title"), max_length=100)
content = models.TextField(_("content")) content = models.TextField(_("content"))
@@ -378,7 +383,7 @@ Voici un exemple d'implémentation de ce système :
owner_group = models.ForeignKey( # (1)! owner_group = models.ForeignKey( # (1)!
Group, related_name="owned_articles", default=settings.SITH_GROUP_ROOT_ID Group, related_name="owned_articles", default=settings.SITH_GROUP_ROOT_ID
) )
# relation many-to-many # relation many-to-many
edit_groups = models.ManyToManyField( # (2)! edit_groups = models.ManyToManyField( # (2)!
Group, Group,
@@ -386,7 +391,7 @@ Voici un exemple d'implémentation de ce système :
verbose_name=_("edit groups"), verbose_name=_("edit groups"),
blank=True, blank=True,
) )
# relation many-to-many # relation many-to-many
view_groups = models.ManyToManyField( # (3)! view_groups = models.ManyToManyField( # (3)!
Group, Group,
@@ -529,10 +534,7 @@ class NewsQuerySet(models.QuerySet): # (1)!
return self return self
# sinon, on retourne les nouvelles modérées ou dont l'utilisateur # sinon, on retourne les nouvelles modérées ou dont l'utilisateur
# est l'auteur # est l'auteur
return self.filter( return self.filter(models.Q(is_moderated=True) | models.Q(author=user))
models.Q(is_moderated=True)
| models.Q(author=user)
)
class News(models.Model): class News(models.Model):
+1 -1
View File
@@ -66,7 +66,7 @@ dev = [
"django-debug-toolbar>=7.0.0,<8", "django-debug-toolbar>=7.0.0,<8",
"ipython>=9.14.1,<10.0.0", "ipython>=9.14.1,<10.0.0",
"pre-commit>=4.6.0,<5.0.0", "pre-commit>=4.6.0,<5.0.0",
"ruff>=0.15.19,<1.0.0", "ruff>=0.16.0,<1.0.0",
"djhtml>=3.0.11,<4.0.0", "djhtml>=3.0.11,<4.0.0",
"faker>=40.23.0,<41.0.0", "faker>=40.23.0,<41.0.0",
"rjsmin>=1.2.5,<2.0.0", "rjsmin>=1.2.5,<2.0.0",
Generated
+26 -26
View File
@@ -972,9 +972,9 @@ resolution-markers = [
"python_full_version < '3.13'", "python_full_version < '3.13'",
] ]
dependencies = [ dependencies = [
{ name = "pydantic", marker = "python_full_version < '3.13'" }, { name = "pydantic" },
{ name = "python-dateutil", marker = "python_full_version < '3.13'" }, { name = "python-dateutil" },
{ name = "tzdata", marker = "python_full_version < '3.13'" }, { name = "tzdata" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/0c/a3/506fe8d9416472588ff30d4c97a7e477f680a098c74a9f2050bd84182a75/ical-12.0.0.tar.gz", hash = "sha256:2f1c7450bd1eff586322273360f44931eb0919dc048c7284f1647037624be7c4", size = 125412, upload-time = "2025-11-13T06:00:04.95Z" } sdist = { url = "https://files.pythonhosted.org/packages/0c/a3/506fe8d9416472588ff30d4c97a7e477f680a098c74a9f2050bd84182a75/ical-12.0.0.tar.gz", hash = "sha256:2f1c7450bd1eff586322273360f44931eb0919dc048c7284f1647037624be7c4", size = 125412, upload-time = "2025-11-13T06:00:04.95Z" }
wheels = [ wheels = [
@@ -989,9 +989,9 @@ resolution-markers = [
"python_full_version >= '3.13'", "python_full_version >= '3.13'",
] ]
dependencies = [ dependencies = [
{ name = "pydantic", marker = "python_full_version >= '3.13'" }, { name = "pydantic" },
{ name = "python-dateutil", marker = "python_full_version >= '3.13'" }, { name = "python-dateutil" },
{ name = "tzdata", marker = "python_full_version >= '3.13'" }, { name = "tzdata" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/f5/1c/dc7378c5ba63e8b0f2987bd827a1e40bd27196d37a7082be0593551e8ed8/ical-13.2.5.tar.gz", hash = "sha256:1cc3116e6f522eeeaa694b3e20b58dbfbe4b281954a8d3d28892cfb61f03fd40", size = 131405, upload-time = "2026-05-24T16:51:56.017Z" } sdist = { url = "https://files.pythonhosted.org/packages/f5/1c/dc7378c5ba63e8b0f2987bd827a1e40bd27196d37a7082be0593551e8ed8/ical-13.2.5.tar.gz", hash = "sha256:1cc3116e6f522eeeaa694b3e20b58dbfbe4b281954a8d3d28892cfb61f03fd40", size = 131405, upload-time = "2026-05-24T16:51:56.017Z" }
wheels = [ wheels = [
@@ -2074,27 +2074,27 @@ wheels = [
[[package]] [[package]]
name = "ruff" name = "ruff"
version = "0.15.19" version = "0.16.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d5/e6/15800dfde183a1a106594016c912b4c12d050a301989d1aca6cb63759fe8/ruff-0.15.19.tar.gz", hash = "sha256:edc27f7172a93b32b102687009d6a588508815072141543ae603a8b9b0823063", size = 4772071, upload-time = "2026-06-24T01:10:46.942Z" } sdist = { url = "https://files.pythonhosted.org/packages/4d/94/1e5e4967626faf12fa56999cd6222dff6992ceb086ad7945756baf70c7a7/ruff-0.16.0.tar.gz", hash = "sha256:e460aafd5495ec89efaa6ced2e4a9a581116451e1c88b9d37ef497e0f8e93982", size = 4790557, upload-time = "2026-07-23T19:11:30.981Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/88/4c/9ded7626c39a0440c575bf69e2bf500d443388272c842662c59852ee7fcd/ruff-0.15.19-py3-none-linux_armv6l.whl", hash = "sha256:922d1eb283161564759bd49f507e91dc6112c15da8bd5b84ed714e086243cf86", size = 10950859, upload-time = "2026-06-24T01:10:38.491Z" }, { url = "https://files.pythonhosted.org/packages/4b/81/1c8818fee7ce1a04cd7d1b3172e0a8f8e4f1dc4feb7fc390e16daa8af323/ruff-0.16.0-py3-none-linux_armv6l.whl", hash = "sha256:e5115729eb08c585e5121978ba5d5b60caeae394ce21b9fb5e6cd33a1c6c9b1e", size = 10754633, upload-time = "2026-07-23T19:10:46.415Z" },
{ url = "https://files.pythonhosted.org/packages/fb/ef/c211505ece1d00ef493d58e54e3b6383c946a21e9874774eb531f2512cf3/ruff-0.15.19-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:4d190d8f62a0b94aba8f721116538a9ee29b1e74d26650846ba9b99f0ae21c40", size = 11294529, upload-time = "2026-06-24T01:10:36.481Z" }, { url = "https://files.pythonhosted.org/packages/23/df/beaf59c09d68db84304d555f188b276a77132a5d5b0b67a5c762aa143628/ruff-0.16.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3c954b1d580bfa035b41654f7858cc7e71d5fc3ac5b723dd62bd9133830ed522", size = 10969164, upload-time = "2026-07-23T19:10:50.271Z" },
{ url = "https://files.pythonhosted.org/packages/fe/93/78d462e7d39968e58094dc57be7d09ffb14ce37da5b68ed70338a35a1f21/ruff-0.15.19-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5a2c86ba6870dd415a9d9eb8be94d7924ebec6a26ffc7958ec7ca29d4bff967d", size = 10641416, upload-time = "2026-06-24T01:10:48.923Z" }, { url = "https://files.pythonhosted.org/packages/42/ce/741cd197496a1abbf51352710fd15ed995d2a2be87189c1da26a450d6e83/ruff-0.16.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e01c21d10eb1b29f47b7454e1f4056db9a3f0260c646aa88457c610291db9f81", size = 10488846, upload-time = "2026-07-23T19:10:52.639Z" },
{ url = "https://files.pythonhosted.org/packages/76/c4/5cb66cfd1f865d5cca908b86c93ac785e7f572193d3c7426079ca6643e24/ruff-0.15.19-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82b432bc087264aea70fd25ac198918b70bd9e2aa0db4297b0bb91bbfbbc63ce", size = 11015582, upload-time = "2026-06-24T01:10:30.089Z" }, { url = "https://files.pythonhosted.org/packages/52/2a/a2db8e88cade358f5cdcb05674a917751074109315d014eb6352d9a893f7/ruff-0.16.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e364e5ed22ed8dc05082fd78e35308618260907ac2d3c1d637b2e682415b6c9", size = 10889729, upload-time = "2026-07-23T19:10:54.89Z" },
{ url = "https://files.pythonhosted.org/packages/51/9f/8ecfaec10cf5eecd28fbc00ff4fb867db90a1be54bf3d39ebf93f893cd52/ruff-0.15.19-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8530a09d03b3a8c994f8b559a7dcdabc690bcd3f78ef276c38c83166798ebf56", size = 10744059, upload-time = "2026-06-24T01:10:32.48Z" }, { url = "https://files.pythonhosted.org/packages/42/65/62a771694ebd63029dc953e27dbad40e1588bd4860ff9fe881018fddaa49/ruff-0.16.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d327b8fc113a1d4421a04f3839d3752057c8dd1ee320223a6f3f52d04ada462a", size = 10568275, upload-time = "2026-07-23T19:10:56.993Z" },
{ url = "https://files.pythonhosted.org/packages/35/6b/983249d04562bc2d590edd75f32455cdb473affb3ba4bc8d883e939c697d/ruff-0.15.19-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87bf21fb3875fe69f0eacc825411657e2e85589cce633c35c0adf1113649c62b", size = 11568461, upload-time = "2026-06-24T01:10:17.435Z" }, { url = "https://files.pythonhosted.org/packages/3f/e2/ced249fe8af5f086c5c58cc21cc3356d50f32f7401c5df87050c999620a7/ruff-0.16.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b50c55e263103586b3dcf5f73d479eb8cb5fdb6098fec59a62891dab653717", size = 11385112, upload-time = "2026-07-23T19:10:59.615Z" },
{ url = "https://files.pythonhosted.org/packages/eb/39/bc7794f127b18f492a3b4ee82bba5a900c985ff13b72b46f46e3c171ba34/ruff-0.15.19-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f9b229cb3ef56ecc2c1c8ebeca64b7a7740ccaef40a9eb097e78dde5a8560b83", size = 12429690, upload-time = "2026-06-24T01:10:40.638Z" }, { url = "https://files.pythonhosted.org/packages/87/0b/05154977a8fd69eeb6c103271f55403bfd8711f5c0f8ed07489d95a504e7/ruff-0.16.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ff4a79ce3ec0172f3241943835de1c4cb4e2dcd07f0f8c2d02603dbbbee4b17", size = 12207008, upload-time = "2026-07-23T19:11:02.154Z" },
{ url = "https://files.pythonhosted.org/packages/0a/3b/0de6859e698ed11c8a49e765196c8d333599b6a546c0715df39b6ba1aa2e/ruff-0.15.19-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6c754515be7b76afe6e7e62df7776709571bcfc1631183828afcf3bafa869e3", size = 11693067, upload-time = "2026-06-24T01:10:25.681Z" }, { url = "https://files.pythonhosted.org/packages/fb/29/98225831a3a1eab0e02f4acc6ca6559a98611dcc68b6965ff4b7234627c1/ruff-0.16.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e95c448fca1fb2a18372a9440926c5a6ee789639bb975c72e7ae6d0b04218ab4", size = 11650842, upload-time = "2026-07-23T19:11:04.557Z" },
{ url = "https://files.pythonhosted.org/packages/89/3d/0b1f30f84bee9ae6ae8d349c2ba8b6f4b040966744efdd3acc804ae7c024/ruff-0.15.19-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a498f82e0f4d8904c4e0aea5139cdfac1f39d19a3c51d491292f63a36e83b2e", size = 11616911, upload-time = "2026-06-24T01:10:44.809Z" }, { url = "https://files.pythonhosted.org/packages/91/66/6bd3cf90500653d55dc0ffc8507aa8300bd49d0214b2e8cb4d3fef2943ba/ruff-0.16.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f11a8d11010301d0a398a2fdef67691feca7294da6aef55e2150e8fa2cd520b", size = 11400718, upload-time = "2026-07-23T19:11:09.233Z" },
{ url = "https://files.pythonhosted.org/packages/4d/eb/c90bd3dfc12eed9032c2c1bfe05105b93a1b2c8bce555db6308315b853ce/ruff-0.15.19-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:d48caa34488fb521fd0ef4aea2b0e8fe758298df044138f0d67b687a6a0d07ed", size = 11649343, upload-time = "2026-06-24T01:10:23.472Z" }, { url = "https://files.pythonhosted.org/packages/8e/a2/a54eb4eae05d66364050a5d3b8a9c5ef88196531b3cbe7109d873f87f819/ruff-0.16.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:48044c678e9cb8698246c99b14aaccfa6601dea7379eb48a6f8f73f7a6d86cd0", size = 11426177, upload-time = "2026-07-23T19:11:11.994Z" },
{ url = "https://files.pythonhosted.org/packages/82/91/01caa13602a2f12fae5edbe8caf78b3c1e6db1293132aee6959eecce095c/ruff-0.15.19-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4171b6613effa9363cd46dd4f75bd1827b6d1b946b5e278ed0c600d305379445", size = 10977610, upload-time = "2026-06-24T01:10:50.892Z" }, { url = "https://files.pythonhosted.org/packages/1a/be/16e3eea4b2a478a496919f5e36f17c4559e54620bd3bbac5d6affa068006/ruff-0.16.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7aa0959bad8eb8bef50340154fc9b58678dae31fa4293afa38b44b6e552c0213", size = 10856126, upload-time = "2026-07-23T19:11:14.221Z" },
{ url = "https://files.pythonhosted.org/packages/3c/51/acb817922feab9ecbb3201377d4dbe7a25f1395e46545820061973f03468/ruff-0.15.19-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:27c15b2a241dd4d995557949a094fe78b8ad99122a38ccae1595849bcc947b3f", size = 10744900, upload-time = "2026-06-24T01:10:42.726Z" }, { url = "https://files.pythonhosted.org/packages/a2/84/252eb8b868a16eec7257c14f504f77537e734b2d69c762e639e588e304a3/ruff-0.16.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:28ea2b7df8ebf7f9da6b7d47b230ab48f387c0a29be3b474c4d0740e197bb9af", size = 10571208, upload-time = "2026-07-23T19:11:16.378Z" },
{ url = "https://files.pythonhosted.org/packages/84/bc/5c8ca46b8a7a3f2b16cfbec88721d772b1c93912904e8f8c2e49470fea63/ruff-0.15.19-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ed03b7862d68f0a8771d50ee129980cbf1b113f96e250b73954bc292f689e0bb", size = 11293560, upload-time = "2026-06-24T01:10:21.262Z" }, { url = "https://files.pythonhosted.org/packages/21/09/817a482f542f7570cbb4554b26e896610c7114f539b1d9e2d2145bf6bef6/ruff-0.16.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:33a3dfac8c35f81498dea9181bccc2f4c4bc8f1521a1dd9406e77643e0f0fb09", size = 11063329, upload-time = "2026-07-23T19:11:19.173Z" },
{ url = "https://files.pythonhosted.org/packages/81/e0/4a888cbe4d5523b3f77a2b1fa043f46cfeba1b32eac35dcfadee0578fa8a/ruff-0.15.19-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:08143f0685ae278b30727ea72e90c61e5bd9c31b91aac4f5bb989538f73d24b8", size = 11696533, upload-time = "2026-06-24T01:10:53.046Z" }, { url = "https://files.pythonhosted.org/packages/2e/23/9403c180ca1cb9b1f7335f5c3e5305c09d49ea5b345196682a36028bde4a/ruff-0.16.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a5237a0bda500d30d81b8e07a6973a5cbc772864cbf746ae2f4e8a2e01c9f4ed", size = 11489751, upload-time = "2026-07-23T19:11:21.74Z" },
{ url = "https://files.pythonhosted.org/packages/98/43/c34b2fcd79262a85161764a97aaca89c3e4f574340ab61430cefa2bdd2c1/ruff-0.15.19-py3-none-win32.whl", hash = "sha256:8f47f0f92952af2557212bb10cf3e695cd4cf28b2c6e42cdb18ec6c9ebfa19da", size = 10986299, upload-time = "2026-06-24T01:10:55.185Z" }, { url = "https://files.pythonhosted.org/packages/b2/1d/1b2ef7bcde851c78d7f17f1cca13fd6dc695fc4b3d6197941e72cae5b132/ruff-0.16.0-py3-none-win32.whl", hash = "sha256:7fab76fa065c873f41ff744347c6e77bcc3dfec4bcc754dc26b63d23c0f7f5fb", size = 10785885, upload-time = "2026-07-23T19:11:23.947Z" },
{ url = "https://files.pythonhosted.org/packages/22/e8/15fd23e02b2442b56b2026b455977bc3057aa34b26e6323d1e99e8531a9f/ruff-0.15.19-py3-none-win_amd64.whl", hash = "sha256:efeca47ee3f9d4a7162655a3b8e6ee4a878646044233978d4d2c1ff8cdd914f0", size = 12123473, upload-time = "2026-06-24T01:10:27.74Z" }, { url = "https://files.pythonhosted.org/packages/b2/a3/d5e4ef7a56be3f928ffb90b94c25ba7d3cb9c7fe0736aeaaedf361770712/ruff-0.16.0-py3-none-win_amd64.whl", hash = "sha256:429c117f022bf481fabd9d551e7a3952b24c65e6ef44337ea09d90bebef14472", size = 11923141, upload-time = "2026-07-23T19:11:26.409Z" },
{ url = "https://files.pythonhosted.org/packages/30/66/9a73695e31eaee04f35d8475998bf8ab354465f9c638936d76111603dcc5/ruff-0.15.19-py3-none-win_arm64.whl", hash = "sha256:6c6b607466e47349332eb1d9be52fb1467423fc07c217341af41cd0f3f0573be", size = 11376779, upload-time = "2026-06-24T01:10:34.465Z" }, { url = "https://files.pythonhosted.org/packages/cb/9a/8415f2657cbe200f41a4531ccededf135505a92d4a012229121f885b26f9/ruff-0.16.0-py3-none-win_arm64.whl", hash = "sha256:14296fedcd2705c77ab8235439278bbb38f285cf7da5528b00b3e330c3d4872d", size = 11273407, upload-time = "2026-07-23T19:11:28.705Z" },
] ]
[[package]] [[package]]
@@ -2226,7 +2226,7 @@ dev = [
{ name = "ipython", specifier = ">=9.14.1,<10.0.0" }, { name = "ipython", specifier = ">=9.14.1,<10.0.0" },
{ name = "pre-commit", specifier = ">=4.6.0,<5.0.0" }, { name = "pre-commit", specifier = ">=4.6.0,<5.0.0" },
{ name = "rjsmin", specifier = ">=1.2.5,<2.0.0" }, { name = "rjsmin", specifier = ">=1.2.5,<2.0.0" },
{ name = "ruff", specifier = ">=0.15.19,<1.0.0" }, { name = "ruff", specifier = ">=0.16.0,<1.0.0" },
] ]
docs = [ docs = [
{ name = "mkdocs", specifier = ">=1.6.1,<2.0.0" }, { name = "mkdocs", specifier = ">=1.6.1,<2.0.0" },