Skip to content
This repository has been archived by the owner on Oct 2, 2021. It is now read-only.

Commit

Permalink
Switch to mypy
Browse files Browse the repository at this point in the history
This is a work-in-progress attempt at switching over to mypy as part of
 #85. There's still some work to be done (e.g. mypy ignore comments need
to be added where appropriate) and I'm currently working with some
local changes pyre's stubs, but I wanted to track the work being done.
  • Loading branch information
dirn committed Dec 17, 2020
1 parent cf853c6 commit 64ba65c
Show file tree
Hide file tree
Showing 55 changed files with 43 additions and 133 deletions.
2 changes: 1 addition & 1 deletion src/.coveragerc → .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ omit =

[run]
branch = true
data_file = ../.coverage
data_file = .coverage
4 changes: 0 additions & 4 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ force_sort_within_sections = true
include_trailing_comma = true
multi_line_output = 3

[.pyre_configuration]
indent_size = 2
indent_style = space

[*.rst]
indent_size = 4
indent_style = space
Expand Down
17 changes: 1 addition & 16 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,5 @@ ignore = E203, E231, E266, E501, W503
max-line-length = 80
max-complexity = 18
per-file-ignores =
src/awards/settings/dev.py: F405
# TODO: Remove these once
# https://github.com/facebook/pyre-check/pull/256,
# https://github.com/facebook/pyre-check/pull/260,
# https://github.com/facebook/pyre-check/pull/261, and
# https://github.com/facebook/pyre-check/pull/262 can be used.
src/applications/forms.py: B950
src/applications/migrations/0003_auto_20200507_0125.py: B950
src/applications/models.py: B950
src/applications/test_views.py: B950
src/awards/urls.py: B950
src/homepage/test_views.py: B950
src/users/migrations/0001_initial.py: B950
src/users/forms.py: B950
src/users/models.py: B950
src/users/views.py: B950
awards/settings/dev.py: F405
select = B,C,E,F,W,T4,B9
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ environment. It can be output without running the unit tests with::
Type checks
-----------

The type checks are done using pyre_ and can be run with::
The type checks are done using Mypy_ and can be run with::

$ tox -e types

Expand Down Expand Up @@ -128,9 +128,9 @@ will be removed from the repository.
.. _citext: https://www.postgresql.org/docs/current/citext.html
.. _Hacktoberfest: https://hacktoberfest.digitalocean.com
.. _ipython: https://ipython.readthedocs.io
.. _Mypy: https://mypy.readthedocs.io
.. _PostgreSQL: https://www.postgresql.org
.. _psql: https://www.postgresql.org/docs/current/app-psql.html
.. _pyre: https://pyre-check.org
.. _tox: https://tox.readthedocs.io
.. _watchman: https://facebook.github.io/watchman/

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
26 changes: 4 additions & 22 deletions src/applications/forms.py → applications/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ class FinancialAidApplicationForm(ApplicationForm):
type = Application.Type.FINANCIAL_AID

