diff --git a/.gitignore b/.gitignore index 93b26b8..89a475d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ __pycache__/ *.py[cod] *$py.class +.pytest_cache/ # C extensions *.so diff --git a/openapi_core/__init__.py b/openapi_core/__init__.py index d00e903..e8e7031 100644 --- a/openapi_core/__init__.py +++ b/openapi_core/__init__.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- + +"""Python 2.7 backward compatibility""" +import openapi_core._python27_patch + """OpenAPI core module""" from openapi_core.shortcuts import ( create_spec, validate_parameters, validate_body, validate_data, diff --git a/openapi_core/_python27_patch.py b/openapi_core/_python27_patch.py new file mode 100644 index 0000000..81fc3df --- /dev/null +++ b/openapi_core/_python27_patch.py @@ -0,0 +1,14 @@ +import functools +try: + from functools import lru_cache + +except ImportError: + from backports.functools_lru_cache import lru_cache + functools.lru_cache = lru_cache + +try: + from functools import partialmethod + +except ImportError: + from backports.functools_partialmethod import partialmethod + functools.partialmethod = partialmethod diff --git a/openapi_core/schema/schemas/models.py b/openapi_core/schema/schemas/models.py index 4e37cde..b783cae 100644 --- a/openapi_core/schema/schemas/models.py +++ b/openapi_core/schema/schemas/models.py @@ -81,7 +81,7 @@ class Schema(object): ) def get_all_required_properties_names(self): - required = self.required.copy() + required = self.required[:] for subschema in self.all_of: subschema_req = subschema.get_all_required_properties() diff --git a/openapi_core/schema/schemas/util.py b/openapi_core/schema/schemas/util.py index 18c0585..337b925 100644 --- a/openapi_core/schema/schemas/util.py +++ b/openapi_core/schema/schemas/util.py @@ -1,10 +1,11 @@ """OpenAPI core schemas util module""" from distutils.util import strtobool from json import dumps +from six import string_types def forcebool(val): - if isinstance(val, str): + if isinstance(val, string_types): val = strtobool(val) return bool(val) diff --git a/openapi_core/validation/util.py b/openapi_core/validation/util.py index bbe0811..62a3cb4 100644 --- a/openapi_core/validation/util.py +++ b/openapi_core/validation/util.py @@ -1,5 +1,21 @@ """OpenAPI core validation util module""" -from yarl import URL +try: + from urllib.parse import urlparse + +except ImportError: + from urlparse import urlparse + + +def is_absolute(url): + return url.startswith('//') or '://' in url + + +def path_qs(url): + pr = urlparse(url) + result = pr.path + if pr.query: + result += '?' + pr.query + return result def get_operation_pattern(server_url, request_url_pattern): @@ -7,6 +23,6 @@ def get_operation_pattern(server_url, request_url_pattern): if server_url[-1] == "/": # operations have to start with a slash, so do not remove it server_url = server_url[:-1] - if URL(server_url).is_absolute(): + if is_absolute(server_url): return request_url_pattern.replace(server_url, "", 1) - return URL(request_url_pattern).path_qs.replace(server_url, "", 1) + return path_qs(request_url_pattern).replace(server_url, "", 1) diff --git a/requirements.txt b/requirements.txt index 6792e19..f13ec83 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ openapi-spec-validator six -yarl<1.2.0 lazy-object-proxy diff --git a/requirements_2.7.txt b/requirements_2.7.txt new file mode 100644 index 0000000..624bfea --- /dev/null +++ b/requirements_2.7.txt @@ -0,0 +1,5 @@ +openapi-spec-validator +six +backports.functools-lru-cache +backports.functools-partialmethod +enum34 diff --git a/setup.py b/setup.py index 839ceae..3bb9b26 100644 --- a/setup.py +++ b/setup.py @@ -53,6 +53,8 @@ init_path = os.path.join('openapi_core', '__init__.py') init_py = read_file(init_path) metadata = get_metadata(init_py) +py27 = '_2.7' if sys.version_info < (3,) else '' + setup( name='openapi-core', @@ -69,11 +71,12 @@ setup( "Topic :: Software Development :: Libraries :: Python Modules", "Operating System :: OS Independent", 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Topic :: Software Development :: Libraries', ], - install_requires=read_requirements('requirements.txt'), + install_requires=read_requirements('requirements{}.txt'.format(py27)), tests_require=read_requirements('requirements_dev.txt'), extras_require={ 'flask': ["werkzeug"],