Repository: getmoto/moto

Issue:
Upgrade flake8 to allow type-ignore comments
Can we upgrade flake8 to the latest version? That's 4.0.1 at the time of writing.

We need to upgrade for compatibility with the mypy static type checker. Mypy's use was approved in #4944.

Mypy supports the use of [control comments](https://mypy.readthedocs.io/en/stable/common_issues.html#spurious-errors-and-locally-silencing-the-checker) to silence type errors.

In my [organizations-fixes](https://github.com/iainelder/moto/tree/organizations-fixes) branch I'm experimenting with adding types to the organizations models. I've added some control comments where the types are not strictly correct and I don't want to fix it yet.

An example from OrganizationsBackend:

```python
    def create_organizational_unit(self, **kwargs: Any) -> ot.CreateOrganizationalUnitResponseTypeDef:
        # TODO: Arg type needs to be FakeOrganization, but it can sometimes be None.
        new_ou = FakeOrganizationalUnit(self.org, **kwargs)  # type: ignore[arg-type]
        self.ou.append(new_ou)
        self.attach_policy(PolicyId=utils.DEFAULT_POLICY_ID, TargetId=new_ou.id)
        return {"OrganizationalUnit": new_ou.describe()}
```

flake8, well, "flakes out" at this:

```
moto/organizations/models.py:418:62: F821 undefined name 'ignore'
moto/organizations/models.py:418:62: F821 undefined name 'arg'
```

In requirements-dev.txt flake8 is pinned to 3.7.8.

That [version of flake8](https://github.com/PyCQA/flake8/blob/3.7.8/setup.cfg#L16) depends on pyflakes:

```text
    pyflakes >= 2.1.0, < 2.2.0
```

In my virtualenv it resolves pyflakes to v2.1.1.

That version of pyflakes is incompatible with mypy's control comments to ignore type errors.

This was fixed in [pyflakes 2.2.0](https://github.com/PyCQA/pyflakes/blob/2.2.0/NEWS.rst).

> * Allow type ignore to be followed by a code `# type: ignore[attr-defined]`

flake8 v4.0.1 generates about 60 linting errors on the moto code. If we upgrade flake8, those will have to be addressed as well.



Discussion:
Make sense @iainelder. I'll create a PR that fixes the linting issues on the new flake8.

Resolving patch:
diff --git a/moto/apigatewayv2/responses.py b/moto/apigatewayv2/responses.py
--- a/moto/apigatewayv2/responses.py
+++ b/moto/apigatewayv2/responses.py
@@ -738,7 +738,7 @@ def get_vpc_link(self):
 
     def get_vpc_links(self):
         vpc_links = self.apigatewayv2_backend.get_vpc_links()
-        return 200, {}, json.dumps({"items": [l.to_json() for l in vpc_links]})
+        return 200, {}, json.dumps({"items": [link.to_json() for link in vpc_links]})
 
     def update_vpc_link(self):
         vpc_link_id = self.path.split("/")[-1]
diff --git a/moto/dax/exceptions.py b/moto/dax/exceptions.py
--- a/moto/dax/exceptions.py
+++ b/moto/dax/exceptions.py
@@ -9,5 +9,5 @@ def __init__(self, message):
 class ClusterNotFoundFault(JsonRESTError):
     def __init__(self, name=None):
         # DescribeClusters and DeleteCluster use a different message for the same error
-        msg = f"Cluster {name} not found." if name else f"Cluster not found."
+        msg = f"Cluster {name} not found." if name else "Cluster not found."
         super().__init__("ClusterNotFoundFault", msg)
diff --git a/moto/ec2/_models/vpcs.py b/moto/ec2/_models/vpcs.py
--- a/moto/ec2/_models/vpcs.py
+++ b/moto/ec2/_models/vpcs.py
@@ -482,7 +482,7 @@ def associate_vpc_cidr_block(
         association_set = vpc.associate_vpc_cidr_block(
             cidr_block, amazon_provided_ipv6_cidr_block
         )
-        for route_table in self.route_tables.values():
+        for route_table in self.route_tables.copy().values():
             if route_table.vpc_id == vpc_id:
                 if amazon_provided_ipv6_cidr_block:
                     self.create_route(


Test patch:
diff --git a/tests/test_cloudformation/test_cloudformation_custom_resources.py b/tests/test_cloudformation/test_cloudformation_custom_resources.py
--- a/tests/test_cloudformation/test_cloudformation_custom_resources.py
+++ b/tests/test_cloudformation/test_cloudformation_custom_resources.py
@@ -105,7 +105,9 @@ def test_create_custom_lambda_resource__verify_cfnresponse_failed():
     )
     execution_failed.should.equal(True)
 
-    printed_events = [l for l in logs if l.startswith("{'RequestType': 'Create'")]
+    printed_events = [
+        line for line in logs if line.startswith("{'RequestType': 'Create'")
+    ]
     printed_events.should.have.length_of(1)
     original_event = json.loads(printed_events[0].replace("'", '"'))
     original_event.should.have.key("RequestType").equals("Create")
diff --git a/tests/test_cognitoidp/test_cognitoidp.py b/tests/test_cognitoidp/test_cognitoidp.py
--- a/tests/test_cognitoidp/test_cognitoidp.py
+++ b/tests/test_cognitoidp/test_cognitoidp.py
@@ -414,7 +414,7 @@ def test_create_user_pool_string_schema_min_bigger_than_max():
         )
     ex.value.response["Error"]["Code"].should.equal("InvalidParameterException")
     ex.value.response["Error"]["Message"].should.equal(
-        f"user.email: Max length cannot be less than min length."
+        "user.email: Max length cannot be less than min length."
     )
     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
 
@@ -435,7 +435,7 @@ def test_create_user_pool_number_schema_min_bigger_than_max():
         )
     ex.value.response["Error"]["Code"].should.equal("InvalidParameterException")
     ex.value.response["Error"]["Message"].should.equal(
-        f"user.updated_at: Max value cannot be less than min value."
+        "user.updated_at: Max value cannot be less than min value."
     )
     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
 
@@ -482,7 +482,7 @@ def test_add_custom_attributes_existing_attribute():
 
     ex.value.response["Error"]["Code"].should.equal("InvalidParameterException")
     ex.value.response["Error"]["Message"].should.equal(
-        f"custom:banana: Existing attribute already has name dev:custom:banana."
+        "custom:banana: Existing attribute already has name dev:custom:banana."
     )
     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
 
@@ -1824,7 +1824,7 @@ def test_admin_confirm_sign_up_non_existing_user():
 
     err = exc.value.response["Error"]
     err["Code"].should.equal("UserNotFoundException")
-    err["Message"].should.equal(f"User does not exist.")
+    err["Message"].should.equal("User does not exist.")
 
 
 @mock_cognitoidp
@@ -1879,7 +1879,7 @@ def test_admin_resend_invitation_missing_user():
         )
     err = exc.value.response["Error"]
     err["Code"].should.equal("UserNotFoundException")
-    err["Message"].should.equal(f"User does not exist.")
+    err["Message"].should.equal("User does not exist.")
 
 
 @mock_cognitoidp
@@ -1965,7 +1965,7 @@ def test_admin_get_missing_user():
 
     err = exc.value.response["Error"]
     err["Code"].should.equal("UserNotFoundException")
-    err["Message"].should.equal(f"User does not exist.")
+    err["Message"].should.equal("User does not exist.")
 
 
 @mock_cognitoidp
@@ -1982,7 +1982,7 @@ def test_admin_get_missing_user_with_username_attributes():
 
     err = exc.value.response["Error"]
     err["Code"].should.equal("UserNotFoundException")
-    err["Message"].should.equal(f"User does not exist.")
+    err["Message"].should.equal("User does not exist.")
 
 
 @mock_cognitoidp
diff --git a/tests/test_dynamodb/exceptions/test_dynamodb_exceptions.py b/tests/test_dynamodb/exceptions/test_dynamodb_exceptions.py
--- a/tests/test_dynamodb/exceptions/test_dynamodb_exceptions.py
+++ b/tests/test_dynamodb/exceptions/test_dynamodb_exceptions.py
@@ -522,7 +522,7 @@ def update_email_transact(email):
             }
         }
 
