diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 863f531f..00000000 --- a/.appveyor.yml +++ /dev/null @@ -1,33 +0,0 @@ -version: '{build}' -image: Visual Studio 2017 - -environment: - matrix: - # Available python versions and their locations on https://www.appveyor.com/docs/build-environment/#python - - PYTHON: C:\Python27-x64 - TOXENV: py27 - - PYTHON: C:\Python36-x64 - TOXENV: py36 - - PYTHON: C:\Python37-x64 - TOXENV: py37 - -build: off - -install: -- cmd: SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH% -- cmd: pip install tox - -before_test: -- cmd: python --version -- cmd: pip --version -- cmd: tox --version - -test_script: -- cmd: >- - tox - -# Uncomment the following block to enable remote desktop debugging (https://www.appveyor.com/docs/how-to/rdp-to-build-worker/) -# init: -# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) -# on_failure: -# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78f339c4..0a2848e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,14 +3,13 @@ name: build on: push jobs: tox: - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: tox: - - py27 - - py36 - - py37 + - py38 + - py310 - pre-commit - mypy - docs @@ -19,6 +18,6 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: - python-version: 3.7 + python-version: 3.10 - run: pip install tox - run: tox -e ${{ matrix.tox }} diff --git a/README.rst b/README.rst index f4b90319..4b754fae 100644 --- a/README.rst +++ b/README.rst @@ -64,7 +64,7 @@ Setup tox # Install git pre-commit hooks - .tox/py27/bin/pre-commit install + .tox/py310/bin/pre-commit install Contributing diff --git a/bravado_core/_compat.py b/bravado_core/_compat.py index 25278ad4..e3ca62ea 100644 --- a/bravado_core/_compat.py +++ b/bravado_core/_compat.py @@ -1,20 +1,5 @@ # -*- coding: utf-8 -*- -import sys - - -if sys.version_info[0] == 2: # pragma: no cover # py2 - from functools32 import wraps # noqa: F401 -else: # pragma: no cover # py3+ - from functools import wraps # noqa: F401 - - -try: - from collections.abc import Mapping # noqa: F401 # pragma: no cover # py3.3+ -except ImportError: # pragma: no cover - from collections import Mapping # noqa: F401 # py3.2 or older - - -if sys.version_info[0:2] <= (3, 4): # pragma: no cover # py3.4 or older - from inspect import getargspec as get_function_spec # noqa: F401 -else: # pragma: no cover # py3.5+ - from inspect import getfullargspec as get_function_spec # noqa: F401 +# TODO: remove this module entirely. +from collections.abc import Mapping # noqa: F401 +from functools import wraps # noqa: F401 +from inspect import getfullargspec as get_function_spec # noqa: F401 diff --git a/bravado_core/_compat_typing.py b/bravado_core/_compat_typing.py index e8cf3bc3..be9b9640 100644 --- a/bravado_core/_compat_typing.py +++ b/bravado_core/_compat_typing.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- import typing + from mypy_extensions import Arg try: diff --git a/bravado_core/_decorators.py b/bravado_core/_decorators.py index 121cd686..f35dc298 100644 --- a/bravado_core/_decorators.py +++ b/bravado_core/_decorators.py @@ -54,7 +54,7 @@ def wrapper(value): return value return func(value) - return wrapper + return wrapper # type: ignore return external_wrapper @@ -82,4 +82,4 @@ def wrapper(*args, **kwargs): except RecursiveCallException: return lambda *new_args, **new_kawrgs: func(*args, **kwargs)(*new_args, **new_kawrgs) - return wrapper + return wrapper # type: ignore diff --git a/bravado_core/exception.py b/bravado_core/exception.py index 3905e9af..4244cc88 100644 --- a/bravado_core/exception.py +++ b/bravado_core/exception.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- import sys +import typing import six -import typing if getattr(typing, 'TYPE_CHECKING', False): diff --git a/bravado_core/formatter.py b/bravado_core/formatter.py index 0a79db87..7347bf08 100644 --- a/bravado_core/formatter.py +++ b/bravado_core/formatter.py @@ -7,11 +7,11 @@ import base64 import functools +import typing import dateutil.parser import pytz import six -import typing from bravado_core import schema from bravado_core.exception import SwaggerMappingError diff --git a/bravado_core/marshal.py b/bravado_core/marshal.py index ce390183..6320830f 100644 --- a/bravado_core/marshal.py +++ b/bravado_core/marshal.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- +import typing import warnings from functools import partial -import typing from six import iteritems from bravado_core import _decorators diff --git a/bravado_core/model.py b/bravado_core/model.py index 781f6c26..c124f736 100644 --- a/bravado_core/model.py +++ b/bravado_core/model.py @@ -3,10 +3,10 @@ import functools import logging import re +import typing from copy import deepcopy from warnings import warn -import typing from six import add_metaclass from six import iteritems from six import string_types diff --git a/bravado_core/operation.py b/bravado_core/operation.py index 2c859f56..e44d5f19 100644 --- a/bravado_core/operation.py +++ b/bravado_core/operation.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import logging - import typing + from six import iteritems from six import PY2 diff --git a/bravado_core/param.py b/bravado_core/param.py index bf3b9aa0..08758bb9 100644 --- a/bravado_core/param.py +++ b/bravado_core/param.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- import logging +import typing from functools import partial import simplejson as json import six -import typing from six.moves.urllib.parse import quote from bravado_core import schema diff --git a/bravado_core/resource.py b/bravado_core/resource.py index b0c937a7..259c3210 100644 --- a/bravado_core/resource.py +++ b/bravado_core/resource.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- import logging +import typing from collections import defaultdict from copy import deepcopy from itertools import chain -import typing from six import iteritems from six import iterkeys from six import PY2 diff --git a/bravado_core/schema.py b/bravado_core/schema.py index af88fb37..66c00102 100644 --- a/bravado_core/schema.py +++ b/bravado_core/schema.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import copy - import typing + from six import iteritems from six import string_types diff --git a/bravado_core/security_definition.py b/bravado_core/security_definition.py index 4475e95e..656d369f 100644 --- a/bravado_core/security_definition.py +++ b/bravado_core/security_definition.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- import logging -from copy import deepcopy - import typing +from copy import deepcopy if getattr(typing, 'TYPE_CHECKING', False): diff --git a/bravado_core/security_requirement.py b/bravado_core/security_requirement.py index 438a1132..144028cd 100644 --- a/bravado_core/security_requirement.py +++ b/bravado_core/security_requirement.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- import logging +import typing import six -import typing from bravado_core.exception import SwaggerSchemaError diff --git a/bravado_core/spec.py b/bravado_core/spec.py index 531f7764..00ba35b5 100644 --- a/bravado_core/spec.py +++ b/bravado_core/spec.py @@ -2,12 +2,12 @@ import json import logging import os.path +import typing import warnings from copy import deepcopy from itertools import chain import requests -import typing import yaml from jsonref import JsonRef from jsonschema import FormatChecker @@ -410,7 +410,7 @@ def _force_deref(self, ref_dict): # Restore attached resolution scope before resolving since the # resolver doesn't have a traversal history (accumulated scope_stack) # when asked to resolve. - with in_scope(self.resolver, ref_dict): + with in_scope(self.resolver, ref_dict): # type: ignore reference_value = ref_dict['$ref'] # type: ignore _, target = self.resolver.resolve(reference_value) return target diff --git a/bravado_core/swagger20_validator.py b/bravado_core/swagger20_validator.py index 1b761887..c69bf4a1 100644 --- a/bravado_core/swagger20_validator.py +++ b/bravado_core/swagger20_validator.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import functools - import typing + from jsonschema import FormatChecker from jsonschema import RefResolver from jsonschema import validators diff --git a/bravado_core/unmarshal.py b/bravado_core/unmarshal.py index 4ec6cd15..2c0bf415 100644 --- a/bravado_core/unmarshal.py +++ b/bravado_core/unmarshal.py @@ -5,10 +5,10 @@ Unmarshaling is the operation that converts a "JSON" object into its python representation. The operation should also take care of converting types accordingly to the defined :class:`bravado_core.formatter.SwaggerFormat`s. """ +import typing import warnings from functools import partial -import typing from six import iteritems from bravado_core import _decorators diff --git a/bravado_core/util.py b/bravado_core/util.py index 1c8be57a..c6684972 100644 --- a/bravado_core/util.py +++ b/bravado_core/util.py @@ -2,9 +2,9 @@ import copy import inspect import re - import typing from enum import Enum + from six import iteritems from six import iterkeys diff --git a/bravado_core/validate.py b/bravado_core/validate.py index a58094de..89e7ffc2 100644 --- a/bravado_core/validate.py +++ b/bravado_core/validate.py @@ -5,9 +5,9 @@ customize the behavior. """ import sys +import typing import jsonschema -import typing from six import itervalues from six import reraise diff --git a/mypy.ini b/mypy.ini index b0077d13..e4aca620 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,6 +1,6 @@ [mypy] ignore_missing_imports = True -python_version = 2.7 +python_version = 3.10 strict_optional = True warn_redundant_casts = True disallow_untyped_calls = True diff --git a/requirements-dev.txt b/requirements-dev.txt index bc696d5f..ed986a81 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,8 +1,16 @@ -# Unit test dependencies +# TODO: avoids an issue with hanging forever in tests (CORESERV-12009). +jsonschema<4 mock -mypy-extensions; python_version>='3.5' -mypy; python_version>='3.5' +mypy +mypy-extensions pre-commit +pytest pytest-benchmark[histogram] pytest-cov -pytest<4.7 # need support for Python 2.7, see https://docs.pytest.org/en/latest/py27-py34-deprecation.html +types-mock +types-python-dateutil +types-pytz +types-pyyaml +types-requests +types-simplejson +types-six diff --git a/setup.py b/setup.py index d072d1f9..3a1320ef 100755 --- a/setup.py +++ b/setup.py @@ -3,28 +3,11 @@ # Copyright (c) 2013, Digium, Inc. # Copyright (c) 2014-2015, Yelp, Inc. import os -import sys from setuptools import setup import bravado_core -install_requires = [ - "jsonref", - "jsonschema[format]>=2.5.1", - "python-dateutil", - "pyyaml", - 'requests', - "simplejson", - "six", - "swagger-spec-validator>=2.0.1", - "pytz", - "msgpack>=0.5.2", -] - -# pyrsistent dropped python2 support in 0.17.0 -if sys.version_info < (3, 5): - install_requires.append('pyrsistent<0.17') setup( name="bravado-core", @@ -37,6 +20,7 @@ "README.rst", ), ).read(), + long_description_content_type='text/markdown', author="Digium, Inc. and Yelp, Inc.", author_email="opensource+bravado-core@yelp.com", url="https://github.com/Yelp/bravado-core", @@ -47,20 +31,26 @@ "Topic :: Software Development :: Libraries :: Python Modules", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + ], + install_requires=[ + "jsonref", + "jsonschema[format]>=2.5.1", + "python-dateutil", + "pyyaml", + 'requests', + "simplejson", + "six", + "swagger-spec-validator>=2.0.1", + "pytz", + "msgpack>=0.5.2", ], - install_requires=install_requires, package_data={ 'bravado_core': ['py.typed'], }, - # https://mypy.readthedocs.io/en/latest/installed_packages.html - zip_safe=False, - extras_require={ - ':python_version<"3.5"': ['typing'], - ':python_version<"3.4"': ['enum34'], - ':python_version<"3.2"': ['functools32'], - }, - python_requires='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,!=3.5.0', + python_requires='>=3.8', ) diff --git a/tests/model/create_model_repr_test.py b/tests/model/create_model_repr_test.py index c872ae8b..e1b3799f 100644 --- a/tests/model/create_model_repr_test.py +++ b/tests/model/create_model_repr_test.py @@ -1,8 +1,4 @@ # -*- coding: utf-8 -*- -import pytest -import six - - def test_success(user): expected = "User(email=None, firstName=None, id=None, lastName=None, password=None, phone=None, userStatus=None, username=None)" # noqa assert expected == repr(user) @@ -13,15 +9,7 @@ def test_allOf(cat, cat_spec, cat_swagger_spec): assert expected == repr(cat) -@pytest.mark.skipif(six.PY3, reason="py2 has ascii default strings") -def test_unicode_py2(user): - user.firstName = 'Ümlaut' - expected = r"User(email=None, firstName='\xc3\x9cmlaut', id=None, lastName=None, password=None, phone=None, userStatus=None, username=None)" # noqa - assert expected == repr(user) - - -@pytest.mark.skipif(six.PY2, reason="py3 has unicode default strings") -def test_unicode_py3(user): +def test_unicode(user): user.firstName = 'Ümlaut' expected = "User(email=None, firstName='Ümlaut', id=None, lastName=None, password=None, phone=None, userStatus=None, username=None)" # noqa assert expected == repr(user) diff --git a/tests/spec/Spec/deref_flattened_spec_test.py b/tests/spec/Spec/deref_flattened_spec_test.py index 68c86c29..23b6e23e 100644 --- a/tests/spec/Spec/deref_flattened_spec_test.py +++ b/tests/spec/Spec/deref_flattened_spec_test.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- +from typing import Any + from six import iterkeys from six import itervalues -from typing import Any from bravado_core.schema import is_dict_like from bravado_core.schema import is_list_like diff --git a/tests/spec/build_http_handlers_test.py b/tests/spec/build_http_handlers_test.py index 55d9ca80..269c360b 100644 --- a/tests/spec/build_http_handlers_test.py +++ b/tests/spec/build_http_handlers_test.py @@ -10,10 +10,6 @@ def _build_http_client(content): - # required for py27/py34 compatibility - if hasattr(content, 'decode'): - content = content.decode("utf-8") - mock_response = mock.Mock() mock_response.content = StringIO(content) mock_response.json.side_effect = lambda *args, **kwargs: json.loads(content) diff --git a/tox.ini b/tox.ini index ce08dbb2..8fef2199 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ filterwarnings = ignore:.*will be deprecated in the next major release. Please use the more general entry-point offered in.*:DeprecationWarning [tox] -envlist = py27, py36, py37, mypy, pre-commit +envlist = py38, py310, mypy, pre-commit [testenv] deps = @@ -12,7 +12,7 @@ commands = python -m pytest --cov --capture=no --benchmark-skip {posargs:tests} [testenv:benchmark] -basepython = python3.7 +basepython = /usr/bin/python3.10 deps = -rrequirements-dev.txt commands = @@ -23,7 +23,7 @@ commands = --benchmark-histogram=.benchmarks/benchmark [testenv:mypy] -basepython = python3.7 +basepython = /usr/bin/python3.10 commands = mypy bravado_core tests @@ -39,7 +39,7 @@ exclude = .svn,CVS,.bzr,.hg,.git,__pycache__,.tox,docs,virtualenv_run max_line_length = 130 [testenv:pre-commit] -basepython = python2.7 +basepython = /usr/bin/python3.10 deps = pre-commit>0.12.0 setenv =