We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Any reason why "futures" is a requirement?
It's listed in [requirements-aws.txt](https://github.com/DataBiosphere/toil/blob/95982020dd263ed2b3ad5c41cd99fee19a6bdb30/requirements-aws.txt#L4)
```
futures>=3.1.1, <4
```
And seems to be behind this [Cactus CI error](https://ucsc-ci.com/comparativegenomicstoolkit/cactus/-/jobs/8808) that I'm getting all of the sudden (via Cactus's [Dockerfile](https://github.com/ComparativeGenomicsToolkit/cactus/blob/4259ad72fce9c1e81c5c7f13b2dd3bb8619eb4dc/Dockerfile#L46-L48)):
```
ERROR: Could not find a version that satisfies the requirement futures<4,>=3.1.1; extra == "all" (from toil[all]) (from versions: 0.2.python3, 0.1, 0.2, 1.0, 2.0, 2.1, 2.1.1, 2.1.2, 2.1.3, 2.1.4, 2.1.5, 2.1.6, 2.2.0, 3.0.0, 3.0.1, 3.0.2, 3.0.3, 3.0.4, 3.0.5, 3.1.0, 3.1.1)
```
Where it seems that pip just stopped wanting to make wheels of it altogether.  I'm guessing this may have something to do with [futures](https://pypi.org/project/futures/) being python 2-specific?

┆Issue is synchronized with this [Jira Story](https://ucsc-cgl.atlassian.net/browse/TOIL-1139)
┆friendlyId: TOIL-1139


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/toil/lib/aws/utils.py`
Content:
```
1 # Copyright (C) 2015-2021 Regents of the University of California
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 import logging
15 import sys
16 from typing import Any, Dict, List, Optional, Union, cast
17 
18 from toil.lib.aws import session
19 from toil.lib.misc import printq
20 from toil.lib.retry import retry
21 
22 if sys.version_info >= (3, 8):
23     from typing import Literal
24 else:
25     from typing_extensions import Literal
26 
27 try:
28     from boto.exception import BotoServerError
29     from mypy_boto3_s3 import S3Client, S3ServiceResource
30     from mypy_boto3_s3.literals import BucketLocationConstraintType
31     from mypy_boto3_s3.service_resource import Bucket
32     from mypy_boto3_sdb import SimpleDBClient
33     from mypy_boto3_iam import IAMClient, IAMServiceResource
34 except ImportError:
35     BotoServerError = None  # type: ignore
36     # AWS/boto extra is not installed
37 
38 logger = logging.getLogger(__name__)
39 
40 
41 @retry(errors=[BotoServerError])
42 def delete_iam_role(
43     role_name: str, region: Optional[str] = None, quiet: bool = True
44 ) -> None:
45     from boto.iam.connection import IAMConnection
46     # TODO: the Boto3 type hints are a bit oversealous here; they want hundreds
47     # of overloads of the client-getting methods to exist based on the literal
48     # string passed in, to return exactly the right kind of client or resource.
49     # So we end up having to wrap all the calls in casts, which kind of defeats
50     # the point of a nice fluent method you can call with the name of the thing
51     # you want; we should have been calling iam_client() and so on all along if
52     # we wanted MyPy to be able to understand us. So at some point we should
53     # consider revising our API here to be less annoying to explain to the type
54     # checker.
55     iam_client = cast(IAMClient, session.client('iam', region_name=region))
56     iam_resource = cast(IAMServiceResource, session.resource('iam', region_name=region))
57     boto_iam_connection = IAMConnection()
58     role = iam_resource.Role(role_name)
59     # normal policies
60     for attached_policy in role.attached_policies.all():
61         printq(f'Now dissociating policy: {attached_policy.policy_name} from role {role.name}', quiet)
62         role.detach_policy(PolicyArn=attached_policy.arn)
63     # inline policies
64     for inline_policy in role.policies.all():
65         printq(f'Deleting inline policy: {inline_policy.policy_name} from role {role.name}', quiet)
66         # couldn't find an easy way to remove inline policies with boto3; use boto
67         boto_iam_connection.delete_role_policy(role.name, inline_policy.policy_name)
68     iam_client.delete_role(RoleName=role_name)
69     printq(f'Role {role_name} successfully deleted.', quiet)
70 
71 
72 @retry(errors=[BotoServerError])
73 def delete_iam_instance_profile(
74     instance_profile_name: str, region: Optional[str] = None, quiet: bool = True
75 ) -> None:
76     iam_resource = cast(IAMServiceResource, session.resource("iam", region_name=region))
77     instance_profile = iam_resource.InstanceProfile(instance_profile_name)
78     if instance_profile.roles is not None:
79         # The type stubs think this is somehow just one role, when it's a
80         # collection. See <https://github.com/vemel/mypy_boto3_builder/issues/122>.
81         for role in instance_profile.roles: #type: ignore
82             printq(f'Now dissociating role: {role.name} from instance profile {instance_profile_name}', quiet)
83             instance_profile.remove_role(RoleName=role.name)
84     instance_profile.delete()
85     printq(f'Instance profile "{instance_profile_name}" successfully deleted.', quiet)
86 
87 
88 @retry(errors=[BotoServerError])
89 def delete_sdb_domain(
90     sdb_domain_name: str, region: Optional[str] = None, quiet: bool = True
91 ) -> None:
92     sdb_client = cast(SimpleDBClient, session.client("sdb", region_name=region))
93     sdb_client.delete_domain(DomainName=sdb_domain_name)
94     printq(f'SBD Domain: "{sdb_domain_name}" successfully deleted.', quiet)
95 
96 
97 @retry(errors=[BotoServerError])
98 def delete_s3_bucket(bucket: str, region: Optional[str], quiet: bool = True) -> None:
99     printq(f'Deleting s3 bucket in region "{region}": {bucket}', quiet)
100     s3_client = cast(S3Client, session.client('s3', region_name=region))
101     s3_resource = cast(S3ServiceResource, session.resource('s3', region_name=region))
102 
103     paginator = s3_client.get_paginator('list_object_versions')
104     try:
105         for response in paginator.paginate(Bucket=bucket):
106             # Versions and delete markers can both go in here to be deleted.
107             # They both have Key and VersionId, but there's no shared base type
108             # defined for them in the stubs to express that. See
109             # <https://github.com/vemel/mypy_boto3_builder/issues/123>. So we
110             # have to do gymnastics to get them into the same list.
111             to_delete: List[Dict[str, Any]] = cast(List[Dict[str, Any]], response.get('Versions', [])) + \
112                                               cast(List[Dict[str, Any]], response.get('DeleteMarkers', []))
113             for entry in to_delete:
114                 printq(f"    Deleting {entry['Key']} version {entry['VersionId']}", quiet)
115                 s3_client.delete_object(Bucket=bucket, Key=entry['Key'], VersionId=entry['VersionId'])
116         s3_resource.Bucket(bucket).delete()
117         printq(f'\n * Deleted s3 bucket successfully: {bucket}\n\n', quiet)
118     except s3_client.exceptions.NoSuchBucket:
119         printq(f'\n * S3 bucket no longer exists: {bucket}\n\n', quiet)
120 
121 
122 def create_s3_bucket(
123     s3_session: "S3ServiceResource",
124     bucket_name: str,
125     region: Union["BucketLocationConstraintType", Literal["us-east-1"]],
126 ) -> "Bucket":
127     """
128     Create an AWS S3 bucket, using the given Boto3 S3 session, with the
129     given name, in the given region.
130 
131     Supports the us-east-1 region, where bucket creation is special.
132 
133     *ALL* S3 bucket creation should use this function.
134     """
135     logger.debug("Creating bucket '%s' in region %s.", bucket_name, region)
136     if region == "us-east-1":  # see https://github.com/boto/boto3/issues/125
137         bucket = s3_session.create_bucket(Bucket=bucket_name)
138     else:
139         bucket = s3_session.create_bucket(
140             Bucket=bucket_name,
141             CreateBucketConfiguration={"LocationConstraint": region},
142         )
143     return bucket
144
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/toil/lib/aws/utils.py b/src/toil/lib/aws/utils.py
--- a/src/toil/lib/aws/utils.py
+++ b/src/toil/lib/aws/utils.py
@@ -76,9 +76,7 @@
     iam_resource = cast(IAMServiceResource, session.resource("iam", region_name=region))
     instance_profile = iam_resource.InstanceProfile(instance_profile_name)
     if instance_profile.roles is not None:
-        # The type stubs think this is somehow just one role, when it's a
-        # collection. See <https://github.com/vemel/mypy_boto3_builder/issues/122>.
-        for role in instance_profile.roles: #type: ignore
+        for role in instance_profile.roles:
             printq(f'Now dissociating role: {role.name} from instance profile {instance_profile_name}', quiet)
             instance_profile.remove_role(RoleName=role.name)
     instance_profile.delete()

{"golden_diff": "diff --git a/src/toil/lib/aws/utils.py b/src/toil/lib/aws/utils.py\n--- a/src/toil/lib/aws/utils.py\n+++ b/src/toil/lib/aws/utils.py\n@@ -76,9 +76,7 @@\n     iam_resource = cast(IAMServiceResource, session.resource(\"iam\", region_name=region))\n     instance_profile = iam_resource.InstanceProfile(instance_profile_name)\n     if instance_profile.roles is not None:\n-        # The type stubs think this is somehow just one role, when it's a\n-        # collection. See <https://github.com/vemel/mypy_boto3_builder/issues/122>.\n-        for role in instance_profile.roles: #type: ignore\n+        for role in instance_profile.roles:\n             printq(f'Now dissociating role: {role.name} from instance profile {instance_profile_name}', quiet)\n             instance_profile.remove_role(RoleName=role.name)\n     instance_profile.delete()\n", "issue": "Any reason why \"futures\" is a requirement?\nIt's listed in [requirements-aws.txt](https://github.com/DataBiosphere/toil/blob/95982020dd263ed2b3ad5c41cd99fee19a6bdb30/requirements-aws.txt#L4)\n```\nfutures>=3.1.1, <4\n```\nAnd seems to be behind this [Cactus CI error](https://ucsc-ci.com/comparativegenomicstoolkit/cactus/-/jobs/8808) that I'm getting all of the sudden (via Cactus's [Dockerfile](https://github.com/ComparativeGenomicsToolkit/cactus/blob/4259ad72fce9c1e81c5c7f13b2dd3bb8619eb4dc/Dockerfile#L46-L48)):\n```\nERROR: Could not find a version that satisfies the requirement futures<4,>=3.1.1; extra == \"all\" (from toil[all]) (from versions: 0.2.python3, 0.1, 0.2, 1.0, 2.0, 2.1, 2.1.1, 2.1.2, 2.1.3, 2.1.4, 2.1.5, 2.1.6, 2.2.0, 3.0.0, 3.0.1, 3.0.2, 3.0.3, 3.0.4, 3.0.5, 3.1.0, 3.1.1)\n```\nWhere it seems that pip just stopped wanting to make wheels of it altogether.  I'm guessing this may have something to do with [futures](https://pypi.org/project/futures/) being python 2-specific?\n\n\u2506Issue is synchronized with this [Jira Story](https://ucsc-cgl.atlassian.net/browse/TOIL-1139)\n\u2506friendlyId: TOIL-1139\n\n", "before_files": [{"content": "# Copyright (C) 2015-2021 Regents of the University of California\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport logging\nimport sys\nfrom typing import Any, Dict, List, Optional, Union, cast\n\nfrom toil.lib.aws import session\nfrom toil.lib.misc import printq\nfrom toil.lib.retry import retry\n\nif sys.version_info >= (3, 8):\n    from typing import Literal\nelse:\n    from typing_extensions import Literal\n\ntry:\n    from boto.exception import BotoServerError\n    from mypy_boto3_s3 import S3Client, S3ServiceResource\n    from mypy_boto3_s3.literals import BucketLocationConstraintType\n    from mypy_boto3_s3.service_resource import Bucket\n    from mypy_boto3_sdb import SimpleDBClient\n    from mypy_boto3_iam import IAMClient, IAMServiceResource\nexcept ImportError:\n    BotoServerError = None  # type: ignore\n    # AWS/boto extra is not installed\n\nlogger = logging.getLogger(__name__)\n\n\n@retry(errors=[BotoServerError])\ndef delete_iam_role(\n    role_name: str, region: Optional[str] = None, quiet: bool = True\n) -> None:\n    from boto.iam.connection import IAMConnection\n    # TODO: the Boto3 type hints are a bit oversealous here; they want hundreds\n    # of overloads of the client-getting methods to exist based on the literal\n    # string passed in, to return exactly the right kind of client or resource.\n    # So we end up having to wrap all the calls in casts, which kind of defeats\n    # the point of a nice fluent method you can call with the name of the thing\n    # you want; we should have been calling iam_client() and so on all along if\n    # we wanted MyPy to be able to understand us. So at some point we should\n    # consider revising our API here to be less annoying to explain to the type\n    # checker.\n    iam_client = cast(IAMClient, session.client('iam', region_name=region))\n    iam_resource = cast(IAMServiceResource, session.resource('iam', region_name=region))\n    boto_iam_connection = IAMConnection()\n    role = iam_resource.Role(role_name)\n    # normal policies\n    for attached_policy in role.attached_policies.all():\n        printq(f'Now dissociating policy: {attached_policy.policy_name} from role {role.name}', quiet)\n        role.detach_policy(PolicyArn=attached_policy.arn)\n    # inline policies\n    for inline_policy in role.policies.all():\n        printq(f'Deleting inline policy: {inline_policy.policy_name} from role {role.name}', quiet)\n        # couldn't find an easy way to remove inline policies with boto3; use boto\n        boto_iam_connection.delete_role_policy(role.name, inline_policy.policy_name)\n    iam_client.delete_role(RoleName=role_name)\n    printq(f'Role {role_name} successfully deleted.', quiet)\n\n\n@retry(errors=[BotoServerError])\ndef delete_iam_instance_profile(\n    instance_profile_name: str, region: Optional[str] = None, quiet: bool = True\n) -> None:\n    iam_resource = cast(IAMServiceResource, session.resource(\"iam\", region_name=region))\n    instance_profile = iam_resource.InstanceProfile(instance_profile_name)\n    if instance_profile.roles is not None:\n        # The type stubs think this is somehow just one role, when it's a\n        # collection. See <https://github.com/vemel/mypy_boto3_builder/issues/122>.\n        for role in instance_profile.roles: #type: ignore\n            printq(f'Now dissociating role: {role.name} from instance profile {instance_profile_name}', quiet)\n            instance_profile.remove_role(RoleName=role.name)\n    instance_profile.delete()\n    printq(f'Instance profile \"{instance_profile_name}\" successfully deleted.', quiet)\n\n\n@retry(errors=[BotoServerError])\ndef delete_sdb_domain(\n    sdb_domain_name: str, region: Optional[str] = None, quiet: bool = True\n) -> None:\n    sdb_client = cast(SimpleDBClient, session.client(\"sdb\", region_name=region))\n    sdb_client.delete_domain(DomainName=sdb_domain_name)\n    printq(f'SBD Domain: \"{sdb_domain_name}\" successfully deleted.', quiet)\n\n\n@retry(errors=[BotoServerError])\ndef delete_s3_bucket(bucket: str, region: Optional[str], quiet: bool = True) -> None:\n    printq(f'Deleting s3 bucket in region \"{region}\": {bucket}', quiet)\n    s3_client = cast(S3Client, session.client('s3', region_name=region))\n    s3_resource = cast(S3ServiceResource, session.resource('s3', region_name=region))\n\n    paginator = s3_client.get_paginator('list_object_versions')\n    try:\n        for response in paginator.paginate(Bucket=bucket):\n            # Versions and delete markers can both go in here to be deleted.\n            # They both have Key and VersionId, but there's no shared base type\n            # defined for them in the stubs to express that. See\n            # <https://github.com/vemel/mypy_boto3_builder/issues/123>. So we\n            # have to do gymnastics to get them into the same list.\n            to_delete: List[Dict[str, Any]] = cast(List[Dict[str, Any]], response.get('Versions', [])) + \\\n                                              cast(List[Dict[str, Any]], response.get('DeleteMarkers', []))\n            for entry in to_delete:\n                printq(f\"    Deleting {entry['Key']} version {entry['VersionId']}\", quiet)\n                s3_client.delete_object(Bucket=bucket, Key=entry['Key'], VersionId=entry['VersionId'])\n        s3_resource.Bucket(bucket).delete()\n        printq(f'\\n * Deleted s3 bucket successfully: {bucket}\\n\\n', quiet)\n    except s3_client.exceptions.NoSuchBucket:\n        printq(f'\\n * S3 bucket no longer exists: {bucket}\\n\\n', quiet)\n\n\ndef create_s3_bucket(\n    s3_session: \"S3ServiceResource\",\n    bucket_name: str,\n    region: Union[\"BucketLocationConstraintType\", Literal[\"us-east-1\"]],\n) -> \"Bucket\":\n    \"\"\"\n    Create an AWS S3 bucket, using the given Boto3 S3 session, with the\n    given name, in the given region.\n\n    Supports the us-east-1 region, where bucket creation is special.\n\n    *ALL* S3 bucket creation should use this function.\n    \"\"\"\n    logger.debug(\"Creating bucket '%s' in region %s.\", bucket_name, region)\n    if region == \"us-east-1\":  # see https://github.com/boto/boto3/issues/125\n        bucket = s3_session.create_bucket(Bucket=bucket_name)\n    else:\n        bucket = s3_session.create_bucket(\n            Bucket=bucket_name,\n            CreateBucketConfiguration={\"LocationConstraint\": region},\n        )\n    return bucket\n", "path": "src/toil/lib/aws/utils.py"}], "after_files": [{"content": "# Copyright (C) 2015-2021 Regents of the University of California\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport logging\nimport sys\nfrom typing import Any, Dict, List, Optional, Union, cast\n\nfrom toil.lib.aws import session\nfrom toil.lib.misc import printq\nfrom toil.lib.retry import retry\n\nif sys.version_info >= (3, 8):\n    from typing import Literal\nelse:\n    from typing_extensions import Literal\n\ntry:\n    from boto.exception import BotoServerError\n    from mypy_boto3_s3 import S3Client, S3ServiceResource\n    from mypy_boto3_s3.literals import BucketLocationConstraintType\n    from mypy_boto3_s3.service_resource import Bucket\n    from mypy_boto3_sdb import SimpleDBClient\n    from mypy_boto3_iam import IAMClient, IAMServiceResource\nexcept ImportError:\n    BotoServerError = None  # type: ignore\n    # AWS/boto extra is not installed\n\nlogger = logging.getLogger(__name__)\n\n\n@retry(errors=[BotoServerError])\ndef delete_iam_role(\n    role_name: str, region: Optional[str] = None, quiet: bool = True\n) -> None:\n    from boto.iam.connection import IAMConnection\n    # TODO: the Boto3 type hints are a bit oversealous here; they want hundreds\n    # of overloads of the client-getting methods to exist based on the literal\n    # string passed in, to return exactly the right kind of client or resource.\n    # So we end up having to wrap all the calls in casts, which kind of defeats\n    # the point of a nice fluent method you can call with the name of the thing\n    # you want; we should have been calling iam_client() and so on all along if\n    # we wanted MyPy to be able to understand us. So at some point we should\n    # consider revising our API here to be less annoying to explain to the type\n    # checker.\n    iam_client = cast(IAMClient, session.client('iam', region_name=region))\n    iam_resource = cast(IAMServiceResource, session.resource('iam', region_name=region))\n    boto_iam_connection = IAMConnection()\n    role = iam_resource.Role(role_name)\n    # normal policies\n    for attached_policy in role.attached_policies.all():\n        printq(f'Now dissociating policy: {attached_policy.policy_name} from role {role.name}', quiet)\n        role.detach_policy(PolicyArn=attached_policy.arn)\n    # inline policies\n    for inline_policy in role.policies.all():\n        printq(f'Deleting inline policy: {inline_policy.policy_name} from role {role.name}', quiet)\n        # couldn't find an easy way to remove inline policies with boto3; use boto\n        boto_iam_connection.delete_role_policy(role.name, inline_policy.policy_name)\n    iam_client.delete_role(RoleName=role_name)\n    printq(f'Role {role_name} successfully deleted.', quiet)\n\n\n@retry(errors=[BotoServerError])\ndef delete_iam_instance_profile(\n    instance_profile_name: str, region: Optional[str] = None, quiet: bool = True\n) -> None:\n    iam_resource = cast(IAMServiceResource, session.resource(\"iam\", region_name=region))\n    instance_profile = iam_resource.InstanceProfile(instance_profile_name)\n    if instance_profile.roles is not None:\n        for role in instance_profile.roles:\n            printq(f'Now dissociating role: {role.name} from instance profile {instance_profile_name}', quiet)\n            instance_profile.remove_role(RoleName=role.name)\n    instance_profile.delete()\n    printq(f'Instance profile \"{instance_profile_name}\" successfully deleted.', quiet)\n\n\n@retry(errors=[BotoServerError])\ndef delete_sdb_domain(\n    sdb_domain_name: str, region: Optional[str] = None, quiet: bool = True\n) -> None:\n    sdb_client = cast(SimpleDBClient, session.client(\"sdb\", region_name=region))\n    sdb_client.delete_domain(DomainName=sdb_domain_name)\n    printq(f'SBD Domain: \"{sdb_domain_name}\" successfully deleted.', quiet)\n\n\n@retry(errors=[BotoServerError])\ndef delete_s3_bucket(bucket: str, region: Optional[str], quiet: bool = True) -> None:\n    printq(f'Deleting s3 bucket in region \"{region}\": {bucket}', quiet)\n    s3_client = cast(S3Client, session.client('s3', region_name=region))\n    s3_resource = cast(S3ServiceResource, session.resource('s3', region_name=region))\n\n    paginator = s3_client.get_paginator('list_object_versions')\n    try:\n        for response in paginator.paginate(Bucket=bucket):\n            # Versions and delete markers can both go in here to be deleted.\n            # They both have Key and VersionId, but there's no shared base type\n            # defined for them in the stubs to express that. See\n            # <https://github.com/vemel/mypy_boto3_builder/issues/123>. So we\n            # have to do gymnastics to get them into the same list.\n            to_delete: List[Dict[str, Any]] = cast(List[Dict[str, Any]], response.get('Versions', [])) + \\\n                                              cast(List[Dict[str, Any]], response.get('DeleteMarkers', []))\n            for entry in to_delete:\n                printq(f\"    Deleting {entry['Key']} version {entry['VersionId']}\", quiet)\n                s3_client.delete_object(Bucket=bucket, Key=entry['Key'], VersionId=entry['VersionId'])\n        s3_resource.Bucket(bucket).delete()\n        printq(f'\\n * Deleted s3 bucket successfully: {bucket}\\n\\n', quiet)\n    except s3_client.exceptions.NoSuchBucket:\n        printq(f'\\n * S3 bucket no longer exists: {bucket}\\n\\n', quiet)\n\n\ndef create_s3_bucket(\n    s3_session: \"S3ServiceResource\",\n    bucket_name: str,\n    region: Union[\"BucketLocationConstraintType\", Literal[\"us-east-1\"]],\n) -> \"Bucket\":\n    \"\"\"\n    Create an AWS S3 bucket, using the given Boto3 S3 session, with the\n    given name, in the given region.\n\n    Supports the us-east-1 region, where bucket creation is special.\n\n    *ALL* S3 bucket creation should use this function.\n    \"\"\"\n    logger.debug(\"Creating bucket '%s' in region %s.\", bucket_name, region)\n    if region == \"us-east-1\":  # see https://github.com/boto/boto3/issues/125\n        bucket = s3_session.create_bucket(Bucket=bucket_name)\n    else:\n        bucket = s3_session.create_bucket(\n            Bucket=bucket_name,\n            CreateBucketConfiguration={\"LocationConstraint\": region},\n        )\n    return bucket\n", "path": "src/toil/lib/aws/utils.py"}]}