From e6a31dd99b1c7cc182f09f90e1548a1c510b6f67 Mon Sep 17 00:00:00 2001 From: "Terence D. Honles" Date: Tue, 19 Oct 2021 11:21:11 +0200 Subject: [PATCH 1/2] Pin to jsonschema<4 and update config for testing on recent Python versions --- .appveyor.yml | 6 +++++- .github/workflows/ci.yml | 26 ++++++++++++++++++++++---- bravado_core/_decorators.py | 4 ++-- mypy.ini | 3 +++ requirements-dev.txt | 4 +--- requirements-typing.txt | 14 ++++++++++++++ setup.py | 5 ++++- tox.ini | 11 +++++++---- 8 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 requirements-typing.txt diff --git a/.appveyor.yml b/.appveyor.yml index 863f531f..48b71f1b 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,5 +1,5 @@ version: '{build}' -image: Visual Studio 2017 +image: Visual Studio 2019 environment: matrix: @@ -10,6 +10,10 @@ environment: TOXENV: py36 - PYTHON: C:\Python37-x64 TOXENV: py37 + - PYTHON: C:\Python38-x64 + TOXENV: py38 + - PYTHON: C:\Python39-x64 + TOXENV: py39 build: off diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78f339c4..1cc8ad1b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,15 +2,33 @@ name: build on: push jobs: + pytest: + runs-on: ubuntu-18.04 + strategy: + fail-fast: false + matrix: + python-version: + - '2.7' + - '3.6' + - '3.7' + - '3.8' + - '3.9' + - '3.10' + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - run: pip install tox + - run: | + tox -e py$(tr -d "." <<<"${{ matrix.python-version }}") + tox: runs-on: ubuntu-18.04 strategy: fail-fast: false matrix: tox: - - py27 - - py36 - - py37 - pre-commit - mypy - docs @@ -19,6 +37,6 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: - python-version: 3.7 + python-version: '3.9' - run: pip install tox - run: tox -e ${{ matrix.tox }} 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/mypy.ini b/mypy.ini index b0077d13..132377fc 100644 --- a/mypy.ini +++ b/mypy.ini @@ -6,6 +6,9 @@ warn_redundant_casts = True disallow_untyped_calls = True check_untyped_defs = True disallow_untyped_defs = True +pretty = True +show_error_codes = True +show_error_context = True # # This is needed to allow gradual typing of the library # # Remove the exceptions defined below once the module is completely typed diff --git a/requirements-dev.txt b/requirements-dev.txt index bc696d5f..cd1a0a89 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,8 +1,6 @@ # Unit test dependencies mock -mypy-extensions; python_version>='3.5' -mypy; python_version>='3.5' 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 diff --git a/requirements-typing.txt b/requirements-typing.txt new file mode 100644 index 00000000..ea1fc997 --- /dev/null +++ b/requirements-typing.txt @@ -0,0 +1,14 @@ +# mypy dependencies +mypy-extensions +mypy[python2] +# Restrict pytest to a version which does not publish types which are +# in Python3 format and will break on Python2. +pytest<6 +types-enum34 +# Restrict types-mock to a version which supports Python2 +types-mock==0.1.5 +types-python-dateutil +types-pytz +types-PyYAML +types-simplejson +types-six diff --git a/setup.py b/setup.py index e4fef594..675557ed 100755 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ install_requires = [ "jsonref", - "jsonschema[format]>=2.5.1", + "jsonschema[format]>=2.5.1,<4.0.0", "python-dateutil", "pyyaml", "simplejson", @@ -49,6 +49,9 @@ "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", ], install_requires=install_requires, package_data={ diff --git a/tox.ini b/tox.ini index ce08dbb2..54d37a05 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 = py27, py3{6,7,8,9,10}, 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 = python3.9 deps = -rrequirements-dev.txt commands = @@ -23,9 +23,12 @@ commands = --benchmark-histogram=.benchmarks/benchmark [testenv:mypy] -basepython = python3.7 +basepython = python3.9 +deps = + -rrequirements-dev.txt + -rrequirements-typing.txt commands = - mypy bravado_core tests + mypy bravado_core tests {posargs} [testenv:docs] deps = From 9f1280b70f63f9c7da5fc3aac7e7bb4d09d4938b Mon Sep 17 00:00:00 2001 From: "Terence D. Honles" Date: Tue, 19 Oct 2021 11:50:08 +0200 Subject: [PATCH 2/2] Update `check_object_deepcopy` - To report more than `` - To properly exclude `str` and `unicode` on Python3 and Python2 respectively. - To exclude `bool` and `bytes` which are also immutable - To log types of the offending objects in case they need to be special cased in the future. --- tests/conftest.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 8126277f..a12c3924 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,8 +7,10 @@ import simplejson as json import yaml from mock import Mock +from six import binary_type from six import iteritems from six import iterkeys +from six import text_type from six.moves.urllib import parse as urlparse from six.moves.urllib.request import pathname2url from six.moves.urllib.request import url2pathname @@ -302,12 +304,15 @@ def check_object_deepcopy(obj): ) if id(getattr(obj, attr_name, None)) == id(getattr(obj_copy, attr_name, None)) } - assert not any( + # This is an `any` check, but it will save the offending values and allow pytest to report them + immutable_types = (type(None), bool, binary_type, text_type, tuple) + assert not { + attr_name: (attr_value, type(attr_value)) + for attr_name, attr_value in iteritems(attributes_with_same_id) # If `attr_name: attr_value` is in attributes_with_same_id then attr_value id did not change # after deepcopy. As immutable types do not create new instances for deepcopy we need to ensure # that all the occurrences of "same-id" are related to immutable types. - not isinstance(attr_value, (type(None), str, tuple)) - for attr_name, attr_value in iteritems(attributes_with_same_id) - ) + if not isinstance(attr_value, immutable_types) + } return obj_copy