From 4c24e7fb189737765cb9495a5902829bf07ed669 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Sun, 28 Jul 2024 08:40:30 +0100 Subject: [PATCH 1/8] Update django-stubs from 5.0.2 to 5.0.3 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 8261ef56..d525bb68 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -14,7 +14,7 @@ watchfiles==0.21.0 # https://github.com/samuelcolvin/watchfiles # Testing # ------------------------------------------------------------------------------ mypy==1.10.0 # https://github.com/python/mypy -django-stubs[compatible-mypy]==5.0.2 # https://github.com/typeddjango/django-stubs +django-stubs[compatible-mypy]==5.0.3 # https://github.com/typeddjango/django-stubs pytest==8.3.2 # https://github.com/pytest-dev/pytest pytest-sugar==1.0.0 # https://github.com/Frozenball/pytest-sugar {%- if cookiecutter.use_drf == "y" %} From 9b42473bad2cd2cc2c890c31070856616f93103b Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Fri, 19 Jul 2024 21:14:25 +0100 Subject: [PATCH 2/8] Update mypy from 1.10.0 to 1.11.0 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 8261ef56..aef66327 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -13,7 +13,7 @@ watchfiles==0.21.0 # https://github.com/samuelcolvin/watchfiles # Testing # ------------------------------------------------------------------------------ -mypy==1.10.0 # https://github.com/python/mypy +mypy==1.11.0 # https://github.com/python/mypy django-stubs[compatible-mypy]==5.0.2 # https://github.com/typeddjango/django-stubs pytest==8.3.2 # https://github.com/pytest-dev/pytest pytest-sugar==1.0.0 # https://github.com/Frozenball/pytest-sugar From a8105bdc9fd9b8a0b117ec0d081b1b85844c90b2 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Sun, 28 Jul 2024 09:59:08 +0200 Subject: [PATCH 3/8] Fix signature for UserUpdateView.get_object --- .../{{cookiecutter.project_slug}}/users/views.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py index 3f20f268..942f3e3f 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py @@ -1,5 +1,6 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.messages.views import SuccessMessageMixin +from django.db.models import QuerySet from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView @@ -28,12 +29,12 @@ class UserUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): fields = ["name"] success_message = _("Information successfully updated") - def get_success_url(self): + def get_success_url(self) -> str: # for mypy to know that the user is authenticated assert self.request.user.is_authenticated return self.request.user.get_absolute_url() - def get_object(self): + def get_object(self, queryset: QuerySet | None=None) -> User: return self.request.user @@ -43,7 +44,7 @@ user_update_view = UserUpdateView.as_view() class UserRedirectView(LoginRequiredMixin, RedirectView): permanent = False - def get_redirect_url(self): + def get_redirect_url(self) -> str: {%- if cookiecutter.username_type == "email" %} return reverse("users:detail", kwargs={"pk": self.request.user.pk}) {%- else %} From 6355464230548fff50b498619ea43513376000d9 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Sun, 28 Jul 2024 10:04:55 +0200 Subject: [PATCH 4/8] Add type guard --- .../{{cookiecutter.project_slug}}/users/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py index 942f3e3f..8bb1838c 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py @@ -35,6 +35,8 @@ class UserUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): return self.request.user.get_absolute_url() def get_object(self, queryset: QuerySet | None=None) -> User: + # for mypy to know that the user is authenticated + assert self.request.user.is_authenticated return self.request.user From bb8a1b6637e0563490c67cdfe76841097deba7fa Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Sun, 28 Jul 2024 10:18:38 +0200 Subject: [PATCH 5/8] Add AuthenticatedHttpRequest type for helping with LoginRequiredMixin views --- .../{{cookiecutter.project_slug}}/users/views.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py index 8bb1838c..ca3e104e 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py @@ -1,6 +1,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.db.models import QuerySet +from django.http import HttpRequest from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView @@ -10,6 +11,11 @@ from django.views.generic import UpdateView from {{ cookiecutter.project_slug }}.users.models import User +class AuthenticatedHttpRequest(HttpRequest): + """For mypy to know that the user is authenticated.""" + user: User + + class UserDetailView(LoginRequiredMixin, DetailView): model = User {%- if cookiecutter.username_type == "email" %} @@ -19,6 +25,7 @@ class UserDetailView(LoginRequiredMixin, DetailView): slug_field = "username" slug_url_kwarg = "username" {%- endif %} + request: AuthenticatedHttpRequest user_detail_view = UserDetailView.as_view() @@ -28,15 +35,12 @@ class UserUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): model = User fields = ["name"] success_message = _("Information successfully updated") + request: AuthenticatedHttpRequest def get_success_url(self) -> str: - # for mypy to know that the user is authenticated - assert self.request.user.is_authenticated return self.request.user.get_absolute_url() def get_object(self, queryset: QuerySet | None=None) -> User: - # for mypy to know that the user is authenticated - assert self.request.user.is_authenticated return self.request.user @@ -45,6 +49,7 @@ user_update_view = UserUpdateView.as_view() class UserRedirectView(LoginRequiredMixin, RedirectView): permanent = False + request: AuthenticatedHttpRequest def get_redirect_url(self) -> str: {%- if cookiecutter.username_type == "email" %} From 429f4681006030ce59a6d6e3f9db082733c3221c Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Sun, 28 Jul 2024 10:27:20 +0200 Subject: [PATCH 6/8] Revert to simpler type guard fix --- .../{{cookiecutter.project_slug}}/users/views.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py index ca3e104e..e7655f12 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py @@ -1,7 +1,6 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.db.models import QuerySet -from django.http import HttpRequest from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView @@ -11,11 +10,6 @@ from django.views.generic import UpdateView from {{ cookiecutter.project_slug }}.users.models import User -class AuthenticatedHttpRequest(HttpRequest): - """For mypy to know that the user is authenticated.""" - user: User - - class UserDetailView(LoginRequiredMixin, DetailView): model = User {%- if cookiecutter.username_type == "email" %} @@ -25,7 +19,6 @@ class UserDetailView(LoginRequiredMixin, DetailView): slug_field = "username" slug_url_kwarg = "username" {%- endif %} - request: AuthenticatedHttpRequest user_detail_view = UserDetailView.as_view() @@ -35,12 +28,13 @@ class UserUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): model = User fields = ["name"] success_message = _("Information successfully updated") - request: AuthenticatedHttpRequest def get_success_url(self) -> str: + assert self.request.user.is_authenticated # type guard return self.request.user.get_absolute_url() def get_object(self, queryset: QuerySet | None=None) -> User: + assert self.request.user.is_authenticated # type guard return self.request.user @@ -49,7 +43,6 @@ user_update_view = UserUpdateView.as_view() class UserRedirectView(LoginRequiredMixin, RedirectView): permanent = False - request: AuthenticatedHttpRequest def get_redirect_url(self) -> str: {%- if cookiecutter.username_type == "email" %} From 676aa25a3731cfaee44a67a3d7160b110c4a0565 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Sun, 28 Jul 2024 20:40:32 +0100 Subject: [PATCH 7/8] Update django-stubs from 5.0.2 to 5.0.4 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 8261ef56..13848404 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -14,7 +14,7 @@ watchfiles==0.21.0 # https://github.com/samuelcolvin/watchfiles # Testing # ------------------------------------------------------------------------------ mypy==1.10.0 # https://github.com/python/mypy -django-stubs[compatible-mypy]==5.0.2 # https://github.com/typeddjango/django-stubs +django-stubs[compatible-mypy]==5.0.4 # https://github.com/typeddjango/django-stubs pytest==8.3.2 # https://github.com/pytest-dev/pytest pytest-sugar==1.0.0 # https://github.com/Frozenball/pytest-sugar {%- if cookiecutter.use_drf == "y" %} From 4413b25706cb26093aed067637606d3c275c528e Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Wed, 31 Jul 2024 15:02:04 +0100 Subject: [PATCH 8/8] Remove compatible-mypy extra from djangorestframework-stubs Looks like the latest version should work with mypy 1.11: https://github.com/typeddjango/djangorestframework-stubs/pull/642 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 00e583db..21280bb0 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -18,7 +18,7 @@ django-stubs[compatible-mypy]==5.0.4 # https://github.com/typeddjango/django-st pytest==8.3.2 # https://github.com/pytest-dev/pytest pytest-sugar==1.0.0 # https://github.com/Frozenball/pytest-sugar {%- if cookiecutter.use_drf == "y" %} -djangorestframework-stubs[compatible-mypy]==3.15.0 # https://github.com/typeddjango/djangorestframework-stubs +djangorestframework-stubs==3.15.0 # https://github.com/typeddjango/djangorestframework-stubs {%- endif %} # Documentation