Repository: boto/botocore
Pull request #2818 (2022-11-21 20:13:39)

Resolve endpoint with default partition when no region is set
Addresses https://github.com/aws/aws-cli/issues/7455.

Changes endpoint resolution to resolve the endpoint for the default AWS partition when no region is given.

codecov-commenter: # [Codecov](https://codecov.io/gh/boto/botocore/pull/2818?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto) Report
Base: **93.49**% // Head: **93.46**% // Decreases project coverage by **`-0.03%`** :warning:
> Coverage data is based on head [(`64381e1`)](https://codecov.io/gh/boto/botocore/pull/2818?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto) compared to base [(`2df5c5b`)](https://codecov.io/gh/boto/botocore/commit/2df5c5baf51325b16b8d2891b74e4731cdfea06f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto).
> Patch coverage: 100.00% of modified lines in pull request are covered.

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff             @@
##           develop    #2818      +/-   ##
===========================================
- Coverage    93.49%   93.46%   -0.04%     
===========================================
  Files           63       63              
  Lines        13346    13349       +3     
===========================================
- Hits         12478    12476       -2     
- Misses         868      873       +5     
```


| [Impacted Files](https://codecov.io/gh/boto/botocore/pull/2818?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto) | Coverage Δ | |
|---|---|---|
| [botocore/endpoint\_provider.py](https://codecov.io/gh/boto/botocore/pull/2818/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvZW5kcG9pbnRfcHJvdmlkZXIucHk=) | `99.35% <100.00%> (-0.01%)` | :arrow_down: |
| [botocore/compat.py](https://codecov.io/gh/boto/botocore/pull/2818/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvY29tcGF0LnB5) | `91.33% <0.00%> (-1.34%)` | :arrow_down: |
| [botocore/httpsession.py](https://codecov.io/gh/boto/botocore/pull/2818/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvaHR0cHNlc3Npb24ucHk=) | `91.40% <0.00%> (-0.40%)` | :arrow_down: |
| [botocore/utils.py](https://codecov.io/gh/boto/botocore/pull/2818/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvdXRpbHMucHk=) | `79.07% <0.00%> (-0.13%)` | :arrow_down: |
| [botocore/client.py](https://codecov.io/gh/boto/botocore/pull/2818/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvY2xpZW50LnB5) | `97.84% <0.00%> (+0.01%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/boto/botocore/pull/2818?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto).


Patch:
diff --git a/.changes/next-release/bugfix-Endpoints-16572.json b/.changes/next-release/bugfix-Endpoints-16572.json
new file mode 100644
index 000000000..382634c9f
--- /dev/null
+++ b/.changes/next-release/bugfix-Endpoints-16572.json
@@ -0,0 +1,5 @@
+{
+  "type": "bugfix",
+  "category": "Endpoints",
+  "description": "Resolve endpoint with default partition when no region is set"
+}
diff --git a/botocore/endpoint_provider.py b/botocore/endpoint_provider.py
index 68e5a00e6..138815b18 100644
--- a/botocore/endpoint_provider.py
+++ b/botocore/endpoint_provider.py
@@ -202,13 +202,12 @@ class RuleSetStandardLibary:
         :type value: str
         :rtype: dict
         """
-        if value is None:
-            return None
-
         partitions = self.partitions_data['partitions']
-        for partition in partitions:
-            if self.is_partition_match(value, partition):
-                return self.format_partition_output(partition)
+
+        if value is not None:
+            for partition in partitions:
+                if self.is_partition_match(value, partition):
+                    return self.format_partition_output(partition)
 
         # return the default partition if no matches were found
         aws_partition = partitions[0]


Test patch:
diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py
index 2c5ec4fce..e4dc8c2ea 100644
--- a/tests/functional/conftest.py
+++ b/tests/functional/conftest.py
@@ -22,5 +22,6 @@ def patched_session(monkeypatch):
     monkeypatch.setenv('AWS_SECRET_ACCESS_KEY', 'secret_key')
     monkeypatch.setenv('AWS_CONFIG_FILE', 'no-exist-foo')
     monkeypatch.delenv('AWS_PROFILE', raising=False)
+    monkeypatch.delenv('AWS_DEFAULT_REGION', raising=False)
     session = create_session()
     return session
diff --git a/tests/functional/test_sts.py b/tests/functional/test_sts.py
index e9d498de8..2040fb301 100644
--- a/tests/functional/test_sts.py
+++ b/tests/functional/test_sts.py
@@ -288,3 +288,29 @@ class TestSTSEndpoints(BaseSessionTest):
             expected_url='https://sts.not-real.amazonaws.com/',
             expected_signing_region='not-real',
         )
+
+
+def test_assume_role_with_saml_no_region_custom_endpoint(patched_session):
+    # When an endpoint_url and no region are given, AssumeRoleWithSAML should
+    # resolve to the endpoint_url and succeed, not fail in endpoint resolution:
+    # https://github.com/aws/aws-cli/issues/7455
+
+    client = patched_session.create_client(
+        'sts', region_name=None, endpoint_url="https://custom.endpoint.aws"
+    )
+    assert client.meta.region_name is None
+
+    mock_response_body = b"""\
+<AssumeRoleWithSAMLResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
+    <AssumeRoleWithSAMLResult></AssumeRoleWithSAMLResult>
+</AssumeRoleWithSAMLResponse>
+"""
+    with ClientHTTPStubber(client) as http_stubber:
+        http_stubber.add_response(body=mock_response_body)
+        client.assume_role_with_saml(
+            RoleArn='arn:aws:iam::123456789:role/RoleA',
+            PrincipalArn='arn:aws:iam::123456789:role/RoleB',
+            SAMLAssertion='xxxx',
+        )
+    captured_request = http_stubber.requests[0]
+    assert captured_request.url == "https://custom.endpoint.aws/"
diff --git a/tests/unit/test_endpoint_provider.py b/tests/unit/test_endpoint_provider.py
index 742978373..614bc0d4f 100644
--- a/tests/unit/test_endpoint_provider.py
+++ b/tests/unit/test_endpoint_provider.py
@@ -205,8 +205,9 @@ def test_endpoint_resolution(
     assert endpoint.headers == expected_endpoint.get("headers", {})
 
 
-def test_none_doesnt_use_default_partition(rule_lib):
-    assert rule_lib.aws_partition(None) is None
+def test_none_returns_default_partition(rule_lib):
+    partition_dict = rule_lib.aws_partition(None)
+    assert partition_dict['name'] == "aws"
 
 
 def test_no_match_region_returns_default_partition(rule_lib):