use ruff for formating

Co-authored-by: Bartuccio Antoine <klmp200@users.noreply.github.com>
This commit is contained in:
thomas girod 2024-06-24 11:56:38 +02:00
parent e06bc7dba3
commit 9bdf3fc4ac
16 changed files with 105 additions and 181 deletions

View File

@ -8,15 +8,17 @@ on:
workflow_dispatch: workflow_dispatch:
jobs: jobs:
black: ruff:
name: Black format name: Ruff lint & format
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out repository - uses: actions/checkout@v4
uses: actions/checkout@v3 - name: ruff format
- name: Setup Project uses: chartboost/ruff-action@v1 # format
uses: ./.github/actions/setup_project with:
- run: poetry run black --check . args: format --diff
- name: ruff check
uses: chartboost/ruff-action@v1 # lint
tests: tests:
name: Run tests and generate coverage report name: Run tests and generate coverage report

View File

@ -599,7 +599,7 @@ class OperationPDFView(CanViewMixin, DetailView):
payment_mode = "" payment_mode = ""
for m in settings.SITH_ACCOUNTING_PAYMENT_METHOD: for m in settings.SITH_ACCOUNTING_PAYMENT_METHOD:
if m[0] == mode: if m[0] == mode:
payment_mode += "[\u00D7]" payment_mode += "[\u00d7]"
else: else:
payment_mode += "[ ]" payment_mode += "[ ]"
payment_mode += " %s\n" % (m[1]) payment_mode += " %s\n" % (m[1])

View File

