Repository: getmoto/moto

Issue:
can not stop mocking after moto==1.3.14
### versions

```bash
$ python --version
Python 3.6.8
$ pip freeze | grep boto
boto==2.49.0
boto3==1.10.19
botocore==1.13.19
```

### Reporting Bugs

I mock only DynamoDB and run S3 client on real environment. But it has not worked since I update moto to `1.3.14`.

Here is a minimum sample code.

```python
import boto3
import moto


if __name__ == '__main__':
    print(moto.__version__)
    mock = moto.mock_dynamodb2()
    mock.start()
    boto3.client('dynamodb')
    mock.stop()
    bucket = boto3.resource('s3').Bucket('test-bucket')
    print(list(bucket.objects.filter(Prefix='dummy')))
```

Although this code works on `moto==1.3.13`,

```bash
$ AWS_ACCESS_KEY_ID=xxx AWS_SECRET_ACCESS_KEY=xxx AWS_DEFAULT_REGION=xxx python main.py 
1.3.13
[s3.ObjectSummary(bucket_name='test-bucket', key='dummy')]
```

does not work on `moto==1.3.14`.

```bash
$ AWS_ACCESS_KEY_ID=xxx AWS_SECRET_ACCESS_KEY=xxx AWS_DEFAULT_REGION=xxx python main.py 
1.3.14
Traceback (most recent call last):
  File "main.py", line 12, in <module>
    print(list(bucket.objects.filter(Prefix='dummy')))
  File "/home/nakagawa/.pyenv/versions/3.6.8/lib/python3.6/site-packages/boto3/resources/collection.py", line 83, in __iter__
    for page in self.pages():
  File "/home/nakagawa/.pyenv/versions/3.6.8/lib/python3.6/site-packages/boto3/resources/collection.py", line 166, in pages
    for page in pages:
  File "/home/nakagawa/.pyenv/versions/3.6.8/lib/python3.6/site-packages/botocore/paginate.py", line 255, in __iter__
    response = self._make_request(current_kwargs)
  File "/home/nakagawa/.pyenv/versions/3.6.8/lib/python3.6/site-packages/botocore/paginate.py", line 332, in _make_request
    return self._method(**current_kwargs)
  File "/home/nakagawa/.pyenv/versions/3.6.8/lib/python3.6/site-packages/botocore/client.py", line 357, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/home/nakagawa/.pyenv/versions/3.6.8/lib/python3.6/site-packages/botocore/client.py", line 661, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (InvalidAccessKeyId) when calling the ListObjects operation: The AWS Access Key Id you provided does not exist in our records.
```


Discussion:
What happens when you use the Context Manager: https://github.com/spulec/moto#context-manager ?
You mean using Context Manager like following?

```python
import boto3
import moto


if __name__ == '__main__':
    print(moto.__version__)
    with moto.mock_dynamodb2():
        boto3.client('dynamodb')
    bucket = boto3.resource('s3').Bucket('test-bucket')
    print(list(bucket.objects.filter(Prefix='dummy')))
```

It does not work as well.

```bash
$ AWS_ACCESS_KEY_ID=xxx AWS_SECRET_ACCESS_KEY=xxx AWS_DEFAULT_REGION=xxx python main.py 
1.3.14
Traceback (most recent call last):
  File "main.py", line 10, in <module>
    print(list(bucket.objects.filter(Prefix='dummy')))
  File "/home/nakagawa/.pyenv/versions/3.6.8/lib/python3.6/site-packages/boto3/resources/collection.py", line 83, in __iter__
    for page in self.pages():
  File "/home/nakagawa/.pyenv/versions/3.6.8/lib/python3.6/site-packages/boto3/resources/collection.py", line 166, in pages
    for page in pages:
  File "/home/nakagawa/.pyenv/versions/3.6.8/lib/python3.6/site-packages/botocore/paginate.py", line 255, in __iter__
    response = self._make_request(current_kwargs)
  File "/home/nakagawa/.pyenv/versions/3.6.8/lib/python3.6/site-packages/botocore/paginate.py", line 332, in _make_request
    return self._method(**current_kwargs)
  File "/home/nakagawa/.pyenv/versions/3.6.8/lib/python3.6/site-packages/botocore/client.py", line 357, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/home/nakagawa/.pyenv/versions/3.6.8/lib/python3.6/site-packages/botocore/client.py", line 661, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (InvalidAccessKeyId) when calling the ListObjects operation: The AWS Access Key Id you provided does not exist in our records.
```
Well that's no good :(
Hmm... while doing some debugging, I found that in botocore's `credentials.py`, the `access_key` and `secret_key` are set to `foobar_key`, and `foobar_secret`, respectively.
For some reason, the `.stop()` function is not unsetting the `FAKE_KEYS`:
```
    def start(self, reset=True):
        self.env_variables_mocks.start()

        self.__class__.nested_count += 1
        if reset:
            for backend in self.backends.values():
                backend.reset()

        self.enable_patching()

    def stop(self):
        self.env_variables_mocks.stop()
        self.__class__.nested_count -= 1

        if self.__class__.nested_count < 0:
            raise RuntimeError("Called stop() before start().")

        if self.__class__.nested_count == 0:
            self.disable_patching()
```
I have a hunch that what we need to do is mock the boto3 `DEFAULT_SESSION` so that it is `None` after the the mocks stop. 

