1
0
mirror of https://github.com/enpaul/kodak.git synced 2024-11-23 15:07:13 +00:00

Fix typing errors

Fix missing dependencies in static tox envs
This commit is contained in:
Ethan Paul 2021-10-30 11:51:41 -04:00
parent 158db1209b
commit 19739d17f4
No known key found for this signature in database
GPG Key ID: D0E2CBF1245E92BF
8 changed files with 37 additions and 13 deletions

View File

@ -136,7 +136,7 @@ class ManipCropConfig:
def from_env(cls, key: str): def from_env(cls, key: str):
"""Build dataclass from environment""" """Build dataclass from environment"""
return cls( return cls(
anchor=_get_enum_by_value( anchor=_get_enum_by_value( # type: ignore
f"KODAK_MANIP_{key}_CROP_ANCHOR", constants.CropAnchor, cls.anchor f"KODAK_MANIP_{key}_CROP_ANCHOR", constants.CropAnchor, cls.anchor
), ),
horizontal=_get_int(f"KODAK_MANIP_{key}_CROP_HORIZONTAL", cls.horizontal), horizontal=_get_int(f"KODAK_MANIP_{key}_CROP_HORIZONTAL", cls.horizontal),
@ -173,16 +173,16 @@ class ManipScaleConfig:
) )
if strategy == constants.ScaleStrategy.ABSOLUTE: if strategy == constants.ScaleStrategy.ABSOLUTE:
parser = _get_int parser = _get_int # type: ignore
elif strategy == constants.ScaleStrategy.RELATIVE: elif strategy == constants.ScaleStrategy.RELATIVE:
parser = _get_float parser = _get_float # type: ignore
else: else:
raise RuntimeError("This path should not be possible") raise RuntimeError("This path should not be possible")
return cls( return cls(
strategy=strategy, strategy=strategy, # type: ignore
vertical=parser(f"KODAK_MANIP_{key}_SCALE_VERTICAL", cls.vertical), vertical=parser(f"KODAK_MANIP_{key}_SCALE_VERTICAL", cls.vertical), # type: ignore
horizontal=parser(f"KODAK_MANIP_{key}_SCALE_HORIZONTAL", cls.horizontal), horizontal=parser(f"KODAK_MANIP_{key}_SCALE_HORIZONTAL", cls.horizontal), # type: ignore
) )
@ -198,8 +198,8 @@ class ManipConfig:
""" """
name: str name: str
crop: ManipCropConfig = field(default_factory=ManipCropConfig.from_env) crop: ManipCropConfig = field(default_factory=ManipCropConfig)
scale: ManipScaleConfig = field(default_factory=ManipScaleConfig.from_env) scale: ManipScaleConfig = field(default_factory=ManipScaleConfig)
formats: Set[constants.ImageFormat] = field( formats: Set[constants.ImageFormat] = field(
default_factory=lambda: constants.DEFAULT_SUPPORTED_FORMATS default_factory=lambda: constants.DEFAULT_SUPPORTED_FORMATS
) )

View File

@ -1,5 +1,6 @@
import logging import logging
from typing import Tuple from typing import Tuple
from typing import Type
import peewee import peewee
@ -13,7 +14,7 @@ from kodak.database.alias import AliasRecord
from kodak.database.image import ImageRecord from kodak.database.image import ImageRecord
MODELS: Tuple[KodakModel, ...] = (ImageRecord, AliasRecord, AccessRecord) MODELS: Tuple[Type[KodakModel], ...] = (ImageRecord, AliasRecord, AccessRecord)
def initialize(config: KodakConfig): def initialize(config: KodakConfig):

View File

@ -1,12 +1,15 @@
import datetime import datetime
import enum import enum
import hashlib import typing
import uuid import uuid
from typing import NamedTuple from typing import NamedTuple
from typing import Type from typing import Type
import peewee import peewee
if typing.TYPE_CHECKING:
import _hashlib
INTERFACE = peewee.DatabaseProxy() INTERFACE = peewee.DatabaseProxy()
@ -22,7 +25,7 @@ class Checksum(NamedTuple):
digest: str digest: str
@classmethod @classmethod
def from_hash(cls, data: hashlib._hashlib.HASH): # pylint: disable=protected-access def from_hash(cls, data: "_hashlib.HASH"):
"""Construct from a hashlib object""" """Construct from a hashlib object"""
return cls(algorithm=data.name, digest=data.hexdigest()) return cls(algorithm=data.name, digest=data.hexdigest())