@ -861,8 +861,7 @@ class MailingFormTest(TestCase):
reverse("club:mailing", kwargs={"club_id": self.bdf.id}), reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_REMOVE_SUBSCRIPTION, "action": MailingForm.ACTION_REMOVE_SUBSCRIPTION,
"removal_%d" "removal_%d" % mde.id: [
% mde.id: [
user.id user.id
for user in mde.subscriptions.filter( for user in mde.subscriptions.filter(
user__in=[self.rbatsbak, self.comunity] user__in=[self.rbatsbak, self.comunity]

View File

@ -698,9 +698,11 @@ class User(AbstractBaseUser):
<em>%s</em> <em>%s</em>
</a> </a>
""" % ( """ % (
self.profile_pict.get_download_url() (
if self.profile_pict self.profile_pict.get_download_url()
else staticfiles_storage.url("core/img/unknown.jpg"), if self.profile_pict
else staticfiles_storage.url("core/img/unknown.jpg")
),
_("Profile"), _("Profile"),
escape(self.get_display_name()), escape(self.get_display_name()),
) )

View File

@ -23,9 +23,9 @@
# #
""" """
This page is useful for custom migration tricks. This page is useful for custom migration tricks.
Sometimes, when you need to have a migration hack and you think it can be Sometimes, when you need to have a migration hack and you think it can be
useful again, put it there, we never know if we might need the hack again. useful again, put it there, we never know if we might need the hack again.
""" """
from django.db import connection, migrations from django.db import connection, migrations

View File

@ -314,9 +314,8 @@ class QuickNotifMixin:
quick_notif_list = [] quick_notif_list = []
def dispatch(self, request, *arg, **kwargs): def dispatch(self, request, *arg, **kwargs):
self.quick_notif_list = ( # In some cases, the class can stay instanciated, so we need to reset the list
[] self.quick_notif_list = []
) # In some cases, the class can stay instanciated, so we need to reset the list
return super(QuickNotifMixin, self).dispatch(request, *arg, **kwargs) return super(QuickNotifMixin, self).dispatch(request, *arg, **kwargs)
def get_success_url(self): def get_success_url(self):

View File

@ -97,12 +97,10 @@ class _MultipleFieldMixin:
return result return result
class MultipleFileField(_MultipleFieldMixin, forms.FileField): class MultipleFileField(_MultipleFieldMixin, forms.FileField): ...
...
class MultipleImageField(_MultipleFieldMixin, forms.ImageField): class MultipleImageField(_MultipleFieldMixin, forms.ImageField): ...
...
class AddFilesForm(forms.Form): class AddFilesForm(forms.Form):

View File

@ -15,7 +15,7 @@
# #
""" """
This module contains views to manage Groups This module contains views to manage Groups
""" """
from django.views.generic.edit import UpdateView, CreateView, DeleteView from django.views.generic.edit import UpdateView, CreateView, DeleteView

View File

@ -100,9 +100,8 @@ def search_club(query, as_json=False):
if query: if query:
clubs = Club.objects.filter(name__icontains=query).all() clubs = Club.objects.filter(name__icontains=query).all()
clubs = clubs[:5] clubs = clubs[:5]
if ( if as_json:
as_json # Re-loads json to avoid double encoding by JsonResponse, but still benefit from serializers
): # Re-loads json to avoid double encoding by JsonResponse, but still benefit from serializers
clubs = json.loads(serializers.serialize("json", clubs, fields=("name"))) clubs = json.loads(serializers.serialize("json", clubs, fields=("name")))
else: else:
clubs = list(clubs) clubs = list(clubs)

View File

@ -141,9 +141,11 @@ class CounterTabsMixin(TabedViewMixin):
"url": reverse_lazy( "url": reverse_lazy(
"counter:details", "counter:details",
kwargs={ kwargs={
"counter_id": self.object.stock_owner.counter.id "counter_id": (
if hasattr(self.object, "stock_owner") self.object.stock_owner.counter.id
else self.object.id if hasattr(self.object, "stock_owner")
else self.object.id
)
}, },
), ),
"slug": "counter", "slug": "counter",
@ -160,9 +162,11 @@ class CounterTabsMixin(TabedViewMixin):
"url": reverse_lazy( "url": reverse_lazy(
"counter:cash_summary", "counter:cash_summary",
kwargs={ kwargs={
"counter_id": self.object.stock_owner.counter.id "counter_id": (
if hasattr(self.object, "stock_owner") self.object.stock_owner.counter.id
else self.object.id if hasattr(self.object, "stock_owner")
else self.object.id
)
}, },
), ),
"slug": "cash_summary", "slug": "cash_summary",
@ -174,9 +178,11 @@ class CounterTabsMixin(TabedViewMixin):
"url": reverse_lazy( "url": reverse_lazy(
"counter:last_ops", "counter:last_ops",
kwargs={ kwargs={
"counter_id": self.object.stock_owner.counter.id "counter_id": (
if hasattr(self.object, "stock_owner") self.object.stock_owner.counter.id
else self.object.id if hasattr(self.object, "stock_owner")
else self.object.id
)
}, },
), ),
"slug": "last_ops", "slug": "last_ops",
@ -189,9 +195,11 @@ class CounterTabsMixin(TabedViewMixin):
"url": reverse_lazy( "url": reverse_lazy(
"stock:take_items", "stock:take_items",
kwargs={ kwargs={
"stock_id": self.object.stock.id "stock_id": (
if hasattr(self.object, "stock") self.object.stock.id
else self.object.stock_owner.id if hasattr(self.object, "stock")
else self.object.stock_owner.id
)
}, },
), ),
"slug": "take_items_from_stock", "slug": "take_items_from_stock",

View File

@ -1,70 +1,66 @@
Configurer son environnement de développement Configurer son environnement de développement
============================================= =============================================
Le projet n'est en aucun cas lié à un quelconque environnement de développement. Il est possible pour chacun de travailler avec les outils dont il a envie et d'utiliser l'éditeur de code avec lequel il est le plus à l'aise. Le projet n'est en aucun cas lié à un quelconque environnement de développement.
Il est possible pour chacun de travailler avec les outils dont il a envie et d'utiliser l'éditeur de code avec lequel il est le plus à l'aise.
Pour donner une idée, Skia a écrit une énorme partie de projet avec l'éditeur *Vim* sur du GNU/Linux Pour donner une idée, Skia a écrit une énorme partie de projet avec l'éditeur *Vim* sur du GNU/Linux
alors que Sli a utilisé *Sublime Text* sur MacOS et que Maréchal travaille avec PyCharm alors que Sli a utilisé *Sublime Text* sur MacOS et que Maréchal travaille avec PyCharm
sur Windows muni de WSL. sur ~~Windows muni de WSL~~ Arch Linux btw.
Configurer Black pour son éditeur Configurer Ruff pour son éditeur
--------------------------------- ---------------------------------
.. note:: .. note::
Black est inclus dans les dépendances du projet. Ruff est inclus dans les dépendances du projet.
Si vous avez réussi à terminer l'installation, vous n'avez donc pas de configuration Si vous avez réussi à terminer l'installation, vous n'avez donc pas de configuration
supplémentaire à effectuer. supplémentaire à effectuer.
Pour utiliser Black, placez-vous à la racine du projet et lancez la commande suivante : Pour utiliser Ruff, placez-vous à la racine du projet et lancez la commande suivante :
.. code-block:: .. code-block::
black . ruff format # pour formatter le code
ruff check # pour linter le code
Black va alors faire son travail sur l'ensemble du projet puis vous dire quels documents Ruff va alors faire son travail sur l'ensemble du projet puis vous dire
ont été reformatés. si des documents ont été reformatés (si vous avez fait `ruff format`)
ou bien s'il y a des erreurs à réparer (si vous avez faire `ruff check`).
Appeler Black en ligne de commandes avant de pousser votre code sur Github Appeler Ruff en ligne de commandes avant de pousser votre code sur Github
est une technique qui marche très bien. est une technique qui marche très bien.
Cependant, vous risquez de souvent l'oublier. Cependant, vous risquez de souvent l'oublier.
Or, lorsque le code est mal formaté, la pipeline bloque les PR sur les branches protégées. Or, lorsque le code ne respecte pas les standards de qualité,
la pipeline bloque les PR sur les branches protégées.
Pour éviter de vous faire régulièrement blacked, vous pouvez configurer Pour éviter de vous faire régulièrement avoir, vous pouvez configurer
votre éditeur pour que Black fasse son travail automatiquement à chaque édition d'un fichier. votre éditeur pour que Ruff fasse son travail automatiquement à chaque édition d'un fichier.
Nous tenterons de vous faire ici un résumé pour deux éditeurs de textes populaires Nous tenterons de vous faire ici un résumé pour deux éditeurs de textes populaires
que sont VsCode et Sublime Text. que sont VsCode et Sublime Text.
VsCode VsCode
~~~~~~ ~~~~~~
.. warning:: Installez l'extension Ruff pour VsCode.
Ensuite, ajoutez ceci dans votre configuration :
Il faut installer black dans son environement virtuel pour cet éditeur
Black est directement pris en charge par l'extension pour le Python de VsCode, il suffit de rentrer la configuration suivante :
.. sourcecode:: json .. sourcecode:: json
{ {
"python.formatting.provider": "black", "[python]": {
"editor.formatOnSave": true "editor.formatOnSave": true,
"editor.defaultFormatter": "charliermarsh.ruff"
}
} }
Sublime Text Sublime Text
~~~~~~~~~~~~ ~~~~~~~~~~~~
Il est tout d'abord nécessaire d'installer ce plugin : https://packagecontrol.io/packages/sublack. Vous devez installer ce plugin : https://packagecontrol.io/packages/LSP-ruff.
Suivez ensuite les instructions données dans la description du plugin.
Il suffit ensuite d'ajouter dans les settings du projet (ou directement dans les settings globales) : Si vous utilisez le plugin `anaconda <http://damnwidget.github.io/anaconda/>`__, pensez à modifier les paramètres du linter pep8 pour éviter de recevoir des warnings dans le formatage de ruff comme ceci :
.. sourcecode:: json
{
"sublack.black_on_save": true
}
Si vous utilisez le plugin `anaconda <http://damnwidget.github.io/anaconda/>`__, pensez à modifier les paramètres du linter pep8 pour éviter de recevoir des warnings dans le formatage de black comme ceci :
.. sourcecode:: json .. sourcecode:: json

View File

@ -114,9 +114,7 @@ class EbouticTest(TestCase):
def test_submit_basket(self): def test_submit_basket(self):
self.client.login(username="subscriber", password="plop") self.client.login(username="subscriber", password="plop")
self.client.cookies[ self.client.cookies["basket_items"] = """[
"basket_items"
] = """[
{"id": 2, "name": "Cotis 2 semestres", "quantity": 1, "unit_price": 28}, {"id": 2, "name": "Cotis 2 semestres", "quantity": 1, "unit_price": 28},
{"id": 4, "name": "Barbar", "quantity": 3, "unit_price": 1.7} {"id": 4, "name": "Barbar", "quantity": 3, "unit_price": 1.7}
]""" ]"""
@ -150,9 +148,7 @@ class EbouticTest(TestCase):
def test_submit_invalid_basket(self): def test_submit_invalid_basket(self):
self.client.login(username="subscriber", password="plop") self.client.login(username="subscriber", password="plop")
max_id = Product.objects.aggregate(res=Max("id"))["res"] max_id = Product.objects.aggregate(res=Max("id"))["res"]
self.client.cookies[ self.client.cookies["basket_items"] = f"""[
"basket_items"
] = f"""[
{{"id": {max_id + 1}, "name": "", "quantity": 1, "unit_price": 28}} {{"id": {max_id + 1}, "name": "", "quantity": 1, "unit_price": 28}}
]""" ]"""
response = self.client.get(reverse("eboutic:command")) response = self.client.get(reverse("eboutic:command"))
@ -168,9 +164,7 @@ class EbouticTest(TestCase):
def test_submit_basket_illegal_quantity(self): def test_submit_basket_illegal_quantity(self):
self.client.login(username="subscriber", password="plop") self.client.login(username="subscriber", password="plop")
self.client.cookies[ self.client.cookies["basket_items"] = """[
"basket_items"
] = """[
{"id": 4, "name": "Barbar", "quantity": -1, "unit_price": 1.7} {"id": 4, "name": "Barbar", "quantity": -1, "unit_price": 1.7}
]""" ]"""
response = self.client.get(reverse("eboutic:command")) response = self.client.get(reverse("eboutic:command"))
@ -182,9 +176,7 @@ class EbouticTest(TestCase):
reverse("core:user_profile", kwargs={"user_id": self.old_subscriber.id}) reverse("core:user_profile", kwargs={"user_id": self.old_subscriber.id})
) )
self.assertTrue("Non cotisant" in str(response.content)) self.assertTrue("Non cotisant" in str(response.content))
self.client.cookies[ self.client.cookies["basket_items"] = """[
"basket_items"
] = """[
{"id": 2, "name": "Cotis 2 semestres", "quantity": 1, "unit_price": 28} {"id": 2, "name": "Cotis 2 semestres", "quantity": 1, "unit_price": 28}
]""" ]"""
response = self.client.get(reverse("eboutic:command")) response = self.client.get(reverse("eboutic:command"))

126
poetry.lock generated
View File

@ -64,52 +64,6 @@ files = [
{file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"},
] ]
[[package]]
name = "black"
version = "23.12.1"
description = "The uncompromising code formatter."
optional = false
python-versions = ">=3.8"
files = [
{file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"},
{file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"},
{file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"},
{file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"},
{file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"},
{file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"},
{file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"},
{file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"},
{file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"},
{file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"},
{file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"},
{file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"},
{file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"},
{file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"},
{file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"},
{file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"},
{file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"},
{file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"},
{file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"},
{file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"},
{file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"},
{file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"},
]
[package.dependencies]
click = ">=8.0.0"
mypy-extensions = ">=0.4.3"
packaging = ">=22.0"
pathspec = ">=0.9.0"
platformdirs = ">=2"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
[package.extras]
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
uvloop = ["uvloop (>=0.15.2)"]
[[package]] [[package]]
name = "certifi" name = "certifi"
version = "2024.6.2" version = "2024.6.2"
@ -295,20 +249,6 @@ files = [
{file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
] ]
[[package]]
name = "click"
version = "8.1.7"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.7"
files = [
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
]
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]] [[package]]
name = "colorama" name = "colorama"
version = "0.4.6" version = "0.4.6"
@ -868,17 +808,6 @@ files = [
{file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"},
] ]
[[package]]
name = "mypy-extensions"
version = "1.0.0"
description = "Type system extensions for programs checked with the mypy type checker."
optional = false
python-versions = ">=3.5"
files = [
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
]
[[package]] [[package]]
name = "packaging" name = "packaging"
version = "24.1" version = "24.1"
@ -905,17 +834,6 @@ files = [
qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"]
testing = ["docopt", "pytest"] testing = ["docopt", "pytest"]
[[package]]
name = "pathspec"
version = "0.12.1"
description = "Utility library for gitignore style pattern matching of file paths."
optional = false
python-versions = ">=3.8"
files = [
{file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
{file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
]
[[package]] [[package]]
name = "pexpect" name = "pexpect"
version = "4.9.0" version = "4.9.0"
@ -1031,22 +949,6 @@ files = [
docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"]
tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
[[package]]
name = "platformdirs"
version = "4.2.2"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
optional = false
python-versions = ">=3.8"
files = [
{file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"},
{file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"},
]
[package.extras]
docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"]
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"]
type = ["mypy (>=1.8)"]
[[package]] [[package]]
name = "prompt-toolkit" name = "prompt-toolkit"
version = "3.0.47" version = "3.0.47"
@ -1272,6 +1174,32 @@ urllib3 = ">=1.21.1,<3"
socks = ["PySocks (>=1.5.6,!=1.5.7)"] socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "ruff"
version = "0.4.10"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
{file = "ruff-0.4.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5c2c4d0859305ac5a16310eec40e4e9a9dec5dcdfbe92697acd99624e8638dac"},
{file = "ruff-0.4.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a79489607d1495685cdd911a323a35871abfb7a95d4f98fc6f85e799227ac46e"},
{file = "ruff-0.4.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1dd1681dfa90a41b8376a61af05cc4dc5ff32c8f14f5fe20dba9ff5deb80cd6"},
{file = "ruff-0.4.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c75c53bb79d71310dc79fb69eb4902fba804a81f374bc86a9b117a8d077a1784"},
{file = "ruff-0.4.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18238c80ee3d9100d3535d8eb15a59c4a0753b45cc55f8bf38f38d6a597b9739"},
{file = "ruff-0.4.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d8f71885bce242da344989cae08e263de29752f094233f932d4f5cfb4ef36a81"},
{file = "ruff-0.4.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:330421543bd3222cdfec481e8ff3460e8702ed1e58b494cf9d9e4bf90db52b9d"},
{file = "ruff-0.4.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e9b6fb3a37b772628415b00c4fc892f97954275394ed611056a4b8a2631365e"},
{file = "ruff-0.4.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f54c481b39a762d48f64d97351048e842861c6662d63ec599f67d515cb417f6"},
{file = "ruff-0.4.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:67fe086b433b965c22de0b4259ddfe6fa541c95bf418499bedb9ad5fb8d1c631"},
{file = "ruff-0.4.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:acfaaab59543382085f9eb51f8e87bac26bf96b164839955f244d07125a982ef"},
{file = "ruff-0.4.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3cea07079962b2941244191569cf3a05541477286f5cafea638cd3aa94b56815"},
{file = "ruff-0.4.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:338a64ef0748f8c3a80d7f05785930f7965d71ca260904a9321d13be24b79695"},
{file = "ruff-0.4.10-py3-none-win32.whl", hash = "sha256:ffe3cd2f89cb54561c62e5fa20e8f182c0a444934bf430515a4b422f1ab7b7ca"},
{file = "ruff-0.4.10-py3-none-win_amd64.whl", hash = "sha256:67f67cef43c55ffc8cc59e8e0b97e9e60b4837c8f21e8ab5ffd5d66e196e25f7"},
{file = "ruff-0.4.10-py3-none-win_arm64.whl", hash = "sha256:dd1fcee327c20addac7916ca4e2653fbbf2e8388d8a6477ce5b4e986b68ae6c0"},
{file = "ruff-0.4.10.tar.gz", hash = "sha256:3aa4f2bc388a30d346c56524f7cacca85945ba124945fe489952aadb6b5cd804"},
]
[[package]] [[package]]
name = "sentry-sdk" name = "sentry-sdk"
version = "1.45.0" version = "1.45.0"
@ -1633,4 +1561,4 @@ filelock = ">=3.4"
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10,<3.12" python-versions = "^3.10,<3.12"
content-hash = "fe98c5784d71478c6da090c2adae73fbbff3ef47e0cd5fa8893811e4b357949b" content-hash = "78f859d93ec1f207dbdebd5b608abfac44f87bb254a37ebeafaaf1823f605a71"

View File

@ -52,7 +52,7 @@ tomli = "^2.0.1"
freezegun = "^1.2.2" # used to test time-dependent code freezegun = "^1.2.2" # used to test time-dependent code
django-debug-toolbar = "^4.0.0" django-debug-toolbar = "^4.0.0"
ipython = "^7.28.0" ipython = "^7.28.0"
black = "^23.3.0" ruff = "^0.4.10"
[tool.poetry.group.tests.dependencies] [tool.poetry.group.tests.dependencies]
coverage = "^7.5.4" coverage = "^7.5.4"

View File

@ -567,7 +567,7 @@ SITH_SUBSCRIPTIONS = {
"name": _("One year for free(CA offer)"), "name": _("One year for free(CA offer)"),
"price": 0, "price": 0,
"duration": 2, "duration": 2,
} },
# To be completed.... # To be completed....
} }

View File

@ -29,6 +29,7 @@ Including another URLconf
1. Add an import: from blog import urls as blog_urls 1. Add an import: from blog import urls as blog_urls
2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls)) 2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls))
""" """
from django.urls import include, path from django.urls import include, path
from django.contrib import admin from django.contrib import admin
from django.conf import settings from django.conf import settings