diff --git a/.circleci/config.yml b/.circleci/config.yml index 3471ea3a..7ffc3582 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,14 +5,14 @@ orbs: ship: auth0/ship@0.5.0 codecov: codecov/codecov@3 -executors: - python_3_10: - docker: - - image: cimg/python:3.10 - jobs: - build: - executor: python_3_10 + build_and_test: + parameters: + py_version: + type: string + default: "3.10" + docker: + - image: cimg/python:<< parameters.py_version >> steps: - checkout - python/install-packages: @@ -20,12 +20,19 @@ jobs: - run: pre-commit run --all-files - run: coverage run -m unittest - run: bash <(curl -s https://codecov.io/bash) - - run: make -C docs html + - when: + condition: + equal: [ "3.10", << parameters.py_version >> ] + steps: + - run: make -C docs html workflows: main: jobs: - - build + - build_and_test: + matrix: + parameters: + py_version: [ "3.7", "3.8", "3.9", "3.10", "3.11" ] - ship/python-publish: prefix-tag: false context: @@ -36,4 +43,4 @@ workflows: only: - master requires: - - build + - build_and_test diff --git a/README.md b/README.md index 9d7cc3d3..be4b5101 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,7 @@ You can install the auth0 Python SDK using the following command. pip install auth0-python ``` -For python3, use the following command -``` -pip3 install auth0-python -``` -Python 3.2 and 3.3 have reached [EOL](https://en.wikipedia.org/wiki/CPython#Version_history) and support will be removed in the near future. +> Requires Python 3.7 or higher. ### Usage diff --git a/auth0/v3/test_async/test_async_auth0.py b/auth0/v3/test_async/test_async_auth0.py index 972ec044..d9be2fe9 100644 --- a/auth0/v3/test_async/test_async_auth0.py +++ b/auth0/v3/test_async/test_async_auth0.py @@ -3,8 +3,8 @@ import platform import re import sys +import unittest from tempfile import TemporaryFile -from unittest import IsolatedAsyncioTestCase import aiohttp from aioresponses import CallbackResult, aioresponses @@ -27,7 +27,11 @@ def callback(url, **kwargs): return callback, mock -class TestAsyncify(IsolatedAsyncioTestCase): +@unittest.skipIf( + not hasattr(unittest, "IsolatedAsyncioTestCase"), + "python 3.7 doesn't have IsolatedAsyncioTestCase", +) +class TestAuth0(getattr(unittest, "IsolatedAsyncioTestCase", object)): @aioresponses() async def test_get(self, mocked): callback, mock = get_callback() diff --git a/auth0/v3/test_async/test_async_token_verifier.py b/auth0/v3/test_async/test_async_token_verifier.py index fb6d0e26..7fa6b866 100644 --- a/auth0/v3/test_async/test_async_token_verifier.py +++ b/auth0/v3/test_async/test_async_token_verifier.py @@ -54,7 +54,13 @@ def get_pem_bytes(rsa_public_key): ) -class TestAsyncAsymmetricSignatureVerifier(unittest.IsolatedAsyncioTestCase): +@unittest.skipIf( + not hasattr(unittest, "IsolatedAsyncioTestCase"), + "python 3.7 doesn't have IsolatedAsyncioTestCase", +) +class TestAsyncAsymmetricSignatureVerifier( + getattr(unittest, "IsolatedAsyncioTestCase", object) +): @aioresponses() async def test_async_asymmetric_verifier_fetches_key(self, mocked): callback, mock = get_callback(200, JWKS_RESPONSE_SINGLE_KEY) @@ -67,7 +73,11 @@ async def test_async_asymmetric_verifier_fetches_key(self, mocked): self.assertEqual(get_pem_bytes(key), RSA_PUB_KEY_1_PEM) -class TestAsyncJwksFetcher(unittest.IsolatedAsyncioTestCase): +@unittest.skipIf( + not hasattr(unittest, "IsolatedAsyncioTestCase"), + "python 3.7 doesn't have IsolatedAsyncioTestCase", +) +class TestAsyncJwksFetcher(getattr(unittest, "IsolatedAsyncioTestCase", object)): @aioresponses() async def test_async_get_jwks_json_twice_on_cache_expired(self, mocked): fetcher = AsyncJwksFetcher(JWKS_URI, cache_ttl=1) @@ -213,7 +223,11 @@ async def test_async_fails_to_fetch_jwks_json_after_retrying_twice(self, mocked) self.assertEqual(mock.call_count, 2) -class TestAsyncTokenVerifier(unittest.IsolatedAsyncioTestCase): +@unittest.skipIf( + not hasattr(unittest, "IsolatedAsyncioTestCase"), + "python 3.7 doesn't have IsolatedAsyncioTestCase", +) +class TestAsyncTokenVerifier(getattr(unittest, "IsolatedAsyncioTestCase", object)): @aioresponses() async def test_RS256_token_signature_passes(self, mocked): callback, mock = get_callback(200, {"keys": [PUBLIC_KEY]}) diff --git a/auth0/v3/test_async/test_asyncify.py b/auth0/v3/test_async/test_asyncify.py index 439f61c1..18f9998b 100644 --- a/auth0/v3/test_async/test_asyncify.py +++ b/auth0/v3/test_async/test_asyncify.py @@ -3,8 +3,8 @@ import platform import re import sys +import unittest from tempfile import TemporaryFile -from unittest import IsolatedAsyncioTestCase import aiohttp from aioresponses import CallbackResult, aioresponses @@ -50,7 +50,11 @@ def callback(url, **kwargs): return callback, mock -class TestAsyncify(IsolatedAsyncioTestCase): +@unittest.skipIf( + not hasattr(unittest, "IsolatedAsyncioTestCase"), + "python 3.7 doesn't have IsolatedAsyncioTestCase", +) +class TestAsyncify(getattr(unittest, "IsolatedAsyncioTestCase", object)): @aioresponses() async def test_get(self, mocked): callback, mock = get_callback() diff --git a/setup.py b/setup.py index f20cdfaf..ef51345d 100644 --- a/setup.py +++ b/setup.py @@ -29,17 +29,14 @@ def find_version(): author_email="support@auth0.com", license="MIT", packages=find_packages(), - install_requires=["requests>=2.14.0", "pyjwt[crypto]>=1.7.1"], + install_requires=["requests>=2.14.0", "pyjwt[crypto]>=2.6.0"], extras_require={"test": ["coverage", "mock>=1.3.0", "pre-commit"]}, - python_requires=">=2.7, !=3.0.*, !=3.1.*", + python_requires=">=3.7", classifiers=[ - "Development Status :: 4 - Beta", + "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Operating System :: OS Independent", "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9",