mirror of
https://github.com/kevin1024/vcrpy.git
synced 2025-12-09 09:13:23 +00:00
Fix #382 - boto3 compatibility
* Add support for PyYaml5.1 * Unpin requests in Tox * Unpin urllib3 in Tox * Unpin Flask in Tox * Add env vars to Tox for boto3 tests
This commit is contained in:
@@ -10,6 +10,7 @@ env:
|
|||||||
- TOX_SUFFIX="httplib2"
|
- TOX_SUFFIX="httplib2"
|
||||||
- TOX_SUFFIX="boto3"
|
- TOX_SUFFIX="boto3"
|
||||||
- TOX_SUFFIX="urllib3121"
|
- TOX_SUFFIX="urllib3121"
|
||||||
|
- TOX_SUFFIX="urllib3"
|
||||||
- TOX_SUFFIX="tornado4"
|
- TOX_SUFFIX="tornado4"
|
||||||
- TOX_SUFFIX="aiohttp"
|
- TOX_SUFFIX="aiohttp"
|
||||||
matrix:
|
matrix:
|
||||||
@@ -45,9 +46,9 @@ matrix:
|
|||||||
- env: TOX_SUFFIX="flakes"
|
- env: TOX_SUFFIX="flakes"
|
||||||
python: "pypy3.5-5.9.0"
|
python: "pypy3.5-5.9.0"
|
||||||
- env: TOX_SUFFIX="aiohttp"
|
- env: TOX_SUFFIX="aiohttp"
|
||||||
python: 2.7
|
python: "2.7"
|
||||||
- env: TOX_SUFFIX="aiohttp"
|
- env: TOX_SUFFIX="aiohttp"
|
||||||
python: pypy
|
python: "pypy2.7-7.0"
|
||||||
python:
|
python:
|
||||||
- 2.7
|
- 2.7
|
||||||
- 3.5
|
- 3.5
|
||||||
|
|||||||
2
tests/fixtures/migration/new_cassette.yaml
vendored
2
tests/fixtures/migration/new_cassette.yaml
vendored
@@ -9,7 +9,7 @@ interactions:
|
|||||||
method: GET
|
method: GET
|
||||||
uri: http://httpbin.org/ip
|
uri: http://httpbin.org/ip
|
||||||
response:
|
response:
|
||||||
body: {string: !!python/unicode "{\n \"origin\": \"217.122.164.194\"\n}"}
|
body: {string: "{\n \"origin\": \"217.122.164.194\"\n}"}
|
||||||
headers:
|
headers:
|
||||||
access-control-allow-origin: ['*']
|
access-control-allow-origin: ['*']
|
||||||
content-type: [application/json]
|
content-type: [application/json]
|
||||||
|
|||||||
@@ -1,15 +1,46 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
import os
|
||||||
|
|
||||||
boto3 = pytest.importorskip("boto3")
|
boto3 = pytest.importorskip("boto3")
|
||||||
|
|
||||||
import boto3 # NOQA
|
import boto3 # NOQA
|
||||||
|
import botocore # NOQA
|
||||||
import vcr # NOQA
|
import vcr # NOQA
|
||||||
|
|
||||||
bucket = 'boto3-demo-1337' # a bucket you can access
|
ses = boto3.Session(
|
||||||
key = 'test/my_test.txt' # key with r+w access
|
aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'],
|
||||||
content = 'hello world i am a string' # content to put in the test file
|
aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
|
||||||
|
aws_session_token=None,
|
||||||
|
region_name=os.environ['AWS_DEFAULT_REGION'],
|
||||||
|
# botocore_session=None,
|
||||||
|
# profile_name=None
|
||||||
|
)
|
||||||
|
|
||||||
|
IAM_CLIENT = ses.client('iam')
|
||||||
|
|
||||||
|
try:
|
||||||
|
from botocore import awsrequest # NOQA
|
||||||
|
|
||||||
|
botocore_awsrequest = True
|
||||||
|
except ImportError:
|
||||||
|
botocore_awsrequest = False
|
||||||
|
|
||||||
|
|
||||||
def test_boto_stubs(tmpdir):
|
# skip tests if boto does not use vendored requests anymore
|
||||||
|
# https://github.com/boto/botocore/pull/1495
|
||||||
|
boto3_skip_vendored_requests = pytest.mark.skipif(
|
||||||
|
botocore_awsrequest,
|
||||||
|
reason='botocore version {ver} does not use vendored requests anymore.'.format(
|
||||||
|
ver=botocore.__version__))
|
||||||
|
|
||||||
|
boto3_skip_awsrequest = pytest.mark.skipif(
|
||||||
|
not botocore_awsrequest,
|
||||||
|
reason='botocore version {ver} still uses vendored requests.'.format(
|
||||||
|
ver=botocore.__version__))
|
||||||
|
|
||||||
|
|
||||||
|
@boto3_skip_vendored_requests
|
||||||
|
def test_boto_vendored_stubs(tmpdir):
|
||||||
with vcr.use_cassette(str(tmpdir.join('boto3-stubs.yml'))):
|
with vcr.use_cassette(str(tmpdir.join('boto3-stubs.yml'))):
|
||||||
# Perform the imports within the patched context so that
|
# Perform the imports within the patched context so that
|
||||||
# HTTPConnection, VerifiedHTTPSConnection refers to the patched version.
|
# HTTPConnection, VerifiedHTTPSConnection refers to the patched version.
|
||||||
@@ -23,45 +54,59 @@ def test_boto_stubs(tmpdir):
|
|||||||
VerifiedHTTPSConnection('hostname.does.not.matter')
|
VerifiedHTTPSConnection('hostname.does.not.matter')
|
||||||
|
|
||||||
|
|
||||||
|
@boto3_skip_awsrequest
|
||||||
|
def test_boto3_awsrequest_stubs(tmpdir):
|
||||||
|
with vcr.use_cassette(str(tmpdir.join('boto3-stubs.yml'))):
|
||||||
|
from botocore.awsrequest import AWSHTTPConnection, AWSHTTPSConnection
|
||||||
|
from vcr.stubs.boto3_stubs import VCRRequestsHTTPConnection, VCRRequestsHTTPSConnection
|
||||||
|
assert issubclass(VCRRequestsHTTPConnection, AWSHTTPConnection)
|
||||||
|
assert issubclass(VCRRequestsHTTPSConnection, AWSHTTPSConnection)
|
||||||
|
AWSHTTPConnection('hostname.does.not.matter')
|
||||||
|
AWSHTTPSConnection('hostname.does.not.matter')
|
||||||
|
|
||||||
|
|
||||||
def test_boto3_without_vcr():
|
def test_boto3_without_vcr():
|
||||||
s3_resource = boto3.resource('s3')
|
username = 'user'
|
||||||
b = s3_resource.Bucket(bucket)
|
response = IAM_CLIENT.get_user(UserName=username)
|
||||||
b.put_object(Key=key, Body=content)
|
|
||||||
|
|
||||||
# retrieve content to check it
|
assert response['User']['UserName'] == username
|
||||||
o = s3_resource.Object(bucket, key).get()
|
|
||||||
|
|
||||||
# decode for python3
|
|
||||||
assert content == o['Body'].read().decode('utf-8')
|
|
||||||
|
|
||||||
|
|
||||||
def test_boto_medium_difficulty(tmpdir):
|
def test_boto_medium_difficulty(tmpdir):
|
||||||
s3_resource = boto3.resource('s3')
|
username = 'user'
|
||||||
b = s3_resource.Bucket(bucket)
|
|
||||||
with vcr.use_cassette(str(tmpdir.join('boto3-medium.yml'))):
|
with vcr.use_cassette(str(tmpdir.join('boto3-medium.yml'))):
|
||||||
b.put_object(Key=key, Body=content)
|
response = IAM_CLIENT.get_user(UserName=username)
|
||||||
o = s3_resource.Object(bucket, key).get()
|
assert response['User']['UserName'] == username
|
||||||
assert content == o['Body'].read().decode('utf-8')
|
|
||||||
|
|
||||||
with vcr.use_cassette(str(tmpdir.join('boto3-medium.yml'))) as cass:
|
with vcr.use_cassette(str(tmpdir.join('boto3-medium.yml'))) as cass:
|
||||||
b.put_object(Key=key, Body=content)
|
response = IAM_CLIENT.get_user(UserName=username)
|
||||||
o = s3_resource.Object(bucket, key).get()
|
assert response['User']['UserName'] == username
|
||||||
assert content == o['Body'].read().decode('utf-8')
|
|
||||||
assert cass.all_played
|
assert cass.all_played
|
||||||
|
|
||||||
|
|
||||||
def test_boto_hardcore_mode(tmpdir):
|
def test_boto_hardcore_mode(tmpdir):
|
||||||
|
username = 'user'
|
||||||
with vcr.use_cassette(str(tmpdir.join('boto3-hardcore.yml'))):
|
with vcr.use_cassette(str(tmpdir.join('boto3-hardcore.yml'))):
|
||||||
s3_resource = boto3.resource('s3')
|
ses = boto3.Session(
|
||||||
b = s3_resource.Bucket(bucket)
|
aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'],
|
||||||
b.put_object(Key=key, Body=content)
|
aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
|
||||||
o = s3_resource.Object(bucket, key).get()
|
region_name=os.environ['AWS_DEFAULT_REGION'],
|
||||||
assert content == o['Body'].read().decode('utf-8')
|
)
|
||||||
|
|
||||||
|
iam_client = ses.client('iam')
|
||||||
|
response = iam_client.get_user(UserName=username)
|
||||||
|
assert response['User']['UserName'] == username
|
||||||
|
|
||||||
with vcr.use_cassette(str(tmpdir.join('boto3-hardcore.yml'))) as cass:
|
with vcr.use_cassette(str(tmpdir.join('boto3-hardcore.yml'))) as cass:
|
||||||
s3_resource = boto3.resource('s3')
|
ses = boto3.Session(
|
||||||
b = s3_resource.Bucket(bucket)
|
aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'],
|
||||||
b.put_object(Key=key, Body=content)
|
aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
|
||||||
o = s3_resource.Object(bucket, key).get()
|
aws_session_token=None,
|
||||||
assert content == o['Body'].read().decode('utf-8')
|
region_name=os.environ['AWS_DEFAULT_REGION'],
|
||||||
|
)
|
||||||
|
|
||||||
|
iam_client = ses.client('iam')
|
||||||
|
response = iam_client.get_user(UserName=username)
|
||||||
|
assert response['User']['UserName'] == username
|
||||||
assert cass.all_played
|
assert cass.all_played
|
||||||
|
|||||||
6
tox.ini
6
tox.ini
@@ -22,6 +22,7 @@ deps =
|
|||||||
requests: requests>=2.22.0
|
requests: requests>=2.22.0
|
||||||
httplib2: httplib2
|
httplib2: httplib2
|
||||||
urllib3121: urllib3==1.21.1
|
urllib3121: urllib3==1.21.1
|
||||||
|
urllib3: urllib3
|
||||||
{py27,py35,py36,pypy}-tornado4: tornado>=4,<5
|
{py27,py35,py36,pypy}-tornado4: tornado>=4,<5
|
||||||
{py27,py35,py36,pypy}-tornado4: pytest-tornado
|
{py27,py35,py36,pypy}-tornado4: pytest-tornado
|
||||||
{py27,py35,py36}-tornado4: pycurl
|
{py27,py35,py36}-tornado4: pycurl
|
||||||
@@ -29,6 +30,9 @@ deps =
|
|||||||
aiohttp: aiohttp
|
aiohttp: aiohttp
|
||||||
aiohttp: pytest-asyncio
|
aiohttp: pytest-asyncio
|
||||||
aiohttp: pytest-aiohttp
|
aiohttp: pytest-aiohttp
|
||||||
|
passenv =
|
||||||
|
AWS_ACCESS_KEY_ID
|
||||||
|
AWS_DEFAULT_REGION
|
||||||
|
AWS_SECRET_ACCESS_KEY
|
||||||
[flake8]
|
[flake8]
|
||||||
max_line_length = 110
|
max_line_length = 110
|
||||||
|
|||||||
@@ -190,6 +190,7 @@ class Cassette(object):
|
|||||||
self._serializer = serializer or yamlserializer
|
self._serializer = serializer or yamlserializer
|
||||||
self._match_on = match_on
|
self._match_on = match_on
|
||||||
self._before_record_request = before_record_request or (lambda x: x)
|
self._before_record_request = before_record_request or (lambda x: x)
|
||||||
|
log.info(self._before_record_request)
|
||||||
self._before_record_response = before_record_response or (lambda x: x)
|
self._before_record_response = before_record_response or (lambda x: x)
|
||||||
self.inject = inject
|
self.inject = inject
|
||||||
self.record_mode = record_mode
|
self.record_mode = record_mode
|
||||||
@@ -225,6 +226,7 @@ class Cassette(object):
|
|||||||
|
|
||||||
def append(self, request, response):
|
def append(self, request, response):
|
||||||
"""Add a request, response pair to this cassette"""
|
"""Add a request, response pair to this cassette"""
|
||||||
|
log.info("Appending request %s and response %s", request, response)
|
||||||
request = self._before_record_request(request)
|
request = self._before_record_request(request)
|
||||||
if not request:
|
if not request:
|
||||||
return
|
return
|
||||||
|
|||||||
84
vcr/patch.py
84
vcr/patch.py
@@ -6,21 +6,29 @@ from .compat import contextlib, mock
|
|||||||
from .stubs import VCRHTTPConnection, VCRHTTPSConnection
|
from .stubs import VCRHTTPConnection, VCRHTTPSConnection
|
||||||
from six.moves import http_client as httplib
|
from six.moves import http_client as httplib
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
# Save some of the original types for the purposes of unpatching
|
# Save some of the original types for the purposes of unpatching
|
||||||
_HTTPConnection = httplib.HTTPConnection
|
_HTTPConnection = httplib.HTTPConnection
|
||||||
_HTTPSConnection = httplib.HTTPSConnection
|
_HTTPSConnection = httplib.HTTPSConnection
|
||||||
|
|
||||||
|
|
||||||
# Try to save the original types for boto3
|
# Try to save the original types for boto3
|
||||||
try:
|
try:
|
||||||
import botocore.vendored.requests.packages.urllib3.connectionpool as cpool
|
from botocore.awsrequest import AWSHTTPSConnection, AWSHTTPConnection
|
||||||
except ImportError: # pragma: no cover
|
except ImportError:
|
||||||
pass
|
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
|
||||||
else:
|
else:
|
||||||
_Boto3VerifiedHTTPSConnection = cpool.VerifiedHTTPSConnection
|
_Boto3VerifiedHTTPSConnection = AWSHTTPSConnection
|
||||||
_cpoolBoto3HTTPConnection = cpool.HTTPConnection
|
_cpoolBoto3HTTPConnection = AWSHTTPConnection
|
||||||
_cpoolBoto3HTTPSConnection = cpool.HTTPSConnection
|
_cpoolBoto3HTTPSConnection = AWSHTTPSConnection
|
||||||
|
|
||||||
cpool = None
|
cpool = None
|
||||||
# Try to save the original types for urllib3
|
# Try to save the original types for urllib3
|
||||||
@@ -44,7 +52,6 @@ else:
|
|||||||
_cpoolHTTPConnection = cpool.HTTPConnection
|
_cpoolHTTPConnection = cpool.HTTPConnection
|
||||||
_cpoolHTTPSConnection = cpool.HTTPSConnection
|
_cpoolHTTPSConnection = cpool.HTTPSConnection
|
||||||
|
|
||||||
|
|
||||||
# Try to save the original types for httplib2
|
# Try to save the original types for httplib2
|
||||||
try:
|
try:
|
||||||
import httplib2
|
import httplib2
|
||||||
@@ -55,7 +62,6 @@ else:
|
|||||||
_HTTPSConnectionWithTimeout = httplib2.HTTPSConnectionWithTimeout
|
_HTTPSConnectionWithTimeout = httplib2.HTTPSConnectionWithTimeout
|
||||||
_SCHEME_TO_CONNECTION = httplib2.SCHEME_TO_CONNECTION
|
_SCHEME_TO_CONNECTION = httplib2.SCHEME_TO_CONNECTION
|
||||||
|
|
||||||
|
|
||||||
# Try to save the original types for boto
|
# Try to save the original types for boto
|
||||||
try:
|
try:
|
||||||
import boto.https_connection
|
import boto.https_connection
|
||||||
@@ -64,7 +70,6 @@ except ImportError: # pragma: no cover
|
|||||||
else:
|
else:
|
||||||
_CertValidatingHTTPSConnection = boto.https_connection.CertValidatingHTTPSConnection
|
_CertValidatingHTTPSConnection = boto.https_connection.CertValidatingHTTPSConnection
|
||||||
|
|
||||||
|
|
||||||
# Try to save the original types for Tornado
|
# Try to save the original types for Tornado
|
||||||
try:
|
try:
|
||||||
import tornado.simple_httpclient
|
import tornado.simple_httpclient
|
||||||
@@ -74,7 +79,6 @@ else:
|
|||||||
_SimpleAsyncHTTPClient_fetch_impl = \
|
_SimpleAsyncHTTPClient_fetch_impl = \
|
||||||
tornado.simple_httpclient.SimpleAsyncHTTPClient.fetch_impl
|
tornado.simple_httpclient.SimpleAsyncHTTPClient.fetch_impl
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import tornado.curl_httpclient
|
import tornado.curl_httpclient
|
||||||
except ImportError: # pragma: no cover
|
except ImportError: # pragma: no cover
|
||||||
@@ -99,6 +103,7 @@ class CassettePatcherBuilder(object):
|
|||||||
return self._build_patchers_from_mock_triples(
|
return self._build_patchers_from_mock_triples(
|
||||||
function(self, *args, **kwargs)
|
function(self, *args, **kwargs)
|
||||||
)
|
)
|
||||||
|
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
def __init__(self, cassette):
|
def __init__(self, cassette):
|
||||||
@@ -184,13 +189,26 @@ class CassettePatcherBuilder(object):
|
|||||||
return ()
|
return ()
|
||||||
return self._urllib3_patchers(cpool, requests_stubs)
|
return self._urllib3_patchers(cpool, requests_stubs)
|
||||||
|
|
||||||
|
@_build_patchers_from_mock_triples_decorator
|
||||||
def _boto3(self):
|
def _boto3(self):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import botocore.vendored.requests.packages.urllib3.connectionpool as cpool
|
# botocore using awsrequest
|
||||||
|
import botocore.awsrequest as cpool
|
||||||
except ImportError: # pragma: no cover
|
except ImportError: # pragma: no cover
|
||||||
return ()
|
try:
|
||||||
from .stubs import boto3_stubs
|
# botocore using vendored requests
|
||||||
return self._urllib3_patchers(cpool, boto3_stubs)
|
import botocore.vendored.requests.packages.urllib3.connectionpool as cpool
|
||||||
|
except ImportError: # pragma: no cover
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
from .stubs import boto3_stubs
|
||||||
|
yield self._urllib3_patchers(cpool, boto3_stubs)
|
||||||
|
else:
|
||||||
|
from .stubs import boto3_stubs
|
||||||
|
log.debug("Patching boto3 cpool with %s", cpool)
|
||||||
|
yield cpool.AWSHTTPConnectionPool, 'ConnectionCls', boto3_stubs.VCRRequestsHTTPConnection
|
||||||
|
yield cpool.AWSHTTPSConnectionPool, 'ConnectionCls', boto3_stubs.VCRRequestsHTTPSConnection
|
||||||
|
|
||||||
def _patched_get_conn(self, connection_pool_class, connection_class_getter):
|
def _patched_get_conn(self, connection_pool_class, connection_class_getter):
|
||||||
get_conn = connection_pool_class._get_conn
|
get_conn = connection_pool_class._get_conn
|
||||||
@@ -407,22 +425,36 @@ def reset_patchers():
|
|||||||
yield mock.patch.object(cpool.HTTPSConnectionPool, 'ConnectionCls', _cpoolHTTPSConnection)
|
yield mock.patch.object(cpool.HTTPSConnectionPool, 'ConnectionCls', _cpoolHTTPSConnection)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import botocore.vendored.requests.packages.urllib3.connectionpool as cpool
|
# unpatch botocore with awsrequest
|
||||||
|
import botocore.awsrequest as cpool
|
||||||
except ImportError: # pragma: no cover
|
except ImportError: # pragma: no cover
|
||||||
pass
|
try:
|
||||||
|
# unpatch botocore with vendored requests
|
||||||
|
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)
|
||||||
else:
|
else:
|
||||||
# unpatch requests v1.x
|
if hasattr(cpool.AWSHTTPConnectionPool, 'ConnectionCls'):
|
||||||
yield mock.patch.object(cpool, 'VerifiedHTTPSConnection', _Boto3VerifiedHTTPSConnection)
|
yield mock.patch.object(cpool.AWSHTTPConnectionPool, 'ConnectionCls',
|
||||||
yield mock.patch.object(cpool, 'HTTPConnection', _cpoolBoto3HTTPConnection)
|
|
||||||
# unpatch requests v2.x
|
|
||||||
if hasattr(cpool.HTTPConnectionPool, 'ConnectionCls'):
|
|
||||||
yield mock.patch.object(cpool.HTTPConnectionPool, 'ConnectionCls',
|
|
||||||
_cpoolBoto3HTTPConnection)
|
_cpoolBoto3HTTPConnection)
|
||||||
yield mock.patch.object(cpool.HTTPSConnectionPool, 'ConnectionCls',
|
yield mock.patch.object(cpool.AWSHTTPSConnectionPool, 'ConnectionCls',
|
||||||
_cpoolBoto3HTTPSConnection)
|
_cpoolBoto3HTTPSConnection)
|
||||||
|
|
||||||
if hasattr(cpool, 'HTTPSConnection'):
|
if hasattr(cpool, 'AWSHTTPSConnection'):
|
||||||
yield mock.patch.object(cpool, 'HTTPSConnection', _cpoolBoto3HTTPSConnection)
|
yield mock.patch.object(cpool, 'AWSHTTPSConnection', _cpoolBoto3HTTPSConnection)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import httplib2 as cpool
|
import httplib2 as cpool
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import warnings
|
|||||||
from six import BytesIO, text_type
|
from six import BytesIO, text_type
|
||||||
from six.moves.urllib.parse import urlparse, parse_qsl
|
from six.moves.urllib.parse import urlparse, parse_qsl
|
||||||
from .util import CaseInsensitiveDict
|
from .util import CaseInsensitiveDict
|
||||||
|
import logging
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Request(object):
|
class Request(object):
|
||||||
@@ -18,6 +21,7 @@ class Request(object):
|
|||||||
else:
|
else:
|
||||||
self.body = body
|
self.body = body
|
||||||
self.headers = headers
|
self.headers = headers
|
||||||
|
log.debug("Invoking Request %s", self.uri)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def headers(self):
|
def headers(self):
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ class VCRConnection(object):
|
|||||||
self._port_postfix(),
|
self._port_postfix(),
|
||||||
url,
|
url,
|
||||||
)
|
)
|
||||||
|
log.debug("Absolute URI: %s", uri)
|
||||||
return uri
|
return uri
|
||||||
|
|
||||||
def _url(self, uri):
|
def _url(self, uri):
|
||||||
|
|||||||
@@ -1,11 +1,21 @@
|
|||||||
'''Stubs for boto3'''
|
"""Stubs for boto3"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
# boto using awsrequest
|
||||||
|
from botocore.awsrequest import AWSHTTPConnection as HTTPConnection
|
||||||
|
from botocore.awsrequest import AWSHTTPSConnection as VerifiedHTTPSConnection
|
||||||
|
|
||||||
|
except ImportError: # pragma: nocover
|
||||||
|
# boto using vendored requests
|
||||||
|
# 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.
|
||||||
|
try:
|
||||||
|
from urllib3.connectionpool import HTTPConnection, VerifiedHTTPSConnection
|
||||||
|
except ImportError: # pragma: nocover
|
||||||
|
from requests.packages.urllib3.connectionpool import HTTPConnection, VerifiedHTTPSConnection
|
||||||
|
|
||||||
from botocore.vendored.requests.packages.urllib3.connectionpool import HTTPConnection, VerifiedHTTPSConnection
|
|
||||||
from ..stubs import VCRHTTPConnection, VCRHTTPSConnection
|
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):
|
class VCRRequestsHTTPConnection(VCRHTTPConnection, HTTPConnection):
|
||||||
_baseclass = HTTPConnection
|
_baseclass = HTTPConnection
|
||||||
|
|||||||
Reference in New Issue
Block a user