From 1ffda5c48d6ffc0c5cc93bb0130b27dee38a728b Mon Sep 17 00:00:00 2001 From: Brian Rue Date: Thu, 23 Feb 2023 13:35:59 -0800 Subject: [PATCH] - Add python versions, update and refine framework versions - Fix tests so that tests containing py3 syntax are skipped when running on py2 - Update CI matrix, get CI passing on full matrix --- .github/workflows/ci.yml | 322 +++++++++----------- rollbar/test/__init__.py | 22 +- rollbar/test/asgi_tests/test_integration.py | 6 + rollbar/test/test_rollbar.py | 4 +- rollbar/test/test_serializable_transform.py | 9 +- rollbar/test/test_shortener_transform.py | 2 + rollbar/test/twisted_tests/test_twisted.py | 4 +- setup.py | 4 +- 8 files changed, 188 insertions(+), 185 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd042284..04373c7c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,198 +12,166 @@ jobs: runs-on: ubuntu-18.04 strategy: matrix: - python-version: [2.7, 3.4, 3.5, 3.6, 3.7, 3.8] + python-version: [2.7, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, '3.10', 3.11] framework: - - FLASK_VERSION=0.10.1 Werkzeug\>=0.7,\<1.0 - - FLASK_VERSION=0.11.1 Werkzeug\>=0.7,\<1.0 - - FLASK_VERSION=0.12.4 Werkzeug\>=0.7,\<1.0 - - FLASK_VERSION=1.0.2 - - TWISTED_VERSION=15.5.0 treq==15.1.0 zope.interface==4.1.3 - - TWISTED_VERSION=16.1.0 treq==16.12.0 zope.interface==4.1.3 - - TWISTED_VERSION=16.2.0 treq==16.12.0 zope.interface==4.1.3 - - TWISTED_VERSION=16.3.0 treq==16.12.0 zope.interface==4.2.0 - - TWISTED_VERSION=16.4.0 treq==16.12.0 zope.interface==4.5.0 - - TWISTED_VERSION=16.5.0 treq==16.12.0 zope.interface==4.5.0 - - TWISTED_VERSION=16.6.0 treq==16.12.0 zope.interface==4.5.0 - - TWISTED_VERSION=17.1.0 treq==16.12.0 zope.interface==4.5.0 + - FLASK_VERSION=0.12.5 Werkzeug\>=0.7,\<1.0 + - FLASK_VERSION=1.1.4 + - FLASK_VERSION=2.2.3 - DJANGO_VERSION=1.11.29 - - DJANGO_VERSION=2.0.13 - - DJANGO_VERSION=2.1.15 - - DJANGO_VERSION=2.2.26 - - DJANGO_VERSION=3.0.14 - - DJANGO_VERSION=3.1.14 - - DJANGO_VERSION=3.2.11 - - DJANGO_VERSION=4.0.1 - - PYRAMID_VERSION=1.9.2 - - PYRAMID_VERSION=1.10.4 - - STARLETTE_VERSION=0.12.12 httpx==0.18.1 python-multipart==0.0.5 + - DJANGO_VERSION=2.2.28 + - DJANGO_VERSION=3.2.18 + - DJANGO_VERSION=4.0.10 + - DJANGO_VERSION=4.1.7 + - TWISTED_VERSION=17.1.0 treq==16.12.0 zope.interface==4.5.0 + - TWISTED_VERSION=20.3.0 + - TWISTED_VERSION=21.7.0 + - TWISTED_VERSION=22.10.0 + - PYRAMID_VERSION=1.10.8 - STARLETTE_VERSION=0.12.13 httpx==0.18.1 python-multipart==0.0.5 - STARLETTE_VERSION=0.14.2 httpx==0.18.1 python-multipart==0.0.5 - FASTAPI_VERSION=0.40.0 httpx==0.18.1 python-multipart==0.0.5 - FASTAPI_VERSION=0.50.0 httpx==0.18.1 python-multipart==0.0.5 - FASTAPI_VERSION=0.63.0 httpx==0.18.1 python-multipart==0.0.5 exclude: - - python-version: 2.7 - framework: DJANGO_VERSION=2.0.13 - - python-version: 2.7 - framework: DJANGO_VERSION=2.1.15 - - python-version: 2.7 - framework: DJANGO_VERSION=2.2.26 - - python-version: 2.7 - framework: DJANGO_VERSION=3.0.14 - - python-version: 2.7 - framework: DJANGO_VERSION=3.1.14 - - python-version: 2.7 - framework: DJANGO_VERSION=3.2.11 - - python-version: 2.7 - framework: DJANGO_VERSION=4.0.1 - - python-version: 3.4 - framework: DJANGO_VERSION=2.1.15 - - python-version: 3.4 - framework: DJANGO_VERSION=2.2.26 - - python-version: 3.4 - framework: DJANGO_VERSION=3.0.14 - - python-version: 3.4 - framework: DJANGO_VERSION=3.1.14 - - python-version: 3.4 - framework: DJANGO_VERSION=3.2.11 - - python-version: 3.4 - framework: DJANGO_VERSION=4.0.1 - - python-version: 3.5 - framework: DJANGO_VERSION=3.0.14 - - python-version: 3.5 - framework: DJANGO_VERSION=3.1.14 - - python-version: 3.5 - framework: DJANGO_VERSION=3.2.11 - - python-version: 3.5 - framework: DJANGO_VERSION=4.0.1 - - python-version: 3.6 - framework: DJANGO_VERSION=4.0.1 - - python-version: 3.7 - framework: DJANGO_VERSION=4.0.1 - - python-version: 3.8 - framework: DJANGO_VERSION=1.11.29 - - python-version: 3.8 - framework: DJANGO_VERSION=2.0.13 - - python-version: 3.8 - framework: DJANGO_VERSION=2.1.15 - - # twisted/treq setup.py allows: - # Twisted < 18.7.0 on python < 3.7 - # Twisted >= 18.7.0 on python >= 3.7 - # So we put twisted < 18.x in the matrix - # and disallow python 3.7 and 3.8 here. - - python-version: 3.7 - framework: TWISTED_VERSION=15.5.0 treq==15.1.0 zope.interface==4.1.3 - - python-version: 3.7 - framework: TWISTED_VERSION=16.1.0 treq==16.12.0 zope.interface==4.1.3 - - python-version: 3.7 - framework: TWISTED_VERSION=16.2.0 treq==16.12.0 zope.interface==4.1.3 - - python-version: 3.7 - framework: TWISTED_VERSION=16.3.0 treq==16.12.0 zope.interface==4.2.0 - - python-version: 3.7 - framework: TWISTED_VERSION=16.4.0 treq==17.8.0 zope.interface==4.2.0 - - python-version: 3.7 - framework: TWISTED_VERSION=16.5.0 treq==17.8.0 zope.interface==4.2.0 - - python-version: 3.7 - framework: TWISTED_VERSION=16.6.0 treq==17.8.0 zope.interface==4.3.0 - - python-version: 3.7 - framework: TWISTED_VERSION=17.1.0 treq==20.4.1 zope.interface==4.3.0 - - python-version: 3.8 - framework: TWISTED_VERSION=15.5.0 treq==15.1.0 zope.interface==4.1.3 - - python-version: 3.8 - framework: TWISTED_VERSION=16.1.0 treq==16.12.0 zope.interface==4.1.3 - - python-version: 3.8 - framework: TWISTED_VERSION=16.2.0 treq==16.12.0 zope.interface==4.1.3 - - python-version: 3.8 - framework: TWISTED_VERSION=16.3.0 treq==16.12.0 zope.interface==4.2.0 - - python-version: 3.8 - framework: TWISTED_VERSION=16.4.0 treq==17.8.0 zope.interface==4.2.0 - - python-version: 3.8 - framework: TWISTED_VERSION=16.5.0 treq==17.8.0 zope.interface==4.3.0 - - python-version: 3.8 - framework: TWISTED_VERSION=16.6.0 treq==17.8.0 zope.interface==4.3.0 - - python-version: 3.8 - framework: TWISTED_VERSION=17.1.0 treq==20.4.1 zope.interface==4.3.0 - - - python-version: 2.7 - framework: STARLETTE_VERSION=0.12.12 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 2.7 - framework: STARLETTE_VERSION=0.12.13 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 2.7 - framework: STARLETTE_VERSION=0.14.2 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 3.4 - framework: STARLETTE_VERSION=0.12.12 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 3.4 - framework: STARLETTE_VERSION=0.12.13 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 3.4 - framework: STARLETTE_VERSION=0.14.2 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 3.5 - framework: STARLETTE_VERSION=0.12.12 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 3.5 - framework: STARLETTE_VERSION=0.12.13 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 3.5 - framework: STARLETTE_VERSION=0.14.2 httpx==0.18.1 python-multipart==0.0.5 + # Test frameworks on the python versions they support, according to pypi registry + # Flask + - framework: FLASK_VERSION=1.1.4 + python-version: 3.4 + - framework: FLASK_VERSION=2.2.3 + python-version: 2.7 + - framework: FLASK_VERSION=2.2.3 + python-version: 3.4 + - framework: FLASK_VERSION=2.2.3 + python-version: 3.5 + - framework: FLASK_VERSION=2.2.3 + python-version: 3.6 + + # Django + - framework: DJANGO_VERSION=1.11.29 + python-version: 3.8 + - framework: DJANGO_VERSION=1.11.29 + python-version: 3.9 + - framework: DJANGO_VERSION=1.11.29 + python-version: '3.10' + - framework: DJANGO_VERSION=1.11.29 + python-version: 3.11 + - framework: DJANGO_VERSION=2.2.28 + python-version: 2.7 + - framework: DJANGO_VERSION=2.2.28 + python-version: 3.4 + - framework: DJANGO_VERSION=3.2.18 + python-version: 2.7 + - framework: DJANGO_VERSION=3.2.18 + python-version: 3.4 + - framework: DJANGO_VERSION=3.2.18 + python-version: 3.5 + - framework: DJANGO_VERSION=4.0.10 + python-version: 2.7 + - framework: DJANGO_VERSION=4.0.10 + python-version: 3.4 + - framework: DJANGO_VERSION=4.0.10 + python-version: 3.5 + - framework: DJANGO_VERSION=4.0.10 + python-version: 3.6 + - framework: DJANGO_VERSION=4.0.10 + python-version: 3.7 + - framework: DJANGO_VERSION=4.1.7 + python-version: 2.7 + - framework: DJANGO_VERSION=4.1.7 + python-version: 3.4 + - framework: DJANGO_VERSION=4.1.7 + python-version: 3.5 + - framework: DJANGO_VERSION=4.1.7 + python-version: 3.6 + - framework: DJANGO_VERSION=4.1.7 + python-version: 3.7 + + # Twisted + - framework: TWISTED_VERSION=17.1.0 treq==16.12.0 zope.interface==4.5.0 + python-version: 3.4 + - framework: TWISTED_VERSION=17.1.0 treq==16.12.0 zope.interface==4.5.0 + python-version: 3.5 + - framework: TWISTED_VERSION=17.1.0 treq==16.12.0 zope.interface==4.5.0 + python-version: 3.6 + - framework: TWISTED_VERSION=17.1.0 treq==16.12.0 zope.interface==4.5.0 + python-version: 3.7 + - framework: TWISTED_VERSION=17.1.0 treq==16.12.0 zope.interface==4.5.0 + python-version: 3.8 + - framework: TWISTED_VERSION=17.1.0 treq==16.12.0 zope.interface==4.5.0 + python-version: 3.9 + - framework: TWISTED_VERSION=17.1.0 treq==16.12.0 zope.interface==4.5.0 + python-version: '3.10' + - framework: TWISTED_VERSION=17.1.0 treq==16.12.0 zope.interface==4.5.0 + python-version: 3.11 + - framework: TWISTED_VERSION=20.3.0 + python-version: 2.7 + - framework: TWISTED_VERSION=20.3.0 + python-version: 3.4 + - framework: TWISTED_VERSION=20.3.0 + python-version: 3.11 + - framework: TWISTED_VERSION=21.7.0 + python-version: 2.7 + - framework: TWISTED_VERSION=21.7.0 + python-version: 3.4 + - framework: TWISTED_VERSION=21.7.0 + python-version: 3.5 + - framework: TWISTED_VERSION=22.10.0 + python-version: 2.7 + - framework: TWISTED_VERSION=22.10.0 + python-version: 3.4 + - framework: TWISTED_VERSION=22.10.0 + python-version: 3.5 + - framework: TWISTED_VERSION=22.10.0 + python-version: 3.6 + + + # Starlette + - framework: STARLETTE_VERSION=0.12.13 httpx==0.18.1 python-multipart==0.0.5 + python-version: 2.7 + - framework: STARLETTE_VERSION=0.12.13 httpx==0.18.1 python-multipart==0.0.5 + python-version: 3.4 + - framework: STARLETTE_VERSION=0.12.13 httpx==0.18.1 python-multipart==0.0.5 + python-version: 3.5 + - framework: STARLETTE_VERSION=0.14.2 httpx==0.18.1 python-multipart==0.0.5 + python-version: 2.7 + - framework: STARLETTE_VERSION=0.14.2 httpx==0.18.1 python-multipart==0.0.5 + python-version: 3.4 + - framework: STARLETTE_VERSION=0.14.2 httpx==0.18.1 python-multipart==0.0.5 + python-version: 3.5 + + # Fastapi + - framework: FASTAPI_VERSION=0.40.0 httpx==0.18.1 python-multipart==0.0.5 + python-version: 2.7 + - framework: FASTAPI_VERSION=0.40.0 httpx==0.18.1 python-multipart==0.0.5 + python-version: 3.4 + - framework: FASTAPI_VERSION=0.40.0 httpx==0.18.1 python-multipart==0.0.5 + python-version: 3.5 + - framework: FASTAPI_VERSION=0.50.0 httpx==0.18.1 python-multipart==0.0.5 + python-version: 2.7 + - framework: FASTAPI_VERSION=0.50.0 httpx==0.18.1 python-multipart==0.0.5 + python-version: 3.4 + - framework: FASTAPI_VERSION=0.50.0 httpx==0.18.1 python-multipart==0.0.5 + python-version: 3.5 + + - framework: FASTAPI_VERSION=0.63.0 httpx==0.18.1 python-multipart==0.0.5 + python-version: 2.7 + - framework: FASTAPI_VERSION=0.63.0 httpx==0.18.1 python-multipart==0.0.5 + python-version: 3.4 + - framework: FASTAPI_VERSION=0.63.0 httpx==0.18.1 python-multipart==0.0.5 + python-version: 3.5 - - python-version: 2.7 - framework: FASTAPI_VERSION=0.40.0 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 2.7 - framework: FASTAPI_VERSION=0.50.0 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 2.7 - framework: FASTAPI_VERSION=0.63.0 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 3.4 - framework: FASTAPI_VERSION=0.40.0 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 3.4 - framework: FASTAPI_VERSION=0.50.0 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 3.4 - framework: FASTAPI_VERSION=0.63.0 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 3.5 - framework: FASTAPI_VERSION=0.40.0 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 3.5 - framework: FASTAPI_VERSION=0.50.0 httpx==0.18.1 python-multipart==0.0.5 - - python-version: 3.5 - framework: FASTAPI_VERSION=0.63.0 httpx==0.18.1 python-multipart==0.0.5 - include: - - python-version: 2.7 - framework: FLASK_VERSION=0.9 - - python-version: 3.4 - framework: DJANGO_VERSION=1.7.11 - - python-version: 3.4 - framework: DJANGO_VERSION=1.8.19 - - python-version: 3.4 - framework: DJANGO_VERSION=1.9.13 - - python-version: 3.4 - framework: DJANGO_VERSION=1.10.8 - - python-version: 3.5 - framework: DJANGO_VERSION=1.8.19 - - python-version: 3.5 - framework: DJANGO_VERSION=1.9.13 - - python-version: 3.5 - framework: DJANGO_VERSION=1.10.8 - - python-version: 3.7 - framework: TWISTED_VERSION=18.9.0 treq==20.4.1 zope.interface==4.5.0 - - python-version: 3.7 - framework: TWISTED_VERSION=19.10.0 treq==20.4.1 zope.interface==4.6.0 - - python-version: 3.7 - framework: TWISTED_VERSION=20.3.0 treq==20.4.1 zope.interface==4.7.0 - - python-version: 3.8 - framework: TWISTED_VERSION=18.9.0 treq==20.4.1 zope.interface==4.5.0 - - python-version: 3.8 - framework: TWISTED_VERSION=19.10.0 treq==20.4.1 zope.interface==4.6.0 - - python-version: 3.8 - framework: TWISTED_VERSION=20.3.0 treq==20.4.1 zope.interface==4.7.0 steps: - uses: actions/checkout@v2 with: submodules: recursive - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: pip install setuptools==39.2.0 --force-reinstall + #- name: Install setuptools for 2.7,3.4 + # run: pip install setuptools==39.2.0 --force-reinstall - name: Install Python 2 dependencies if: ${{ contains(matrix.python-version, '2.7') }} @@ -215,17 +183,17 @@ jobs: - name: Install Python 3.4 dependencies if: ${{ contains(matrix.python-version, '3.4') }} # certifi uses the 'typing' from Python 3.5 module starting in 2022.5.18 - run: pip install certifi==2021.10.8 "typing-extensions<4" incremental==21.3.0 + run: pip install six==1.16.0 certifi==2021.10.8 requests==2.21.0 "typing-extensions<4" incremental==21.3.0 blinker==1.4 WebOb==1.8.7 - name: Install Python 3.5 dependencies if: ${{ contains(matrix.python-version, '3.5') }} # typing-extensions dropped support for Python 3.5 in version 4 - run: pip install "typing-extensions<4" + run: pip install six==1.16.0 "typing-extensions<4" requests==2.24.0 blinker==1.5 WebOb==1.8.7 - name: Install Python 3.6 dependencies if: ${{ contains(matrix.python-version, '3.6') }} # typing-extensions dropped support for Python 3.6 in version 4.2 - run: pip install "typing-extensions<4.2" + run: pip install six==1.16.0 "typing-extensions<4.2" requests==2.27.0 - name: Set the framework run: echo ${{ matrix.framework }} >> $GITHUB_ENV diff --git a/rollbar/test/__init__.py b/rollbar/test/__init__.py index c9dbc82f..9a6903ad 100644 --- a/rollbar/test/__init__.py +++ b/rollbar/test/__init__.py @@ -1,4 +1,5 @@ import unittest +import sys SNOWMAN = b'\xe2\x98\x83' @@ -9,5 +10,24 @@ class BaseTest(unittest.TestCase): pass +class SkipAsyncTestLoader(unittest.TestLoader): + """ + Python 2 does not have the async keyword, so when tests are run under python 2.7 the loader + will fail with a syntaxerror. This loader class does the following: + - try to load as normal + - if loading fails because of a syntax error in python < 3.4, skip the file. + """ + def _get_module_from_name(self, name): + try: + return super(SkipAsyncTestLoader, self)._get_module_from_name(name) + except SyntaxError as e: + if sys.version_info < (3, 5): + return None + else: + raise + + def discover(): - return unittest.defaultTestLoader.discover(__name__) + loader = SkipAsyncTestLoader() + suite = loader.discover(__name__) + return suite diff --git a/rollbar/test/asgi_tests/test_integration.py b/rollbar/test/asgi_tests/test_integration.py index 84578094..23312aed 100644 --- a/rollbar/test/asgi_tests/test_integration.py +++ b/rollbar/test/asgi_tests/test_integration.py @@ -1,6 +1,12 @@ +import unittest +import sys + from rollbar.test import BaseTest +ALLOWED_PYTHON_VERSION = sys.version_info >= (3, 5) + +@unittest.skipUnless(ALLOWED_PYTHON_VERSION, 'ASGI implementation requires Python3.5+') class IntegrationTest(BaseTest): def test_should_integrate_if__integrate_defined(self): from rollbar.contrib.asgi.integration import IntegrationBase diff --git a/rollbar/test/test_rollbar.py b/rollbar/test/test_rollbar.py index d1b9ec46..26d9ab6f 100644 --- a/rollbar/test/test_rollbar.py +++ b/rollbar/test/test_rollbar.py @@ -1383,8 +1383,8 @@ def _raise(password='sensitive', clear='text'): self.assertEqual(2, len(payload['data']['body']['trace']['frames'][-1]['argspec'])) self.assertEqual('password', payload['data']['body']['trace']['frames'][-1]['argspec'][0]) - self.assertRegex(payload['data']['body']['trace']['frames'][-1]['locals']['password'], r'\*+') - self.assertRegex(payload['data']['body']['trace']['frames'][-1]['locals']['headers']['Authorization'], r'\*+') + six.assertRegex(self, payload['data']['body']['trace']['frames'][-1]['locals']['password'], r'\*+') + six.assertRegex(self, payload['data']['body']['trace']['frames'][-1]['locals']['headers']['Authorization'], r'\*+') self.assertEqual('clear', payload['data']['body']['trace']['frames'][-1]['argspec'][1]) self.assertEqual('text', payload['data']['body']['trace']['frames'][-1]['locals']['clear']) diff --git a/rollbar/test/test_serializable_transform.py b/rollbar/test/test_serializable_transform.py index 3a2351f4..3a3cab85 100644 --- a/rollbar/test/test_serializable_transform.py +++ b/rollbar/test/test_serializable_transform.py @@ -2,6 +2,7 @@ import base64 import copy import enum +import sys try: # Python 3 @@ -147,7 +148,13 @@ def test_encode_int(self): def test_encode_empty_tuple(self): start = () expected = () - self._assertSerialized(start, expected) + + skip_id_check = False + # different behavior in 3.11 + if sys.version_info >= (3, 11): + skip_id_check = True + + self._assertSerialized(start, expected, skip_id_check=skip_id_check) def test_encode_empty_list(self): start = [] diff --git a/rollbar/test/test_shortener_transform.py b/rollbar/test/test_shortener_transform.py index 20736f94..11fffb2f 100644 --- a/rollbar/test/test_shortener_transform.py +++ b/rollbar/test/test_shortener_transform.py @@ -103,6 +103,8 @@ def test_shorten_frozenset(self): def test_shorten_array(self): expected = 'array(\'l\', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...])' + if sys.version_info >= (3, 10): + expected = '[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]' self._assert_shortened('array', expected) def test_shorten_deque(self): diff --git a/rollbar/test/twisted_tests/test_twisted.py b/rollbar/test/twisted_tests/test_twisted.py index 66a57305..c8e4939a 100644 --- a/rollbar/test/twisted_tests/test_twisted.py +++ b/rollbar/test/twisted_tests/test_twisted.py @@ -54,7 +54,7 @@ def test_base_case(self, send_payload): self.proto.dataReceived('8') self.assertEqual(int(self.tr.value()), 64) - self.assertEqual(send_payload.called, False) + self.assertFalse(send_payload.called) @mock.patch('rollbar.send_payload') def test_caught_exception(self, send_payload): @@ -63,7 +63,7 @@ def test_caught_exception(self, send_payload): errors = self.flushLoggedErrors(ValueError) self.assertEqual(len(errors), 1) - self.assertEqual(send_payload.called, True) + self.assertTrue(send_payload.called) payload = send_payload.call_args[0][0] data = payload['data'] diff --git a/setup.py b/setup.py index e9f6178c..70688372 100644 --- a/setup.py +++ b/setup.py @@ -82,8 +82,8 @@ # always installs the latest version of the package. 'requests>=0.12.1; python_version == "2.7"', 'requests>=0.12.1; python_version >= "3.6"', - 'requests<2.26,>=0.12.1; python_version == "3.5"', - 'requests<2.22,>=0.12.1; python_version == "3.4"', + 'requests>=0.12.1; python_version == "3.5"', + 'requests>=0.12.1; python_version == "3.4"', 'six>=1.9.0' ], tests_require=tests_require,