View File

@ -29,6 +29,12 @@ class ImageResourceDeletedError(ClientError):
status = 410 status = 410
class IAmATeapotError(ClientError):
"""User tried to brew coffee, but application is a teapot"""
status = 418
class ServerError(KodakException): class ServerError(KodakException):
"""Error while processing server side data""" """Error while processing server side data"""

View File

@ -1,4 +1,5 @@
from typing import Tuple from typing import Tuple
from typing import Type
from kodak.resources._shared import KodakResource from kodak.resources._shared import KodakResource
from kodak.resources.alias import ImageAlias from kodak.resources.alias import ImageAlias
@ -7,7 +8,7 @@ from kodak.resources.image import Image
from kodak.resources.openapi import OpenAPI from kodak.resources.openapi import OpenAPI
RESOURCES: Tuple[KodakResource, ...] = ( RESOURCES: Tuple[Type[KodakResource], ...] = (
Heartbeat, Heartbeat,
Image, Image,
ImageAlias, ImageAlias,

View File

@ -12,6 +12,7 @@ from kodak import exceptions
@contextlib.contextmanager @contextlib.contextmanager
def mockenv(patch, env: Dict[str, str]): def mockenv(patch, env: Dict[str, str]):
"""Simple context manager for patching in a bunch of env vars"""
for key, value in env.items(): for key, value in env.items():
patch.setenv(key, value) patch.setenv(key, value)
yield yield
@ -20,6 +21,8 @@ def mockenv(patch, env: Dict[str, str]):
def test_conf_global(monkeypatch): def test_conf_global(monkeypatch):
"""Test the global config object and env parser"""
assert configuration.KodakConfig() == configuration.load() assert configuration.KodakConfig() == configuration.load()
with mockenv( with mockenv(
@ -53,6 +56,8 @@ def test_conf_global(monkeypatch):
def test_conf_database(monkeypatch): def test_conf_database(monkeypatch):
"""Test the database config object and env parser"""
with mockenv(monkeypatch, {"KODAK_DATABASE_BACKEND": "couchdb"}): with mockenv(monkeypatch, {"KODAK_DATABASE_BACKEND": "couchdb"}):
with pytest.raises(exceptions.ConfigurationError): with pytest.raises(exceptions.ConfigurationError):
configuration.load() configuration.load()
@ -94,6 +99,8 @@ def test_conf_database(monkeypatch):
def test_conf_manip(monkeypatch): def test_conf_manip(monkeypatch):
"""Test the manipulation config object and env parser"""
with mockenv( with mockenv(
monkeypatch, monkeypatch,
{ {

View File

@ -10,11 +10,15 @@ yaml = ruamel.yaml.YAML(typ="safe") # pylint: disable=invalid-name
def test_openapi(): def test_openapi():
"""Validate the OpenAPI specification document structure"""
openapi_spec_validator.validate_spec( openapi_spec_validator.validate_spec(
yaml.load(importlib.resources.read_text("kodak", "openapi.yaml")) yaml.load(importlib.resources.read_text("kodak", "openapi.yaml"))
) )
def test_openapi_version(): def test_openapi_version():
"""Check that the OpenAPI metadata matches the package metadata"""
spec = yaml.load(importlib.resources.read_text("kodak", "openapi.yaml")) spec = yaml.load(importlib.resources.read_text("kodak", "openapi.yaml"))
assert spec["info"]["version"] == __about__.__version__ assert spec["info"]["version"] == __about__.__version__
assert spec["info"]["license"]["name"] == __about__.__license__
assert spec["info"]["title"].lower() == __about__.__title__.lower()

View File

@ -44,8 +44,10 @@ description = Static formatting and quality enforcement for the tests
basepython = python3.8 basepython = python3.8
ignore_errors = true ignore_errors = true
locked_deps = locked_deps =
pylint
mypy mypy
pylint
pytest
openapi-spec-validator
commands = commands =
pylint --rcfile {toxinidir}/.pylintrc {toxinidir}/tests/ pylint --rcfile {toxinidir}/.pylintrc {toxinidir}/tests/
mypy --ignore-missing-imports --no-strict-optional {toxinidir}/tests/ mypy --ignore-missing-imports --no-strict-optional {toxinidir}/tests/