diff --git a/.travis.yml b/.travis.yml index e605fe0a9..c6df9a1c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ python: - "3.6" - "3.7" - "3.8" + - "3.9" dist: xenial addons: apt: diff --git a/setup.py b/setup.py index 8ea8be741..d25896ffb 100755 --- a/setup.py +++ b/setup.py @@ -42,6 +42,7 @@ 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', 'Framework :: Django', 'Framework :: Django :: 1.11', 'Framework :: Django :: 2.0', diff --git a/tests/tests.py b/tests/tests.py index 52c3a6eb7..75dad26a4 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -225,6 +225,33 @@ def test_get_manylinux_python38(self): self.assertTrue(os.path.isfile(path)) os.remove(path) + def test_get_manylinux_python39(self): + z = Zappa(runtime="python3.9") + self.assertIsNotNone(z.get_cached_manylinux_wheel("psycopg2-binary", "2.9.1")) + self.assertIsNone(z.get_cached_manylinux_wheel("derp_no_such_thing", "0.0")) + + # mock with a known manylinux wheel package so that code for downloading them gets invoked + mock_installed_packages = {"psycopg2-binary": "2.8.4"} + with mock.patch( + "zappa.core.Zappa.get_installed_packages", + return_value=mock_installed_packages, + ): + z = Zappa(runtime="python3.9") + path = z.create_lambda_zip(handler_file=os.path.realpath(__file__)) + self.assertTrue(os.path.isfile(path)) + os.remove(path) + + # same, but with an ABI3 package + mock_installed_packages = {"cryptography": "2.8"} + with mock.patch( + "zappa.core.Zappa.get_installed_packages", + return_value=mock_installed_packages, + ): + z = Zappa(runtime="python3.9") + path = z.create_lambda_zip(handler_file=os.path.realpath(__file__)) + self.assertTrue(os.path.isfile(path)) + os.remove(path) + def test_getting_installed_packages(self, *args): z = Zappa(runtime="python3.6") diff --git a/zappa/__init__.py b/zappa/__init__.py index 8c1d448fa..355a88078 100644 --- a/zappa/__init__.py +++ b/zappa/__init__.py @@ -1,6 +1,6 @@ import sys -SUPPORTED_VERSIONS = [(3, 6), (3, 7), (3, 8)] +SUPPORTED_VERSIONS = [(3, 6), (3, 7), (3, 8), (3, 9)] if sys.version_info[:2] not in SUPPORTED_VERSIONS: formatted_supported_versions = [ diff --git a/zappa/core.py b/zappa/core.py index 78fc5ff5b..dc9d80719 100644 --- a/zappa/core.py +++ b/zappa/core.py @@ -309,15 +309,17 @@ def __init__( self.manylinux_suffix_start = "cp36m" elif self.runtime == "python3.7": self.manylinux_suffix_start = "cp37m" - else: + elif self.runtime == "python3.8": # The 'm' has been dropped in python 3.8+ since builds with and without pymalloc are ABI compatible # See https://github.com/pypa/manylinux for a more detailed explanation self.manylinux_suffix_start = "cp38" + else: + self.manylinux_suffix_start = "cp39" # AWS Lambda supports manylinux1/2010 and manylinux2014 manylinux_suffixes = ("2014", "2010", "1") self.manylinux_wheel_file_match = re.compile( - f'^.*{self.manylinux_suffix_start}-manylinux({"|".join(manylinux_suffixes)})_x86_64.whl$' + f'^.*{self.manylinux_suffix_start}-(manylinux_\d+_\d+_x86_64[.])?manylinux({"|".join(manylinux_suffixes)})_x86_64.whl$' ) self.manylinux_wheel_abi3_file_match = re.compile( f'^.*cp3.-abi3-manylinux({"|".join(manylinux_suffixes)})_x86_64.whl$' diff --git a/zappa/utilities.py b/zappa/utilities.py index 6149a575a..d146971e7 100644 --- a/zappa/utilities.py +++ b/zappa/utilities.py @@ -200,8 +200,10 @@ def get_runtime_from_python_version(): return "python3.6" elif sys.version_info[1] <= 7: return "python3.7" - else: + elif sys.version_info[1] <= 8: return "python3.8" + else: + return "python3.9" ##