Skip to content

Commit

Permalink
Updated type checker version
Browse files Browse the repository at this point in the history
  • Loading branch information
fbanados committed Aug 22, 2024
1 parent bf3c85e commit bdce421
Show file tree
Hide file tree
Showing 17 changed files with 317 additions and 274 deletions.
31 changes: 13 additions & 18 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,49 @@ url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]
black = ">=19.10b0"
pytest = "==7.4.4"
pytest-django = "==4.4.0"
black = "*"
pytest = "*"
pytest-django = "*"
pytest-cov = "*"
pytest-datadir = "*"
pytest-mypy = "*"
hypothesis = {version = "*", extras = ["django"]}
codecov = "*"
pysnooper = "*"
python-levenshtein = "*"
django-debug-toolbar = "~=3.6"
django-debug-toolbar = "*"
isort = "*"
toml = "*"
mypy = "*"
mypy = "~=1.7"
django-stubs = "~=4.2"
pytest-env = "*"
jupyterlab = "*"
appnope = "*"
nb_black = "==1.0.5"
pandas = "*"
statsmodels = "*"
pandas-stubs = "*"
sphinx = "*"
myst-parser = "*"

[packages]
colorama = "~=0.4"
colorama = "*"
coverage = "*"
cree-sro-syllabics = ">=2020.6.23"
Django = "~=4.2"
typing-extensions = "~=4.0"
attrs = "~=23.2"
django-js-reverse = "~=0.9"
typing-extensions = "*"
attrs = "*"
django-js-reverse = "*"
secure = "*"
snowballstemmer = "*"
dawg2 = "~=0.12"
dawg2 = "*"
environs = {extras = ["django"], version = "*"}
hfst-optimized-lookup = "*"
tqdm = "*"
whitenoise = "*"
foma = {subdirectory = "foma/python", git = "https://github.com/andrewdotn/foma"}
uwsgi = "*"
gensim = "*"
scipy = "==1.10.1"
more-itertools = "~=8.7.0"
scipy = "*"
more-itertools = "*"
types-requests = "*"
requests = "*"

Expand All @@ -62,7 +61,3 @@ ensuretestdb = "env USE_TEST_DB=true ./crkeng-manage ensuretestdb"

[requires]
python_version = "3.10"

[pipenv]
# this allows "black>=19.10b0" to work
allow_prereleases = true
454 changes: 235 additions & 219 deletions Pipfile.lock

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion mypy.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
[mypy]
plugins = mypy_django_plugin.main
mypy_path = ./src

[mypy.plugins.django-stubs]
django_settings_module = crkeng.site.settings

[mypy-CreeDictionary.API.migrations.*]
# Skip checking Django-auto-generated migration code
Expand Down Expand Up @@ -43,7 +48,7 @@ ignore_missing_imports = True
# “It is the view of the Django Technical Board that inline type
# annotations should not be added to Django at the current time … the
# barrier for further inline changes will be high.”
ignore_missing_imports = True
#ignore_missing_imports = True

