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

Switch to mypy #88

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
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
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