travel_requested = forms.BooleanField(
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/262.
label=_("Do you need assistance with travel?"),
required=False,
)
Expand All @@ -32,13 +31,9 @@ class Meta:
"lodging_requested",
)
labels = {
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/262.
"background": _("Tell us a little bit more about yourself"),
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/262.
"lodging_requested": _("Do you need assistance with lodging?"),
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/262.
"reason_to_attend": _("Why are you interested in attending PyGotham?"),
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/262.
"travel_amount": _("What is the estimated cost (USD)?"),
}
widgets = {
Expand All @@ -51,39 +46,28 @@ def clean(self) -> Dict[str, Any]:
travel_amount = cleaned_data.get("travel_amount") or 0
if travel_amount < 0:
raise forms.ValidationError(
{
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/262.
"travel_amount": _(
"Your estimated travel costs cannot be negative."
)
}
{"travel_amount": _("Your estimated travel costs cannot be negative.")}
)

travel_requested = cleaned_data.get("travel_requested")
if travel_requested:
if not travel_amount:
raise forms.ValidationError(
{
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/262.
"travel_amount": _(
"Your estimated travel costs must be greater than $0.00."
)
}
)
elif travel_amount:
raise forms.ValidationError(
{
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/262.
"travel_requested": _(
"You must request travel assistance before providing an estimated cost."
)
}
msg = _(
"You must request travel assistance before providing an estimated cost."
)
raise forms.ValidationError({"travel_requested": msg})

return cleaned_data

def clean_lodging_requested(self) -> bool:
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/261.
return bool(self.cleaned_data.get("lodging_requested"))


Expand All @@ -94,9 +78,7 @@ class Meta:
model = Application
fields = ("background", "reason_to_attend")
labels = {
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/262.
"background": _("Tell us a little bit about yourself"),
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/262.
"reason_to_attend": _("Why are you interested in attending PyGotham?"),
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name="application",
name="travel_amount",
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/260.
field=models.DecimalField(
blank=True, decimal_places=2, max_digits=10, null=True
),
Expand Down
9 changes: 0 additions & 9 deletions src/applications/models.py → applications/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,35 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _

# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
User = get_user_model()


class Application(models.Model):
# pyre-ignore[11]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
class Status(models.TextChoices):
PENDING = "pending"

# pyre-ignore[11]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
class Type(models.TextChoices):
FINANCIAL_AID = "finaid"
SCHOLARSHIP = "scholarship"

# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
applicant = models.ForeignKey(User, on_delete=models.DO_NOTHING)
background = models.TextField(_("applicant background"))
reason_to_attend = models.TextField(_("reason the applicant wishes to attend"))
status = models.CharField(
max_length=20,
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
choices=Status.choices,
default=Status.PENDING,
)
type = models.CharField(
max_length=11,
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
choices=Type.choices,
default=Type.SCHOLARSHIP,
)
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/260.
travel_amount = models.DecimalField(
max_digits=10, decimal_places=2, blank=True, null=True
)
lodging_requested = models.BooleanField(null=True)

def __str__(self) -> str:
# pyre-ignore[19]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
type_ = Application.Type(self.type)
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
return f"{type_.label} application for {self.applicant}"
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ def test_financial_aid_lodging_requested_is_treated_as_boolean() -> None:

form = FinancialAidApplicationForm(other_fields)
assert form.is_valid()
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/261.
assert form.cleaned_data["lodging_requested"] is False


Expand Down
11 changes: 2 additions & 9 deletions src/applications/test_views.py → applications/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
from django.contrib.auth import get_user_model
from django.http import Http404, HttpRequest
from django.test import Client
from factory.django import DjangoModelFactory
from factory.django import DjangoModelFactory # type: ignore[import]
import pytest
from sesame.utils import get_query_string
from sesame.utils import get_query_string # type: ignore[import]

from applications.models import Application
from applications.views import apply


# pyre-ignore[13]: Investigate type stubs for factory-boy.
class ApplicationFactory(DjangoModelFactory):
class Meta:
model = Application
Expand All @@ -24,29 +23,25 @@ class Meta:

class UserFactory(DjangoModelFactory):
class Meta:
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
model = get_user_model()
django_get_or_create = ("email",)

email = "[email protected]"


@pytest.mark.django_db
# pyre-ignore[11]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
def test_that_one_of_form_type_and_pk_is_required_by_apply(client: Client) -> None:
user = UserFactory()
qs = get_query_string(user)
client.get(f"/login/magic{qs}")

request = HttpRequest()
request.user = user
# pyre-ignore[16]: pyre doesn't think ExceptionInfo as an __enter__.
with pytest.raises(Http404):
apply(request, form_type=None, pk=None)


@pytest.mark.django_db
# pyre-ignore[11]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
def test_user_can_edit_their_application(client: Client) -> None:
user = UserFactory()
qs = get_query_string(user)
Expand All @@ -67,7 +62,6 @@ def test_user_can_edit_their_application(client: Client) -> None:


@pytest.mark.django_db
# pyre-ignore[11]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
def test_user_can_view_their_application(client: Client) -> None:
user = UserFactory()
qs = get_query_string(user)
Expand All @@ -80,7 +74,6 @@ def test_user_can_view_their_application(client: Client) -> None:


@pytest.mark.django_db
# pyre-ignore[11]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
def test_user_cant_view_someone_elses_application(client: Client) -> None:
user = UserFactory()
other = UserFactory(email=f"other+{user.email}")
Expand Down
File renamed without changes.
4 changes: 0 additions & 4 deletions src/applications/urls.py → applications/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,15 @@
app_name = "applications"

urlpatterns = [
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
path("edit/<int:pk>", apply, name="edit"),
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
path(
"financial-aid",
apply,
{"form_type": FinancialAidApplicationForm},
name="financial_aid",
),
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
path(
"ticket", apply, {"form_type": ScholarshipApplicationForm}, name="scholarship"
),
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
path("view/<int:pk>", view, name="view"),
]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 6 additions & 3 deletions src/awards/settings/base.py → awards/settings/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from __future__ import annotations

import os
from typing import List

from decouple import config
from decouple import config # type: ignore[import]

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Expand All @@ -9,7 +12,7 @@
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/

ALLOWED_HOSTS = []
ALLOWED_HOSTS: List[str] = []


# Application definition
Expand Down Expand Up @@ -77,7 +80,7 @@
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators

# Password-based login isn't supported.
AUTH_PASSWORD_VALIDATORS = []
AUTH_PASSWORD_VALIDATORS: List[str] = []

AUTH_USER_MODEL = "users.User"

Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion src/awards/settings/prod.py → awards/settings/prod.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from decouple import config
from decouple import config # type: ignore[import]

from awards.settings.base import * # NOQA

Expand Down
File renamed without changes.
11 changes: 1 addition & 10 deletions src/awards/urls.py → awards/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,27 @@
from users.views import login, magic_login

urlpatterns = [
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
path(
"", TemplateView.as_view(template_name="homepage/index.html"), name="homepage"
),
# pyre doesn't include stubs for the Django admin.
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
path(
"admin/login/",
RedirectView.as_view(
pattern_name=settings.LOGIN_URL, permanent=True, query_string=True
),
),
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
path("admin/", admin.site.urls), # type: ignore
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
path("apply/", include("applications.urls", namespace="applications")),
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
path("login", login, name="login"),
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
path("login/magic", magic_login, name="magic-login"),
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
path("logout", LogoutView.as_view(), name="logout"),
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
path("users/", include("users.urls", namespace="users")),
]

if settings.DEBUG:
import debug_toolbar
import debug_toolbar # type: ignore[import]

urlpatterns = [
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
path("__debug__/", include(debug_toolbar.urls)),
] + urlpatterns
File renamed without changes.
5 changes: 5 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.test import Client


def client() -> Client:
return Client()
File renamed without changes.
File renamed without changes.
7 changes: 2 additions & 5 deletions src/homepage/test_views.py → homepage/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,20 @@

from django.contrib.auth import get_user_model
from django.test import Client
from factory.django import DjangoModelFactory
from factory.django import DjangoModelFactory # type: ignore[import]
import pytest
from sesame.utils import get_query_string
from sesame.utils import get_query_string # type: ignore[import]


class UserFactory(DjangoModelFactory):
class Meta:
# pyre-ignore[16]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
model = get_user_model()
django_get_or_create = ("email",)

email = "[email protected]"


@pytest.mark.django_db
# pyre-ignore[11]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
def test_login_link_is_not_shown_to_logged_in_users(client: Client) -> None:
user = UserFactory()
qs = get_query_string(user)
Expand All @@ -27,7 +25,6 @@ def test_login_link_is_not_shown_to_logged_in_users(client: Client) -> None:
assert b"log in" not in response.content.lower()


# pyre-ignore[11]: This is fixed by https://github.com/facebook/pyre-check/pull/256.
def test_login_link_is_shown_to_guests(client: Client) -> None:
response = client.get("/")
assert b"log in" in response.content.lower()
File renamed without changes.
Loading

0 comments on commit 64ba65c

Please sign in to comment.