[mypy-django_js_reverse.*]
ignore_missing_imports = True
Expand Down
10 changes: 7 additions & 3 deletions src/CreeDictionary/API/search/presentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,11 @@ def serialize(self) -> SerializedPresentationResult:
"definitions": serialize_definitions(
# given changes in django 4.1, the previous approach can fail.
# check first that the wordform actually exists before trying to get the reverse manager.
self.wordform.definitions.all() if not self.wordform._state.adding else [],
(
self.wordform.definitions.all()
if not self.wordform._state.adding
else []
),
# This is the only place include_auto_definitions is used,
# because we only auto-translate non-lemmas, and this is the
# only place where a non-lemma search result appears.
Expand Down Expand Up @@ -359,7 +363,7 @@ def serialize_wordform(
if key not in result:
result[key] = wordform.linguist_info[key]

return result
return cast(SerializedWordform, result)


def serialize_definitions(
Expand Down Expand Up @@ -452,7 +456,7 @@ def emoji_for_value(choice: str) -> str:


def get_lexical_info(
result_analysis: RichAnalysis,
result_analysis: Optional[RichAnalysis],
animate_emoji: str,
show_emoji: str,
dict_source: list,
Expand Down
13 changes: 8 additions & 5 deletions src/CreeDictionary/CreeDictionary/test_views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
import re
from http import HTTPStatus
from typing import Dict, Optional
from typing import Dict, Optional, cast

import pytest
from django.http import (
Expand Down Expand Up @@ -147,10 +147,13 @@ def test_paradigm_from_full_page_and_api(client: Client):
# Get fragment from API request:
response = client.get(
reverse("cree-dictionary-paradigm-detail"),
{
"lemma-id": wordform.id,
"paradigm-size": paradigm_size,
},
cast(
Dict[str, int | str],
{
"lemma-id": wordform.id,
"paradigm-size": paradigm_size,
},
),
)
assert response.status_code == HTTPStatus.OK
html_fragment = response.content.decode("UTF-8")
Expand Down
15 changes: 7 additions & 8 deletions src/CreeDictionary/CreeDictionary/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ def entry_details(request, slug: str):
:param slug: the stable unique ID of the lemma
"""
lemma = Wordform.objects.filter(slug=slug, is_lemma=True)
lemmas = Wordform.objects.filter(slug=slug, is_lemma=True)

if lemma.count() != 1:
if lemmas.count() != 1:
# The result is either empty or ambiguous; either way, do a search!
return redirect(url_for_query(slug.split("@")[0] or ""))

lemma = lemma.get()
lemma = lemmas.get()

if rich_analysis := lemma.analysis:
morphemes = rich_analysis.generate_with_morphemes(lemma.text)
Expand All @@ -81,8 +81,7 @@ def entry_details(request, slug: str):
if size not in sizes:
size = default_size

paradigm = paradigm_for(lemma, size)
paradigm = get_recordings_from_paradigm(paradigm, request)
paradigm = get_recordings_from_paradigm(paradigm_for(lemma, size), request)

paradigm_context.update(
paradigm=paradigm, paradigm_size=size, paradigm_sizes=sizes
Expand Down Expand Up @@ -306,7 +305,7 @@ def query_help(request): # pragma: no cover
)


@staff_member_required()
@staff_member_required
def fst_tool(request):
context = {}

Expand Down Expand Up @@ -405,10 +404,10 @@ def paradigm_for(wordform: Wordform, paradigm_size: str) -> Optional[Paradigm]:
manager = default_paradigm_manager()

if name := wordform.paradigm:
fst_lemma = wordform.lemma.text
fst_lemma = wordform.lemma.text if wordform.lemma else None

if settings.MORPHODICT_ENABLE_FST_LEMMA_SUPPORT:
fst_lemma = wordform.lemma.fst_lemma
fst_lemma = wordform.lemma.fst_lemma if wordform.lemma else None

if paradigm := manager.paradigm_for(name, fst_lemma, paradigm_size):
return paradigm
Expand Down
4 changes: 2 additions & 2 deletions src/CreeDictionary/cvd/definition_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def definition_to_cvd_key(d: Definition) -> CvdKey:
json.dumps(
[
# Every lemma has a stable unique identifier
d.wordform.lemma.slug,
getattr(d.wordform.lemma, "slug"),
# These next two should fields should identify non-lemma wordforms
d.wordform.text,
d.wordform.raw_analysis,
Expand Down Expand Up @@ -71,5 +71,5 @@ def wordform_query_matches(query: WordformQuery, wordform: Wordform):
("raw_analysis" in query and wordform.raw_analysis == query["raw_analysis"])
or ("raw_analysis__isnull" in query and wordform.raw_analysis is None)
)
and wordform.lemma.slug == query["lemma__slug"]
and getattr(wordform.lemma, "slug") == query["lemma__slug"]
)
6 changes: 5 additions & 1 deletion src/CreeDictionary/phrase_translate/translate.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,13 @@ def translate_and_print_wordforms(wordforms: Iterable[Wordform]):
print(f"wordform: {wordform.text} {wordform.analysis}")

lemma = wordform.lemma

if lemma is None:
continue

print(f" lemma: {lemma.analysis}")

for d in wordform.lemma.definitions.all():
for d in lemma.definitions.all():
# Don’t try to re-translate already-translated items
if d.auto_translation_source_id is not None:
continue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ def handle(self, *args, **options) -> None:
ret = r.features()
ret["query"] = query
ret["wordform_text"] = r.wordform.text
ret["lemma_wordform_text"] = r.wordform.lemma.text
ret["lemma_wordform_text"] = (
r.wordform.lemma.text if r.wordform.lemma else None
)
ret["definitions"] = [
[d.text, ", ".join(c.abbrv for c in d.citations.all())]
for d in r.wordform.definitions.all()
Expand Down
2 changes: 1 addition & 1 deletion src/crkeng/app/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class DisplayMode(Preference):
# (Short) linguistic labels; e.g., 1Sg → 2Sg, Present Tense
"linguistic": "Linguistic labels",
# nêhiyawêwin labels; e.g., niya → kiya, mêkwâc
"source_language": settings.MORPHODICT_LANGUAGE_ENDONYM + " labels",
"source_language": str(settings.MORPHODICT_LANGUAGE_ENDONYM) + " labels",
}
default = "english"

Expand Down
6 changes: 3 additions & 3 deletions src/crkeng/site/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@
#
# Morphodict assumes that the `text` of all Wordform are written in the default
# orthography.
MORPHODICT_ORTHOGRAPHY = {
MORPHODICT_ORTHOGRAPHY: Orthographies = {
# All entries in Wordform should be written in SRO (êîôâ)
"default": "Latn-y",
"available": {
# 'Latn' is Okimāsis/Wolvegrey's SRO
"Latn-y": {
"name": "SRO (êîôâ) with y",
"converter": "CreeDictionary.CreeDictionary.orthography.to_y"
},
"converter": "CreeDictionary.CreeDictionary.orthography.to_y",
},
"Latn": {"name": "SRO (êîôâ) with ý"},
"Latn-x-macron-y": {
"name": "SRO (ēīōā) with y",
Expand Down
9 changes: 6 additions & 3 deletions src/morphodict/lexicon/importer/test_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import pytest
from django.core.management import call_command
from django.db import IntegrityError
from pytest_django.fixtures import _django_db_fixture_helper
from pytest_django.fixtures import _django_db_helper
from pytest_django.plugin import DjangoDbBlocker

from morphodict.lexicon.models import (
Wordform,
Expand Down Expand Up @@ -89,7 +90,7 @@ def parametrize_incremental(f):


@pytest.fixture(scope="class")
def class_scoped_db(request, django_db_blocker):
def class_scoped_db(request: pytest.FixtureRequest, django_db_blocker: DjangoDbBlocker):
"""A class-scoped DB fixture
The normal pytest-django `db` fixture is function-scoped, meaning that it
Expand All @@ -99,7 +100,9 @@ def class_scoped_db(request, django_db_blocker):
with multiple tests in which the same DB transaction is used for all tests
in the class.
"""
_django_db_fixture_helper(request=request, django_db_blocker=django_db_blocker)
_django_db_helper(
request=request, django_db_setup=None, django_db_blocker=django_db_blocker
)


# Tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ def run(self):
# Avoid dupes for this wordform
seen_source_language_keywords: set[str] = set()

slug_base = wf.slug.split("@")[0]
slug_base = wf.slug.split("@")[0] if wf.slug else None
if wf.text != slug_base and slug_base:
self.add_source_language_keyword(
wf, slug_base, seen_source_language_keywords
Expand Down
2 changes: 1 addition & 1 deletion src/morphodict/lexicon/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def get_queryset(self):


# This type is the int pk for a saved wordform, or (text, analysis) for an unsaved one.
WordformKey = Union[int, tuple[str, str]]
WordformKey = Union[str, int, tuple[str, str]]


class DiacriticPreservingJsonEncoder(DjangoJSONEncoder):
Expand Down
4 changes: 4 additions & 0 deletions src/morphodict/preference/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def change_preference(request: HttpRequest, name: str):
if value not in preference.choices:
return HttpResponse(status=HTTPStatus.BAD_REQUEST)

# Make the typechecker see that value is not None after the previous check:
if value is None:
return HttpResponse(status=HTTPStatus.BAD_REQUEST)

if who_asked_us := request.headers.get("Referer"):
# Force the browser to refresh the page that issued this request.
response = HttpResponse(status=HTTPStatus.SEE_OTHER)
Expand Down
5 changes: 4 additions & 1 deletion src/morphodict/site/checks.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from django.conf import settings
from django.core.checks import Error, register
from typing import Optional

_MORPHODICT_REQUIRED_SETTING_SENTINEL = object()
_MORPHODICT_REQUIRED_SETTING_SENTINEL = None

RequiredString = Optional[str]


@register()
Expand Down
17 changes: 11 additions & 6 deletions src/morphodict/site/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@

import os
import secrets
from typing import Optional
from typing import Optional, TypedDict, Dict

from environs import Env

from . import base_dir_setup
from .checks import _MORPHODICT_REQUIRED_SETTING_SENTINEL
from .checks import _MORPHODICT_REQUIRED_SETTING_SENTINEL, RequiredString
from .hostutils import HOSTNAME
from .save_secret_key import save_secret_key

Expand Down Expand Up @@ -267,7 +267,6 @@ def defaultDatabasePath():

USE_I18N = True

USE_L10N = True

USE_TZ = True

Expand Down Expand Up @@ -385,18 +384,24 @@ def defaultDatabasePath():

# The name of the source language, written in the target language. Used in
# default templates to describe what language the dictionary is for.
MORPHODICT_SOURCE_LANGUAGE_NAME = _MORPHODICT_REQUIRED_SETTING_SENTINEL
MORPHODICT_SOURCE_LANGUAGE_NAME: RequiredString = _MORPHODICT_REQUIRED_SETTING_SENTINEL

# An optional, shorter name for the language. Currently only used in the search
# bar placeholder, to show “Search in Cree” instead of “Search in Plains Cree”
MORPHODICT_SOURCE_LANGUAGE_SHORT_NAME: Optional[str] = None

# The name of the language, in the language itself, e.g., ‘nêhiyawêwin’
MORPHODICT_LANGUAGE_ENDONYM = _MORPHODICT_REQUIRED_SETTING_SENTINEL
MORPHODICT_LANGUAGE_ENDONYM: RequiredString = _MORPHODICT_REQUIRED_SETTING_SENTINEL


# The marketing / brand / public-facing name of the dictionary
MORPHODICT_DICTIONARY_NAME = _MORPHODICT_REQUIRED_SETTING_SENTINEL
MORPHODICT_DICTIONARY_NAME: RequiredString = _MORPHODICT_REQUIRED_SETTING_SENTINEL

# Used for the bulk search API
SPEECH_DB_EQ = ["_"]

Orthography = TypedDict("Orthography", {"name": str, "converter": str}, total=False)

Orthographies = TypedDict(
"Orthographies", {"default": str, "available": Dict[str, Orthography]}
)

0 comments on commit bdce421

Please sign in to comment.