aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2022-12-08 19:28:02 +0100
committerDaniel Schadt <kingdread@gmx.de>2022-12-08 19:28:02 +0100
commit3934e4379e6445720fe991bd0263936a9542601b (patch)
tree7e1c609880e807a84796b4a2a85618cb9936a674
parent2fae8e0d39f436976d90cfb94ac31a1a4427771d (diff)
downloadfietsboek-3934e4379e6445720fe991bd0263936a9542601b.tar.gz
fietsboek-3934e4379e6445720fe991bd0263936a9542601b.tar.bz2
fietsboek-3934e4379e6445720fe991bd0263936a9542601b.zip
first try with mypy
It would be nice to gradually improve the typing situation in Fietsboek. At least the parts that do not do heavy metaprogramming should have types. For most of the API, we already have types in the doc strings, so those could be removed then.
-rw-r--r--.mypy.ini14
-rw-r--r--fietsboek/config.py2
-rw-r--r--fietsboek/pages.py15
-rw-r--r--fietsboek/updater/__init__.py8
-rw-r--r--fietsboek/util.py2
-rw-r--r--fietsboek/views/browse.py5
-rw-r--r--fietsboek/views/tileproxy.py4
-rw-r--r--tox.ini14
8 files changed, 48 insertions, 16 deletions
diff --git a/.mypy.ini b/.mypy.ini
new file mode 100644
index 0000000..79f0c44
--- /dev/null
+++ b/.mypy.ini
@@ -0,0 +1,14 @@
+[mypy]
+follow_imports = silent
+check_untyped_defs = True
+allow_redefinition = True
+exclude = fietsboek/updater/scripts/.+\.py
+
+[mypy-pyramid.*]
+ignore_missing_imports = True
+
+[mypy-sqlalchemy.*]
+ignore_missing_imports = True
+
+[mypy-zope.*]
+ignore_missing_imports = True
diff --git a/fietsboek/config.py b/fietsboek/config.py
index 05fd4f6..74dc4d8 100644
--- a/fietsboek/config.py
+++ b/fietsboek/config.py
@@ -142,7 +142,7 @@ class Config(BaseModel):
session_key: str
"""Session key."""
- available_locales: PyramidList = ["en", "de"]
+ available_locales: PyramidList = PyramidList(["en", "de"])
"""Available locales."""
email_from: str = Field(alias="email.from")
diff --git a/fietsboek/pages.py b/fietsboek/pages.py
index e94a493..d8fd859 100644
--- a/fietsboek/pages.py
+++ b/fietsboek/pages.py
@@ -1,6 +1,7 @@
"""Module containing logic to support "static" pages."""
import enum
import re
+from typing import List, Optional
import markdown
@@ -91,20 +92,21 @@ class Page:
parser = markdown.Markdown(extensions=["meta"])
content = parser.convert(text)
- title = parser.Meta.get('title', [''])[0]
+ title = parser.Meta.get('title', [''])[0] # type: ignore
if not title:
raise PageException("Missing `title`")
- link_name = parser.Meta.get('link-name', [''])[0]
+ link_name = parser.Meta.get('link-name', [''])[0] # type: ignore
if not link_name:
raise PageException("Missing `link-name`")
- slug = parser.Meta.get('slug', [''])[0]
+ slug = parser.Meta.get('slug', [''])[0] # type: ignore
if not slug:
raise PageException("Missing `slug`")
+ locale_filter: Optional[List[re.Pattern]]
try:
- locale_filter = list(map(re.compile, parser.Meta.get('locale', [])))
+ locale_filter = list(map(re.compile, parser.Meta.get('locale', []))) # type: ignore
except re.error as exc:
raise PageException("Invalid locale regex") from exc
if not locale_filter:
@@ -115,12 +117,13 @@ class Page:
'logged-out': UserFilter.LOGGED_OUT,
'everyone': UserFilter.EVERYONE,
}
- user_filter = filter_map.get(parser.Meta.get('show-to', ['everyone'])[0].lower())
+ user_filter = filter_map.get(
+ parser.Meta.get('show-to', ['everyone'])[0].lower()) # type: ignore
if user_filter is None:
raise PageException("Invalid `show-to` filter")
try:
- menu_index = int(parser.Meta.get('index', ['0'])[0])
+ menu_index = int(parser.Meta.get('index', ['0'])[0]) # type: ignore
except ValueError as exc:
raise PageException("Invalid value for `index`") from exc
diff --git a/fietsboek/updater/__init__.py b/fietsboek/updater/__init__.py
index a5bcf0e..d336daf 100644
--- a/fietsboek/updater/__init__.py
+++ b/fietsboek/updater/__init__.py
@@ -5,6 +5,7 @@ import random
import string
import importlib.util
from pathlib import Path
+from typing import List
# Compat for Python < 3.9
import importlib_resources
@@ -151,7 +152,7 @@ class Updater:
def _make_schedule(self, wanted, dependencies):
wanted = set(wanted)
- queue = []
+ queue: List[str] = []
while wanted:
next_updates = {
update
@@ -233,7 +234,7 @@ class Updater:
current_alembic = context.get_current_heads()
LOGGER.debug("Found alembic versions: %s", current_alembic)
assert len(current_alembic) == 1
- current_alembic = current_alembic[0]
+ current_alembic = current_alembic[0] # type: ignore
loader = jinja2.DictLoader({"revision.py": TEMPLATE})
env = jinja2.Environment(loader=loader, autoescape=False)
@@ -291,7 +292,8 @@ class UpdateScript:
def __init__(self, source, name):
self.name = name
spec = importlib.util.spec_from_loader(f"{__name__}.{name}", None)
- self.module = importlib.util.module_from_spec(spec)
+ self.module = importlib.util.module_from_spec(spec) # type: ignore
+ assert self.module
exec(source, self.module.__dict__) # pylint: disable=exec-used
def __repr__(self):
diff --git a/fietsboek/util.py b/fietsboek/util.py
index 71f5d16..a500d1e 100644
--- a/fietsboek/util.py
+++ b/fietsboek/util.py
@@ -58,7 +58,7 @@ def safe_markdown(md_source):
:return: The safe HTML transformed version.
:rtype: Markup
"""
- html = markdown.markdown(md_source, output_format='html5')
+ html = markdown.markdown(md_source, output_format='html')
html = bleach.clean(html, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES)
return Markup(html)
diff --git a/fietsboek/views/browse.py b/fietsboek/views/browse.py
index c01d4f6..986ae5e 100644
--- a/fietsboek/views/browse.py
+++ b/fietsboek/views/browse.py
@@ -1,6 +1,7 @@
"""Views for browsing all tracks."""
import datetime
from io import RawIOBase
+from typing import List
from zipfile import ZipFile, ZIP_DEFLATED
from pyramid.view import view_config
@@ -212,7 +213,7 @@ class FilterCollection(Filter):
:rtype: FilterCollection
"""
# pylint: disable=singleton-comparison
- filters = []
+ filters: List[Filter] = []
if request.params.get('search-terms'):
term = request.params.get('search-terms').strip()
filters.append(SearchFilter([term]))
@@ -341,7 +342,7 @@ def archive(request):
def generate():
try:
stream = Stream()
- with ZipFile(stream, "w", ZIP_DEFLATED) as zipfile:
+ with ZipFile(stream, "w", ZIP_DEFLATED) as zipfile: # type: ignore
for track in tracks:
zipfile.writestr(f"track_{track.id}.gpx", track.gpx_data)
yield stream.readall()
diff --git a/fietsboek/views/tileproxy.py b/fietsboek/views/tileproxy.py
index 3e2abc1..f484caf 100644
--- a/fietsboek/views/tileproxy.py
+++ b/fietsboek/views/tileproxy.py
@@ -9,7 +9,7 @@ Additionally, this protects the users' IP, as only fietsboek can see it.
import datetime
import random
import logging
-from typing import NamedTuple
+from typing import NamedTuple, Optional
from itertools import chain
from pyramid.view import view_config
@@ -33,7 +33,7 @@ class TileSource(NamedTuple):
"""URL with placeholders."""
layer_type: LayerType
"""Type of this layer."""
- zoom: int
+ zoom: Optional[int]
"""Max zoom of this layer."""
access: LayerAccess
"""Access restrictions to use this layer."""
diff --git a/tox.ini b/tox.ini
index 66e9870..9f69f7e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -5,7 +5,7 @@ per-file-ignores =
fietsboek/models/__init__.py:F401
[tox]
-envlist = python,pylint,pylint-tests,flake8
+envlist = python,pylint,pylint-tests,flake8,mypy
isolated_build = true
[testenv]
@@ -44,3 +44,15 @@ allowlist_externals = make
changedir={toxinidir}{/}doc
commands =
make html
+
+[testenv:mypy]
+deps =
+ mypy
+ types-Markdown
+ types-bleach
+ types-babel
+ types-redis
+ types-requests
+usedevelop = true
+commands =
+ mypy fietsboek