diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 98d11c1..dcdbbaf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,5 @@ --- -default_stages: [commit, push] +default_stages: [pre-commit, pre-push] default_language_version: # force all unspecified python hooks to run python3 python: python3 @@ -10,37 +10,22 @@ repos: - id: check-hooks-apply - repo: https://github.com/asottile/pyupgrade - rev: v2.19.0 + rev: v3.20.0 hooks: - id: pyupgrade - args: ["--py36-plus"] + args: ["--py39-plus"] - - repo: local + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 25.1.0 hooks: - - id: flynt - name: Convert to f-strings with flynt - entry: flynt - language: python - additional_dependencies: ['flynt==0.76'] - - id: black - name: black - entry: black - language: system - require_serial: true - types: [python] + - repo: https://github.com/pycqa/isort + rev: 6.0.1 + hooks: - id: isort - name: isort - entry: isort - args: ['--filter-files'] - language: system - require_serial: true - types: [python] - - id: pyflakes - name: pyflakes - entry: pyflakes - language: system - require_serial: true - types: [python] + - repo: https://github.com/pycqa/flake8 + rev: 7.3.0 + hooks: + - id: flake8 diff --git a/openapi_spec_validator/__init__.py b/openapi_spec_validator/__init__.py index 62a25a2..11869de 100644 --- a/openapi_spec_validator/__init__.py +++ b/openapi_spec_validator/__init__.py @@ -1,4 +1,5 @@ """OpenAPI spec validator module.""" + from openapi_spec_validator.shortcuts import validate from openapi_spec_validator.shortcuts import validate_spec from openapi_spec_validator.shortcuts import validate_spec_url diff --git a/openapi_spec_validator/__main__.py b/openapi_spec_validator/__main__.py index bc97714..aed7114 100644 --- a/openapi_spec_validator/__main__.py +++ b/openapi_spec_validator/__main__.py @@ -1,8 +1,8 @@ import logging import sys from argparse import ArgumentParser +from collections.abc import Sequence from typing import Optional -from typing import Sequence from jsonschema.exceptions import ValidationError from jsonschema.exceptions import best_match diff --git a/openapi_spec_validator/readers.py b/openapi_spec_validator/readers.py index 4af9270..ac0480a 100644 --- a/openapi_spec_validator/readers.py +++ b/openapi_spec_validator/readers.py @@ -1,18 +1,17 @@ import sys from os import path from pathlib import Path -from typing import Tuple from jsonschema_path.handlers import all_urls_handler from jsonschema_path.handlers import file_handler from jsonschema_path.typing import Schema -def read_from_stdin(filename: str) -> Tuple[Schema, str]: +def read_from_stdin(filename: str) -> tuple[Schema, str]: return file_handler(sys.stdin), "" # type: ignore -def read_from_filename(filename: str) -> Tuple[Schema, str]: +def read_from_filename(filename: str) -> tuple[Schema, str]: if not path.isfile(filename): raise OSError(f"No such file: {filename}") diff --git a/openapi_spec_validator/schemas/__init__.py b/openapi_spec_validator/schemas/__init__.py index 8141788..e1147bc 100644 --- a/openapi_spec_validator/schemas/__init__.py +++ b/openapi_spec_validator/schemas/__init__.py @@ -1,4 +1,5 @@ """OpenAIP spec validator schemas module.""" + from functools import partial from jsonschema.validators import Draft4Validator diff --git a/openapi_spec_validator/schemas/utils.py b/openapi_spec_validator/schemas/utils.py index 7b2fd92..34dfe0f 100644 --- a/openapi_spec_validator/schemas/utils.py +++ b/openapi_spec_validator/schemas/utils.py @@ -1,14 +1,14 @@ """OpenAIP spec validator schemas utils module.""" + from importlib.resources import as_file from importlib.resources import files from os import path -from typing import Tuple from jsonschema_path.readers import FilePathReader from jsonschema_path.typing import Schema -def get_schema(version: str) -> Tuple[Schema, str]: +def get_schema(version: str) -> tuple[Schema, str]: schema_path = f"resources/schemas/v{version}/schema.json" ref = files("openapi_spec_validator") / schema_path with as_file(ref) as resource_path: diff --git a/openapi_spec_validator/shortcuts.py b/openapi_spec_validator/shortcuts.py index 70c2c8f..a1e2e57 100644 --- a/openapi_spec_validator/shortcuts.py +++ b/openapi_spec_validator/shortcuts.py @@ -1,8 +1,8 @@ """OpenAPI spec validator shortcuts module.""" + import warnings -from typing import Mapping +from collections.abc import Mapping from typing import Optional -from typing import Type from jsonschema_path import SchemaPath from jsonschema_path.handlers import all_urls_handler @@ -50,7 +50,7 @@ def validate( def validate_url( spec_url: str, - cls: Optional[Type[SpecValidator]] = None, + cls: Optional[type[SpecValidator]] = None, ) -> None: spec = all_urls_handler(spec_url) return validate(spec, base_uri=spec_url, cls=cls) @@ -82,7 +82,7 @@ def validate_spec( def validate_spec_url( spec_url: str, validator: Optional[SupportsValidation] = None, - cls: Optional[Type[SpecValidator]] = None, + cls: Optional[type[SpecValidator]] = None, ) -> None: warnings.warn( "validate_spec_url shortcut is deprecated. Use validate_url instead.", diff --git a/openapi_spec_validator/validation/caches.py b/openapi_spec_validator/validation/caches.py index acc6b36..5bbb5c6 100644 --- a/openapi_spec_validator/validation/caches.py +++ b/openapi_spec_validator/validation/caches.py @@ -1,7 +1,6 @@ +from collections.abc import Iterable +from collections.abc import Iterator from typing import Generic -from typing import Iterable -from typing import Iterator -from typing import List from typing import TypeVar T = TypeVar("T") @@ -14,7 +13,7 @@ class CachedIterable(Iterable[T], Generic[T]): It should not be iterated by his own. """ - cache: List[T] + cache: list[T] iter: Iterator[T] completed: bool diff --git a/openapi_spec_validator/validation/decorators.py b/openapi_spec_validator/validation/decorators.py index 191c035..3fa4986 100644 --- a/openapi_spec_validator/validation/decorators.py +++ b/openapi_spec_validator/validation/decorators.py @@ -1,10 +1,11 @@ """OpenAPI spec validator validation decorators module.""" + import logging +from collections.abc import Iterable +from collections.abc import Iterator from functools import wraps from typing import Any from typing import Callable -from typing import Iterable -from typing import Iterator from typing import TypeVar from jsonschema.exceptions import ValidationError @@ -19,7 +20,7 @@ def wraps_errors( - func: Callable[..., Any] + func: Callable[..., Any], ) -> Callable[..., Iterator[ValidationError]]: @wraps(func) def wrapper(*args: Any, **kwds: Any) -> Iterator[ValidationError]: @@ -35,7 +36,7 @@ def wrapper(*args: Any, **kwds: Any) -> Iterator[ValidationError]: def wraps_cached_iter( - func: Callable[[Args], Iterator[T]] + func: Callable[[Args], Iterator[T]], ) -> Callable[[Args], CachedIterable[T]]: @wraps(func) def wrapper(*args: Any, **kwargs: Any) -> CachedIterable[T]: @@ -46,7 +47,7 @@ def wrapper(*args: Any, **kwargs: Any) -> CachedIterable[T]: def unwraps_iter( - func: Callable[[Args], Iterable[T]] + func: Callable[[Args], Iterable[T]], ) -> Callable[[Args], Iterator[T]]: @wraps(func) def wrapper(*args: Any, **kwargs: Any) -> Iterator[T]: diff --git a/openapi_spec_validator/validation/keywords.py b/openapi_spec_validator/validation/keywords.py index 877a3fe..c752ff4 100644 --- a/openapi_spec_validator/validation/keywords.py +++ b/openapi_spec_validator/validation/keywords.py @@ -1,9 +1,8 @@ import string +from collections.abc import Iterator +from collections.abc import Sequence from typing import TYPE_CHECKING from typing import Any -from typing import Sequence -from typing import Iterator -from typing import List from typing import Optional from typing import cast @@ -68,7 +67,7 @@ class SchemaValidator(KeywordValidator): def __init__(self, registry: "KeywordValidatorRegistry"): super().__init__(registry) - self.schema_ids_registry: Optional[List[int]] = [] + self.schema_ids_registry: Optional[list[int]] = [] @property def default_validator(self) -> ValueValidator: @@ -113,8 +112,9 @@ def __call__( all_of = schema / "allOf" for inner_schema in all_of: yield from self(inner_schema, require_properties=False) - nested_properties += list(self._collect_properties(inner_schema)) - + nested_properties += list( + self._collect_properties(inner_schema) + ) if "anyOf" in schema: any_of = schema / "anyOf" @@ -154,8 +154,12 @@ def __call__( require_properties=False, ) - required = "required" in schema and (schema / "required").read_value() or [] - properties = "properties" in schema and (schema / "properties").keys() or [] + required = ( + "required" in schema and (schema / "required").read_value() or [] + ) + properties = ( + "properties" in schema and (schema / "properties").keys() or [] + ) if "allOf" in schema: extra_properties = list( set(required) - set(properties) - set(nested_properties) @@ -305,7 +309,7 @@ class OperationValidator(KeywordValidator): def __init__(self, registry: "KeywordValidatorRegistry"): super().__init__(registry) - self.operation_ids_registry: Optional[List[str]] = [] + self.operation_ids_registry: Optional[list[str]] = [] @property def responses_validator(self) -> ResponsesValidator: @@ -356,8 +360,7 @@ def __call__( for path in self._get_path_params_from_url(url): if path not in all_params: yield UnresolvableParameterError( - "Path parameter '{}' for '{}' operation in '{}' " - "was not resolved".format(path, name, url) + f"Path parameter '{path}' for '{name}' operation in '{url}' was not resolved" ) return diff --git a/openapi_spec_validator/validation/protocols.py b/openapi_spec_validator/validation/protocols.py index 3e7403c..1dd8b00 100644 --- a/openapi_spec_validator/validation/protocols.py +++ b/openapi_spec_validator/validation/protocols.py @@ -1,4 +1,4 @@ -from typing import Iterator +from collections.abc import Iterator from typing import Optional from typing import Protocol from typing import runtime_checkable @@ -10,21 +10,18 @@ @runtime_checkable class SupportsValidation(Protocol): - def is_valid(self, instance: Schema) -> bool: - ... + def is_valid(self, instance: Schema) -> bool: ... def iter_errors( self, instance: Schema, base_uri: str = "", spec_url: Optional[str] = None, - ) -> Iterator[OpenAPIValidationError]: - ... + ) -> Iterator[OpenAPIValidationError]: ... def validate( self, instance: Schema, base_uri: str = "", spec_url: Optional[str] = None, - ) -> None: - ... + ) -> None: ... diff --git a/openapi_spec_validator/validation/proxies.py b/openapi_spec_validator/validation/proxies.py index 964266d..81250be 100644 --- a/openapi_spec_validator/validation/proxies.py +++ b/openapi_spec_validator/validation/proxies.py @@ -1,11 +1,9 @@ """OpenAPI spec validator validation proxies module.""" + import warnings -from collections.abc import Hashable -from typing import Any -from typing import Iterator -from typing import Mapping +from collections.abc import Iterator +from collections.abc import Mapping from typing import Optional -from typing import Tuple from jsonschema.exceptions import ValidationError from jsonschema_path.typing import Schema @@ -59,7 +57,7 @@ def iter_errors( class DetectValidatorProxy: - def __init__(self, choices: Mapping[Tuple[str, str], SpecValidatorProxy]): + def __init__(self, choices: Mapping[tuple[str, str], SpecValidatorProxy]): self.choices = choices def detect(self, instance: Schema) -> SpecValidatorProxy: diff --git a/openapi_spec_validator/validation/registries.py b/openapi_spec_validator/validation/registries.py index b9ddc5e..85bcf4e 100644 --- a/openapi_spec_validator/validation/registries.py +++ b/openapi_spec_validator/validation/registries.py @@ -1,15 +1,14 @@ from __future__ import annotations +from collections.abc import Mapping from typing import DefaultDict -from typing import Mapping -from typing import Type from openapi_spec_validator.validation.keywords import KeywordValidator class KeywordValidatorRegistry(DefaultDict[str, KeywordValidator]): def __init__( - self, keyword_validators: Mapping[str, Type[KeywordValidator]] + self, keyword_validators: Mapping[str, type[KeywordValidator]] ): super().__init__() self.keyword_validators = keyword_validators diff --git a/openapi_spec_validator/validation/types.py b/openapi_spec_validator/validation/types.py index 90d83ba..aa54c23 100644 --- a/openapi_spec_validator/validation/types.py +++ b/openapi_spec_validator/validation/types.py @@ -1,5 +1,3 @@ -from typing import Type - from openapi_spec_validator.validation.validators import SpecValidator -SpecValidatorType = Type[SpecValidator] +SpecValidatorType = type[SpecValidator] diff --git a/openapi_spec_validator/validation/validators.py b/openapi_spec_validator/validation/validators.py index 397f022..5e5703b 100644 --- a/openapi_spec_validator/validation/validators.py +++ b/openapi_spec_validator/validation/validators.py @@ -1,12 +1,11 @@ """OpenAPI spec validator validation validators module.""" + import logging import warnings +from collections.abc import Iterator +from collections.abc import Mapping from functools import lru_cache -from typing import Iterator -from typing import List -from typing import Mapping from typing import Optional -from typing import Type from typing import cast from jsonschema.exceptions import ValidationError @@ -31,10 +30,10 @@ class SpecValidator: resolver_handlers = default_handlers - keyword_validators: Mapping[str, Type[keywords.KeywordValidator]] = { + keyword_validators: Mapping[str, type[keywords.KeywordValidator]] = { "__root__": keywords.RootValidator, } - root_keywords: List[str] = [] + root_keywords: list[str] = [] schema_validator: Validator = NotImplemented def __init__( diff --git a/openapi_spec_validator/versions/consts.py b/openapi_spec_validator/versions/consts.py index 6b5ea7d..e864595 100644 --- a/openapi_spec_validator/versions/consts.py +++ b/openapi_spec_validator/versions/consts.py @@ -1,5 +1,3 @@ -from typing import List - from openapi_spec_validator.versions.datatypes import SpecVersion OPENAPIV2 = SpecVersion( @@ -20,4 +18,4 @@ minor="1", ) -VERSIONS: List[SpecVersion] = [OPENAPIV2, OPENAPIV30, OPENAPIV31] +VERSIONS: list[SpecVersion] = [OPENAPIV2, OPENAPIV30, OPENAPIV31] diff --git a/openapi_spec_validator/versions/finders.py b/openapi_spec_validator/versions/finders.py index 803cabc..2fc9405 100644 --- a/openapi_spec_validator/versions/finders.py +++ b/openapi_spec_validator/versions/finders.py @@ -1,5 +1,4 @@ from re import compile -from typing import List from jsonschema_path.typing import Schema @@ -10,7 +9,7 @@ class SpecVersionFinder: pattern = compile(r"(?P\d+)\.(?P\d+)(\..*)?") - def __init__(self, versions: List[SpecVersion]) -> None: + def __init__(self, versions: list[SpecVersion]) -> None: self.versions = versions def find(self, spec: Schema) -> SpecVersion: diff --git a/tests/integration/validation/test_exceptions.py b/tests/integration/validation/test_exceptions.py index c8f5961..efdcf03 100644 --- a/tests/integration/validation/test_exceptions.py +++ b/tests/integration/validation/test_exceptions.py @@ -3,7 +3,6 @@ from openapi_spec_validator.validation.exceptions import ( DuplicateOperationIDError, ) -from openapi_spec_validator.validation.exceptions import ExtraParametersError from openapi_spec_validator.validation.exceptions import OpenAPIValidationError from openapi_spec_validator.validation.exceptions import ( UnresolvableParameterError, diff --git a/tests/integration/validation/test_validators.py b/tests/integration/validation/test_validators.py index 305e1f8..d5d64b6 100644 --- a/tests/integration/validation/test_validators.py +++ b/tests/integration/validation/test_validators.py @@ -32,7 +32,7 @@ def test_valid(self, factory, spec_file): validator.validate() - assert validator.is_valid() == True + assert validator.is_valid() @pytest.mark.parametrize( "spec_file", @@ -49,7 +49,7 @@ def test_validation_failed(self, factory, spec_file): with pytest.raises(OpenAPIValidationError): validator.validate() - assert validator.is_valid() == False + assert not validator.is_valid() @pytest.mark.parametrize( "spec_file", @@ -90,7 +90,7 @@ def test_valid(self, factory, spec_file): validator.validate() - assert validator.is_valid() == True + assert validator.is_valid() @pytest.mark.parametrize( "spec_file", @@ -107,7 +107,7 @@ def test_failed(self, factory, spec_file): with pytest.raises(OpenAPIValidationError): validator.validate() - assert validator.is_valid() == False + assert not validator.is_valid() @pytest.mark.parametrize( "spec_file", diff --git a/tox.ini b/tox.ini index 0f99522..ad31b6a 100644 --- a/tox.ini +++ b/tox.ini @@ -7,3 +7,7 @@ deps = -rrequirements_dev.txt commands = python setup.py test + +[flake8] +max-line-length = 79 +extend-ignore = E203,E501,E701