diff --git a/moto/__init__.py b/moto/__init__.py index 911630ba3..6cad9295d 100644 --- a/moto/__init__.py +++ b/moto/__init__.py @@ -3,30 +3,8 @@ import sys from contextlib import ContextDecorator -def lazy_load( - module_name, - element, - boto3_name=None, - backend=None, - warn_repurpose=False, - use_instead=None, -): +def lazy_load(module_name, element, boto3_name=None, backend=None): def f(*args, **kwargs): - if warn_repurpose: - import warnings - - warnings.warn( - f"Module {element} has been deprecated, and will be repurposed in a later release. " - "Please see https://github.com/spulec/moto/issues/4526 for more information." - ) - if use_instead: - import warnings - - used, recommended = use_instead - warnings.warn( - f"Module {used} has been deprecated, and will be removed in a later release. Please use {recommended} instead. " - "See https://github.com/spulec/moto/issues/4526 for more information." - ) module = importlib.import_module(module_name, "moto") return getattr(module, element)(*args, **kwargs) @@ -77,9 +55,6 @@ mock_dax = lazy_load(".dax", "mock_dax") mock_dms = lazy_load(".dms", "mock_dms") mock_ds = lazy_load(".ds", "mock_ds") mock_dynamodb = lazy_load(".dynamodb", "mock_dynamodb") -mock_dynamodb2 = lazy_load( - ".dynamodb", "mock_dynamodb", use_instead=("mock_dynamodb2", "mock_dynamodb") -) mock_dynamodbstreams = lazy_load(".dynamodbstreams", "mock_dynamodbstreams") mock_elasticbeanstalk = lazy_load( ".elasticbeanstalk", "mock_elasticbeanstalk", backend="eb_backends" @@ -137,7 +112,6 @@ mock_polly = lazy_load(".polly", "mock_polly") mock_quicksight = lazy_load(".quicksight", "mock_quicksight") mock_ram = lazy_load(".ram", "mock_ram") mock_rds = lazy_load(".rds", "mock_rds") -mock_rds2 = lazy_load(".rds", "mock_rds", use_instead=("mock_rds2", "mock_rds")) mock_redshift = lazy_load(".redshift", "mock_redshift") mock_redshiftdata = lazy_load( ".redshiftdata", "mock_redshiftdata", boto3_name="redshift-data" @@ -190,11 +164,7 @@ class MockAll(ContextDecorator): def __init__(self): self.mocks = [] for mock in dir(sys.modules["moto"]): - if ( - mock.startswith("mock_") - and not mock.endswith("_deprecated") - and not mock == ("mock_all") - ): + if mock.startswith("mock_") and not mock == ("mock_all"): self.mocks.append(globals()[mock]()) def __enter__(self): diff --git a/moto/backends.py b/moto/backends.py index ff4137487..2680e73c4 100644 --- a/moto/backends.py +++ b/moto/backends.py @@ -3,11 +3,7 @@ import moto import sys -decorators = [ - d - for d in dir(moto) - if d.startswith("mock_") and not d.endswith("_deprecated") and not d == "mock_all" -] +decorators = [d for d in dir(moto) if d.startswith("mock_") and not d == "mock_all"] decorator_functions = [getattr(moto, f) for f in decorators] BACKENDS = {f.boto3_name: (f.name, f.backend) for f in decorator_functions} BACKENDS["dynamodb_v20111205"] = ("dynamodb_v20111205", "dynamodb_backends") diff --git a/moto/dynamodb/parsing/executors.py b/moto/dynamodb/parsing/executors.py index 2b403ff14..3ca092754 100644 --- a/moto/dynamodb/parsing/executors.py +++ b/moto/dynamodb/parsing/executors.py @@ -270,7 +270,7 @@ class UpdateExpressionExecutor(object): def execute(self, node=None): """ - As explained in moto.dynamodb2.parsing.expressions.NestableExpressionParserMixin._create_node the order of nodes + As explained in moto.dynamodb.parsing.expressions.NestableExpressionParserMixin._create_node the order of nodes in the AST can be translated of the order of statements in the expression. As such we can start at the root node and process the nodes 1-by-1. If no specific execution for the node type is defined we can execute the children in order since it will be a container node that is expandable and left child will be first in the statement. diff --git a/moto/dynamodb/parsing/expressions.py b/moto/dynamodb/parsing/expressions.py index b3d2562cc..0c558fdd3 100644 --- a/moto/dynamodb/parsing/expressions.py +++ b/moto/dynamodb/parsing/expressions.py @@ -116,7 +116,7 @@ class NestableExpressionParserMixin(object): self.target_clauses looks like: ( SET a=3 >> REMOVE b ) Returns: - moto.dynamodb2.ast_nodes.Node: Node of an AST representing the Expression as produced by the factory. + moto.dynamodb.ast_nodes.Node: Node of an AST representing the Expression as produced by the factory. """ assert len(self.target_clauses) > 0, "No nodes for {cn}".format( cn=self.__class__.__name__ @@ -151,7 +151,7 @@ class ExpressionParser(metaclass=abc.ABCMeta): Start parsing the token_list from token_pos for the factory type. Returns: - moto.dynamodb2.ast_nodes.Node: AST which is root node of resulting abstract syntax tree + moto.dynamodb.ast_nodes.Node: AST which is root node of resulting abstract syntax tree """ @classmethod @@ -164,7 +164,7 @@ class ExpressionParser(metaclass=abc.ABCMeta): """ Args: - token(moto.dynamodb2.tokens.Token): + token(moto.dynamodb.tokens.Token): Returns: bool: True if token is a possible start for entries processed by `cls` @@ -200,7 +200,7 @@ class ExpressionParser(metaclass=abc.ABCMeta): Get the next token to be processed Returns: - moto.dynamodb2.tokens.Token: or None if no more next token + moto.dynamodb.tokens.Token: or None if no more next token """ try: return self.token_list[self.token_pos] @@ -413,7 +413,7 @@ class NestableBinExpressionParser(ExpressionParser): self.target_nodes looks like: ( a >> + >> :val >> - >> :val2 ) Returns: - moto.dynamodb2.ast_nodes.Node: Node of an AST representing the Expression as produced by the factory. + moto.dynamodb.ast_nodes.Node: Node of an AST representing the Expression as produced by the factory. """ if len(self.target_nodes) == 1: return UpdateExpressionValue(children=[self.target_nodes.popleft()]) diff --git a/moto/dynamodb/responses.py b/moto/dynamodb/responses.py index b0fa105b8..93b7467bb 100644 --- a/moto/dynamodb/responses.py +++ b/moto/dynamodb/responses.py @@ -134,8 +134,8 @@ class DynamoHandler(BaseResponse): @property def dynamodb_backend(self): """ - :return: DynamoDB2 Backend - :rtype: moto.dynamodb2.models.DynamoDBBackend + :return: DynamoDB Backend + :rtype: moto.dynamodb.models.DynamoDBBackend """ return dynamodb_backends[self.current_account][self.region] diff --git a/tests/test_dynamodb2/__init__.py b/tests/test_dynamodb2/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/test_dynamodb2/test_dynamodb.py b/tests/test_dynamodb2/test_dynamodb.py deleted file mode 100644 index 197f2eed1..000000000 --- a/tests/test_dynamodb2/test_dynamodb.py +++ /dev/null @@ -1,140 +0,0 @@ -import boto3 -import sure # noqa # pylint: disable=unused-import -import pytest - -from boto3.dynamodb.conditions import Key -from moto import mock_dynamodb2 - - -def test_deprecation_warning(): - with pytest.warns(None) as record: - mock_dynamodb2() - str(record[0].message).should.contain( - "Module mock_dynamodb2 has been deprecated, and will be removed in a later release" - ) - - -""" -Copy some basics test from DynamoDB -Verify that the behaviour still works using the 'mock_dynamodb2' decorator -""" - - -@mock_dynamodb2 -def test_basic_projection_expression_using_get_item(): - dynamodb = boto3.resource("dynamodb", region_name="us-east-1") - - # Create the DynamoDB table. - dynamodb.create_table( - TableName="users", - KeySchema=[ - {"AttributeName": "forum_name", "KeyType": "HASH"}, - {"AttributeName": "subject", "KeyType": "RANGE"}, - ], - AttributeDefinitions=[ - {"AttributeName": "forum_name", "AttributeType": "S"}, - {"AttributeName": "subject", "AttributeType": "S"}, - ], - ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5}, - ) - table = dynamodb.Table("users") - - table.put_item( - Item={"forum_name": "the-key", "subject": "123", "body": "some test message"} - ) - - table.put_item( - Item={ - "forum_name": "not-the-key", - "subject": "123", - "body": "some other test message", - } - ) - result = table.get_item( - Key={"forum_name": "the-key", "subject": "123"}, - ProjectionExpression="body, subject", - ) - - result["Item"].should.be.equal({"subject": "123", "body": "some test message"}) - - # The projection expression should not remove data from storage - result = table.get_item(Key={"forum_name": "the-key", "subject": "123"}) - - result["Item"].should.be.equal( - {"forum_name": "the-key", "subject": "123", "body": "some test message"} - ) - - -@mock_dynamodb2 -def test_condition_expression_with_dot_in_attr_name(): - dynamodb = boto3.resource("dynamodb", region_name="us-east-2") - table_name = "Test" - dynamodb.create_table( - TableName=table_name, - KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}], - AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}], - BillingMode="PAY_PER_REQUEST", - ) - table = dynamodb.Table(table_name) - - email_like_str = "test@foo.com" - record = {"id": "key-0", "first": {email_like_str: {"third": {"VALUE"}}}} - table.put_item(Item=record) - - table.update_item( - Key={"id": "key-0"}, - UpdateExpression="REMOVE #first.#second, #other", - ExpressionAttributeNames={ - "#first": "first", - "#second": email_like_str, - "#third": "third", - "#other": "other", - }, - ExpressionAttributeValues={":value": "VALUE", ":one": 1}, - ConditionExpression="size(#first.#second.#third) = :one AND contains(#first.#second.#third, :value)", - ReturnValues="ALL_NEW", - ) - - item = table.get_item(Key={"id": "key-0"})["Item"] - item.should.equal({"id": "key-0", "first": {}}) - - -@mock_dynamodb2 -def test_query_filter_boto3(): - table_schema = { - "KeySchema": [ - {"AttributeName": "pk", "KeyType": "HASH"}, - {"AttributeName": "sk", "KeyType": "RANGE"}, - ], - "AttributeDefinitions": [ - {"AttributeName": "pk", "AttributeType": "S"}, - {"AttributeName": "sk", "AttributeType": "S"}, - ], - } - - dynamodb = boto3.resource("dynamodb", region_name="us-east-1") - table = dynamodb.create_table( - TableName="test-table", BillingMode="PAY_PER_REQUEST", **table_schema - ) - - for i in range(0, 3): - table.put_item(Item={"pk": "pk", "sk": "sk-{}".format(i)}) - - res = table.query(KeyConditionExpression=Key("pk").eq("pk")) - res["Items"].should.have.length_of(3) - - res = table.query(KeyConditionExpression=Key("pk").eq("pk") & Key("sk").lt("sk-1")) - res["Items"].should.have.length_of(1) - res["Items"].should.equal([{"pk": "pk", "sk": "sk-0"}]) - - res = table.query(KeyConditionExpression=Key("pk").eq("pk") & Key("sk").lte("sk-1")) - res["Items"].should.have.length_of(2) - res["Items"].should.equal([{"pk": "pk", "sk": "sk-0"}, {"pk": "pk", "sk": "sk-1"}]) - - res = table.query(KeyConditionExpression=Key("pk").eq("pk") & Key("sk").gt("sk-1")) - res["Items"].should.have.length_of(1) - res["Items"].should.equal([{"pk": "pk", "sk": "sk-2"}]) - - res = table.query(KeyConditionExpression=Key("pk").eq("pk") & Key("sk").gte("sk-1")) - res["Items"].should.have.length_of(2) - res["Items"].should.equal([{"pk": "pk", "sk": "sk-1"}, {"pk": "pk", "sk": "sk-2"}]) diff --git a/tests/test_rds2/test_rds2.py b/tests/test_rds2/test_rds2.py deleted file mode 100644 index 41aa6a58e..000000000 --- a/tests/test_rds2/test_rds2.py +++ /dev/null @@ -1,80 +0,0 @@ -import boto3 -import pytest -import sure # noqa # pylint: disable=unused-import - -from moto import mock_rds2 -from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID - - -def test_deprecation_warning(): - with pytest.warns(None) as record: - mock_rds2() - str(record[0].message).should.contain( - "Module mock_rds2 has been deprecated, and will be removed in a later release." - ) - str(record[0].message).should.contain("Please use mock_rds instead.") - - -@mock_rds2 -def test_create_db_cluster__verify_default_properties(): - client = boto3.client("rds", region_name="eu-north-1") - - resp = client.create_db_cluster( - DBClusterIdentifier="cluster-id", - Engine="aurora", - MasterUsername="root", - MasterUserPassword="hunter2_", - ) - resp.should.have.key("DBCluster") - - cluster = resp["DBCluster"] - - cluster.shouldnt.have.key( - "DatabaseName" - ) # This was not supplied, so should not be returned - - cluster.should.have.key("AllocatedStorage").equal(1) - cluster.should.have.key("AvailabilityZones") - set(cluster["AvailabilityZones"]).should.equal( - {"eu-north-1a", "eu-north-1b", "eu-north-1c"} - ) - cluster.should.have.key("BackupRetentionPeriod").equal(1) - cluster.should.have.key("DBClusterIdentifier").equal("cluster-id") - cluster.should.have.key("DBClusterParameterGroup").equal("default.aurora8.0") - cluster.should.have.key("DBSubnetGroup").equal("default") - cluster.should.have.key("Status").equal("creating") - cluster.should.have.key("Endpoint").match( - "cluster-id.cluster-[a-z0-9]{12}.eu-north-1.rds.amazonaws.com" - ) - endpoint = cluster["Endpoint"] - expected_readonly = endpoint.replace( - "cluster-id.cluster-", "cluster-id.cluster-ro-" - ) - cluster.should.have.key("ReaderEndpoint").equal(expected_readonly) - cluster.should.have.key("MultiAZ").equal(False) - cluster.should.have.key("Engine").equal("aurora") - cluster.should.have.key("EngineVersion").equal("5.6.mysql_aurora.1.22.5") - cluster.should.have.key("Port").equal(3306) - cluster.should.have.key("MasterUsername").equal("root") - cluster.should.have.key("PreferredBackupWindow").equal("01:37-02:07") - cluster.should.have.key("PreferredMaintenanceWindow").equal("wed:02:40-wed:03:10") - cluster.should.have.key("ReadReplicaIdentifiers").equal([]) - cluster.should.have.key("DBClusterMembers").equal([]) - cluster.should.have.key("VpcSecurityGroups") - cluster.should.have.key("HostedZoneId") - cluster.should.have.key("StorageEncrypted").equal(False) - cluster.should.have.key("DbClusterResourceId").match(r"cluster-[A-Z0-9]{26}") - cluster.should.have.key("DBClusterArn").equal( - f"arn:aws:rds:eu-north-1:{ACCOUNT_ID}:cluster:cluster-id" - ) - cluster.should.have.key("AssociatedRoles").equal([]) - cluster.should.have.key("IAMDatabaseAuthenticationEnabled").equal(False) - cluster.should.have.key("EngineMode").equal("provisioned") - cluster.should.have.key("DeletionProtection").equal(False) - cluster.should.have.key("HttpEndpointEnabled").equal(False) - cluster.should.have.key("CopyTagsToSnapshot").equal(False) - cluster.should.have.key("CrossAccountClone").equal(False) - cluster.should.have.key("DeletionProtection").equal(False) - cluster.should.have.key("DomainMemberships").equal([]) - cluster.should.have.key("TagList").equal([]) - cluster.should.have.key("ClusterCreateTime")