It appears that:
```
    def _register_credential_provider(self):
        self._components.lazy_register_component(
            'credential_provider',
            lambda:  botocore.credentials.create_credential_resolver(self))
```
... is being cached and used after the mock has ended.

Resolving patch:
diff --git a/moto/core/models.py b/moto/core/models.py
--- a/moto/core/models.py
+++ b/moto/core/models.py
@@ -44,6 +44,7 @@ def __init__(self, backends):
             "AWS_ACCESS_KEY_ID": "foobar_key",
             "AWS_SECRET_ACCESS_KEY": "foobar_secret",
         }
+        self.default_session_mock = mock.patch("boto3.DEFAULT_SESSION", None)
         self.env_variables_mocks = mock.patch.dict(os.environ, FAKE_KEYS)
 
         if self.__class__.nested_count == 0:
@@ -62,6 +63,7 @@ def __exit__(self, *args):
         self.stop()
 
     def start(self, reset=True):
+        self.default_session_mock.start()
         self.env_variables_mocks.start()
 
         self.__class__.nested_count += 1
@@ -72,6 +74,7 @@ def start(self, reset=True):
         self.enable_patching()
 
     def stop(self):
+        self.default_session_mock.stop()
         self.env_variables_mocks.stop()
         self.__class__.nested_count -= 1
 


Test patch:
diff --git a/tests/test_awslambda/test_lambda.py b/tests/test_awslambda/test_lambda.py
--- a/tests/test_awslambda/test_lambda.py
+++ b/tests/test_awslambda/test_lambda.py
@@ -1001,10 +1001,10 @@ def test_list_versions_by_function_for_nonexistent_function():
 @mock_lambda
 @mock_sqs
 def test_create_event_source_mapping():
-    sqs = boto3.resource("sqs")
+    sqs = boto3.resource("sqs", region_name="us-east-1")
     queue = sqs.create_queue(QueueName="test-sqs-queue1")
 
-    conn = boto3.client("lambda")
+    conn = boto3.client("lambda", region_name="us-east-1")
     func = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
@@ -1030,11 +1030,11 @@ def test_create_event_source_mapping():
 @mock_lambda
 @mock_sqs
 def test_invoke_function_from_sqs():
-    logs_conn = boto3.client("logs")
-    sqs = boto3.resource("sqs")
+    logs_conn = boto3.client("logs", region_name="us-east-1")
+    sqs = boto3.resource("sqs", region_name="us-east-1")
     queue = sqs.create_queue(QueueName="test-sqs-queue1")
 
-    conn = boto3.client("lambda")
+    conn = boto3.client("lambda", region_name="us-east-1")
     func = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
@@ -1054,7 +1054,7 @@ def test_invoke_function_from_sqs():
     assert response["EventSourceArn"] == queue.attributes["QueueArn"]
     assert response["State"] == "Enabled"
 
-    sqs_client = boto3.client("sqs")
+    sqs_client = boto3.client("sqs", region_name="us-east-1")
     sqs_client.send_message(QueueUrl=queue.url, MessageBody="test")
     start = time.time()
     while (time.time() - start) < 30:
@@ -1081,8 +1081,8 @@ def test_invoke_function_from_sqs():
 @mock_lambda
 @mock_dynamodb2
 def test_invoke_function_from_dynamodb():
-    logs_conn = boto3.client("logs")
-    dynamodb = boto3.client("dynamodb")
+    logs_conn = boto3.client("logs", region_name="us-east-1")
+    dynamodb = boto3.client("dynamodb", region_name="us-east-1")
     table_name = "table_with_stream"
     table = dynamodb.create_table(
         TableName=table_name,
@@ -1094,7 +1094,7 @@ def test_invoke_function_from_dynamodb():
         },
     )
 
-    conn = boto3.client("lambda")
+    conn = boto3.client("lambda", region_name="us-east-1")
     func = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
@@ -1141,11 +1141,11 @@ def test_invoke_function_from_dynamodb():
 @mock_lambda
 @mock_sqs
 def test_invoke_function_from_sqs_exception():
-    logs_conn = boto3.client("logs")
-    sqs = boto3.resource("sqs")
+    logs_conn = boto3.client("logs", region_name="us-east-1")
+    sqs = boto3.resource("sqs", region_name="us-east-1")
     queue = sqs.create_queue(QueueName="test-sqs-queue1")
 
-    conn = boto3.client("lambda")
+    conn = boto3.client("lambda", region_name="us-east-1")
     func = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