-    update_email_transact(f"test1@moto.com")
+    update_email_transact("test1@moto.com")
     with pytest.raises(ClientError) as exc:
         dynamodb.transact_write_items(
             TransactItems=[
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
@@ -118,7 +118,7 @@ def test_query_filter_boto3():
     )
 
     for i in range(0, 3):
-        table.put_item(Item={"pk": "pk".format(i), "sk": "sk-{}".format(i)})
+        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)
diff --git a/tests/test_ec2/test_ec2_cloudformation.py b/tests/test_ec2/test_ec2_cloudformation.py
--- a/tests/test_ec2/test_ec2_cloudformation.py
+++ b/tests/test_ec2/test_ec2_cloudformation.py
@@ -703,7 +703,7 @@ def test_vpc_endpoint_creation():
     ec2_client = boto3.client("ec2", region_name="us-west-1")
     vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
     subnet1 = ec2.create_subnet(
-        VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone=f"us-west-1a"
+        VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-1a"
     )
 
     subnet_template = {
diff --git a/tests/test_ec2/test_elastic_ip_addresses.py b/tests/test_ec2/test_elastic_ip_addresses.py
--- a/tests/test_ec2/test_elastic_ip_addresses.py
+++ b/tests/test_ec2/test_elastic_ip_addresses.py
@@ -9,8 +9,6 @@
 from moto import mock_ec2
 from tests import EXAMPLE_AMI_ID
 
-import logging
-
 
 @mock_ec2
 def test_eip_allocate_classic():
@@ -104,7 +102,6 @@ def test_specific_eip_allocate_vpc():
     vpc = client.allocate_address(Domain="vpc", Address="127.38.43.222")
     vpc["Domain"].should.be.equal("vpc")
     vpc["PublicIp"].should.be.equal("127.38.43.222")
-    logging.debug("vpc alloc_id:".format(vpc["AllocationId"]))
 
 
 @mock_ec2
diff --git a/tests/test_ec2/test_prefix_lists.py b/tests/test_ec2/test_prefix_lists.py
--- a/tests/test_ec2/test_prefix_lists.py
+++ b/tests/test_ec2/test_prefix_lists.py
@@ -54,7 +54,7 @@ def test_describe_managed_prefix_lists():
 
     all_lists = ec2.describe_managed_prefix_lists()["PrefixLists"]
     [pl["PrefixListId"] for pl in all_lists].should.contain(pl_id)
-    set([l["OwnerId"] for l in all_lists]).should.equal({"aws", ACCOUNT_ID})
+    set([pl["OwnerId"] for pl in all_lists]).should.equal({"aws", ACCOUNT_ID})
 
 
 @mock_ec2
@@ -64,7 +64,7 @@ def test_describe_managed_prefix_lists_with_prefix():
     default_lists = ec2.describe_managed_prefix_lists()["PrefixLists"]
     if not settings.TEST_SERVER_MODE:
         # ServerMode is not guaranteed to only have AWS prefix lists
-        set([l["OwnerId"] for l in default_lists]).should.equal({"aws"})
+        set([pl["OwnerId"] for pl in default_lists]).should.equal({"aws"})
 
     random_list_id = default_lists[0]["PrefixListId"]
 
@@ -168,7 +168,7 @@ def test_delete_managed_prefix_list():
     ]
     lists_by_id.should.have.length_of(2)
 
