From 77bc97c8da7f652848de970d7be2d2a4195f6a4d Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Sun, 27 Oct 2019 16:58:03 +0800 Subject: [PATCH 1/6] Fix ECR models for Python 3.8 Before this fix, using moto.ecr with Python 3.8 results in the following error: RuntimeError: dictionary keys changed during iteration --- moto/ecr/models.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/moto/ecr/models.py b/moto/ecr/models.py index b03f25dee..f6419269e 100644 --- a/moto/ecr/models.py +++ b/moto/ecr/models.py @@ -2,7 +2,6 @@ from __future__ import unicode_literals import hashlib import re -from copy import copy from datetime import datetime from random import random @@ -27,11 +26,12 @@ class BaseObject(BaseModel): return ''.join(words) def gen_response_object(self): - response_object = copy(self.__dict__) - for key, value in response_object.items(): + response_object = dict() + for key, value in self.__dict__.items(): if '_' in key: response_object[self.camelCase(key)] = value - del response_object[key] + else: + response_object[key] = value return response_object @property From f1ebe8d9467e3b8a8938820061dc4f152452a3c4 Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Sun, 27 Oct 2019 19:38:16 +0800 Subject: [PATCH 2/6] Enable Travis CI tests for Pytho 3.8 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 77dd2ae55..3f73af5aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ python: - 2.7 - 3.6 - 3.7 +- 3.8 env: - TEST_SERVER_MODE=false - TEST_SERVER_MODE=true From 61698f955e69c48b425c2273ceb17865176e55ab Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Sun, 27 Oct 2019 20:00:20 +0800 Subject: [PATCH 3/6] Use new flake8 for Python 3.8 compatibility With the current flake8, which depends on pyflakes<1.7.0,>=1.5.0, linting fails with: AttributeError: 'FlakesChecker' object has no attribute 'CONSTANT' The issue is fixed in pyflakes 2.1.0 [1]. Let's just use the latest flake8. [1] https://github.com/PyCQA/pyflakes/commit/7c74ab0ddccb60a9154c2af5aa4ee4581ccada4a --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 1dd8ef1f8..c5fba292d 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -3,7 +3,7 @@ mock nose sure==1.4.11 coverage -flake8==3.5.0 +flake8==3.7.8 freezegun flask boto>=2.45.0 From 18173a59517e4f57e15a1312b032ec95f476f143 Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Sun, 27 Oct 2019 20:41:22 +0800 Subject: [PATCH 4/6] Replace `# flake8: noqa` with `# noqa` The former syntax is actually a mis-use and rejected since Flake8 3.6 [1]. [1] https://gitlab.com/pycqa/flake8/merge_requests/219 --- moto/__init__.py | 98 +++++++++++++++++------------------ moto/compat.py | 4 +- moto/core/__init__.py | 2 +- moto/dynamodb2/comparisons.py | 12 ++--- moto/swf/models/__init__.py | 18 +++---- scripts/scaffold.py | 2 +- tests/test_ec2/test_vpcs.py | 2 +- 7 files changed, 69 insertions(+), 69 deletions(-) diff --git a/moto/__init__.py b/moto/__init__.py index 8e915933a..36d294657 100644 --- a/moto/__init__.py +++ b/moto/__init__.py @@ -5,55 +5,55 @@ import logging __title__ = 'moto' __version__ = '1.3.14.dev' -from .acm import mock_acm # flake8: noqa -from .apigateway import mock_apigateway, mock_apigateway_deprecated # flake8: noqa -from .athena import mock_athena # flake8: noqa -from .autoscaling import mock_autoscaling, mock_autoscaling_deprecated # flake8: noqa -from .awslambda import mock_lambda, mock_lambda_deprecated # flake8: noqa -from .cloudformation import mock_cloudformation, mock_cloudformation_deprecated # flake8: noqa -from .cloudwatch import mock_cloudwatch, mock_cloudwatch_deprecated # flake8: noqa -from .cognitoidentity import mock_cognitoidentity, mock_cognitoidentity_deprecated # flake8: noqa -from .cognitoidp import mock_cognitoidp, mock_cognitoidp_deprecated # flake8: noqa -from .config import mock_config # flake8: noqa -from .datapipeline import mock_datapipeline, mock_datapipeline_deprecated # flake8: noqa -from .dynamodb import mock_dynamodb, mock_dynamodb_deprecated # flake8: noqa -from .dynamodb2 import mock_dynamodb2, mock_dynamodb2_deprecated # flake8: noqa -from .dynamodbstreams import mock_dynamodbstreams # flake8: noqa -from .ec2 import mock_ec2, mock_ec2_deprecated # flake8: noqa -from .ecr import mock_ecr, mock_ecr_deprecated # flake8: noqa -from .ecs import mock_ecs, mock_ecs_deprecated # flake8: noqa -from .elb import mock_elb, mock_elb_deprecated # flake8: noqa -from .elbv2 import mock_elbv2 # flake8: noqa -from .emr import mock_emr, mock_emr_deprecated # flake8: noqa -from .events import mock_events # flake8: noqa -from .glacier import mock_glacier, mock_glacier_deprecated # flake8: noqa -from .glue import mock_glue # flake8: noqa -from .iam import mock_iam, mock_iam_deprecated # flake8: noqa -from .kinesis import mock_kinesis, mock_kinesis_deprecated # flake8: noqa -from .kms import mock_kms, mock_kms_deprecated # flake8: noqa -from .organizations import mock_organizations # flake8: noqa -from .opsworks import mock_opsworks, mock_opsworks_deprecated # flake8: noqa -from .polly import mock_polly # flake8: noqa -from .rds import mock_rds, mock_rds_deprecated # flake8: noqa -from .rds2 import mock_rds2, mock_rds2_deprecated # flake8: noqa -from .redshift import mock_redshift, mock_redshift_deprecated # flake8: noqa -from .resourcegroups import mock_resourcegroups # flake8: noqa -from .s3 import mock_s3, mock_s3_deprecated # flake8: noqa -from .ses import mock_ses, mock_ses_deprecated # flake8: noqa -from .secretsmanager import mock_secretsmanager # flake8: noqa -from .sns import mock_sns, mock_sns_deprecated # flake8: noqa -from .sqs import mock_sqs, mock_sqs_deprecated # flake8: noqa -from .stepfunctions import mock_stepfunctions # flake8: noqa -from .sts import mock_sts, mock_sts_deprecated # flake8: noqa -from .ssm import mock_ssm # flake8: noqa -from .route53 import mock_route53, mock_route53_deprecated # flake8: noqa -from .swf import mock_swf, mock_swf_deprecated # flake8: noqa -from .xray import mock_xray, mock_xray_client, XRaySegment # flake8: noqa -from .logs import mock_logs, mock_logs_deprecated # flake8: noqa -from .batch import mock_batch # flake8: noqa -from .resourcegroupstaggingapi import mock_resourcegroupstaggingapi # flake8: noqa -from .iot import mock_iot # flake8: noqa -from .iotdata import mock_iotdata # flake8: noqa +from .acm import mock_acm # noqa +from .apigateway import mock_apigateway, mock_apigateway_deprecated # noqa +from .athena import mock_athena # noqa +from .autoscaling import mock_autoscaling, mock_autoscaling_deprecated # noqa +from .awslambda import mock_lambda, mock_lambda_deprecated # noqa +from .cloudformation import mock_cloudformation, mock_cloudformation_deprecated # noqa +from .cloudwatch import mock_cloudwatch, mock_cloudwatch_deprecated # noqa +from .cognitoidentity import mock_cognitoidentity, mock_cognitoidentity_deprecated # noqa +from .cognitoidp import mock_cognitoidp, mock_cognitoidp_deprecated # noqa +from .config import mock_config # noqa +from .datapipeline import mock_datapipeline, mock_datapipeline_deprecated # noqa +from .dynamodb import mock_dynamodb, mock_dynamodb_deprecated # noqa +from .dynamodb2 import mock_dynamodb2, mock_dynamodb2_deprecated # noqa +from .dynamodbstreams import mock_dynamodbstreams # noqa +from .ec2 import mock_ec2, mock_ec2_deprecated # noqa +from .ecr import mock_ecr, mock_ecr_deprecated # noqa +from .ecs import mock_ecs, mock_ecs_deprecated # noqa +from .elb import mock_elb, mock_elb_deprecated # noqa +from .elbv2 import mock_elbv2 # noqa +from .emr import mock_emr, mock_emr_deprecated # noqa +from .events import mock_events # noqa +from .glacier import mock_glacier, mock_glacier_deprecated # noqa +from .glue import mock_glue # noqa +from .iam import mock_iam, mock_iam_deprecated # noqa +from .kinesis import mock_kinesis, mock_kinesis_deprecated # noqa +from .kms import mock_kms, mock_kms_deprecated # noqa +from .organizations import mock_organizations # noqa +from .opsworks import mock_opsworks, mock_opsworks_deprecated # noqa +from .polly import mock_polly # noqa +from .rds import mock_rds, mock_rds_deprecated # noqa +from .rds2 import mock_rds2, mock_rds2_deprecated # noqa +from .redshift import mock_redshift, mock_redshift_deprecated # noqa +from .resourcegroups import mock_resourcegroups # noqa +from .s3 import mock_s3, mock_s3_deprecated # noqa +from .ses import mock_ses, mock_ses_deprecated # noqa +from .secretsmanager import mock_secretsmanager # noqa +from .sns import mock_sns, mock_sns_deprecated # noqa +from .sqs import mock_sqs, mock_sqs_deprecated # noqa +from .stepfunctions import mock_stepfunctions # noqa +from .sts import mock_sts, mock_sts_deprecated # noqa +from .ssm import mock_ssm # noqa +from .route53 import mock_route53, mock_route53_deprecated # noqa +from .swf import mock_swf, mock_swf_deprecated # noqa +from .xray import mock_xray, mock_xray_client, XRaySegment # noqa +from .logs import mock_logs, mock_logs_deprecated # noqa +from .batch import mock_batch # noqa +from .resourcegroupstaggingapi import mock_resourcegroupstaggingapi # noqa +from .iot import mock_iot # noqa +from .iotdata import mock_iotdata # noqa try: diff --git a/moto/compat.py b/moto/compat.py index a92a5f67b..d7f5ab5e6 100644 --- a/moto/compat.py +++ b/moto/compat.py @@ -1,5 +1,5 @@ try: - from collections import OrderedDict # flake8: noqa + from collections import OrderedDict # noqa except ImportError: # python 2.6 or earlier, use backport - from ordereddict import OrderedDict # flake8: noqa + from ordereddict import OrderedDict # noqa diff --git a/moto/core/__init__.py b/moto/core/__init__.py index 801e675df..5e6a4472f 100644 --- a/moto/core/__init__.py +++ b/moto/core/__init__.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from .models import BaseModel, BaseBackend, moto_api_backend # flake8: noqa +from .models import BaseModel, BaseBackend, moto_api_backend # noqa from .responses import ActionAuthenticatorMixin moto_api_backends = {"global": moto_api_backend} diff --git a/moto/dynamodb2/comparisons.py b/moto/dynamodb2/comparisons.py index c6aee7a68..734cfeeb3 100644 --- a/moto/dynamodb2/comparisons.py +++ b/moto/dynamodb2/comparisons.py @@ -91,12 +91,12 @@ class Op(object): # TODO add tests for all of these -EQ_FUNCTION = lambda item_value, test_value: item_value == test_value # flake8: noqa -NE_FUNCTION = lambda item_value, test_value: item_value != test_value # flake8: noqa -LE_FUNCTION = lambda item_value, test_value: item_value <= test_value # flake8: noqa -LT_FUNCTION = lambda item_value, test_value: item_value < test_value # flake8: noqa -GE_FUNCTION = lambda item_value, test_value: item_value >= test_value # flake8: noqa -GT_FUNCTION = lambda item_value, test_value: item_value > test_value # flake8: noqa +EQ_FUNCTION = lambda item_value, test_value: item_value == test_value # noqa +NE_FUNCTION = lambda item_value, test_value: item_value != test_value # noqa +LE_FUNCTION = lambda item_value, test_value: item_value <= test_value # noqa +LT_FUNCTION = lambda item_value, test_value: item_value < test_value # noqa +GE_FUNCTION = lambda item_value, test_value: item_value >= test_value # noqa +GT_FUNCTION = lambda item_value, test_value: item_value > test_value # noqa COMPARISON_FUNCS = { 'EQ': EQ_FUNCTION, diff --git a/moto/swf/models/__init__.py b/moto/swf/models/__init__.py index a8bc57f40..a2bc9a1f7 100644 --- a/moto/swf/models/__init__.py +++ b/moto/swf/models/__init__.py @@ -12,15 +12,15 @@ from ..exceptions import ( SWFTypeDeprecatedFault, SWFValidationException, ) -from .activity_task import ActivityTask # flake8: noqa -from .activity_type import ActivityType # flake8: noqa -from .decision_task import DecisionTask # flake8: noqa -from .domain import Domain # flake8: noqa -from .generic_type import GenericType # flake8: noqa -from .history_event import HistoryEvent # flake8: noqa -from .timeout import Timeout # flake8: noqa -from .workflow_type import WorkflowType # flake8: noqa -from .workflow_execution import WorkflowExecution # flake8: noqa +from .activity_task import ActivityTask # noqa +from .activity_type import ActivityType # noqa +from .decision_task import DecisionTask # noqa +from .domain import Domain # noqa +from .generic_type import GenericType # noqa +from .history_event import HistoryEvent # noqa +from .timeout import Timeout # noqa +from .workflow_type import WorkflowType # noqa +from .workflow_execution import WorkflowExecution # noqa from time import sleep KNOWN_SWF_TYPES = { diff --git a/scripts/scaffold.py b/scripts/scaffold.py index 6c83eeb50..be154f103 100755 --- a/scripts/scaffold.py +++ b/scripts/scaffold.py @@ -119,7 +119,7 @@ def append_mock_to_init_py(service): filtered_lines = [_ for _ in lines if re.match('^from.*mock.*$', _)] last_import_line_index = lines.index(filtered_lines[-1]) - new_line = 'from .{} import mock_{} # flake8: noqa'.format(get_escaped_service(service), get_escaped_service(service)) + new_line = 'from .{} import mock_{} # noqa'.format(get_escaped_service(service), get_escaped_service(service)) lines.insert(last_import_line_index + 1, new_line) body = '\n'.join(lines) + '\n' diff --git a/tests/test_ec2/test_vpcs.py b/tests/test_ec2/test_vpcs.py index ad17deb3c..903c0630d 100644 --- a/tests/test_ec2/test_vpcs.py +++ b/tests/test_ec2/test_vpcs.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals # Ensure 'assert_raises' context manager support for Python 2.6 -import tests.backport_assert_raises # flake8: noqa +import tests.backport_assert_raises # noqa from nose.tools import assert_raises from moto.ec2.exceptions import EC2ClientError from botocore.exceptions import ClientError From 84fb52d0a26603caa8522c7ad90b90ea7ed3d6c5 Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Sun, 27 Oct 2019 21:00:01 +0800 Subject: [PATCH 5/6] Fix remaining flake8 issues Disabling W504 and W605 for now as there are too many instances. --- moto/__init__.py | 2 +- moto/cloudwatch/responses.py | 4 ++-- moto/dynamodb2/comparisons.py | 23 ++++++++--------------- moto/ec2/models.py | 14 +++++++------- moto/ecs/models.py | 4 ++-- moto/iotdata/models.py | 2 +- moto/rds2/models.py | 4 ++-- moto/resourcegroupstaggingapi/models.py | 2 +- moto/ssm/models.py | 6 +++--- tox.ini | 2 +- 10 files changed, 28 insertions(+), 35 deletions(-) diff --git a/moto/__init__.py b/moto/__init__.py index 36d294657..592a20b07 100644 --- a/moto/__init__.py +++ b/moto/__init__.py @@ -1,5 +1,5 @@ from __future__ import unicode_literals -import logging +# import logging # logging.getLogger('boto').setLevel(logging.CRITICAL) __title__ = 'moto' diff --git a/moto/cloudwatch/responses.py b/moto/cloudwatch/responses.py index bf176e1be..b9f20f559 100644 --- a/moto/cloudwatch/responses.py +++ b/moto/cloudwatch/responses.py @@ -96,11 +96,11 @@ class CloudWatchResponse(BaseResponse): extended_statistics = self._get_param('ExtendedStatistics') dimensions = self._get_param('Dimensions') if unit or extended_statistics or dimensions: - raise NotImplemented() + raise NotImplementedError() # TODO: this should instead throw InvalidParameterCombination if not statistics: - raise NotImplemented("Must specify either Statistics or ExtendedStatistics") + raise NotImplementedError("Must specify either Statistics or ExtendedStatistics") datapoints = self.cloudwatch_backend.get_metric_statistics(namespace, metric_name, start_time, end_time, period, statistics) template = self.response_template(GET_METRIC_STATISTICS_TEMPLATE) diff --git a/moto/dynamodb2/comparisons.py b/moto/dynamodb2/comparisons.py index 734cfeeb3..ab0eeb85d 100644 --- a/moto/dynamodb2/comparisons.py +++ b/moto/dynamodb2/comparisons.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals import re -import six -import re from collections import deque from collections import namedtuple @@ -48,11 +46,11 @@ def get_expected(expected): path = AttributePath([key]) if 'Exists' in cond: if cond['Exists']: - conditions.append(FuncAttrExists(path)) + conditions.append(FuncAttrExists(path)) else: - conditions.append(FuncAttrNotExists(path)) + conditions.append(FuncAttrNotExists(path)) elif 'Value' in cond: - conditions.append(OpEqual(path, AttributeValue(cond['Value']))) + conditions.append(OpEqual(path, AttributeValue(cond['Value']))) elif 'ComparisonOperator' in cond: operator_name = cond['ComparisonOperator'] values = [ @@ -221,7 +219,6 @@ class ConditionExpressionParser: # -------------- LITERAL = 'LITERAL' - class Nonterminal: """Enum defining nonterminals for productions.""" @@ -240,7 +237,6 @@ class ConditionExpressionParser: RIGHT_PAREN = 'RIGHT_PAREN' WHITESPACE = 'WHITESPACE' - Node = namedtuple('Node', ['nonterminal', 'kind', 'text', 'value', 'children']) def _lex_condition_expression(self): @@ -286,11 +282,10 @@ class ConditionExpressionParser: if match: match_text = match.group() break - else: # pragma: no cover + else: # pragma: no cover raise ValueError("Cannot parse condition starting at: " + - remaining_expression) + remaining_expression) - value = match_text node = self.Node( nonterminal=nonterminal, kind=self.Kind.LITERAL, @@ -351,7 +346,6 @@ class ConditionExpressionParser: 'size', } - if name.lower() in reserved: # e.g. AND nonterminal = reserved[name.lower()] @@ -748,14 +742,13 @@ class ConditionExpressionParser: elif node.kind == self.Kind.FUNCTION: # size() function_node = node.children[0] - arguments = node.children[1:] + arguments = node.children[1:] function_name = function_node.value arguments = [self._make_operand(arg) for arg in arguments] return FUNC_CLASS[function_name](*arguments) - else: # pragma: no cover + else: # pragma: no cover raise ValueError("Unknown operand: %r" % node) - def _make_op_condition(self, node): if node.kind == self.Kind.OR: lhs, rhs = node.children @@ -796,7 +789,7 @@ class ConditionExpressionParser: return COMPARATOR_CLASS[comparator.value]( self._make_operand(lhs), self._make_operand(rhs)) - else: # pragma: no cover + else: # pragma: no cover raise ValueError("Unknown expression node kind %r" % node.kind) def _assert(self, condition, message, nodes): diff --git a/moto/ec2/models.py b/moto/ec2/models.py index 10d6f2b28..69fd844fd 100644 --- a/moto/ec2/models.py +++ b/moto/ec2/models.py @@ -1229,7 +1229,7 @@ class AmiBackend(object): images = [ami for ami in images if ami.id in ami_ids] if len(images) == 0: - raise InvalidAMIIdError(ami_ids) + raise InvalidAMIIdError(ami_ids) else: # Limit images by launch permissions if exec_users: @@ -3720,8 +3720,8 @@ class VPNConnection(TaggedEC2Resource): self.static_routes = None def get_filter_value(self, filter_name): - return super(VPNConnection, self).get_filter_value( - filter_name, 'DescribeVpnConnections') + return super(VPNConnection, self).get_filter_value( + filter_name, 'DescribeVpnConnections') class VPNConnectionBackend(object): @@ -3950,8 +3950,8 @@ class VpnGateway(TaggedEC2Resource): super(VpnGateway, self).__init__() def get_filter_value(self, filter_name): - return super(VpnGateway, self).get_filter_value( - filter_name, 'DescribeVpnGateways') + return super(VpnGateway, self).get_filter_value( + filter_name, 'DescribeVpnGateways') class VpnGatewayAttachment(object): @@ -4015,8 +4015,8 @@ class CustomerGateway(TaggedEC2Resource): super(CustomerGateway, self).__init__() def get_filter_value(self, filter_name): - return super(CustomerGateway, self).get_filter_value( - filter_name, 'DescribeCustomerGateways') + return super(CustomerGateway, self).get_filter_value( + filter_name, 'DescribeCustomerGateways') class CustomerGatewayBackend(object): diff --git a/moto/ecs/models.py b/moto/ecs/models.py index 5aa9ae2cb..5ba420508 100644 --- a/moto/ecs/models.py +++ b/moto/ecs/models.py @@ -158,8 +158,8 @@ class TaskDefinition(BaseObject): if (original_resource.family != family or original_resource.container_definitions != container_definitions or original_resource.volumes != volumes): - # currently TaskRoleArn isn't stored at TaskDefinition - # instances + # currently TaskRoleArn isn't stored at TaskDefinition + # instances ecs_backend = ecs_backends[region_name] ecs_backend.deregister_task_definition(original_resource.arn) return ecs_backend.register_task_definition( diff --git a/moto/iotdata/models.py b/moto/iotdata/models.py index fec066f07..010017fc3 100644 --- a/moto/iotdata/models.py +++ b/moto/iotdata/models.py @@ -163,7 +163,7 @@ class IoTDataPlaneBackend(BaseBackend): raise InvalidRequestException('State contains an invalid node') if 'version' in payload and thing.thing_shadow.version != payload['version']: - raise ConflictException('Version conflict') + raise ConflictException('Version conflict') new_shadow = FakeShadow.create_from_previous_version(thing.thing_shadow, payload) thing.thing_shadow = new_shadow return thing.thing_shadow diff --git a/moto/rds2/models.py b/moto/rds2/models.py index cd56599e6..b9a250646 100644 --- a/moto/rds2/models.py +++ b/moto/rds2/models.py @@ -875,8 +875,8 @@ class RDS2Backend(BaseBackend): database = self.describe_databases(db_instance_identifier)[0] # todo: certain rds types not allowed to be stopped at this time. if database.is_replica or database.multi_az: - # todo: more db types not supported by stop/start instance api - raise InvalidDBClusterStateFaultError(db_instance_identifier) + # todo: more db types not supported by stop/start instance api + raise InvalidDBClusterStateFaultError(db_instance_identifier) if database.status != 'available': raise InvalidDBInstanceStateError(db_instance_identifier, 'stop') if db_snapshot_identifier: diff --git a/moto/resourcegroupstaggingapi/models.py b/moto/resourcegroupstaggingapi/models.py index 3f15017cc..68430a5bf 100644 --- a/moto/resourcegroupstaggingapi/models.py +++ b/moto/resourcegroupstaggingapi/models.py @@ -244,7 +244,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend): def get_kms_tags(kms_key_id): result = [] for tag in self.kms_backend.list_resource_tags(kms_key_id): - result.append({'Key': tag['TagKey'], 'Value': tag['TagValue']}) + result.append({'Key': tag['TagKey'], 'Value': tag['TagValue']}) return result if not resource_type_filters or 'kms' in resource_type_filters: diff --git a/moto/ssm/models.py b/moto/ssm/models.py index 39bd63ede..e5e52c0c9 100644 --- a/moto/ssm/models.py +++ b/moto/ssm/models.py @@ -210,9 +210,9 @@ class Command(BaseModel): 'An error occurred (InvocationDoesNotExist) when calling the GetCommandInvocation operation') if plugin_name is not None and invocation['PluginName'] != plugin_name: - raise RESTError( - 'InvocationDoesNotExist', - 'An error occurred (InvocationDoesNotExist) when calling the GetCommandInvocation operation') + raise RESTError( + 'InvocationDoesNotExist', + 'An error occurred (InvocationDoesNotExist) when calling the GetCommandInvocation operation') return invocation diff --git a/tox.ini b/tox.ini index 570b5790f..1235a8e2b 100644 --- a/tox.ini +++ b/tox.ini @@ -15,5 +15,5 @@ commands = nosetests {posargs} [flake8] -ignore = E128,E501 +ignore = E128,E501,W504,W605 exclude = moto/packages,dist From 8313142f449887133638d36806b0d21e85644e9b Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Sun, 27 Oct 2019 23:26:49 +0800 Subject: [PATCH 6/6] Use Buster container images for Python 3.8 --- .travis.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3f73af5aa..c69c3ea1f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,14 @@ install: python setup.py sdist if [ "$TEST_SERVER_MODE" = "true" ]; then - docker run --rm -t --name motoserver -e TEST_SERVER_MODE=true -e AWS_SECRET_ACCESS_KEY=server_secret -e AWS_ACCESS_KEY_ID=server_key -v `pwd`:/moto -p 5000:5000 -v /var/run/docker.sock:/var/run/docker.sock python:${TRAVIS_PYTHON_VERSION}-stretch /moto/travis_moto_server.sh & + if [ "$TRAVIS_PYTHON_VERSION" = "3.8" ]; then + # Python 3.8 does not provide Stretch images yet [1] + # [1] https://github.com/docker-library/python/issues/428 + PYTHON_DOCKER_TAG=${TRAVIS_PYTHON_VERSION}-buster + else + PYTHON_DOCKER_TAG=${TRAVIS_PYTHON_VERSION}-stretch + fi + docker run --rm -t --name motoserver -e TEST_SERVER_MODE=true -e AWS_SECRET_ACCESS_KEY=server_secret -e AWS_ACCESS_KEY_ID=server_key -v `pwd`:/moto -p 5000:5000 -v /var/run/docker.sock:/var/run/docker.sock python:${PYTHON_DOCKER_TAG} /moto/travis_moto_server.sh & fi travis_retry pip install boto==2.45.0 travis_retry pip install boto3