diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f359eebd1..94b3153f1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: fail-fast: false max-parallel: 5 matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] django-version: ['3.2', '4.1', '4.2', 'main'] steps: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3edcb2679..c115186ba 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ # vim: set nospell: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: trailing-whitespace args: [--markdown-linebreak-ext=md] @@ -13,19 +13,12 @@ repos: - id: check-added-large-files - id: debug-statements - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.292 + rev: v0.1.14 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] exclude: docs\/.* - - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.5.1" - hooks: - - id: mypy - additional_dependencies: - - types-requests - exclude: testapp - repo: https://github.com/psf/black - rev: "23.9.1" + rev: "24.1.1" hooks: - id: black diff --git a/payments/dotpay/__init__.py b/payments/dotpay/__init__.py index f4636e965..78c491cc2 100644 --- a/payments/dotpay/__init__.py +++ b/payments/dotpay/__init__.py @@ -81,9 +81,9 @@ def get_hidden_fields(self, payment): "currency": payment.currency, "description": payment.description, "lang": self.lang, - "ignore_last_payment_channel": "1" - if self.ignore_last_payment_channel - else "0", + "ignore_last_payment_channel": ( + "1" if self.ignore_last_payment_channel else "0" + ), "ch_lock": "1" if self.lock else "0", "URL": payment.get_success_url(), "URLC": self.get_return_url(payment), diff --git a/payments/models.py b/payments/models.py index 8da98e375..9b1653e45 100644 --- a/payments/models.py +++ b/payments/models.py @@ -70,7 +70,7 @@ def change_status(self, status: PaymentStatus | str, message=""): """ from .signals import status_changed - self.status = status + self.status = status # type: ignore[assignment] self.message = message self.save(update_fields=["status", "message"]) status_changed.send(sender=type(self), instance=self) @@ -83,7 +83,7 @@ def change_fraud_status(self, status: PaymentStatus, message="", commit=True): status, ", ".join(available_statuses) ) ) - self.fraud_status = status + self.fraud_status = status # type: ignore[assignment] self.fraud_message = message if commit: self.save() diff --git a/payments/sofort/__init__.py b/payments/sofort/__init__.py index 7a53bfda3..c5d7b6d28 100644 --- a/payments/sofort/__init__.py +++ b/payments/sofort/__init__.py @@ -58,9 +58,11 @@ def get_form(self, payment, data=None): "interface_version": "django-payments", "amount": payment.total, "currency": payment.currency, - "description": payment.description - if len(payment.description) <= 40 - else (payment.description[:37] + "..."), + "description": ( + payment.description + if len(payment.description) <= 40 + else (payment.description[:37] + "...") + ), "success_url": self.get_return_url(payment), "abort_url": self.get_return_url(payment), "customer_protection": "0", diff --git a/payments/stripe/__init__.py b/payments/stripe/__init__.py index 8e7acf640..55bad7cae 100644 --- a/payments/stripe/__init__.py +++ b/payments/stripe/__init__.py @@ -3,6 +3,7 @@ import json import warnings from decimal import Decimal +from typing import TYPE_CHECKING import stripe @@ -15,6 +16,9 @@ from .forms import PaymentForm from .providers import StripeProviderV3 +if TYPE_CHECKING: + from django import forms + class StripeProvider(BasicProvider): """Provider backend using `Stripe `_. @@ -27,7 +31,7 @@ class StripeProvider(BasicProvider): :param image: Your logo. """ - form_class = ModalPaymentForm + form_class: type[forms.Form] = ModalPaymentForm def __init__(self, public_key, secret_key, image="", name="", **kwargs): stripe.api_key = secret_key diff --git a/payments/stripe/providers.py b/payments/stripe/providers.py index 69c9c2789..5086b13c0 100644 --- a/payments/stripe/providers.py +++ b/payments/stripe/providers.py @@ -132,7 +132,7 @@ def create_session(self, payment): { "customer_data": { "customer_name": "{} {}".format( - payment.billing_first_name, payment.billing_last_nane + payment.billing_first_name, payment.billing_last_name ) } } diff --git a/payments/urls.py b/payments/urls.py index b1decdaec..deb70fcd5 100644 --- a/payments/urls.py +++ b/payments/urls.py @@ -2,6 +2,7 @@ This module is responsible for automatic processing of provider callback data (asynchronous transaction updates). """ + from __future__ import annotations from django.db.transaction import atomic diff --git a/pyproject.toml b/pyproject.toml index 2f86f577c..eae703a18 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,10 +40,16 @@ braintree = ["braintree>=3.14.0"] cybersource = ["suds-community>=0.6"] dev = [ "coverage", + "django-stubs[compatible-mypy]", "mock", "pytest", "pytest-cov", "pytest-django", + "types-braintree", + "types-dj-database-url", + "types-requests", + "types-stripe", + "types-xmltodict", ] docs = ["sphinx_rtd_theme"] mercadopago = ["mercadopago>=2.0.0,<3.0.0"] @@ -62,6 +68,13 @@ exclude_lines = [ "if TYPE_CHECKING:", ] +[tool.mypy] +ignore_missing_imports = true +plugins = ["mypy_django_plugin.main"] + +[tool.django-stubs] +django_settings_module = "test_settings" + [tool.pytest.ini_options] addopts =[ "--cov=payments", diff --git a/testapp/testapp/asgi.py b/testapp/testapp/asgi.py index 9aa05edbe..bd147018a 100644 --- a/testapp/testapp/asgi.py +++ b/testapp/testapp/asgi.py @@ -6,6 +6,7 @@ For more information on this file, see https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ """ + from __future__ import annotations import os diff --git a/testapp/testapp/wsgi.py b/testapp/testapp/wsgi.py index 2b902f76c..ac5739e97 100644 --- a/testapp/testapp/wsgi.py +++ b/testapp/testapp/wsgi.py @@ -6,6 +6,7 @@ For more information on this file, see https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/ """ + from __future__ import annotations import os diff --git a/tox.ini b/tox.ini index 689a1ee73..b3d059c54 100644 --- a/tox.ini +++ b/tox.ini @@ -34,7 +34,14 @@ python = 3.9: py39 3.10: py310 3.11: py311 - 3.12-dev: py312 + 3.12: py312 + 3.13-dev: py313 + +[testenv:mypy] +setenv = + PYTHONPATH = {env:PATH}/testapp +extras = {[testenv]extras} +commands = mypy . [gh-actions:env] DJANGO =