-    set([l["State"] for l in lists_by_id]).should.equal(
+    set([pl["State"] for pl in lists_by_id]).should.equal(
         {"create-complete", "delete-complete"}
     )
 
@@ -186,8 +186,8 @@ def test_describe_prefix_lists():
 
     all_lists = ec2.describe_prefix_lists()["PrefixLists"]
     all_lists.should.have.length_of(2)
-    for l in all_lists:
-        l["PrefixListName"].should.contain("com.amazonaws")
+    for pl in all_lists:
+        pl["PrefixListName"].should.contain("com.amazonaws")
 
 
 @mock_ec2
diff --git a/tests/test_ecr/test_ecr_policy_validation.py b/tests/test_ecr/test_ecr_policy_validation.py
--- a/tests/test_ecr/test_ecr_policy_validation.py
+++ b/tests/test_ecr/test_ecr_policy_validation.py
@@ -333,7 +333,7 @@ def test_validate_error_action_properties(action, error_msg):
             },
             (
                 "numeric instance is lower than the required minimum "
-                f"(minimum: 1, found: 0)"
+                "(minimum: 1, found: 0)"
             ),
         ],
         [
@@ -344,7 +344,7 @@ def test_validate_error_action_properties(action, error_msg):
             },
             (
                 "numeric instance is lower than the required minimum "
-                f"(minimum: 1, found: -1)"
+                "(minimum: 1, found: -1)"
             ),
         ],
     ],
