Skip to content

Commit

Permalink
chore: Add mypy checks
Browse files Browse the repository at this point in the history
  • Loading branch information
pennersr committed Jun 12, 2024
1 parent 38eb311 commit 8eb7afc
Show file tree
Hide file tree
Showing 24 changed files with 78 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jobs:
runs-on: ubuntu-22.04
strategy:
matrix:
extra-env: ['docs', 'black', 'isort', 'flake8', 'standardjs', 'djlint', 'compilemessages']
extra-env: ['docs', 'black', 'isort', 'flake8', 'mypy', 'standardjs', 'djlint', 'compilemessages']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
Expand Down
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,16 @@ test:
pytest allauth/

.PHONY: qa
qa: validate-api-spec
qa: validate-api-spec mypy
flake8 allauth
isort --check-only --diff .
black --check .
djlint --check allauth examples

.PHONY:
.PHONY: mypy
mypy:
mypy allauth/

.PHONY: validate-api-spec
validate-api-spec:
swagger-cli validate docs/headless/openapi-specification/openapi.yaml
2 changes: 1 addition & 1 deletion allauth/account/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def get_search_fields(self, request):
def make_verified(self, request, queryset):
queryset.update(verified=True)

make_verified.short_description = _("Mark selected email addresses as verified")
make_verified.short_description = _("Mark selected email addresses as verified") # type: ignore[attr-defined]


class EmailConfirmationAdmin(admin.ModelAdmin):
Expand Down
2 changes: 1 addition & 1 deletion allauth/account/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ def _base_signup_form_class():
return fc_class


class BaseSignupForm(_base_signup_form_class()):
class BaseSignupForm(_base_signup_form_class()): # type: ignore[misc]
username = forms.CharField(
label=_("Username"),
min_length=app_settings.USERNAME_MIN_LENGTH,
Expand Down
2 changes: 1 addition & 1 deletion allauth/account/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def key_expired(self):
)
return expiration_date <= timezone.now()

key_expired.boolean = True
key_expired.boolean = True # type: ignore[attr-defined]

def confirm(self, request):
if not self.key_expired():
Expand Down
2 changes: 1 addition & 1 deletion allauth/account/tests/test_logout.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


test_username_validators = [
validators.RegexValidator(regex=r"^[a-c]+$", message="not abc", flags=0)
validators.RegexValidator(regex=r"^[a-c]+$", message="not abc")
]


Expand Down
2 changes: 1 addition & 1 deletion allauth/account/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class UUIDUser(AbstractUser):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

class Meta(AbstractUser.Meta):
class Meta(AbstractUser.Meta): # type: ignore[name-defined]
swappable = "AUTH_USER_MODEL"


Expand Down
2 changes: 1 addition & 1 deletion allauth/account/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@


test_username_validators = [
validators.RegexValidator(regex=r"^[a-c]+$", message="not abc", flags=0)
validators.RegexValidator(regex=r"^[a-c]+$", message="not abc")
]


Expand Down
6 changes: 4 additions & 2 deletions allauth/headless/base/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from typing import Optional, Type

from django.utils.decorators import classonlymethod

from allauth.account.stages import LoginStageController
from allauth.account.stages import LoginStage, LoginStageController
from allauth.core.exceptions import ReauthenticationRequired
from allauth.headless.base import response
from allauth.headless.constants import Client
Expand Down Expand Up @@ -28,7 +30,7 @@ def dispatch(self, request, *args, **kwargs):


class AuthenticationStageAPIView(APIView):
stage_class = None
stage_class: Optional[Type[LoginStage]] = None

def handle(self, request, *args, **kwargs):
self.stage = LoginStageController.enter(request, self.stage_class.key)
Expand Down
2 changes: 1 addition & 1 deletion allauth/headless/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ class Flow(str, Enum):
if allauth_settings.MFA_ENABLED:
from allauth.mfa.stages import AuthenticateStage

