From db6fcd624952e131851d28618e02d61a9d03ae15 Mon Sep 17 00:00:00 2001 From: Jacob Fuss <32497805+jfuss@users.noreply.github.com> Date: Tue, 24 Dec 2019 15:46:29 -0600 Subject: [PATCH] chore: Support Python3.8 (#1519) --- appveyor.yml | 12 ++++- requirements/base.txt | 2 - samcli/settings/__init__.py | 1 - setup.py | 1 + .../local/apigw/test_local_apigw_service.py | 14 ++--- .../test_local_lambda_invoke_service.py | 53 ++++++++++++------- 6 files changed, 49 insertions(+), 34 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 5e2758975f..ce91e0a4cb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,7 @@ environment: PYTHON_ARCH: '64' NOSE_PARAMETERIZED_NO_WARN: 1 INSTALL_PY_37_PIP: 1 + INSTALL_PY_38_PIP: 1 - PYTHON_HOME: "C:\\Python37-x64" PYTHON_VERSION: '3.7.4' @@ -21,6 +22,15 @@ environment: RUN_SMOKE: 1 NOSE_PARAMETERIZED_NO_WARN: 1 INSTALL_PY_36_PIP: 1 + INSTALL_PY_38_PIP: 1 + + - PYTHON_HOME: "C:\\Python38-x64" + PYTHON_VERSION: '3.8.0' + PYTHON_ARCH: '64' + RUN_SMOKE: 1 + NOSE_PARAMETERIZED_NO_WARN: 1 + INSTALL_PY_36_PIP: 1 + INSTALL_PY_37_PIP: 1 for: - @@ -102,7 +112,7 @@ for: - sh: "curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py" - sh: "sudo apt-get -y install python3-distutils" - - sh: "python3.8 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 3c8e479a86..36266051c7 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -12,6 +12,4 @@ python-dateutil~=2.6, <2.8.1 requests==2.22.0 serverlessrepo==0.1.9 aws_lambda_builders==0.6.0 -# https://github.com/mhammond/pywin32/issues/1439 -pywin32 < 226; sys_platform == 'win32' tomlkit==0.5.8 diff --git a/samcli/settings/__init__.py b/samcli/settings/__init__.py index 266d363ff6..da4146091e 100644 --- a/samcli/settings/__init__.py +++ b/samcli/settings/__init__.py @@ -1,4 +1,3 @@ -# flake8: noqa """ Default Settings used by the CLI. diff --git a/setup.py b/setup.py index 9c118def11..d6fcc2acca 100644 --- a/setup.py +++ b/setup.py @@ -60,6 +60,7 @@ def read_version(): "Programming Language :: Python", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", "Topic :: Internet", "Topic :: Software Development :: Build Tools", "Topic :: Utilities", diff --git a/tests/unit/local/apigw/test_local_apigw_service.py b/tests/unit/local/apigw/test_local_apigw_service.py index d9f3fd1dc3..8545a29be5 100644 --- a/tests/unit/local/apigw/test_local_apigw_service.py +++ b/tests/unit/local/apigw/test_local_apigw_service.py @@ -226,13 +226,10 @@ def test_request_handler_errors_when_unable_to_read_binary_data(self, service_er result = self.service._request_handler() self.assertEqual(result, failure_mock) - @patch("samcli.local.apigw.local_apigw_service.request") - def test_get_current_route(self, request_patch): + def test_get_current_route(self): request_mock = Mock() - request_mock.endpoint = "path" - request_mock.method = "method" - - request_patch.return_value = request_mock + request_mock.return_value.endpoint = "path" + request_mock.return_value.method = "method" route_key_method_mock = Mock() route_key_method_mock.return_value = "method:path" @@ -241,8 +238,7 @@ def test_get_current_route(self, request_patch): self.assertEqual(self.service._get_current_route(request_mock), "function") - @patch("samcli.local.apigw.local_apigw_service.request") - def test_get_current_route_keyerror(self, request_patch): + def test_get_current_route_keyerror(self): """ When the a HTTP request for given method+path combination is allowed by Flask but not in the list of routes, something is messed up. Flask should be configured only from the list of routes. @@ -252,8 +248,6 @@ def test_get_current_route_keyerror(self, request_patch): request_mock.endpoint = "path" request_mock.method = "method" - request_patch.return_value = request_mock - route_key_method_mock = Mock() route_key_method_mock.return_value = "method:path" self.service._route_key = route_key_method_mock diff --git a/tests/unit/local/lambda_service/test_local_lambda_invoke_service.py b/tests/unit/local/lambda_service/test_local_lambda_invoke_service.py index 14efa11e5c..ff2222a857 100644 --- a/tests/unit/local/lambda_service/test_local_lambda_invoke_service.py +++ b/tests/unit/local/lambda_service/test_local_lambda_invoke_service.py @@ -1,6 +1,7 @@ from unittest import TestCase from unittest.mock import Mock, patch, ANY, call +from samcli.local.lambda_service import local_lambda_invoke_service from samcli.local.lambda_service.local_lambda_invoke_service import LocalLambdaInvokeService from samcli.local.lambdafn.exceptions import FunctionNotFound @@ -46,12 +47,15 @@ def test_create_service_endpoints(self, flask_mock, error_handling_mock): @patch("samcli.local.lambda_service.local_lambda_invoke_service.LocalLambdaInvokeService.service_response") @patch("samcli.local.lambda_service.local_lambda_invoke_service.LambdaOutputParser") - @patch("samcli.local.lambda_service.local_lambda_invoke_service.request") - def test_invoke_request_handler(self, request_mock, lambda_output_parser_mock, service_response_mock): + def test_invoke_request_handler(self, lambda_output_parser_mock, service_response_mock): lambda_output_parser_mock.get_lambda_output.return_value = "hello world", None, False service_response_mock.return_value = "request response" + + request_mock = Mock() request_mock.get_data.return_value = b"{}" + local_lambda_invoke_service.request = request_mock + lambda_runner_mock = Mock() service = LocalLambdaInvokeService(lambda_runner=lambda_runner_mock, port=3000, host="localhost") @@ -63,9 +67,11 @@ def test_invoke_request_handler(self, request_mock, lambda_output_parser_mock, s service_response_mock.assert_called_once_with("hello world", {"Content-Type": "application/json"}, 200) @patch("samcli.local.lambda_service.local_lambda_invoke_service.LambdaErrorResponses") - @patch("samcli.local.lambda_service.local_lambda_invoke_service.request") - def test_invoke_request_handler_on_incorrect_path(self, request_mock, lambda_error_responses_mock): + def test_invoke_request_handler_on_incorrect_path(self, lambda_error_responses_mock): + request_mock = Mock() request_mock.get_data.return_value = b"{}" + local_lambda_invoke_service.request = request_mock + lambda_runner_mock = Mock() lambda_runner_mock.invoke.side_effect = FunctionNotFound @@ -83,11 +89,12 @@ def test_invoke_request_handler_on_incorrect_path(self, request_mock, lambda_err @patch("samcli.local.lambda_service.local_lambda_invoke_service.LocalLambdaInvokeService.service_response") @patch("samcli.local.lambda_service.local_lambda_invoke_service.LambdaOutputParser") - @patch("samcli.local.lambda_service.local_lambda_invoke_service.request") def test_request_handler_returns_process_stdout_when_making_response( - self, request_mock, lambda_output_parser_mock, service_response_mock + self, lambda_output_parser_mock, service_response_mock ): + request_mock = Mock() request_mock.get_data.return_value = b"{}" + local_lambda_invoke_service.request = request_mock lambda_logs = "logs" lambda_response = "response" @@ -128,13 +135,12 @@ def test_construct_error_handling(self, lambda_error_response_mock): @patch("samcli.local.lambda_service.local_lambda_invoke_service.LocalLambdaInvokeService.service_response") @patch("samcli.local.lambda_service.local_lambda_invoke_service.LambdaOutputParser") - @patch("samcli.local.lambda_service.local_lambda_invoke_service.request") - def test_invoke_request_handler_with_lambda_that_errors( - self, request_mock, lambda_output_parser_mock, service_response_mock - ): + def test_invoke_request_handler_with_lambda_that_errors(self, lambda_output_parser_mock, service_response_mock): lambda_output_parser_mock.get_lambda_output.return_value = "hello world", None, True service_response_mock.return_value = "request response" + request_mock = Mock() request_mock.get_data.return_value = b"{}" + local_lambda_invoke_service.request = request_mock lambda_runner_mock = Mock() service = LocalLambdaInvokeService(lambda_runner=lambda_runner_mock, port=3000, host="localhost") @@ -150,11 +156,13 @@ def test_invoke_request_handler_with_lambda_that_errors( @patch("samcli.local.lambda_service.local_lambda_invoke_service.LocalLambdaInvokeService.service_response") @patch("samcli.local.lambda_service.local_lambda_invoke_service.LambdaOutputParser") - @patch("samcli.local.lambda_service.local_lambda_invoke_service.request") - def test_invoke_request_handler_with_no_data(self, request_mock, lambda_output_parser_mock, service_response_mock): + def test_invoke_request_handler_with_no_data(self, lambda_output_parser_mock, service_response_mock): lambda_output_parser_mock.get_lambda_output.return_value = "hello world", None, False service_response_mock.return_value = "request response" + + request_mock = Mock() request_mock.get_data.return_value = None + local_lambda_invoke_service.request = request_mock lambda_runner_mock = Mock() service = LocalLambdaInvokeService(lambda_runner=lambda_runner_mock, port=3000, host="localhost") @@ -169,12 +177,13 @@ def test_invoke_request_handler_with_no_data(self, request_mock, lambda_output_p class TestValidateRequestHandling(TestCase): @patch("samcli.local.lambda_service.local_lambda_invoke_service.LambdaErrorResponses") - @patch("samcli.local.lambda_service.local_lambda_invoke_service.request") - def test_request_with_non_json_data(self, flask_request, lambda_error_responses_mock): + def test_request_with_non_json_data(self, lambda_error_responses_mock): + flask_request = Mock() flask_request.get_data.return_value = b"notat:asdfasdf" flask_request.headers = {} flask_request.content_type = "application/json" flask_request.args = {} + local_lambda_invoke_service.request = flask_request lambda_error_responses_mock.invalid_request_content.return_value = "InvalidRequestContent" @@ -187,12 +196,13 @@ def test_request_with_non_json_data(self, flask_request, lambda_error_responses_ lambda_error_responses_mock.invalid_request_content.assert_called_once_with(expected_called_with) @patch("samcli.local.lambda_service.local_lambda_invoke_service.LambdaErrorResponses") - @patch("samcli.local.lambda_service.local_lambda_invoke_service.request") - def test_request_with_query_strings(self, flask_request, lambda_error_responses_mock): + def test_request_with_query_strings(self, lambda_error_responses_mock): + flask_request = Mock() flask_request.get_data.return_value = None flask_request.headers = {} flask_request.content_type = "application/json" flask_request.args = {"key": "value"} + local_lambda_invoke_service.request = flask_request lambda_error_responses_mock.invalid_request_content.return_value = "InvalidRequestContent" @@ -205,12 +215,13 @@ def test_request_with_query_strings(self, flask_request, lambda_error_responses_ ) @patch("samcli.local.lambda_service.local_lambda_invoke_service.LambdaErrorResponses") - @patch("samcli.local.lambda_service.local_lambda_invoke_service.request") - def test_request_log_type_not_None(self, flask_request, lambda_error_responses_mock): + def test_request_log_type_not_None(self, lambda_error_responses_mock): + flask_request = Mock() flask_request.get_data.return_value = None flask_request.headers = {"X-Amz-Log-Type": "Tail"} flask_request.content_type = "application/json" flask_request.args = {} + local_lambda_invoke_service.request = flask_request lambda_error_responses_mock.not_implemented_locally.return_value = "NotImplementedLocally" @@ -223,12 +234,13 @@ def test_request_log_type_not_None(self, flask_request, lambda_error_responses_m ) @patch("samcli.local.lambda_service.local_lambda_invoke_service.LambdaErrorResponses") - @patch("samcli.local.lambda_service.local_lambda_invoke_service.request") - def test_request_invocation_type_not_ResponseRequest(self, flask_request, lambda_error_responses_mock): + def test_request_invocation_type_not_ResponseRequest(self, lambda_error_responses_mock): + flask_request = Mock() flask_request.get_data.return_value = None flask_request.headers = {"X-Amz-Invocation-Type": "DryRun"} flask_request.content_type = "application/json" flask_request.args = {} + local_lambda_invoke_service.request = flask_request lambda_error_responses_mock.not_implemented_locally.return_value = "NotImplementedLocally" @@ -246,6 +258,7 @@ def test_request_with_no_data(self, flask_request): flask_request.headers = {} flask_request.content_type = "application/json" flask_request.args = {} + local_lambda_invoke_service.request = flask_request response = LocalLambdaInvokeService.validate_request()