diff --git a/tests/test_elb/test_elb.py b/tests/test_elb/test_elb.py
--- a/tests/test_elb/test_elb.py
+++ b/tests/test_elb/test_elb.py
@@ -55,14 +55,14 @@ def test_create_load_balancer(zones, region_name):
     describe["ListenerDescriptions"].should.have.length_of(2)
 
     tcp = [
-        l["Listener"]
-        for l in describe["ListenerDescriptions"]
-        if l["Listener"]["Protocol"] == "TCP"
+        desc["Listener"]
+        for desc in describe["ListenerDescriptions"]
+        if desc["Listener"]["Protocol"] == "TCP"
     ][0]
     http = [
-        l["Listener"]
-        for l in describe["ListenerDescriptions"]
-        if l["Listener"]["Protocol"] == "HTTP"
+        desc["Listener"]
+        for desc in describe["ListenerDescriptions"]
+        if desc["Listener"]["Protocol"] == "HTTP"
     ][0]
     tcp.should.equal(
         {
@@ -566,16 +566,14 @@ def test_get_load_balancers_by_name():
         client.describe_load_balancers(LoadBalancerNames=["unknownlb"])
     err = ex.value.response["Error"]
     err["Code"].should.equal("LoadBalancerNotFound")
-    err["Message"].should.equal(
-        f"The specified load balancer does not exist: unknownlb"
-    )
+    err["Message"].should.equal("The specified load balancer does not exist: unknownlb")
 
     with pytest.raises(ClientError) as ex:
         client.describe_load_balancers(LoadBalancerNames=[lb_name1, "unknownlb"])
     err = ex.value.response["Error"]
     err["Code"].should.equal("LoadBalancerNotFound")
     # Bug - message sometimes shows the lb that does exist
-    err["Message"].should.match(f"The specified load balancer does not exist:")
+    err["Message"].should.match("The specified load balancer does not exist:")
 
 
 @mock_elb
@@ -1003,8 +1001,8 @@ def test_add_remove_tags():
 
     lb_tags = dict(
         [
-            (l["LoadBalancerName"], dict([(d["Key"], d["Value"]) for d in l["Tags"]]))
-            for l in client.describe_tags(LoadBalancerNames=["my-lb", "other-lb"])[
+            (lb["LoadBalancerName"], dict([(d["Key"], d["Value"]) for d in lb["Tags"]]))
+            for lb in client.describe_tags(LoadBalancerNames=["my-lb", "other-lb"])[
                 "TagDescriptions"
             ]
         ]
diff --git a/tests/test_elb/test_elb_policies.py b/tests/test_elb/test_elb_policies.py
--- a/tests/test_elb/test_elb_policies.py
+++ b/tests/test_elb/test_elb_policies.py
@@ -149,16 +149,16 @@ def test_set_policies_of_listener():
     ][0]
 
     http_l = [
-        l
-        for l in balancer["ListenerDescriptions"]
-        if l["Listener"]["Protocol"] == "HTTP"
+        listener
+        for listener in balancer["ListenerDescriptions"]
+        if listener["Listener"]["Protocol"] == "HTTP"
     ][0]
     http_l.should.have.key("PolicyNames").should.equal([])
 
     https_l = [
-        l
-        for l in balancer["ListenerDescriptions"]
-        if l["Listener"]["Protocol"] == "HTTPS"
+        listener
+        for listener in balancer["ListenerDescriptions"]
+        if listener["Listener"]["Protocol"] == "HTTPS"
     ][0]
     https_l.should.have.key("PolicyNames").should.equal(["pname"])
 
diff --git a/tests/test_emrcontainers/test_emrcontainers.py b/tests/test_emrcontainers/test_emrcontainers.py
--- a/tests/test_emrcontainers/test_emrcontainers.py
+++ b/tests/test_emrcontainers/test_emrcontainers.py
@@ -407,7 +407,7 @@ def test_non_existing_id_invalid_cluster_id(self):
         err = exc.value.response["Error"]
 
         assert err["Code"] == "ResourceNotFoundException"
-        assert err["Message"] == f"Job run 123456789abcdefghij doesn't exist."
+        assert err["Message"] == "Job run 123456789abcdefghij doesn't exist."
 
     def test_wrong_job_state(self):
         with pytest.raises(ClientError) as exc:
@@ -581,4 +581,4 @@ def test_non_existing_id_invalid_cluster_id(self):
         err = exc.value.response["Error"]
 
         assert err["Code"] == "ResourceNotFoundException"
-        assert err["Message"] == f"Job run 123456789abcdefghij doesn't exist."
+        assert err["Message"] == "Job run 123456789abcdefghij doesn't exist."
diff --git a/tests/test_es/test_es.py b/tests/test_es/test_es.py
--- a/tests/test_es/test_es.py
+++ b/tests/test_es/test_es.py
@@ -176,7 +176,7 @@ def test_describe_invalid_domain():
     meta["HTTPStatusCode"].should.equal(400)
     err = exc.value.response["Error"]
     err["Message"].should.equal(
-        f"1 validation error detected: Value 'moto.org' at 'domainName' failed to satisfy constraint: Member must satisfy regular expression pattern: [a-z][a-z0-9\\-]+"
+        "1 validation error detected: Value 'moto.org' at 'domainName' failed to satisfy constraint: Member must satisfy regular expression pattern: [a-z][a-z0-9\\-]+"
     )
     err["Code"].should.equal("ValidationException")
 
diff --git a/tests/test_kms/test_kms_boto3.py b/tests/test_kms/test_kms_boto3.py
--- a/tests/test_kms/test_kms_boto3.py
+++ b/tests/test_kms/test_kms_boto3.py
@@ -1041,8 +1041,8 @@ def test__delete_alias__raises_if_alias_is_not_found():
     )
 
 
-def sort(l):
-    return sorted(l, key=lambda d: d.keys())
+def sort(lst):
+    return sorted(lst, key=lambda d: d.keys())
 
 
 def _check_tags(key_id, created_tags, client):
diff --git a/tests/test_logs/test_logs.py b/tests/test_logs/test_logs.py
--- a/tests/test_logs/test_logs.py
+++ b/tests/test_logs/test_logs.py
@@ -1185,7 +1185,7 @@ def test_describe_log_streams_simple_paging():
     # Get stream 1-4
     resp = client.describe_log_streams(logGroupName=group_name, limit=4)
     resp["logStreams"].should.have.length_of(4)
-    [l["logStreamName"] for l in resp["logStreams"]].should.equal(
+    [stream["logStreamName"] for stream in resp["logStreams"]].should.equal(
         ["stream0", "stream1", "stream2", "stream3"]
     )
     resp.should.have.key("nextToken")
@@ -1195,7 +1195,7 @@ def test_describe_log_streams_simple_paging():
         logGroupName=group_name, limit=4, nextToken=str(resp["nextToken"])
     )
     resp["logStreams"].should.have.length_of(4)
-    [l["logStreamName"] for l in resp["logStreams"]].should.equal(
+    [stream["logStreamName"] for stream in resp["logStreams"]].should.equal(
         ["stream4", "stream5", "stream6", "stream7"]
     )
     resp.should.have.key("nextToken")
@@ -1205,7 +1205,7 @@ def test_describe_log_streams_simple_paging():
         logGroupName=group_name, limit=4, nextToken=str(resp["nextToken"])
     )
     resp["logStreams"].should.have.length_of(2)
-    [l["logStreamName"] for l in resp["logStreams"]].should.equal(
+    [stream["logStreamName"] for stream in resp["logStreams"]].should.equal(
         ["stream8", "stream9"]
     )
     resp.should_not.have.key("nextToken")
diff --git a/tests/test_mediaconnect/test_mediaconnect.py b/tests/test_mediaconnect/test_mediaconnect.py
--- a/tests/test_mediaconnect/test_mediaconnect.py
+++ b/tests/test_mediaconnect/test_mediaconnect.py
@@ -209,9 +209,7 @@ def test_add_flow_vpc_interfaces_fails():
         client.add_flow_vpc_interfaces(FlowArn=flow_arn, VpcInterfaces=[])
     err = err.value.response["Error"]
     err["Code"].should.equal("NotFoundException")
-    err["Message"].should.equal(
-        "flow with arn=unknown-flow not found".format(str(flow_arn))
-    )
+    err["Message"].should.equal("flow with arn=unknown-flow not found")
 
 
 @mock_mediaconnect
@@ -256,9 +254,7 @@ def test_remove_flow_vpc_interface_fails():
         )
     err = err.value.response["Error"]
     err["Code"].should.equal("NotFoundException")
-    err["Message"].should.equal(
-        "flow with arn=unknown-flow not found".format(str(flow_arn))
-    )
+    err["Message"].should.equal("flow with arn=unknown-flow not found")
 
 
 @mock_mediaconnect
@@ -293,9 +289,7 @@ def test_add_flow_outputs_fails():
         client.add_flow_outputs(FlowArn=flow_arn, Outputs=[])
     err = err.value.response["Error"]
     err["Code"].should.equal("NotFoundException")
-    err["Message"].should.equal(
-        "flow with arn=unknown-flow not found".format(str(flow_arn))
-    )
+    err["Message"].should.equal("flow with arn=unknown-flow not found")
 
 
 @mock_mediaconnect
@@ -307,9 +301,7 @@ def test_remove_flow_output_fails():
         client.remove_flow_output(FlowArn=flow_arn, OutputArn=output_arn)
     err = err.value.response["Error"]
     err["Code"].should.equal("NotFoundException")
-    err["Message"].should.equal(
-        "flow with arn=unknown-flow not found".format(str(flow_arn))
-    )
+    err["Message"].should.equal("flow with arn=unknown-flow not found")
 
 
 @mock_mediaconnect
diff --git a/tests/test_quicksight/test_quicksight_users.py b/tests/test_quicksight/test_quicksight_users.py
--- a/tests/test_quicksight/test_quicksight_users.py
+++ b/tests/test_quicksight/test_quicksight_users.py
@@ -144,7 +144,7 @@ def test_create_group_membership():
     client.register_user(
         AwsAccountId=ACCOUNT_ID,
         Namespace="default",
-        Email=f"fakeemail@example.com",
+        Email="fakeemail@example.com",
         IdentityType="QUICKSIGHT",
         UserName="user1",
         UserRole="READER",
@@ -175,7 +175,7 @@ def test_describe_group_membership():
     client.register_user(
         AwsAccountId=ACCOUNT_ID,
         Namespace="default",
-        Email=f"fakeemail@example.com",
+        Email="fakeemail@example.com",
         IdentityType="QUICKSIGHT",
         UserName="user1",
         UserRole="READER",
@@ -214,7 +214,7 @@ def test_list_group_memberships():
         client.register_user(
             AwsAccountId=ACCOUNT_ID,
             Namespace="default",
-            Email=f"fakeemail@example.com",
+            Email="fakeemail@example.com",
             IdentityType="QUICKSIGHT",
             UserName=f"user{i}",
             UserRole="READER",
@@ -276,7 +276,7 @@ def test_list_group_memberships__after_deleting_user():
         client.register_user(
             AwsAccountId=ACCOUNT_ID,
             Namespace="default",
-            Email=f"fakeemail@example.com",
+            Email="fakeemail@example.com",
             IdentityType="QUICKSIGHT",
             UserName=f"user{i}",
             UserRole="READER",
diff --git a/tests/test_route53/test_route53.py b/tests/test_route53/test_route53.py
--- a/tests/test_route53/test_route53.py
+++ b/tests/test_route53/test_route53.py
@@ -1441,7 +1441,7 @@ def test_list_resource_recordset_pagination():
 
     # Create A Record.
     a_record_endpoint_payload = {
-        "Comment": f"Create 500 A records",
+        "Comment": "Create 500 A records",
         "Changes": [
             {
                 "Action": "CREATE",
diff --git a/tests/test_s3/test_s3_lambda_integration.py b/tests/test_s3/test_s3_lambda_integration.py
--- a/tests/test_s3/test_s3_lambda_integration.py
+++ b/tests/test_s3/test_s3_lambda_integration.py
@@ -84,7 +84,7 @@ def test_objectcreated_put__invokes_lambda(match_events, actual_event):
         + str(all_logs)
     )
 
-    records = [l for l in all_logs if l.startswith("{'Records'")][0]
+    records = [line for line in all_logs if line.startswith("{'Records'")][0]
     records = json.loads(records.replace("'", '"'))["Records"]
 
     records.should.have.length_of(1)
diff --git a/tests/test_sdb/test_sdb_domains.py b/tests/test_sdb/test_sdb_domains.py
--- a/tests/test_sdb/test_sdb_domains.py
+++ b/tests/test_sdb/test_sdb_domains.py
@@ -64,5 +64,5 @@ def test_delete_domain_invalid():
         sdb.delete_domain(DomainName="a")
     err = exc.value.response["Error"]
     err["Code"].should.equal("InvalidParameterValue")
-    err["Message"].should.equal(f"Value (a) for parameter DomainName is invalid. ")
+    err["Message"].should.equal("Value (a) for parameter DomainName is invalid. ")
     err.should.have.key("BoxUsage")
diff --git a/tests/test_ses/test_ses_boto3.py b/tests/test_ses/test_ses_boto3.py
--- a/tests/test_ses/test_ses_boto3.py
+++ b/tests/test_ses/test_ses_boto3.py
@@ -132,7 +132,7 @@ def test_send_unverified_email_with_chevrons():
     # Sending an email to an unverified source should fail
     with pytest.raises(ClientError) as ex:
         conn.send_email(
-            Source=f"John Smith <foobar@example.com>",  # << Unverified source address
+            Source="John Smith <foobar@example.com>",  # << Unverified source address
             Destination={
                 "ToAddresses": ["blah@example.com"],
                 "CcAddresses": [],
diff --git a/tests/test_sns/test_publish_batch.py b/tests/test_sns/test_publish_batch.py
--- a/tests/test_sns/test_publish_batch.py
+++ b/tests/test_sns/test_publish_batch.py
@@ -49,7 +49,7 @@ def test_publish_batch_non_unique_ids():
         client.publish_batch(
             TopicArn=topic["TopicArn"],
             PublishBatchRequestEntries=[
-                {"Id": f"id", "Message": f"{idx}"} for idx in range(5)
+                {"Id": "id", "Message": f"{idx}"} for idx in range(5)
             ],
         )
     err = exc.value.response["Error"]
@@ -70,7 +70,7 @@ def test_publish_batch_fifo_without_message_group_id():
     with pytest.raises(ClientError) as exc:
         client.publish_batch(
             TopicArn=topic["TopicArn"],
-            PublishBatchRequestEntries=[{"Id": f"id_2", "Message": f"2"}],
+            PublishBatchRequestEntries=[{"Id": "id_2", "Message": "2"}],
         )
     err = exc.value.response["Error"]
     err["Code"].should.equal("InvalidParameter")
@@ -84,9 +84,9 @@ def test_publish_batch_standard_with_message_group_id():
     client = boto3.client("sns", region_name="us-east-1")
     topic_arn = client.create_topic(Name="standard_topic")["TopicArn"]
     entries = [
-        {"Id": f"id_1", "Message": f"1"},
-        {"Id": f"id_2", "Message": f"2", "MessageGroupId": "mgid"},
-        {"Id": f"id_3", "Message": f"3"},
+        {"Id": "id_1", "Message": "1"},
+        {"Id": "id_2", "Message": "2", "MessageGroupId": "mgid"},
+        {"Id": "id_3", "Message": "3"},
     ]
     resp = client.publish_batch(TopicArn=topic_arn, PublishBatchRequestEntries=entries)
 
@@ -112,11 +112,11 @@ def test_publish_batch_to_sqs():
     client = boto3.client("sns", region_name="us-east-1")
     topic_arn = client.create_topic(Name="standard_topic")["TopicArn"]
     entries = [
-        {"Id": f"id_1", "Message": f"1"},
-        {"Id": f"id_2", "Message": f"2", "Subject": "subj2"},
+        {"Id": "id_1", "Message": "1"},
+        {"Id": "id_2", "Message": "2", "Subject": "subj2"},
         {
-            "Id": f"id_3",
-            "Message": f"3",
+            "Id": "id_3",
+            "Message": "3",
             "MessageAttributes": {"a": {"DataType": "String", "StringValue": "v"}},
         },
     ]
diff --git a/tests/test_transcribe/test_transcribe_boto3.py b/tests/test_transcribe/test_transcribe_boto3.py
--- a/tests/test_transcribe/test_transcribe_boto3.py
+++ b/tests/test_transcribe/test_transcribe_boto3.py
@@ -378,9 +378,7 @@ def test_run_transcription_job_s3output_params():
     transcription_job.should.contain("Transcript")
     # Check aws hosted bucket
     transcription_job["Transcript"]["TranscriptFileUri"].should.contain(
-        "https://s3.us-east-1.amazonaws.com/my-output-bucket/bucket-key/MyJob.json".format(
-            region_name
-        )
+        "https://s3.us-east-1.amazonaws.com/my-output-bucket/bucket-key/MyJob.json"
     )
     # A new job without an "OutputKey"
     job_name = "MyJob2"