diff --git a/vcr/patch.py b/vcr/patch.py index b4b5e0e..0c54354 100644 --- a/vcr/patch.py +++ b/vcr/patch.py @@ -22,6 +22,16 @@ else: _cpoolHTTPConnection = cpool.HTTPConnection _cpoolHTTPSConnection = cpool.HTTPSConnection +# Try to save the original types for boto3 +try: + import botocore.vendored.requests.packages.urllib3.connectionpool as cpool +except ImportError: # pragma: no cover + pass +else: + _Boto3VerifiedHTTPSConnection = cpool.VerifiedHTTPSConnection + _cpoolBoto3HTTPConnection = cpool.HTTPConnection + _cpoolBoto3HTTPSConnection = cpool.HTTPSConnection + # Try to save the original types for urllib3 try: @@ -87,7 +97,7 @@ class CassettePatcherBuilder(object): def build(self): return itertools.chain( - self._httplib(), self._requests(), self._urllib3(), + self._httplib(), self._requests(), self._boto3(), self._urllib3(), self._httplib2(), self._boto(), self._tornado(), self._build_patchers_from_mock_triples( self._cassette.custom_patches @@ -165,6 +175,14 @@ class CassettePatcherBuilder(object): from .stubs import requests_stubs return self._urllib3_patchers(cpool, requests_stubs) + def _boto3(self): + try: + import botocore.vendored.requests.packages.urllib3.connectionpool as cpool + except ImportError: # pragma: no cover + return () + from .stubs import boto3_stubs + return self._urllib3_patchers(cpool, boto3_stubs) + def _patched_get_conn(self, connection_pool_class, connection_class_getter): get_conn = connection_pool_class._get_conn @@ -353,6 +371,24 @@ def reset_patchers(): yield mock.patch.object(cpool.HTTPConnectionPool, 'ConnectionCls', _HTTPConnection) yield mock.patch.object(cpool.HTTPSConnectionPool, 'ConnectionCls', _HTTPSConnection) + try: + import botocore.vendored.requests.packages.urllib3.connectionpool as cpool + except ImportError: # pragma: no cover + pass + else: + # unpatch requests v1.x + yield mock.patch.object(cpool, 'VerifiedHTTPSConnection', _Boto3VerifiedHTTPSConnection) + yield mock.patch.object(cpool, 'HTTPConnection', _cpoolBoto3HTTPConnection) + # unpatch requests v2.x + if hasattr(cpool.HTTPConnectionPool, 'ConnectionCls'): + yield mock.patch.object(cpool.HTTPConnectionPool, 'ConnectionCls', + _cpoolBoto3HTTPConnection) + yield mock.patch.object(cpool.HTTPSConnectionPool, 'ConnectionCls', + _cpoolBoto3HTTPSConnection) + + if hasattr(cpool, 'HTTPSConnection'): + yield mock.patch.object(cpool, 'HTTPSConnection', _cpoolBoto3HTTPSConnection) + try: import httplib2 as cpool except ImportError: # pragma: no cover diff --git a/vcr/stubs/boto3_stubs.py b/vcr/stubs/boto3_stubs.py new file mode 100644 index 0000000..43476be --- /dev/null +++ b/vcr/stubs/boto3_stubs.py @@ -0,0 +1,13 @@ +'''Stubs for boto3''' + +from botocore.vendored.requests.packages.urllib3.connectionpool import HTTPConnection, VerifiedHTTPSConnection +from ..stubs import VCRHTTPConnection, VCRHTTPSConnection + +# urllib3 defines its own HTTPConnection classes, which boto3 goes ahead and assumes +# you're using. It includes some polyfills for newer features missing in older pythons. + +class VCRRequestsHTTPConnection(VCRHTTPConnection, HTTPConnection): + _baseclass = HTTPConnection + +class VCRRequestsHTTPSConnection(VCRHTTPSConnection, VerifiedHTTPSConnection): + _baseclass = VerifiedHTTPSConnection