MFA_AUTHENTICATE = AuthenticateStage.key
MFA_AUTHENTICATE = AuthenticateStage.key # type: ignore[has-type]
6 changes: 3 additions & 3 deletions allauth/headless/internal/authkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ def expose_access_token(request) -> typing.Optional[str]:
Determines if a new access token needs to be exposed.
"""
if request.allauth.headless.client != Client.APP:
return
return None
if not request.user.is_authenticated:
return
return None
pre_user = request.allauth.headless._pre_user
if pre_user.is_authenticated and pre_user.pk == request.user.pk:
return
return None
strategy = app_settings.TOKEN_STRATEGY
return strategy.create_access_token(request)
4 changes: 3 additions & 1 deletion allauth/headless/internal/restkit/views.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import json
from typing import Dict, Optional, Type, Union

from django.http import HttpResponseBadRequest
from django.views.generic import View

from allauth.core.exceptions import ImmediateHttpResponse
from allauth.headless.internal.restkit.inputs import Input
from allauth.headless.internal.restkit.response import ErrorResponse


class RESTView(View):
input_class = None
input_class: Union[Optional[Dict[str, Type[Input]]], Type[Input]] = None
handle_json_input = True

def dispatch(self, request, *args, **kwargs):
Expand Down
7 changes: 5 additions & 2 deletions allauth/headless/tokens/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@


class SessionTokenStrategy(AbstractTokenStrategy):
def create_session_token(self, request: HttpRequest) -> typing.Optional[str]:
def create_session_token(self, request: HttpRequest) -> str:
if not request.session.session_key:
request.session.save()
return request.session.session_key
key = request.session.session_key
assert isinstance(key, str) # We did save.
return key

def lookup_session(self, session_token: str) -> typing.Optional[SessionBase]:
session_key = session_token
if sessionkit.session_store().exists(session_key):
return sessionkit.session_store(session_key)
return None
6 changes: 4 additions & 2 deletions allauth/mfa/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from django.urls import include, path
from typing import List, Union

from django.urls import URLPattern, URLResolver, include, path

from allauth.mfa import app_settings, views


urlpatterns = [
urlpatterns: List[Union[URLPattern, URLResolver]] = [
path("authenticate/", views.authenticate, name="mfa_authenticate"),
path("reauthenticate/", views.reauthenticate, name="mfa_reauthenticate"),
]
Expand Down
6 changes: 4 additions & 2 deletions allauth/socialaccount/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import List

from django import forms
from django.contrib import admin

Expand All @@ -10,7 +12,7 @@
class SocialAppForm(forms.ModelForm):
class Meta:
model = SocialApp
exclude = []
exclude: List[str] = []
widgets = {
"client_id": forms.TextInput(attrs={"size": "100"}),
"key": forms.TextInput(attrs={"size": "100"}),
Expand Down Expand Up @@ -59,7 +61,7 @@ def truncated_token(self, token):
ret = ret[0:max_chars] + "...(truncated)"
return ret

truncated_token.short_description = "Token"
truncated_token.short_description = "Token" # type: ignore[attr-defined]


admin.site.register(SocialApp, SocialAppAdmin)
Expand Down
2 changes: 1 addition & 1 deletion allauth/socialaccount/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class SocialApp(models.Model):
# a ManyToManyField. Note that Facebook requires an app per domain
# (unless the domains share a common base name).
# blank=True allows for disabling apps without removing them
sites = models.ManyToManyField("sites.Site", blank=True)
sites = models.ManyToManyField("sites.Site", blank=True) # type: ignore[var-annotated]

class Meta:
verbose_name = _("social application")
Expand Down
8 changes: 6 additions & 2 deletions allauth/socialaccount/providers/mediawiki/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
)


settings = getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}).get("mediawiki", {})
provider_settings: dict = getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}).get(
"mediawiki", {}
)


class MediaWikiOAuth2Adapter(OAuth2Adapter):
provider_id = "mediawiki"
REST_API = settings.get("REST_API", "https://meta.wikimedia.org/w/rest.php")
REST_API = provider_settings.get(
"REST_API", "https://meta.wikimedia.org/w/rest.php"
)
access_token_url = REST_API + "/oauth2/access_token"
authorize_url = REST_API + "/oauth2/authorize"
profile_url = REST_API + "/oauth2/resource/profile"
Expand Down
2 changes: 1 addition & 1 deletion allauth/socialaccount/providers/openid_connect/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from allauth.tests import TestCase


class OpenIDConnectTests(OpenIDConnectTests, TestCase):
class MainOpenIDConnectTests(OpenIDConnectTests, TestCase):
provider_id = "oidc-server"


Expand Down
4 changes: 2 additions & 2 deletions allauth/socialaccount/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def setup_app(provider_id):


class OAuthTestsMixin(object):
provider_id = None
provider_id: str

def get_mocked_response(self):
pass
Expand Down Expand Up @@ -144,7 +144,7 @@ class Class(OAuthTestsMixin, TestCase):


class OAuth2TestsMixin(object):
provider_id = None
provider_id: str

def get_mocked_response(self):
pass
Expand Down
4 changes: 1 addition & 3 deletions allauth/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
from django.utils.http import base36_to_int, int_to_base36
from django.views import csrf

from allauth import app_settings

from . import utils
from allauth import app_settings, utils


class MockedResponse(object):
Expand Down
9 changes: 5 additions & 4 deletions allauth/urls.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
from importlib import import_module
from typing import List, Union

from django.urls import include, path
from django.urls import URLPattern, URLResolver, include, path
from django.views.generic.base import RedirectView

from allauth.socialaccount import providers

from . import app_settings


def build_provider_urlpatterns():
def build_provider_urlpatterns() -> List[Union[URLPattern, URLResolver]]:
# Provider urlpatterns, as separate attribute (for reusability).
provider_urlpatterns = []
provider_urlpatterns: List[Union[URLPattern, URLResolver]] = []
provider_classes = providers.registry.get_class_list()

# We need to move the OpenID Connect provider to the end. The reason is that
Expand All @@ -28,7 +29,7 @@ def build_provider_urlpatterns():
return provider_urlpatterns


urlpatterns = []
urlpatterns: List[Union[URLPattern, URLResolver]] = []
if not app_settings.HEADLESS_ONLY:
urlpatterns += [path("", include("allauth.account.urls"))]
if app_settings.MFA_ENABLED:
Expand Down
10 changes: 10 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,13 @@ sections=FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
max-line-length = 88
# Black
ignore = E203, W503, E501, E231

[mypy]
mypy_path = .
plugins =
mypy_django_plugin.main
strict_optional = True
disable_error_code = import-untyped

[mypy.plugins.django-stubs]
django_settings_module = tests.regular.settings
3 changes: 3 additions & 0 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ stdenv.mkDerivation {
isort
djlint
python310
python310Packages.mypy
python310Packages.django-stubs
python310Packages.types-requests
python310Packages.django
python310Packages.flake8
python310Packages.debugpy
Expand Down
12 changes: 12 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ envlist =
isort
black
flake8
mypy
standardjs
compilemessages

Expand Down Expand Up @@ -81,6 +82,17 @@ deps =
commands =
flake8 {posargs:{toxinidir}/allauth}

[testenv:mypy]
deps =
django-stubs==5.0.2
mypy==1.10.0
pytest>=7.4
pytest-django>=4.5.2
types-requests==2.32.0.20240602
python3-saml>=1.15.0,<2.0.0
commands =
mypy {posargs:{toxinidir}/allauth}

[testenv:compilemessages]
skip_install = True
deps = Django
Expand Down

0 comments on commit 8eb7afc

Please sign in to comment.