From 30d0f06a8de8e003e7fe9c18fa50a47f4670fa48 Mon Sep 17 00:00:00 2001 From: p1c2u Date: Mon, 24 May 2021 22:45:04 +0100 Subject: [PATCH] Dataclasses refactor --- openapi_core/casting/schemas/exceptions.py | 8 ++-- openapi_core/contrib/django/requests.py | 14 ++++--- openapi_core/contrib/django/responses.py | 5 ++- openapi_core/contrib/falcon/requests.py | 5 ++- openapi_core/contrib/falcon/responses.py | 5 ++- openapi_core/contrib/flask/requests.py | 6 ++- openapi_core/contrib/flask/responses.py | 5 ++- openapi_core/contrib/requests/requests.py | 6 +-- openapi_core/contrib/requests/responses.py | 4 +- openapi_core/deserializing/exceptions.py | 8 ++-- .../deserializing/parameters/exceptions.py | 6 +-- openapi_core/exceptions.py | 33 +++++++++------- openapi_core/templating/datatypes.py | 10 +++-- .../templating/media_types/exceptions.py | 10 +++-- openapi_core/templating/paths/exceptions.py | 16 ++++---- .../templating/responses/exceptions.py | 10 +++-- openapi_core/templating/responses/finders.py | 2 +- openapi_core/testing/requests.py | 17 +++++--- openapi_core/testing/responses.py | 5 ++- .../unmarshalling/schemas/exceptions.py | 24 ++++++------ openapi_core/validation/datatypes.py | 8 ++-- openapi_core/validation/exceptions.py | 4 +- openapi_core/validation/request/datatypes.py | 39 +++++++++---------- openapi_core/validation/response/datatypes.py | 19 ++++----- requirements.txt | 2 +- setup.cfg | 2 +- .../contrib/flask/test_flask_requests.py | 8 ++-- .../requests/test_requests_requests.py | 13 ++++--- tests/integration/contrib/test_django.py | 17 ++++---- 29 files changed, 177 insertions(+), 134 deletions(-) diff --git a/openapi_core/casting/schemas/exceptions.py b/openapi_core/casting/schemas/exceptions.py index cc10672a..aa50b3f9 100644 --- a/openapi_core/casting/schemas/exceptions.py +++ b/openapi_core/casting/schemas/exceptions.py @@ -1,13 +1,13 @@ -import attr +from dataclasses import dataclass from openapi_core.exceptions import OpenAPIError -@attr.s(hash=True) +@dataclass class CastError(OpenAPIError): """Schema cast operation error""" - value = attr.ib() - type = attr.ib() + value: str + type: str def __str__(self): return "Failed to cast value {value} to type {type}".format( diff --git a/openapi_core/contrib/django/requests.py b/openapi_core/contrib/django/requests.py index b8624bd6..d067ce55 100644 --- a/openapi_core/contrib/django/requests.py +++ b/openapi_core/contrib/django/requests.py @@ -1,8 +1,9 @@ """OpenAPI core contrib django requests module""" import re - from urllib.parse import urljoin +from werkzeug.datastructures import ImmutableMultiDict, Headers + from openapi_core.contrib.django.compat import ( get_request_headers, get_current_scheme_host, ) @@ -43,13 +44,16 @@ def create(cls, request): route = route[:-1] path_pattern = '/' + route + request_headers = get_request_headers(request) path = request.resolver_match and request.resolver_match.kwargs or {} - headers = get_request_headers(request) + query = ImmutableMultiDict(request.GET) + header = Headers(request_headers.items()) + cookie = ImmutableMultiDict(dict(request.COOKIES)) parameters = RequestParameters( path=path, - query=request.GET, - header=list(headers.items()), - cookie=request.COOKIES, + query=query, + header=header, + cookie=cookie, ) current_scheme_host = get_current_scheme_host(request) full_url_pattern = urljoin(current_scheme_host, path_pattern) diff --git a/openapi_core/contrib/django/responses.py b/openapi_core/contrib/django/responses.py index d0e75f79..d32c7566 100644 --- a/openapi_core/contrib/django/responses.py +++ b/openapi_core/contrib/django/responses.py @@ -1,4 +1,6 @@ """OpenAPI core contrib django responses module""" +from werkzeug.datastructures import Headers + from openapi_core.contrib.django.compat import get_response_headers from openapi_core.validation.response.datatypes import OpenAPIResponse @@ -9,9 +11,10 @@ class DjangoOpenAPIResponseFactory: def create(cls, response): mimetype = response["Content-Type"] headers = get_response_headers(response) + header = Headers(headers.items()) return OpenAPIResponse( data=response.content, status_code=response.status_code, - headers=list(headers.items()), + headers=header, mimetype=mimetype, ) diff --git a/openapi_core/contrib/falcon/requests.py b/openapi_core/contrib/falcon/requests.py index 27a5faba..9f6b5292 100644 --- a/openapi_core/contrib/falcon/requests.py +++ b/openapi_core/contrib/falcon/requests.py @@ -1,7 +1,7 @@ """OpenAPI core contrib falcon responses module""" from json import dumps -from werkzeug.datastructures import ImmutableMultiDict +from werkzeug.datastructures import ImmutableMultiDict, Headers from openapi_core.contrib.falcon.compat import get_request_media from openapi_core.validation.request.datatypes import ( @@ -29,11 +29,12 @@ def create(cls, request, default_when_empty={}): mimetype = request.content_type.partition(";")[0] query = ImmutableMultiDict(list(request.params.items())) + header = Headers(request.headers) # Path gets deduced by path finder against spec parameters = RequestParameters( query=query, - header=request.headers, + header=header, cookie=request.cookies, ) url_pattern = request.prefix + request.path diff --git a/openapi_core/contrib/falcon/responses.py b/openapi_core/contrib/falcon/responses.py index b0477956..f99da684 100644 --- a/openapi_core/contrib/falcon/responses.py +++ b/openapi_core/contrib/falcon/responses.py @@ -1,4 +1,6 @@ """OpenAPI core contrib falcon responses module""" +from werkzeug.datastructures import Headers + from openapi_core.contrib.falcon.compat import get_response_text from openapi_core.validation.response.datatypes import OpenAPIResponse @@ -15,10 +17,11 @@ def create(cls, response): mimetype = response.options.default_media_type data = get_response_text(response) + headers = Headers(response.headers) return OpenAPIResponse( data=data, status_code=status_code, - headers=response.headers, + headers=headers, mimetype=mimetype, ) diff --git a/openapi_core/contrib/flask/requests.py b/openapi_core/contrib/flask/requests.py index 7b4ec3bf..6fb9f367 100644 --- a/openapi_core/contrib/flask/requests.py +++ b/openapi_core/contrib/flask/requests.py @@ -1,8 +1,9 @@ """OpenAPI core contrib flask requests module""" import re - from urllib.parse import urljoin +from werkzeug.datastructures import Headers + from openapi_core.validation.request.datatypes import ( RequestParameters, OpenAPIRequest, ) @@ -24,10 +25,11 @@ def create(cls, request): else: path_pattern = cls.path_regex.sub(r'{\1}', request.url_rule.rule) + header = Headers(request.headers) parameters = RequestParameters( path=request.view_args, query=request.args, - header=request.headers, + header=header, cookie=request.cookies, ) full_url_pattern = urljoin(request.host_url, path_pattern) diff --git a/openapi_core/contrib/flask/responses.py b/openapi_core/contrib/flask/responses.py index cb52f5c1..a36a36ac 100644 --- a/openapi_core/contrib/flask/responses.py +++ b/openapi_core/contrib/flask/responses.py @@ -1,4 +1,6 @@ """OpenAPI core contrib flask responses module""" +from werkzeug.datastructures import Headers + from openapi_core.validation.response.datatypes import OpenAPIResponse @@ -6,9 +8,10 @@ class FlaskOpenAPIResponseFactory: @classmethod def create(cls, response): + header = Headers(response.headers) return OpenAPIResponse( data=response.data, status_code=response._status_code, - headers=response.headers, + headers=header, mimetype=response.mimetype, ) diff --git a/openapi_core/contrib/requests/requests.py b/openapi_core/contrib/requests/requests.py index 49c74f5d..7f20f2b9 100644 --- a/openapi_core/contrib/requests/requests.py +++ b/openapi_core/contrib/requests/requests.py @@ -2,7 +2,7 @@ from urllib.parse import urlparse, parse_qs -from werkzeug.datastructures import ImmutableMultiDict +from werkzeug.datastructures import ImmutableMultiDict, Headers from requests import Request from openapi_core.validation.request.datatypes import ( @@ -43,9 +43,9 @@ def create(cls, request): mimetype = request.headers.get('Content-Type') or \ request.headers.get('Accept') - # Headers - request.headers is not an instance of dict + # Headers - request.headers is not an instance of Headers # which is expected - header = dict(request.headers) + header = Headers(dict(request.headers)) # Body # TODO: figure out if request._body_position is relevant diff --git a/openapi_core/contrib/requests/responses.py b/openapi_core/contrib/requests/responses.py index c7d3359e..47725a5e 100644 --- a/openapi_core/contrib/requests/responses.py +++ b/openapi_core/contrib/requests/responses.py @@ -1,4 +1,6 @@ """OpenAPI core contrib requests responses module""" +from werkzeug.datastructures import Headers + from openapi_core.validation.response.datatypes import OpenAPIResponse @@ -7,7 +9,7 @@ class RequestsOpenAPIResponseFactory: @classmethod def create(cls, response): mimetype = response.headers.get('Content-Type') - headers = dict(response.headers) + headers = Headers(dict(response.headers)) return OpenAPIResponse( data=response.content, status_code=response.status_code, diff --git a/openapi_core/deserializing/exceptions.py b/openapi_core/deserializing/exceptions.py index 2ff5774e..b8ae2ed3 100644 --- a/openapi_core/deserializing/exceptions.py +++ b/openapi_core/deserializing/exceptions.py @@ -1,13 +1,13 @@ -import attr +from dataclasses import dataclass from openapi_core.exceptions import OpenAPIError -@attr.s(hash=True) +@dataclass class DeserializeError(OpenAPIError): """Deserialize operation error""" - value = attr.ib() - style = attr.ib() + value: str + style: str def __str__(self): return "Failed to deserialize value {value} with style {style}".format( diff --git a/openapi_core/deserializing/parameters/exceptions.py b/openapi_core/deserializing/parameters/exceptions.py index 6187f2c0..0966d93e 100644 --- a/openapi_core/deserializing/parameters/exceptions.py +++ b/openapi_core/deserializing/parameters/exceptions.py @@ -1,11 +1,11 @@ -import attr +from dataclasses import dataclass from openapi_core.deserializing.exceptions import DeserializeError -@attr.s(hash=True) +@dataclass class EmptyParameterValue(DeserializeError): - name = attr.ib() + name: str def __str__(self): return "Value of parameter cannot be empty: {0}".format(self.name) diff --git a/openapi_core/exceptions.py b/openapi_core/exceptions.py index bdc5eba0..4fcf4d02 100644 --- a/openapi_core/exceptions.py +++ b/openapi_core/exceptions.py @@ -1,5 +1,8 @@ """OpenAPI core exceptions module""" -import attr +from dataclasses import dataclass + +from openapi_core.validation.request.datatypes import OpenAPIRequest +from openapi_core.validation.response.datatypes import OpenAPIResponse class OpenAPIError(Exception): @@ -15,18 +18,18 @@ class MissingHeaderError(OpenAPIHeaderError): pass -@attr.s(hash=True) +@dataclass class MissingHeader(MissingHeaderError): - name = attr.ib() + name: str def __str__(self): return "Missing header (without default value): {0}".format( self.name) -@attr.s(hash=True) +@dataclass class MissingRequiredHeader(MissingHeaderError): - name = attr.ib() + name: str def __str__(self): return "Missing required header: {0}".format(self.name) @@ -41,18 +44,18 @@ class MissingParameterError(OpenAPIParameterError): pass -@attr.s(hash=True) +@dataclass class MissingParameter(MissingParameterError): - name = attr.ib() + name: str def __str__(self): return "Missing parameter (without default value): {0}".format( self.name) -@attr.s(hash=True) +@dataclass class MissingRequiredParameter(MissingParameterError): - name = attr.ib() + name: str def __str__(self): return "Missing required parameter: {0}".format(self.name) @@ -67,17 +70,17 @@ class MissingRequestBodyError(OpenAPIRequestBodyError): pass -@attr.s(hash=True) +@dataclass class MissingRequestBody(MissingRequestBodyError): - request = attr.ib() + request: OpenAPIRequest def __str__(self): return "Missing request body" -@attr.s(hash=True) +@dataclass class MissingRequiredRequestBody(MissingRequestBodyError): - request = attr.ib() + request: OpenAPIRequest def __str__(self): return "Missing required request body" @@ -87,9 +90,9 @@ class OpenAPIResponseError(OpenAPIError): pass -@attr.s(hash=True) +@dataclass class MissingResponseContent(OpenAPIResponseError): - response = attr.ib() + response: OpenAPIResponse def __str__(self): return "Missing response content" diff --git a/openapi_core/templating/datatypes.py b/openapi_core/templating/datatypes.py index 0a03d15d..5aa62d49 100644 --- a/openapi_core/templating/datatypes.py +++ b/openapi_core/templating/datatypes.py @@ -1,10 +1,12 @@ -import attr +from typing import Dict, Optional +from dataclasses import dataclass -@attr.s + +@dataclass class TemplateResult: - pattern = attr.ib(default=None) - variables = attr.ib(default=None) + pattern: Optional[str] = None + variables: Optional[Dict] = None @property def resolved(self): diff --git a/openapi_core/templating/media_types/exceptions.py b/openapi_core/templating/media_types/exceptions.py index aa1240ca..03c429e1 100644 --- a/openapi_core/templating/media_types/exceptions.py +++ b/openapi_core/templating/media_types/exceptions.py @@ -1,4 +1,6 @@ -import attr +from typing import List + +from dataclasses import dataclass from openapi_core.exceptions import OpenAPIError @@ -7,10 +9,10 @@ class MediaTypeFinderError(OpenAPIError): """Media type finder error""" -@attr.s(hash=True) +@dataclass class MediaTypeNotFound(MediaTypeFinderError): - mimetype = attr.ib() - availableMimetypes = attr.ib() + mimetype: str + availableMimetypes: List[str] def __str__(self): return ( diff --git a/openapi_core/templating/paths/exceptions.py b/openapi_core/templating/paths/exceptions.py index 0ed2e7e4..615b9f5e 100644 --- a/openapi_core/templating/paths/exceptions.py +++ b/openapi_core/templating/paths/exceptions.py @@ -1,4 +1,4 @@ -import attr +from dataclasses import dataclass from openapi_core.exceptions import OpenAPIError @@ -7,30 +7,30 @@ class PathError(OpenAPIError): """Path error""" -@attr.s(hash=True) +@dataclass class PathNotFound(PathError): """Find path error""" - url = attr.ib() + url: str def __str__(self): return "Path not found for {0}".format(self.url) -@attr.s(hash=True) +@dataclass class OperationNotFound(PathError): """Find path operation error""" - url = attr.ib() - method = attr.ib() + url: str + method: str def __str__(self): return "Operation {0} not found for {1}".format( self.method, self.url) -@attr.s(hash=True) +@dataclass class ServerNotFound(PathError): """Find server error""" - url = attr.ib() + url: str def __str__(self): return "Server not found for {0}".format(self.url) diff --git a/openapi_core/templating/responses/exceptions.py b/openapi_core/templating/responses/exceptions.py index 3602ae63..1427efc9 100644 --- a/openapi_core/templating/responses/exceptions.py +++ b/openapi_core/templating/responses/exceptions.py @@ -1,4 +1,6 @@ -import attr +from typing import List + +from dataclasses import dataclass from openapi_core.exceptions import OpenAPIError @@ -7,11 +9,11 @@ class ResponseFinderError(OpenAPIError): """Response finder error""" -@attr.s(hash=True) +@dataclass class ResponseNotFound(ResponseFinderError): """Find response error""" - http_status = attr.ib() - responses = attr.ib() + http_status: int + availableresponses: List[str] def __str__(self): return "Unknown response http status: {0}".format( diff --git a/openapi_core/templating/responses/finders.py b/openapi_core/templating/responses/finders.py index 6e5532e9..9518fd90 100644 --- a/openapi_core/templating/responses/finders.py +++ b/openapi_core/templating/responses/finders.py @@ -16,6 +16,6 @@ def find(self, http_status='default'): return self.responses / http_status_range if 'default' not in self.responses: - raise ResponseNotFound(http_status, self.responses) + raise ResponseNotFound(http_status, list(self.responses.keys())) return self.responses / 'default' diff --git a/openapi_core/testing/requests.py b/openapi_core/testing/requests.py index fdde9d61..d7af9495 100644 --- a/openapi_core/testing/requests.py +++ b/openapi_core/testing/requests.py @@ -1,7 +1,7 @@ """OpenAPI core testing requests module""" from urllib.parse import urljoin -from werkzeug.datastructures import ImmutableMultiDict +from werkzeug.datastructures import Headers, ImmutableMultiDict from openapi_core.validation.request.datatypes import ( RequestParameters, OpenAPIRequest, @@ -15,13 +15,18 @@ def create( cls, host_url, method, path, path_pattern=None, args=None, view_args=None, headers=None, cookies=None, data=None, mimetype='application/json'): + path_pattern = path_pattern or path + + path = view_args or {} + query = ImmutableMultiDict(args or {}) + header = Headers(headers or {}) + cookie = ImmutableMultiDict(cookies or {}) parameters = RequestParameters( - path=view_args or {}, - query=ImmutableMultiDict(args or []), - header=headers or {}, - cookie=cookies or {}, + path=path, + query=query, + header=header, + cookie=cookie, ) - path_pattern = path_pattern or path method = method.lower() body = data or '' full_url_pattern = urljoin(host_url, path_pattern) diff --git a/openapi_core/testing/responses.py b/openapi_core/testing/responses.py index 2e19bec6..9eae17eb 100644 --- a/openapi_core/testing/responses.py +++ b/openapi_core/testing/responses.py @@ -1,4 +1,6 @@ """OpenAPI core testing responses module""" +from werkzeug.datastructures import Headers + from openapi_core.validation.response.datatypes import OpenAPIResponse @@ -8,9 +10,10 @@ class MockResponseFactory: def create( cls, data, status_code=200, headers=None, mimetype='application/json'): + headers = Headers(headers or {}) return OpenAPIResponse( data=data, status_code=status_code, - headers=headers or {}, + headers=headers, mimetype=mimetype, ) diff --git a/openapi_core/unmarshalling/schemas/exceptions.py b/openapi_core/unmarshalling/schemas/exceptions.py index 67eede67..20bb63fa 100644 --- a/openapi_core/unmarshalling/schemas/exceptions.py +++ b/openapi_core/unmarshalling/schemas/exceptions.py @@ -1,4 +1,6 @@ -import attr +from typing import List + +from dataclasses import dataclass, field from openapi_core.exceptions import OpenAPIError @@ -18,11 +20,11 @@ class UnmarshallerError(UnmarshalError): pass -@attr.s(hash=True) +@dataclass class InvalidSchemaValue(ValidateError): - value = attr.ib() - type = attr.ib() - schema_errors = attr.ib(factory=tuple) + value: str + type: str + schema_errors: List[Exception] = field(default_factory=list) def __str__(self): return ( @@ -30,12 +32,12 @@ def __str__(self): ).format(value=self.value, type=self.type, errors=self.schema_errors) -@attr.s(hash=True) +@dataclass class InvalidSchemaFormatValue(UnmarshallerError): """Value failed to format with formatter""" - value = attr.ib() - type = attr.ib() - original_exception = attr.ib() + value: str + type: str + original_exception: Exception def __str__(self): return ( @@ -46,10 +48,10 @@ def __str__(self): ) -@attr.s(hash=True) +@dataclass class FormatterNotFoundError(UnmarshallerError): """Formatter not found to unmarshal""" - type_format = attr.ib() + type_format: str def __str__(self): return "Formatter not found for {format} format".format( diff --git a/openapi_core/validation/datatypes.py b/openapi_core/validation/datatypes.py index a5434c25..1eb58b9d 100644 --- a/openapi_core/validation/datatypes.py +++ b/openapi_core/validation/datatypes.py @@ -1,10 +1,12 @@ """OpenAPI core validation datatypes module""" -import attr +from typing import List +from dataclasses import dataclass -@attr.s + +@dataclass class BaseValidationResult: - errors = attr.ib(factory=list) + errors: List[Exception] def raise_for_errors(self): for error in self.errors: diff --git a/openapi_core/validation/exceptions.py b/openapi_core/validation/exceptions.py index 1791fa0e..004068f1 100644 --- a/openapi_core/validation/exceptions.py +++ b/openapi_core/validation/exceptions.py @@ -1,5 +1,5 @@ """OpenAPI core validation exceptions module""" -import attr +from dataclasses import dataclass from openapi_core.exceptions import OpenAPIError @@ -8,7 +8,7 @@ class ValidationError(OpenAPIError): pass -@attr.s(hash=True) +@dataclass class InvalidSecurity(ValidationError): def __str__(self): diff --git a/openapi_core/validation/request/datatypes.py b/openapi_core/validation/request/datatypes.py index 9c0a07b8..f93feb0f 100644 --- a/openapi_core/validation/request/datatypes.py +++ b/openapi_core/validation/request/datatypes.py @@ -1,11 +1,13 @@ """OpenAPI core validation request datatypes module""" -import attr +from typing import Dict, Optional + +from dataclasses import dataclass, field from werkzeug.datastructures import ImmutableMultiDict, Headers from openapi_core.validation.datatypes import BaseValidationResult -@attr.s +@dataclass class RequestParameters: """OpenAPI request parameters dataclass. @@ -15,20 +17,20 @@ class RequestParameters: header Request headers as Headers. cookie - Request cookies as dict. + Request cookies as MultiDict. path Path parameters as dict. Gets resolved against spec if empty. """ - query = attr.ib(factory=ImmutableMultiDict) - header = attr.ib(factory=Headers, converter=Headers) - cookie = attr.ib(factory=dict) - path = attr.ib(factory=dict) + query: ImmutableMultiDict = field(default_factory=ImmutableMultiDict) + header: Headers = field(default_factory=Headers) + cookie: ImmutableMultiDict = field(default_factory=ImmutableMultiDict) + path: Dict = field(default_factory=dict) def __getitem__(self, location): return getattr(self, location) -@attr.s +@dataclass class OpenAPIRequest: """OpenAPI request dataclass. @@ -51,18 +53,15 @@ class OpenAPIRequest: the mimetype would be "text/html". """ - full_url_pattern = attr.ib() - method = attr.ib() - body = attr.ib() - mimetype = attr.ib() - parameters = attr.ib(factory=RequestParameters) + full_url_pattern: str + method: str + body: str + mimetype: str + parameters: RequestParameters = field(default_factory=RequestParameters) -@attr.s +@dataclass class RequestValidationResult(BaseValidationResult): - body = attr.ib(default=None) - parameters = attr.ib(factory=RequestParameters) - security = attr.ib(default=None) - server = attr.ib(default=None) - path = attr.ib(default=None) - operation = attr.ib(default=None) + body: Optional[str] = None + parameters: RequestParameters = field(default_factory=RequestParameters) + security: Optional[Dict[str, str]] = None diff --git a/openapi_core/validation/response/datatypes.py b/openapi_core/validation/response/datatypes.py index ea58a0c7..3fa06fa2 100644 --- a/openapi_core/validation/response/datatypes.py +++ b/openapi_core/validation/response/datatypes.py @@ -1,11 +1,12 @@ """OpenAPI core validation response datatypes module""" -import attr +from typing import Dict, Optional +from dataclasses import dataclass, field from werkzeug.datastructures import Headers from openapi_core.validation.datatypes import BaseValidationResult -@attr.s +@dataclass class OpenAPIResponse: """OpenAPI request dataclass. @@ -19,13 +20,13 @@ class OpenAPIResponse: mimetype Lowercase content type without charset. """ - data = attr.ib() - status_code = attr.ib() - mimetype = attr.ib() - headers = attr.ib(factory=Headers, converter=Headers) + data: str + status_code: int + mimetype: str + headers: Headers = field(default_factory=Headers) -@attr.s +@dataclass class ResponseValidationResult(BaseValidationResult): - data = attr.ib(default=None) - headers = attr.ib(factory=dict) + data: Optional[str] = None + headers: Dict = field(default_factory=dict) diff --git a/requirements.txt b/requirements.txt index 75a2cf77..3542d48a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,6 @@ isodate==0.6.0 dictpath==0.1.3 openapi-spec-validator openapi-schema-validator -attrs parse==1.14.0 more-itertools>=5.0.0 +dataclasses==0.8; python_version=="3.6" diff --git a/setup.cfg b/setup.cfg index 67f4cc8b..7de244ae 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,10 +29,10 @@ install_requires = dictpath openapi-spec-validator openapi-schema-validator - attrs werkzeug parse more-itertools + dataclasses; python_version=="3.6" tests_require = pytest>=5.0.0 pytest-flake8 diff --git a/tests/integration/contrib/flask/test_flask_requests.py b/tests/integration/contrib/flask/test_flask_requests.py index 5de5070f..64d3f8cc 100644 --- a/tests/integration/contrib/flask/test_flask_requests.py +++ b/tests/integration/contrib/flask/test_flask_requests.py @@ -1,6 +1,6 @@ from urllib.parse import urljoin -from werkzeug.datastructures import EnvironHeaders, ImmutableMultiDict +from werkzeug.datastructures import Headers, ImmutableMultiDict from openapi_core.contrib.flask import FlaskOpenAPIRequest from openapi_core.validation.request.datatypes import RequestParameters @@ -15,7 +15,7 @@ def test_simple(self, request_factory, request): path = {} query = ImmutableMultiDict([]) - headers = EnvironHeaders(request.environ) + headers = Headers(request.headers) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, @@ -39,7 +39,7 @@ def test_multiple_values(self, request_factory, request): query = ImmutableMultiDict([ ('a', 'b'), ('a', 'c'), ]) - headers = EnvironHeaders(request.environ) + headers = Headers(request.headers) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, @@ -60,7 +60,7 @@ def test_url_rule(self, request_factory, request): path = {'id': 12} query = ImmutableMultiDict([]) - headers = EnvironHeaders(request.environ) + headers = Headers(request.headers) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, diff --git a/tests/integration/contrib/requests/test_requests_requests.py b/tests/integration/contrib/requests/test_requests_requests.py index 2ea214e3..d6f92d43 100644 --- a/tests/integration/contrib/requests/test_requests_requests.py +++ b/tests/integration/contrib/requests/test_requests_requests.py @@ -4,6 +4,9 @@ from openapi_core.validation.request.datatypes import RequestParameters +from werkzeug.datastructures import Headers + + class TestRequestsOpenAPIRequest: def test_simple(self, request_factory, request): @@ -13,7 +16,7 @@ def test_simple(self, request_factory, request): path = {} query = ImmutableMultiDict([]) - headers = request.headers + headers = Headers(dict(request.headers)) cookies = {} prepared = request.prepare() assert openapi_request.parameters == RequestParameters( @@ -37,7 +40,7 @@ def test_multiple_values(self, request_factory, request): query = ImmutableMultiDict([ ('a', 'b'), ('a', 'c'), ]) - headers = request.headers + headers = Headers(dict(request.headers)) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, @@ -59,9 +62,9 @@ def test_url_rule(self, request_factory, request): # empty when not bound to spec path = {} query = ImmutableMultiDict([]) - headers = ( - ('Content-Type', 'application/json'), - ) + headers = Headers({ + 'Content-Type': 'application/json', + }) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, diff --git a/tests/integration/contrib/test_django.py b/tests/integration/contrib/test_django.py index 76bf5f84..55e5d443 100644 --- a/tests/integration/contrib/test_django.py +++ b/tests/integration/contrib/test_django.py @@ -1,6 +1,7 @@ import sys import pytest +from werkzeug.datastructures import Headers from openapi_core.contrib.django import ( DjangoOpenAPIRequest, DjangoOpenAPIResponse, @@ -71,9 +72,9 @@ def test_no_resolver(self, request_factory): path = {} query = {} - headers = { + headers = Headers({ 'Cookie': '', - } + }) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, @@ -96,9 +97,9 @@ def test_simple(self, request_factory): path = {} query = {} - headers = { + headers = Headers({ 'Cookie': '', - } + }) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, @@ -123,9 +124,9 @@ def test_url_rule(self, request_factory): 'object_id': '1', } query = {} - headers = { + headers = Headers({ 'Cookie': '', - } + }) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, @@ -148,9 +149,9 @@ def test_url_regexp_pattern(self, request_factory): path = {} query = {} - headers = { + headers = Headers({ 'Cookie': '', - } + }) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy