Repository: boto/botocore
Pull request #3036 (2023-10-09 18:14:48)

Remove strict kwarg that was deprecated in Python 3.4
This PR will stop passing the no-longer required `strict` argument to the urllib3 ConnectionPool class. This argument was originally needed in `Python<3.5` (specifically Python 2) to specify support for older HTTP status lines before http/1.0. The functionality went away in HTTPConnection in Python 3.4 ([ref](https://docs.python.org/3/library/http.client.html#http.client.HTTPConnection)).

Starting in urllib3 2.1, this parameter will be removed from the APIs we're using. Given it has no effect on version of Python we support, this should be a no-op for users on _all_ versions of urllib3 we support. You can find a [similar PR](https://github.com/psf/requests/pull/6434) where we've done this in Requests which has been in place for ~6 months without issue.


Patch:
diff --git a/botocore/httpsession.py b/botocore/httpsession.py
index b3fe6e6c0..a5f262a50 100644
--- a/botocore/httpsession.py
+++ b/botocore/httpsession.py
@@ -335,7 +335,6 @@ class URLLib3Session:
 
     def _get_pool_manager_kwargs(self, **extra_kwargs):
         pool_manager_kwargs = {
-            'strict': True,
             'timeout': self._timeout,
             'maxsize': self._max_pool_connections,
             'ssl_context': self._get_ssl_context(),
diff --git a/botocore/parsers.py b/botocore/parsers.py
index ee4688bbb..3f652872e 100644
--- a/botocore/parsers.py
+++ b/botocore/parsers.py
@@ -353,13 +353,15 @@ class ResponseParser:
 
     def _has_unknown_tagged_union_member(self, shape, value):
         if shape.is_tagged_union:
-            if len(value) != 1:
+            cleaned_value = value.copy()
+            cleaned_value.pop("__type", None)
+            if len(cleaned_value) != 1:
                 error_msg = (
                     "Invalid service response: %s must have one and only "
                     "one member set."
                 )
                 raise ResponseParserError(error_msg % shape.name)
-            tag = self._get_first_key(value)
+            tag = self._get_first_key(cleaned_value)
             if tag not in shape.members:
                 msg = (
                     "Received a tagged union response with member "


Test patch:
diff --git a/tests/unit/test_http_session.py b/tests/unit/test_http_session.py
index bd591e110..9e059ad5a 100644
--- a/tests/unit/test_http_session.py
+++ b/tests/unit/test_http_session.py
@@ -148,7 +148,6 @@ class TestURLLib3Session(unittest.TestCase):
 
     def _assert_manager_call(self, manager, *assert_args, **assert_kwargs):
         call_kwargs = {
-            'strict': True,
             'maxsize': mock.ANY,
             'timeout': mock.ANY,
             'ssl_context': mock.ANY,
diff --git a/tests/unit/test_parsers.py b/tests/unit/test_parsers.py
index b26e54d5b..d5f55a29e 100644
--- a/tests/unit/test_parsers.py
+++ b/tests/unit/test_parsers.py
@@ -553,6 +553,35 @@ class TestTaggedUnions(unittest.TestCase):
         with self.assertRaises(parsers.ResponseParserError):
             parser.parse(response, output_shape)
 
+    def test_parser_accepts_type_metadata_with_union(self):
+        parser = parsers.JSONParser()
+        response = b'{"Foo": "mystring", "__type": "mytype"}'
+        headers = {'x-amzn-requestid': 'request-id'}
+        output_shape = model.StructureShape(
+            'OutputShape',
+            {
+                'type': 'structure',
+                'union': True,
+                'members': {
+                    'Foo': {
+                        'shape': 'StringType',
+                    },
+                    'Bar': {
+                        'shape': 'StringType',
+                    },
+                },
+            },
+            model.ShapeResolver({'StringType': {'type': 'string'}}),
+        )
+
+        response = {
+            'body': response,
+            'headers': headers,
+            'status_code': 200,
+        }
+        parsed = parser.parse(response, output_shape)
+        self.assertEqual(parsed['Foo'], 'mystring')
+
 
 class TestHeaderResponseInclusion(unittest.TestCase):
     def create_parser(self):