lint: switch mypy to strict
This commit is contained in:
parent
2bd37c541f
commit
b6542235ce
4
.flake8
4
.flake8
|
@ -1,9 +1,9 @@
|
||||||
[flake8]
|
[flake8]
|
||||||
filename= marshpy tests
|
|
||||||
ignore =
|
ignore =
|
||||||
# Line too long
|
# Line too long
|
||||||
E501
|
E501
|
||||||
include = marshpy,test
|
# at least two spaces before inline comment
|
||||||
|
E261
|
||||||
max-complexity = 10
|
max-complexity = 10
|
||||||
per-file-ignores =
|
per-file-ignores =
|
||||||
# Imported but unused
|
# Imported but unused
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
|
|
||||||
from .config import Config, SiteConfig
|
from .config import Config, SiteConfig
|
||||||
from .utils import report_progress
|
from .utils import report_progress
|
||||||
|
from asyncio import gather
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pickle import dumps, loads
|
from pickle import dumps, loads
|
||||||
from typing import Awaitable, Callable, Generic, TypeVar, Union
|
from typing import Awaitable, Callable, Generic, TypeVar, Union, cast
|
||||||
from urllib.parse import urlparse
|
|
||||||
|
|
||||||
from xdg import xdg_cache_home
|
from xdg import xdg_cache_home
|
||||||
|
|
||||||
|
@ -16,7 +15,9 @@ class Cache(Generic[ResourceType], ABC):
|
||||||
"""Base class for caches"""
|
"""Base class for caches"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def get(self, key: str, fallback: CacheFallback) -> ResourceType:
|
async def get(
|
||||||
|
self, key: str, fallback: CacheFallback[ResourceType]
|
||||||
|
) -> ResourceType:
|
||||||
"""Get an item in the cache, call fallback if it's not present"""
|
"""Get an item in the cache, call fallback if it's not present"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -24,7 +25,9 @@ class Cache(Generic[ResourceType], ABC):
|
||||||
"""Set a resource in the cache"""
|
"""Set a resource in the cache"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def _get_fallback_value(key: str, fallback: CacheFallback[ResourceType]) -> ResourceType:
|
async def _get_fallback_value(
|
||||||
|
key: str, fallback: CacheFallback[ResourceType]
|
||||||
|
) -> ResourceType:
|
||||||
if callable(fallback):
|
if callable(fallback):
|
||||||
result = await fallback(key)
|
result = await fallback(key)
|
||||||
else:
|
else:
|
||||||
|
@ -33,10 +36,12 @@ class Cache(Generic[ResourceType], ABC):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class NullCache(Cache):
|
class NullCache(Cache[ResourceType]):
|
||||||
"""Disabled cache"""
|
"""Disabled cache"""
|
||||||
|
|
||||||
async def get(self, key: str, fallback: CacheFallback) -> ResourceType:
|
async def get(
|
||||||
|
self, key: str, fallback: CacheFallback[ResourceType]
|
||||||
|
) -> ResourceType:
|
||||||
return await self._get_fallback_value(key, fallback)
|
return await self._get_fallback_value(key, fallback)
|
||||||
|
|
||||||
def set(self, key: str, resource: ResourceType) -> None:
|
def set(self, key: str, resource: ResourceType) -> None:
|
||||||
|
@ -46,10 +51,12 @@ class NullCache(Cache):
|
||||||
class FileCache(Cache[ResourceType]):
|
class FileCache(Cache[ResourceType]):
|
||||||
"""Cache on the local filesystem"""
|
"""Cache on the local filesystem"""
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name: str) -> None:
|
||||||
self._name = name
|
self._name = name
|
||||||
|
|
||||||
async def get(self, key: str, fallback: CacheFallback) -> ResourceType:
|
async def get(
|
||||||
|
self, key: str, fallback: CacheFallback[ResourceType]
|
||||||
|
) -> ResourceType:
|
||||||
"""Get an item in the cache, call fallback if it's not present"""
|
"""Get an item in the cache, call fallback if it's not present"""
|
||||||
cache_file_path = self._get_cache_file_path(key)
|
cache_file_path = self._get_cache_file_path(key)
|
||||||
if not cache_file_path.is_file():
|
if not cache_file_path.is_file():
|
||||||
|
@ -104,9 +111,9 @@ class ObjectCache(FileCache[ResourceType]):
|
||||||
return dumps(resource)
|
return dumps(resource)
|
||||||
|
|
||||||
def _deserialize(self, data: bytes) -> ResourceType:
|
def _deserialize(self, data: bytes) -> ResourceType:
|
||||||
return loads(data)
|
return cast(ResourceType, loads(data))
|
||||||
|
|
||||||
|
|
||||||
def _get_key_slug(url: str) -> str:
|
def _get_key_slug(url: str) -> str:
|
||||||
"""Return an unique slug usable as a path name for a given url."""
|
"""Return an unique slug usable as a path name for a given url."""
|
||||||
return url.replace('_', '___').replace('/', '__').replace(':', '_')
|
return url.replace("_", "___").replace("/", "__").replace(":", "_")
|
||||||
|
|
|
@ -52,7 +52,7 @@ async def main(
|
||||||
@argument("right_source", type=str)
|
@argument("right_source", type=str)
|
||||||
@pass_context
|
@pass_context
|
||||||
@_async_command
|
@_async_command
|
||||||
async def css_diff_cli(ctx: ClickContext, right_source) -> None:
|
async def css_diff_cli(ctx: ClickContext, right_source: str) -> None:
|
||||||
"""Diff CSS"""
|
"""Diff CSS"""
|
||||||
config: Config = ctx.obj
|
config: Config = ctx.obj
|
||||||
for _, site in config.sites:
|
for _, site in config.sites:
|
||||||
|
|
|
@ -87,7 +87,8 @@ class Config:
|
||||||
return self._sites.items()
|
return self._sites.items()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def config_cache(self) -> Cache:
|
def config_cache(self) -> Cache[object]:
|
||||||
|
"""Get the cache for configuration"""
|
||||||
return self.get_object_cache("config")
|
return self.get_object_cache("config")
|
||||||
|
|
||||||
def add_site_url(self, name: str, url: str) -> None:
|
def add_site_url(self, name: str, url: str) -> None:
|
||||||
|
@ -97,17 +98,17 @@ class Config:
|
||||||
|
|
||||||
self._sites[name].urls.append(url)
|
self._sites[name].urls.append(url)
|
||||||
|
|
||||||
def get_data_cache(self, name: str):
|
def get_data_cache(self, name: str) -> Cache[bytes]:
|
||||||
"""Get a data cache with the given identifier"""
|
"""Get a data cache with the given identifier"""
|
||||||
if self._use_cache:
|
if self._use_cache:
|
||||||
return DataCache(name)
|
return DataCache(name)
|
||||||
|
|
||||||
return NullCache()
|
return NullCache()
|
||||||
|
|
||||||
def get_object_cache(self, name: str):
|
def get_object_cache(self, name: str) -> Cache[object]:
|
||||||
"""Get an object cache with the given identifier"""
|
"""Get an object cache with the given identifier"""
|
||||||
if self._use_cache:
|
if self._use_cache:
|
||||||
return ObjectCache(name)
|
return ObjectCache[object](name)
|
||||||
|
|
||||||
return NullCache()
|
return NullCache()
|
||||||
|
|
||||||
|
@ -116,7 +117,7 @@ class Config:
|
||||||
name: str,
|
name: str,
|
||||||
mappings: list[tuple[str, str]],
|
mappings: list[tuple[str, str]],
|
||||||
next_source_name: Optional[str] = None,
|
next_source_name: Optional[str] = None,
|
||||||
):
|
) -> None:
|
||||||
"""Add a source overriding given patterns"""
|
"""Add a source overriding given patterns"""
|
||||||
assert name not in self._sources
|
assert name not in self._sources
|
||||||
if next_source_name is None:
|
if next_source_name is None:
|
||||||
|
@ -131,7 +132,7 @@ class Config:
|
||||||
raise Exception(f"No source configured matching {name}")
|
raise Exception(f"No source configured matching {name}")
|
||||||
return self._sources[name]
|
return self._sources[name]
|
||||||
|
|
||||||
def _add_source(self, name: str, source: Source):
|
def _add_source(self, name: str, source: Source) -> None:
|
||||||
if name in self._sources:
|
if name in self._sources:
|
||||||
raise Exception(f"Source {name} already configured")
|
raise Exception(f"Source {name} already configured")
|
||||||
self._sources[name] = source
|
self._sources[name] = source
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
"""Source for remote files"""
|
"""Source for remote files"""
|
||||||
from aiohttp import ClientSession
|
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from re import Pattern
|
from re import Pattern
|
||||||
from re import compile as re_compile
|
from re import compile as re_compile
|
||||||
|
|
||||||
from frontools.cache import DataCache
|
from aiohttp import ClientSession
|
||||||
|
|
||||||
|
from frontools.cache import Cache
|
||||||
|
|
||||||
|
|
||||||
class Source(ABC):
|
class Source(ABC):
|
||||||
|
@ -18,7 +19,7 @@ class Source(ABC):
|
||||||
class CachedSource(Source):
|
class CachedSource(Source):
|
||||||
"""Source loading urls from the internet."""
|
"""Source loading urls from the internet."""
|
||||||
|
|
||||||
def __init__(self, cache: DataCache) -> None:
|
def __init__(self, cache: Cache[bytes]) -> None:
|
||||||
self._cache = cache
|
self._cache = cache
|
||||||
|
|
||||||
async def get_url(self, url: str) -> bytes:
|
async def get_url(self, url: str) -> bytes:
|
||||||
|
|
|
@ -4,7 +4,7 @@ from datetime import datetime
|
||||||
from os.path import expandvars
|
from os.path import expandvars
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from re import compile as re_compile
|
from re import compile as re_compile
|
||||||
from typing import Awaitable
|
from typing import Awaitable, cast
|
||||||
|
|
||||||
from click import progressbar
|
from click import progressbar
|
||||||
from xdg import xdg_config_home
|
from xdg import xdg_config_home
|
||||||
|
@ -43,14 +43,14 @@ async def report_progress(label: str, task_list: TaskListType) -> None:
|
||||||
with progressbar(
|
with progressbar(
|
||||||
length=len(task_list),
|
length=len(task_list),
|
||||||
label=label,
|
label=label,
|
||||||
item_show_func=lambda it: it,
|
item_show_func=lambda it: cast(str, it),
|
||||||
) as progress:
|
) as progress:
|
||||||
|
|
||||||
async def worker():
|
async def worker() -> None:
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
item_name, task = next(iterator)
|
item_name, task = next(iterator)
|
||||||
progress.update(1, current_item=item_name)
|
progress.update(1, current_item=item_name) # type: ignore
|
||||||
await task
|
await task
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
pass
|
pass
|
||||||
|
|
22
noxfile.py
22
noxfile.py
|
@ -14,49 +14,49 @@ VENV_DIR = Path(".venv")
|
||||||
|
|
||||||
|
|
||||||
@nox.session(python=["3.9", "3.10"], reuse_venv=True)
|
@nox.session(python=["3.9", "3.10"], reuse_venv=True)
|
||||||
def tests(session: Session):
|
def tests(session: Session) -> None:
|
||||||
"""Run unit tests."""
|
"""Run unit tests."""
|
||||||
session.install("-e", ".", *PYTEST_PACKAGES)
|
session.install("-e", ".", *PYTEST_PACKAGES)
|
||||||
session.run("pytest")
|
session.run("pytest")
|
||||||
|
|
||||||
|
|
||||||
@nox.session(reuse_venv=True)
|
@nox.session(reuse_venv=True)
|
||||||
def black(session: Session):
|
def black(session: Session) -> None:
|
||||||
"""Check black formatting."""
|
"""Check black formatting."""
|
||||||
session.install("black")
|
session.install("black")
|
||||||
session.run("black", "--check", *LINT_PATHS)
|
session.run("black", "--check", *LINT_PATHS)
|
||||||
|
|
||||||
|
|
||||||
@nox.session(reuse_venv=True)
|
@nox.session(reuse_venv=True)
|
||||||
def flake8(session: Session):
|
def flake8(session: Session) -> None:
|
||||||
"""Run flake8"""
|
"""Run flake8"""
|
||||||
session.install("flake8")
|
session.install("flake8")
|
||||||
session.run("flake8")
|
session.run("flake8", "frontools", "tests")
|
||||||
|
|
||||||
|
|
||||||
@nox.session(reuse_venv=True)
|
@nox.session(reuse_venv=True)
|
||||||
def isort(session: Session):
|
def isort(session: Session) -> None:
|
||||||
"""Check imports sorting"""
|
"""Check imports sorting"""
|
||||||
session.install("isort")
|
session.install("isort")
|
||||||
session.run("isort", "--check", *LINT_PATHS)
|
session.run("isort", "--check", *LINT_PATHS)
|
||||||
|
|
||||||
|
|
||||||
@nox.session(reuse_venv=True)
|
@nox.session(reuse_venv=True)
|
||||||
def mypy(session: Session):
|
def mypy(session: Session) -> None:
|
||||||
"""Run Mypy"""
|
"""Run Mypy"""
|
||||||
session.install("mypy", "types-click")
|
session.install("mypy", "types-click", "-e", ".")
|
||||||
session.run("mypy", *LINT_PATHS)
|
session.run("mypy", "--install-types", *LINT_PATHS)
|
||||||
|
|
||||||
|
|
||||||
@nox.session(reuse_venv=True)
|
@nox.session(reuse_venv=True)
|
||||||
def pylint(session: Session):
|
def pylint(session: Session) -> None:
|
||||||
"""Run pylint"""
|
"""Run pylint"""
|
||||||
session.install("pylint", "-e", ".", *PYTEST_PACKAGES)
|
session.install("pylint", "-e", ".", *PYTEST_PACKAGES)
|
||||||
session.run("pylint", "--rcfile=pyproject.toml", *LINT_PATHS)
|
session.run("pylint", "--rcfile=pyproject.toml", *LINT_PATHS)
|
||||||
|
|
||||||
|
|
||||||
@nox.session(python=False)
|
@nox.session(python=False)
|
||||||
def lint(session: Session):
|
def lint(session: Session) -> None:
|
||||||
"""Run all lint tasks"""
|
"""Run all lint tasks"""
|
||||||
session.notify("black")
|
session.notify("black")
|
||||||
session.notify("flake8")
|
session.notify("flake8")
|
||||||
|
@ -66,7 +66,7 @@ def lint(session: Session):
|
||||||
|
|
||||||
|
|
||||||
@nox.session(python=False)
|
@nox.session(python=False)
|
||||||
def checks(session: Session):
|
def checks(session: Session) -> None:
|
||||||
"""Run all checks"""
|
"""Run all checks"""
|
||||||
session.notify("lint")
|
session.notify("lint")
|
||||||
session.notify("tests")
|
session.notify("tests")
|
||||||
|
|
|
@ -52,6 +52,9 @@ junit_family = "legacy"
|
||||||
addopts = "--cov=frontools --cov-report html"
|
addopts = "--cov=frontools --cov-report html"
|
||||||
testpaths = "tests"
|
testpaths = "tests"
|
||||||
|
|
||||||
|
[tool.mypy]
|
||||||
|
strict=true
|
||||||
|
|
||||||
[[tool.mypy.overrides]]
|
[[tool.mypy.overrides]]
|
||||||
module = [
|
module = [
|
||||||
'pytest',
|
'pytest',
|
||||||
|
@ -65,6 +68,9 @@ ignore_missing_imports = true
|
||||||
[tool.isort]
|
[tool.isort]
|
||||||
profile = "black"
|
profile = "black"
|
||||||
|
|
||||||
|
[tool.pylint.reports]
|
||||||
|
msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}"
|
||||||
|
|
||||||
[tool.pylint.messages_control]
|
[tool.pylint.messages_control]
|
||||||
disable = [
|
disable = [
|
||||||
"invalid-name",
|
"invalid-name",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
"""Frontools unit tests packages"""
|
Loading…
Reference in New Issue