From 30f3b482fe6d2730b197b275a4701f73edec354f Mon Sep 17 00:00:00 2001 From: Kyle Wigley Date: Tue, 1 Dec 2020 18:04:35 -0500 Subject: [PATCH] fix mypy and test py39 --- .circleci/config.yml | 84 ++++++++++++++++----- hologram/__init__.py | 7 +- setup.py | 6 +- third-party-stubs/jsonschema/__init__.pyi | 5 +- third-party-stubs/jsonschema/exceptions.pyi | 5 +- 5 files changed, 76 insertions(+), 31 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0dcc9ec..031652c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,38 +1,65 @@ version: 2 jobs: - py36: + lint: docker: - - image: circleci/python:3.6 - - steps: &test-steps + - image: circleci/python:3.9 + steps: - checkout - # Download and cache dependencies - restore_cache: keys: - - v1-dependencies-{{ checksum "setup.py" }} - # fallback to using the latest cache if no exact match is found - - v1-dependencies- + - v1-lint-{{ checksum "setup.py" }} + - v1-lint- - run: name: "Setup" command: | python3 -m venv venv . venv/bin/activate - python setup.py develop - pip install black pytest mypy - + pip install . black mypy + + - save_cache: + paths: + - ./venv + key: v1-lint-{{ checksum "setup.py" }} + - run: name: "Check code formatting" command: | . venv/bin/activate black --check hologram/ tests/ + - run: + name: "Run mypy" + command: | + . venv/bin/activate + mypy hologram + + py36: + docker: + - image: circleci/python:3.6 + + steps: &test-steps + - checkout + + - restore_cache: + keys: + - v1-unit-{{ checksum "setup.py" }} + # fallback to using the latest cache if no exact match is found + - v1-unit- + + - run: + name: "Setup" + command: | + python3 -m venv venv + . venv/bin/activate + pip install . pytest + - save_cache: paths: - ./venv - key: v1-dependencies-{{ checksum "setup.py" }} + key: v1-unit-{{ checksum "setup.py" }} - run: name: "Run tests" @@ -40,21 +67,38 @@ jobs: . venv/bin/activate pytest - - run: - name: "Run mypy" - command: | - . venv/bin/activate - mypy hologram - py37: docker: - image: circleci/python:3.7 steps: *test-steps + py38: + docker: + - image: circleci/python:3.8 + + steps: *test-steps + + py39: + docker: + - image: circleci/python:3.9 + + steps: *test-steps + workflows: version: 2 build-all: jobs: - - py36 - - py37 + - lint + - py36: + requires: + - lint + - py37: + requires: + - lint + - py38: + requires: + - lint + - py39: + requires: + - lint diff --git a/hologram/__init__.py b/hologram/__init__.py index 5c16b3d..a74035c 100644 --- a/hologram/__init__.py +++ b/hologram/__init__.py @@ -12,6 +12,7 @@ get_type_hints, Callable, Generic, + Hashable, ) import re from datetime import datetime @@ -183,7 +184,8 @@ def as_dict(self) -> Dict: @functools.lru_cache() -def _validate_schema(schema_cls: Type[T]) -> JsonDict: +def _validate_schema(h_schema_cls: Hashable) -> JsonDict: + schema_cls = cast(Type[JsonSchemaMixin], h_schema_cls) # making mypy happy schema = schema_cls.json_schema() jsonschema.Draft7Validator.check_schema(schema) return schema @@ -958,7 +960,8 @@ def _get_field_type_name(field_type: Any) -> str: @classmethod def validate(cls, data: Any): - schema = _validate_schema(cls) + h_cls = cast(Hashable, cls) + schema = _validate_schema(h_cls) validator = jsonschema.Draft7Validator(schema) error = next(iter(validator.iter_errors(data)), None) if error is not None: diff --git a/setup.py b/setup.py index f881201..abf3162 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ def read(f): name="hologram", description="JSON schema generation from dataclasses", long_description=read("README.md"), - long_description_content_type='text/markdown', + long_description_content_type="text/markdown", packages=["hologram"], package_data={"hologram": ["py.typed"]}, version=package_version, @@ -25,8 +25,6 @@ def read(f): author_email="info@fishtowanalytics.com, simon.knibbs@gmail.com", url="https://github.com/fishtown-analytics/hologram", install_requires=requires, - setup_requires=["pytest-runner", "setuptools_scm", "wheel"], - tests_require=["pytest", "flake8", "mypy"], license="MIT", classifiers=[ "Development Status :: 4 - Beta", @@ -35,6 +33,8 @@ def read(f): "Programming Language :: Python", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries", ], ) diff --git a/third-party-stubs/jsonschema/__init__.pyi b/third-party-stubs/jsonschema/__init__.pyi index b306b2a..f6b8582 100644 --- a/third-party-stubs/jsonschema/__init__.pyi +++ b/third-party-stubs/jsonschema/__init__.pyi @@ -3,9 +3,10 @@ from typing import Any, Dict, Iterable # we need the 'as' to tell mypy we want this visible with both names from jsonschema.exceptions import ValidationError as ValidationError - class Draft7Validator: def __init__(self, schema: Dict[str, Any]) -> None: ... @classmethod def check_schema(cls, schema: Dict[str, Any]) -> None: ... - def iter_errors(self, instance, _schema=None) -> Iterable[ValidationError]: ... + def iter_errors( + self, instance, _schema=None + ) -> Iterable[ValidationError]: ... diff --git a/third-party-stubs/jsonschema/exceptions.pyi b/third-party-stubs/jsonschema/exceptions.pyi index ba1d5f0..e9aef1e 100644 --- a/third-party-stubs/jsonschema/exceptions.pyi +++ b/third-party-stubs/jsonschema/exceptions.pyi @@ -1,8 +1,7 @@ from typing import Any, Optional, Tuple, Iterable, TypeVar, Type # we need this to denote that create_from applies to subclasses -T = TypeVar('T', bound=ValidationError) - +T = TypeVar("T", bound=ValidationError) class ValidationError(Exception): def __init__( @@ -18,9 +17,7 @@ class ValidationError(Exception): schema_path: Tuple[Any] = ..., parent: Any = ..., ) -> None: ... - @classmethod def create_from(cls: Type[T], ValidationError) -> T: ... - def best_match(errors: Iterable[ValidationError]) -> ValidationError: ...