@@ -1201,10 +1201,10 @@ def test_invoke_function_from_sqs_exception():
 @mock_lambda
 @mock_sqs
 def test_list_event_source_mappings():
-    sqs = boto3.resource("sqs")
+    sqs = boto3.resource("sqs", region_name="us-east-1")
     queue = sqs.create_queue(QueueName="test-sqs-queue1")
 
-    conn = boto3.client("lambda")
+    conn = boto3.client("lambda", region_name="us-east-1")
     func = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
@@ -1233,10 +1233,10 @@ def test_list_event_source_mappings():
 @mock_lambda
 @mock_sqs
 def test_get_event_source_mapping():
-    sqs = boto3.resource("sqs")
+    sqs = boto3.resource("sqs", region_name="us-east-1")
     queue = sqs.create_queue(QueueName="test-sqs-queue1")
 
-    conn = boto3.client("lambda")
+    conn = boto3.client("lambda", region_name="us-east-1")
     func = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
@@ -1263,10 +1263,10 @@ def test_get_event_source_mapping():
 @mock_lambda
 @mock_sqs
 def test_update_event_source_mapping():
-    sqs = boto3.resource("sqs")
+    sqs = boto3.resource("sqs", region_name="us-east-1")
     queue = sqs.create_queue(QueueName="test-sqs-queue1")
 
-    conn = boto3.client("lambda")
+    conn = boto3.client("lambda", region_name="us-east-1")
     func1 = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
@@ -1307,10 +1307,10 @@ def test_update_event_source_mapping():
 @mock_lambda
 @mock_sqs
 def test_delete_event_source_mapping():
-    sqs = boto3.resource("sqs")
+    sqs = boto3.resource("sqs", region_name="us-east-1")
     queue = sqs.create_queue(QueueName="test-sqs-queue1")
 
-    conn = boto3.client("lambda")
+    conn = boto3.client("lambda", region_name="us-east-1")
     func1 = conn.create_function(
         FunctionName="testFunction",
         Runtime="python2.7",
diff --git a/tests/test_dynamodb2/test_dynamodb.py b/tests/test_dynamodb2/test_dynamodb.py
--- a/tests/test_dynamodb2/test_dynamodb.py
+++ b/tests/test_dynamodb2/test_dynamodb.py
@@ -3119,8 +3119,8 @@ def create_item(price):
 # https://github.com/spulec/moto/issues/1874
 @mock_dynamodb2
 def test_item_size_is_under_400KB():
-    dynamodb = boto3.resource("dynamodb")
-    client = boto3.client("dynamodb")
+    dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
+    client = boto3.client("dynamodb", region_name="us-east-1")
 
     dynamodb.create_table(
         TableName="moto-test",
@@ -3172,7 +3172,7 @@ def assert_failure_due_to_item_size(func, **kwargs):
 @mock_dynamodb2
 # https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html#DDB-Query-request-KeyConditionExpression
 def test_hash_key_cannot_use_begins_with_operations():
-    dynamodb = boto3.resource("dynamodb")
+    dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
     table = dynamodb.create_table(
         TableName="test-table",
         KeySchema=[{"AttributeName": "key", "KeyType": "HASH"}],
@@ -3201,7 +3201,7 @@ def test_hash_key_cannot_use_begins_with_operations():
 
 @mock_dynamodb2
 def test_update_supports_complex_expression_attribute_values():
-    client = boto3.client("dynamodb")
+    client = boto3.client("dynamodb", region_name="us-east-1")
 
     client.create_table(
         AttributeDefinitions=[{"AttributeName": "SHA256", "AttributeType": "S"}],
@@ -3237,7 +3237,7 @@ def test_update_supports_complex_expression_attribute_values():
 
 @mock_dynamodb2
 def test_update_supports_list_append():
-    client = boto3.client("dynamodb")
+    client = boto3.client("dynamodb", region_name="us-east-1")
 
     client.create_table(
         AttributeDefinitions=[{"AttributeName": "SHA256", "AttributeType": "S"}],
@@ -3272,7 +3272,7 @@ def test_update_supports_list_append():
 
 @mock_dynamodb2
 def test_update_catches_invalid_list_append_operation():
-    client = boto3.client("dynamodb")
+    client = boto3.client("dynamodb", region_name="us-east-1")
 
     client.create_table(
         AttributeDefinitions=[{"AttributeName": "SHA256", "AttributeType": "S"}],
diff --git a/tests/test_stepfunctions/test_stepfunctions.py b/tests/test_stepfunctions/test_stepfunctions.py
--- a/tests/test_stepfunctions/test_stepfunctions.py
+++ b/tests/test_stepfunctions/test_stepfunctions.py
@@ -524,7 +524,7 @@ def _get_account_id():
     global account_id
     if account_id:
         return account_id
-    sts = boto3.client("sts")
+    sts = boto3.client("sts", region_name=region)
     identity = sts.get_caller_identity()
     account_id = identity["Account"]
     return account_id