diff --git a/appveyor-windows-build-python.yml b/appveyor-windows-build-python.yml index d983886953..7830f164e8 100644 --- a/appveyor-windows-build-python.yml +++ b/appveyor-windows-build-python.yml @@ -36,18 +36,22 @@ init: install: # Make sure the temp directory exists for Python to use. - # Install python3.8 + # Install python3.8 and python3.9 - "choco install chocolatey-core.extension --version 1.3.3 --force -y" - "choco install python3 --version 3.8.0" + - "choco install python3 --version 3.9.0" - "C:\\Python38\\python.exe -m pip freeze" + - "C:\\Python39\\python.exe -m pip freeze" - "refreshenv" - ps: "mkdir -Force D:\\tmp" - - "SET PATH=%PYTHON_HOME%;%PATH%;C:\\Python36-x64;C:\\Python27-x64;C:\\Python38" + - "SET PATH=%PYTHON_HOME%;%PATH%;C:\\Python36-x64;C:\\Python27-x64;C:\\Python38;C:\\Python39" - "echo %PYTHON_HOME%" - "echo %PATH%" - "python --version" # Check if python3.8 exists on the image - "C:\\Python38\\python.exe --version" + # Check if python3.9 exists on the image + - "C:\\Python39\\python.exe --version" # Upgrade setuptools, wheel and virtualenv - "python -m pip install --upgrade setuptools wheel virtualenv" @@ -58,6 +62,7 @@ install: # python is python3.7 - "python -m pip install --upgrade pip" - "C:\\Python38\\python.exe -m pip install --upgrade pip" + - "C:\\Python39\\python.exe -m pip install --upgrade pip" # Create new virtual environment with chosen python version and activate it - "python -m virtualenv venv" diff --git a/appveyor.yml b/appveyor.yml index f5a19e8cac..0f7cd0ef42 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,7 @@ version: 1.0.{build} image: - Ubuntu - - Visual Studio 2017 + - Visual Studio 2019 environment: AWS_DEFAULT_REGION: us-east-1 @@ -15,6 +15,7 @@ environment: NOSE_PARAMETERIZED_NO_WARN: 1 INSTALL_PY_37_PIP: 1 INSTALL_PY_38_PIP: 1 + INSTALL_PY_39_PIP: 1 AWS_S3: 'AWS_S3_36' AWS_ECR: 'AWS_ECR_36' APPVEYOR_CONSOLE_DISABLE_PTY: true @@ -26,6 +27,7 @@ environment: NOSE_PARAMETERIZED_NO_WARN: 1 INSTALL_PY_36_PIP: 1 INSTALL_PY_38_PIP: 1 + INSTALL_PY_39_PIP: 1 AWS_S3: 'AWS_S3_37' AWS_ECR: 'AWS_ECR_37' APPVEYOR_CONSOLE_DISABLE_PTY: true @@ -37,15 +39,28 @@ environment: NOSE_PARAMETERIZED_NO_WARN: 1 INSTALL_PY_36_PIP: 1 INSTALL_PY_37_PIP: 1 + INSTALL_PY_39_PIP: 1 AWS_S3: 'AWS_S3_38' AWS_ECR: 'AWS_ECR_38' APPVEYOR_CONSOLE_DISABLE_PTY: true + - PYTHON_HOME: "C:\\Python39-x64" + PYTHON_VERSION: '3.9' + PYTHON_ARCH: '64' + RUN_SMOKE: 1 + NOSE_PARAMETERIZED_NO_WARN: 1 + INSTALL_PY_36_PIP: 1 + INSTALL_PY_37_PIP: 1 + INSTALL_PY_38_PIP: 1 + AWS_S3: 'AWS_S3_39' + AWS_ECR: 'AWS_ECR_39' + APPVEYOR_CONSOLE_DISABLE_PTY: true + for: - matrix: only: - - image: Visual Studio 2017 + - image: Visual Studio 2019 install: - "SET PATH=%PYTHON_HOME%;%PATH%" @@ -111,6 +126,8 @@ for: - image: Ubuntu install: + # apt repo for python3.9 installation + - sh: "sudo add-apt-repository ppa:deadsnakes/ppa" # AppVeyor's apt-get cache might be outdated, and the package could potentially be 404. - sh: "sudo apt-get update" @@ -138,16 +155,20 @@ for: - sh: "sudo apt-get -y install python2.7" - sh: "sudo apt-get -y install python3.7" - sh: "sudo apt-get -y install python3.8" + - sh: "sudo apt-get -y install python3.9" - sh: "which python3.8" - - sh: "which python3.6" - sh: "which python3.7" + - sh: "which python3.6" + - sh: "which python3.9" - sh: "which python2.7" - - sh: "PATH=$PATH:/usr/bin/python3.8:/usr/bin/python3.7" + - sh: "PATH=$PATH:/usr/bin/python3.9:/usr/bin/python3.8:/usr/bin/python3.7" - sh: "curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py" - sh: "sudo apt-get -y install python3-distutils" + - sh: "sudo apt-get -y install python3.9-distutils" + - ps: "If ($env:INSTALL_PY_39_PIP) {python3.9 get-pip.py --user}" - ps: "If ($env:INSTALL_PY_38_PIP) {python3.8 get-pip.py --user}" - ps: "If ($env:INSTALL_PY_37_PIP) {python3.7 get-pip.py --user}" - ps: "If ($env:INSTALL_PY_36_PIP) {python3.6 get-pip.py --user}" diff --git a/requirements/base.txt b/requirements/base.txt index fbc368ac92..fd9af35722 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -12,6 +12,6 @@ docker~=4.2.0 dateparser~=1.0 requests==2.25.1 serverlessrepo==0.1.10 -aws_lambda_builders==1.5.0 +aws_lambda_builders==1.6.0 tomlkit==0.7.2 watchdog==2.1.2 diff --git a/requirements/pre-dev.txt b/requirements/pre-dev.txt index 4cbd7d2ec9..346a9e3622 100644 --- a/requirements/pre-dev.txt +++ b/requirements/pre-dev.txt @@ -1 +1 @@ -pylint~=2.9.0 \ No newline at end of file +pylint~=2.9.0 diff --git a/requirements/reproducible-linux.txt b/requirements/reproducible-linux.txt index de89955dce..75f8b8a0e3 100644 --- a/requirements/reproducible-linux.txt +++ b/requirements/reproducible-linux.txt @@ -12,10 +12,10 @@ attrs==20.3.0 \ --hash=sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6 \ --hash=sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700 # via jsonschema -aws-lambda-builders==1.5.0 \ - --hash=sha256:0167b40da88c679e21341852faf59fae2aafe36c22a560de2e4aa75c7b9dd846 \ - --hash=sha256:6fd7fddd50b7bbbb8668c44c638d685123a698bf1a866da2f34b440bca9958ad \ - --hash=sha256:c9f2259656353f98e70c49ed52b6ea8891d1f6853c2b1a9ac891772768d1697e +aws-lambda-builders==1.6.0 \ + --hash=sha256:068840f92520dd37524f464c61e4fd3224c185dda40cd941ddeb0354edcc069b \ + --hash=sha256:2d232e14397519d8e75d4cc1523a31a255c053f97fd784b5513b81fc6c6c5492 \ + --hash=sha256:3e26edb75e78e1420d573cf4bcda1acd424f88a12e754bff971fe8b9bb4545a3 # via aws-sam-cli (setup.py) aws-sam-translator==1.38.0 \ --hash=sha256:0ecadda9cf5ab2318f57f1253181a2151e4c53cd35d21717a923c075a5a65cb6 \ diff --git a/samcli/commands/build/command.py b/samcli/commands/build/command.py index 5958dcfc20..5c450d6589 100644 --- a/samcli/commands/build/command.py +++ b/samcli/commands/build/command.py @@ -38,7 +38,7 @@ \b Supported Runtimes ------------------ -1. Python 2.7, 3.6, 3.7, 3.8 using PIP\n +1. Python 2.7, 3.6, 3.7, 3.8 3.9 using PIP\n 2. Nodejs 14.x, 12.x, 10.x, 8.10, 6.10 using NPM\n 3. Ruby 2.5 using Bundler\n 4. Java 8, Java 11 using Gradle and Maven\n @@ -316,7 +316,6 @@ def do_cli( # pylint: disable=too-many-locals, too-many-statements try: artifacts = builder.build() - stack_output_template_path_by_stack_path = { stack.stack_path: stack.get_output_template_path(ctx.build_dir) for stack in ctx.stacks } diff --git a/samcli/lib/build/workflow_config.py b/samcli/lib/build/workflow_config.py index 146b6bfa77..bec974cc25 100644 --- a/samcli/lib/build/workflow_config.py +++ b/samcli/lib/build/workflow_config.py @@ -151,6 +151,7 @@ def get_layer_subfolder(build_workflow: str) -> str: "python3.6": "python", "python3.7": "python", "python3.8": "python", + "python3.9": "python", "nodejs4.3": "nodejs", "nodejs6.10": "nodejs", "nodejs8.10": "nodejs", @@ -210,6 +211,7 @@ def get_workflow_config( "python3.6": BasicWorkflowSelector(PYTHON_PIP_CONFIG), "python3.7": BasicWorkflowSelector(PYTHON_PIP_CONFIG), "python3.8": BasicWorkflowSelector(PYTHON_PIP_CONFIG), + "python3.9": BasicWorkflowSelector(PYTHON_PIP_CONFIG), "nodejs10.x": BasicWorkflowSelector(NODEJS_NPM_CONFIG), "nodejs12.x": BasicWorkflowSelector(NODEJS_NPM_CONFIG), "nodejs14.x": BasicWorkflowSelector(NODEJS_NPM_CONFIG), diff --git a/samcli/lib/deploy/deployer.py b/samcli/lib/deploy/deployer.py index 8f2ff4a7b2..540535def2 100644 --- a/samcli/lib/deploy/deployer.py +++ b/samcli/lib/deploy/deployer.py @@ -84,6 +84,7 @@ def __init__(self, cloudformation_client, changeset_prefix="samcli-deploy"): self.max_attempts = 3 self.deploy_color = DeployColor() + # pylint: disable=inconsistent-return-statements def has_stack(self, stack_name): """ Checks if a CloudFormation stack with given name exists diff --git a/samcli/local/common/runtime_template.py b/samcli/local/common/runtime_template.py index 2924a5aa9f..6d3759ec4f 100644 --- a/samcli/local/common/runtime_template.py +++ b/samcli/local/common/runtime_template.py @@ -15,7 +15,7 @@ RUNTIME_DEP_TEMPLATE_MAPPING = { "python": [ { - "runtimes": ["python3.8", "python3.7", "python3.6", "python2.7"], + "runtimes": ["python3.9", "python3.8", "python3.7", "python3.6", "python2.7"], "dependency_manager": "pip", "init_location": os.path.join(_templates, "cookiecutter-aws-sam-hello-python"), "build": True, @@ -79,6 +79,7 @@ def get_local_lambda_images_location(mapping, runtime): RUNTIME_TO_DEPENDENCY_MANAGERS = { + "python3.9": ["pip"], "python3.8": ["pip"], "python3.7": ["pip"], "python3.6": ["pip"], @@ -113,7 +114,7 @@ def get_local_lambda_images_location(mapping, runtime): INIT_RUNTIMES = [ # latest of each runtime version "nodejs14.x", - "python3.8", + "python3.9", "ruby2.7", "go1.x", "java11", @@ -122,6 +123,7 @@ def get_local_lambda_images_location(mapping, runtime): "nodejs12.x", "nodejs10.x", # older python runtimes + "python3.8", "python3.7", "python3.6", "python2.7", @@ -138,6 +140,7 @@ def get_local_lambda_images_location(mapping, runtime): "amazon/nodejs14.x-base", "amazon/nodejs12.x-base", "amazon/nodejs10.x-base", + "amazon/python3.9-base", "amazon/python3.8-base", "amazon/python3.7-base", "amazon/python3.6-base", @@ -162,4 +165,5 @@ def get_local_lambda_images_location(mapping, runtime): "python3.7": "Python36", "python3.6": "Python36", "python3.8": "Python36", + "python3.9": "Python36", } diff --git a/samcli/local/docker/lambda_debug_settings.py b/samcli/local/docker/lambda_debug_settings.py index 6bdb7d8a12..9f8ce2fe7d 100644 --- a/samcli/local/docker/lambda_debug_settings.py +++ b/samcli/local/docker/lambda_debug_settings.py @@ -156,6 +156,10 @@ def get_debug_settings(debug_port, debug_args_list, _container_env_vars, runtime entry + ["/var/lang/bin/python3.8"] + debug_args_list + ["/var/runtime/bootstrap.py"], container_env_vars=_container_env_vars, ), + Runtime.python39.value: lambda: DebugSettings( + entry + ["/var/lang/bin/python3.9"] + debug_args_list + ["/var/runtime/bootstrap.py"], + container_env_vars=_container_env_vars, + ), } try: return entrypoint_mapping[runtime]() diff --git a/samcli/local/docker/lambda_image.py b/samcli/local/docker/lambda_image.py index 59e6a36d0a..0c31b20289 100644 --- a/samcli/local/docker/lambda_image.py +++ b/samcli/local/docker/lambda_image.py @@ -30,6 +30,7 @@ class Runtime(Enum): python36 = "python3.6" python37 = "python3.7" python38 = "python3.8" + python39 = "python3.9" ruby25 = "ruby2.5" ruby27 = "ruby2.7" java8 = "java8" diff --git a/setup.py b/setup.py index c61bb25c03..307fd6dec2 100644 --- a/setup.py +++ b/setup.py @@ -71,6 +71,7 @@ def read_version(): "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", "Topic :: Internet", "Topic :: Software Development :: Build Tools", "Topic :: Utilities", diff --git a/tests/integration/buildcmd/test_build_cmd.py b/tests/integration/buildcmd/test_build_cmd.py index 22834ab699..f0980ad7ba 100644 --- a/tests/integration/buildcmd/test_build_cmd.py +++ b/tests/integration/buildcmd/test_build_cmd.py @@ -55,7 +55,7 @@ class TestBuildCommand_PythonFunctions_Images(BuildIntegBase): FUNCTION_LOGICAL_ID_IMAGE = "ImageFunction" - @parameterized.expand([("3.6", False), ("3.7", False), ("3.8", False)]) + @parameterized.expand([("3.6", False), ("3.7", False), ("3.8", False), ("3.9", False)]) @pytest.mark.flaky(reruns=3) def test_with_default_requirements(self, runtime, use_container): overrides = { @@ -97,6 +97,7 @@ class TestBuildCommand_PythonFunctions(BuildIntegBase): ("python3.6", "Python", False), ("python3.7", "Python", False), ("python3.8", "Python", False), + ("python3.9", "Python", False), # numpy 1.20.3 (in PythonPEP600/requirements.txt) only support python 3.7+ ("python3.7", "PythonPEP600", False), ("python3.8", "PythonPEP600", False), @@ -104,6 +105,7 @@ class TestBuildCommand_PythonFunctions(BuildIntegBase): ("python3.6", "Python", "use_container"), ("python3.7", "Python", "use_container"), ("python3.8", "Python", "use_container"), + ("python3.9", "Python", "use_container"), ] ) @pytest.mark.flaky(reruns=3) @@ -1188,12 +1190,12 @@ class TestBuildWithDedupBuilds(DedupBuildIntegBase): ), (False, "Java/gradlew", "aws.example.Hello::myHandler", "aws.example.SecondFunction::myHandler", "java8"), (False, "Node", "main.lambdaHandler", "main.secondLambdaHandler", "nodejs14.x"), - (False, "Python", "main.first_function_handler", "main.second_function_handler", "python3.8"), + (False, "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), (False, "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby2.5"), # container (True, "Java/gradlew", "aws.example.Hello::myHandler", "aws.example.SecondFunction::myHandler", "java8"), (True, "Node", "main.lambdaHandler", "main.secondLambdaHandler", "nodejs14.x"), - (True, "Python", "main.first_function_handler", "main.second_function_handler", "python3.8"), + (True, "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), (True, "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby2.5"), ] ) @@ -1311,12 +1313,12 @@ class TestBuildWithCacheBuilds(CachedBuildIntegBase): ), (False, "Java/gradlew", "aws.example.Hello::myHandler", "aws.example.SecondFunction::myHandler", "java8"), (False, "Node", "main.lambdaHandler", "main.secondLambdaHandler", "nodejs14.x"), - (False, "Python", "main.first_function_handler", "main.second_function_handler", "python3.8"), + (False, "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), (False, "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby2.5"), # container (True, "Java/gradlew", "aws.example.Hello::myHandler", "aws.example.SecondFunction::myHandler", "java8"), (True, "Node", "main.lambdaHandler", "main.secondLambdaHandler", "nodejs14.x"), - (True, "Python", "main.first_function_handler", "main.second_function_handler", "python3.8"), + (True, "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), (True, "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby2.5"), ] ) @@ -1397,12 +1399,12 @@ class TestParallelBuilds(DedupBuildIntegBase): ), (False, "Java/gradlew", "aws.example.Hello::myHandler", "aws.example.SecondFunction::myHandler", "java8"), (False, "Node", "main.lambdaHandler", "main.secondLambdaHandler", "nodejs14.x"), - (False, "Python", "main.first_function_handler", "main.second_function_handler", "python3.8"), + (False, "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), (False, "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby2.5"), # container (True, "Java/gradlew", "aws.example.Hello::myHandler", "aws.example.SecondFunction::myHandler", "java8"), (True, "Node", "main.lambdaHandler", "main.secondLambdaHandler", "nodejs14.x"), - (True, "Python", "main.first_function_handler", "main.second_function_handler", "python3.8"), + (True, "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), (True, "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby2.5"), ] ) diff --git a/tests/integration/init/schemas/test_init_with_schemas_command.py b/tests/integration/init/schemas/test_init_with_schemas_command.py index ad2f2ecb87..205c3e473f 100644 --- a/tests/integration/init/schemas/test_init_with_schemas_command.py +++ b/tests/integration/init/schemas/test_init_with_schemas_command.py @@ -20,7 +20,7 @@ def test_init_interactive_with_event_bridge_app_aws_registry(self): # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates # 1: Zip Packagetype - # 14: Java runtime + # 15: Java runtime # 1: dependency manager maven # eb-app-maven: response to name # 3: select event-bridge app from scratch @@ -31,7 +31,7 @@ def test_init_interactive_with_event_bridge_app_aws_registry(self): user_input = """ 1 1 -14 +15 1 eb-app-maven 3 @@ -56,7 +56,7 @@ def test_init_interactive_with_event_bridge_app_partner_registry(self): # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates # 1: Zip Packagetype - # 14: Java runtime + # 15: Java runtime # 1: dependency manager maven # eb-app-maven: response to name # 3: select event-bridge app from scratch @@ -67,7 +67,7 @@ def test_init_interactive_with_event_bridge_app_partner_registry(self): user_input = """ 1 1 -14 +15 1 eb-app-maven 3 @@ -103,7 +103,7 @@ def test_init_interactive_with_event_bridge_app_pagination(self): # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates # 1: Zip Packagetype - # 14: Java Runtime + # 15: Java Runtime # 1: dependency manager maven # eb-app-maven: response to name # 3: select event-bridge app from scratch @@ -143,7 +143,7 @@ def test_init_interactive_with_event_bridge_app_customer_registry(self): # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates # 1: Zip Packagetype - # 14: Java Runtime + # 15: Java Runtime # 1: dependency manager maven # eb-app-maven: response to name # 3: select event-bridge app from scratch @@ -154,7 +154,7 @@ def test_init_interactive_with_event_bridge_app_customer_registry(self): user_input = """ 1 1 -14 +15 1 eb-app-maven 3 @@ -190,7 +190,7 @@ def test_init_interactive_with_event_bridge_app_aws_schemas_python(self): # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates # 1: Zip Packagetype - # 9: Python 3.7 + # 10: Python 3.7 # eb-app-python37: response to name # 3: select event-bridge app from scratch # Y: Use default profile @@ -200,7 +200,7 @@ def test_init_interactive_with_event_bridge_app_aws_schemas_python(self): user_input = """ 1 1 -9 +10 eb-app-python37 3 Y @@ -222,7 +222,7 @@ def test_init_interactive_with_event_bridge_app_non_default_profile_selection(se # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates # 1: Zip Packagetype - # 9: Python 3.7 + # 10: Python 3.7 # eb-app-python37: response to name # 3: select event-bridge app from scratch # N: Use default profile @@ -234,7 +234,7 @@ def test_init_interactive_with_event_bridge_app_non_default_profile_selection(se user_input = """ 1 1 -9 +10 eb-app-python37 3 N @@ -260,7 +260,7 @@ def test_init_interactive_with_event_bridge_app_non_supported_schemas_region(sel # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates # 1: Zip Pacakgetype - # 9: Python 3.7 + # 10: Python 3.7 # eb-app-python37: response to name # 3: select event-bridge app from scratch # Y: Use default profile @@ -270,7 +270,7 @@ def test_init_interactive_with_event_bridge_app_non_supported_schemas_region(sel user_input = """ 1 1 -9 +10 eb-app-python37 3 Y diff --git a/tests/unit/commands/init/test_cli.py b/tests/unit/commands/init/test_cli.py index 2b69356b14..f35b56a07d 100644 --- a/tests/unit/commands/init/test_cli.py +++ b/tests/unit/commands/init/test_cli.py @@ -652,14 +652,14 @@ def test_init_cli_int_with_image_app_template( # 1: AWS Quick Start Templates # 2: Package type - Image - # 13: Java8 base image + # 14: Java8 base image # 1: dependency manager maven # test-project: response to name user_input = """ 1 2 -13 +14 1 test-project """ diff --git a/tests/unit/local/docker/test_lambda_container.py b/tests/unit/local/docker/test_lambda_container.py index 71b167668f..cce093b463 100644 --- a/tests/unit/local/docker/test_lambda_container.py +++ b/tests/unit/local/docker/test_lambda_container.py @@ -21,6 +21,7 @@ Runtime.python38.value, Runtime.python36.value, Runtime.python27.value, + Runtime.python39.value, ] RUNTIMES_WITH_DEBUG_ENV_VARS_ONLY = [ diff --git a/tests/unit/local/docker/test_lambda_debug_settings.py b/tests/unit/local/docker/test_lambda_debug_settings.py index 1eadb6e6f5..59329186cb 100644 --- a/tests/unit/local/docker/test_lambda_debug_settings.py +++ b/tests/unit/local/docker/test_lambda_debug_settings.py @@ -19,6 +19,7 @@ Runtime.python36, Runtime.python37, Runtime.python38, + Runtime.python39, ]