1
0
mirror of https://github.com/kevin1024/vcrpy.git synced 2025-12-09 17:15:35 +00:00

Compare commits

..

15 Commits

Author SHA1 Message Date
Ivan Malison
e9c690b9e7 Version 1.3.0. 2015-03-23 18:10:26 -07:00
Ivan Malison
bba5df2fbb clarifying comment in patch.py. 2015-03-23 18:00:23 -07:00
Ivan Malison
39c3b15e02 unused imports. 2015-03-23 17:56:46 -07:00
Ivan Malison
c87e6d6f6a Clarifying comments in patch.py. 2015-03-23 17:55:49 -07:00
Ivan Malison
5ab77e22db Use suggested emacs style coding statements (see https://www.python.org/dev/peps/pep-0263/). 2015-03-23 17:55:49 -07:00
Ivan 'Goat' Malison
ec6f27bbad Merge pull request #138 from aisch/patch-and-test-urllib3
update urllib3 patch/stub to be same as used for requests and add tests
2015-03-23 17:47:42 -07:00
aisch
8930c97ff7 rm unused imports 2015-03-23 13:56:48 -07:00
aisch
e6b43a0374 rename urllib3 patch method and rm unused imports from tests 2015-03-23 13:43:30 -07:00
aisch
63ec95be06 update urllib3 patch/stub to be same as used for requests and add tests 2015-03-23 12:12:49 -07:00
Kevin McCarthy
84c45b2742 Merge pull request #136 from abhinav/https-port-fix
Fix default port for HTTPS
2015-02-24 09:12:49 -10:00
Abhinav Gupta
87a25e9ab0 Fix httplib2 integration test. 2015-02-24 00:10:08 -08:00
Abhinav Gupta
2473bdb77a Fix default port for HTTPS. 2015-02-23 23:37:04 -08:00
Ivan 'Goat' Malison
32831d4151 Merge pull request #135 from RomuloOliveira/patch-1
Fix missing quotes on Custom Response Filtering
2015-01-28 12:02:57 -08:00
Rômulo Oliveira
4991d6f1c8 Fix missing quotes on Custom Response Filtering
Missing quotes are bad
2015-01-28 11:34:47 -02:00
Ivan Malison
14ef1e87f7 Add custom_patches section to README.md 2015-01-08 14:02:41 -08:00
16 changed files with 258 additions and 76 deletions

View File

@@ -12,6 +12,9 @@ env:
- WITH_LIB="requests1.x" - WITH_LIB="requests1.x"
- WITH_LIB="httplib2" - WITH_LIB="httplib2"
- WITH_LIB="boto" - WITH_LIB="boto"
- WITH_LIB="urllib31.7"
- WITH_LIB="urllib31.9"
- WITH_LIB="urllib31.10"
matrix: matrix:
allow_failures: allow_failures:
- env: WITH_LIB="boto" - env: WITH_LIB="boto"
@@ -37,4 +40,7 @@ install:
- if [ $WITH_LIB = "requests2.5" ] ; then pip install requests==2.5.0; fi - if [ $WITH_LIB = "requests2.5" ] ; then pip install requests==2.5.0; fi
- if [ $WITH_LIB = "httplib2" ] ; then pip install httplib2; fi - if [ $WITH_LIB = "httplib2" ] ; then pip install httplib2; fi
- if [ $WITH_LIB = "boto" ] ; then pip install boto; fi - if [ $WITH_LIB = "boto" ] ; then pip install boto; fi
- if [ $WITH_LIB = "urllib31.7" ] ; then pip install certifi urllib3==1.7.1; fi
- if [ $WITH_LIB = "urllib31.9" ] ; then pip install certifi urllib3==1.9.1; fi
- if [ $WITH_LIB = "urllib31.10" ] ; then pip install certifi urllib3==1.10.2; fi
script: python setup.py test script: python setup.py test

View File

@@ -336,7 +336,7 @@ argument. It's usage is similar to that of `before_record`:
```python ```python
def scrub_string(string, replacement=''): def scrub_string(string, replacement=''):
def before_record_reponse(response): def before_record_reponse(response):
return response['body']['string] = response['body']['string].replace(string, replacement) return response['body']['string'] = response['body']['string'].replace(string, replacement)
return scrub_string return scrub_string
my_vcr = vcr.VCR( my_vcr = vcr.VCR(
@@ -362,6 +362,23 @@ back from a cassette. VCR will completely ignore those requests as if it
didn't notice them at all, and they will continue to hit the server as if VCR didn't notice them at all, and they will continue to hit the server as if VCR
were not there. were not there.
## Custom Patches
If you use a custom `HTTPConnection` class, or otherwise make http
requests in a way that requires additional patching, you can use the
`custom_patches` keyword argument of the `VCR` and `Cassette` objects
to patch those objects whenever a cassette's context is entered. To
patch a custom version of `HTTPConnection` you can do something like
this:
```
import where_the_custom_https_connection_lives
from vcr.stubs import VCRHTTPSConnection
my_vcr = config.VCR(custom_patches=((where_the_custom_https_connection_lives, 'CustomHTTPSConnection', VCRHTTPSConnection),))
@my_vcr.use_cassette(...)
```
## Installation ## Installation
VCR.py is a package on PyPI, so you can `pip install vcrpy` (first you may need VCR.py is a package on PyPI, so you can `pip install vcrpy` (first you may need
@@ -457,6 +474,8 @@ API in version 1.0.x
## Changelog ## Changelog
* 1.3.0 Fix/add support for urllib3 (thanks @aisch), fix default
port for https (thanks @abhinav).
* 1.2.0 Add custom_patches argument to VCR/Cassette objects to allow * 1.2.0 Add custom_patches argument to VCR/Cassette objects to allow
users to stub custom classes when cassettes become active. users to stub custom classes when cassettes become active.
* 1.1.4 Add force reset around calls to actual connection from stubs, to ensure * 1.1.4 Add force reset around calls to actual connection from stubs, to ensure

View File

@@ -20,7 +20,7 @@ class PyTest(TestCommand):
setup( setup(
name='vcrpy', name='vcrpy',
version='1.2.0', version='1.3.0',
description=( description=(
"Automatically mock your HTTP interactions to simplify and " "Automatically mock your HTTP interactions to simplify and "
"speed up testing" "speed up testing"

View File

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
'''Basic tests for cassettes''' '''Basic tests for cassettes'''
# coding=utf-8
# External imports # External imports
import os import os

View File

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
'''Basic tests about save behavior''' '''Basic tests about save behavior'''
# coding=utf-8
# External imports # External imports
import os import os

View File

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
'''Integration tests with httplib2''' '''Integration tests with httplib2'''
# coding=utf-8
# External imports # External imports
from six.moves.urllib_parse import urlencode from six.moves.urllib_parse import urlencode
@@ -54,7 +54,7 @@ def test_response_headers(scheme, tmpdir):
with vcr.use_cassette(str(tmpdir.join('headers.yaml'))) as cass: with vcr.use_cassette(str(tmpdir.join('headers.yaml'))) as cass:
resp, _ = httplib2.Http().request(url) resp, _ = httplib2.Http().request(url)
assert headers == resp.items() assert set(headers) == set(resp.items())
def test_multiple_requests(scheme, tmpdir): def test_multiple_requests(scheme, tmpdir):

View File

@@ -1,23 +1,17 @@
# -*- coding: utf-8 -*-
'''Test requests' interaction with vcr''' '''Test requests' interaction with vcr'''
# coding=utf-8
import os
import pytest import pytest
import vcr import vcr
from assertions import ( from assertions import assert_cassette_empty, assert_is_json
assert_cassette_empty,
assert_cassette_has_one_response,
assert_is_json
)
requests = pytest.importorskip("requests") requests = pytest.importorskip("requests")
@pytest.fixture(params=["https", "http"]) @pytest.fixture(params=["https", "http"])
def scheme(request): def scheme(request):
""" '''Fixture that returns both http and https.'''
Fixture that returns both http and https
"""
return request.param return request.param

View File

@@ -1,8 +1,5 @@
# -*- coding: utf-8 -*-
'''Integration tests with urllib2''' '''Integration tests with urllib2'''
# coding=utf-8
# External imports
import os
import pytest import pytest
from six.moves.urllib.request import urlopen from six.moves.urllib.request import urlopen
@@ -11,7 +8,7 @@ from six.moves.urllib_parse import urlencode
# Internal imports # Internal imports
import vcr import vcr
from assertions import assert_cassette_empty, assert_cassette_has_one_response from assertions import assert_cassette_has_one_response
@pytest.fixture(params=["https", "http"]) @pytest.fixture(params=["https", "http"])

View File

@@ -0,0 +1,148 @@
'''Integration tests with urllib3'''
# coding=utf-8
import pytest
import vcr
from assertions import assert_cassette_empty, assert_is_json
certifi = pytest.importorskip("certifi")
urllib3 = pytest.importorskip("urllib3")
@pytest.fixture(params=["https", "http"])
def scheme(request):
"""
Fixture that returns both http and https
"""
return request.param
@pytest.fixture(scope='module')
def verify_pool_mgr():
return urllib3.PoolManager(
cert_reqs='CERT_REQUIRED', # Force certificate check.
ca_certs=certifi.where()
)
@pytest.fixture(scope='module')
def pool_mgr():
return urllib3.PoolManager()
def test_status_code(scheme, tmpdir, verify_pool_mgr):
'''Ensure that we can read the status code'''
url = scheme + '://httpbin.org/'
with vcr.use_cassette(str(tmpdir.join('atts.yaml'))):
status_code = verify_pool_mgr.request('GET', url).status
with vcr.use_cassette(str(tmpdir.join('atts.yaml'))):
assert status_code == verify_pool_mgr.request('GET', url).status
def test_headers(scheme, tmpdir, verify_pool_mgr):
'''Ensure that we can read the headers back'''
url = scheme + '://httpbin.org/'
with vcr.use_cassette(str(tmpdir.join('headers.yaml'))):
headers = verify_pool_mgr.request('GET', url).headers
with vcr.use_cassette(str(tmpdir.join('headers.yaml'))):
assert headers == verify_pool_mgr.request('GET', url).headers
def test_body(tmpdir, scheme, verify_pool_mgr):
'''Ensure the responses are all identical enough'''
url = scheme + '://httpbin.org/bytes/1024'
with vcr.use_cassette(str(tmpdir.join('body.yaml'))):
content = verify_pool_mgr.request('GET', url).data
with vcr.use_cassette(str(tmpdir.join('body.yaml'))):
assert content == verify_pool_mgr.request('GET', url).data
def test_auth(tmpdir, scheme, verify_pool_mgr):
'''Ensure that we can handle basic auth'''
auth = ('user', 'passwd')
headers = urllib3.util.make_headers(basic_auth='{0}:{1}'.format(*auth))
url = scheme + '://httpbin.org/basic-auth/user/passwd'
with vcr.use_cassette(str(tmpdir.join('auth.yaml'))):
one = verify_pool_mgr.request('GET', url, headers=headers)
with vcr.use_cassette(str(tmpdir.join('auth.yaml'))):
two = verify_pool_mgr.request('GET', url, headers=headers)
assert one.data == two.data
assert one.status == two.status
def test_auth_failed(tmpdir, scheme, verify_pool_mgr):
'''Ensure that we can save failed auth statuses'''
auth = ('user', 'wrongwrongwrong')
headers = urllib3.util.make_headers(basic_auth='{0}:{1}'.format(*auth))
url = scheme + '://httpbin.org/basic-auth/user/passwd'
with vcr.use_cassette(str(tmpdir.join('auth-failed.yaml'))) as cass:
# Ensure that this is empty to begin with
assert_cassette_empty(cass)
one = verify_pool_mgr.request('GET', url, headers=headers)
two = verify_pool_mgr.request('GET', url, headers=headers)
assert one.data == two.data
assert one.status == two.status == 401
def test_post(tmpdir, scheme, verify_pool_mgr):
'''Ensure that we can post and cache the results'''
data = {'key1': 'value1', 'key2': 'value2'}
url = scheme + '://httpbin.org/post'
with vcr.use_cassette(str(tmpdir.join('verify_pool_mgr.yaml'))):
req1 = verify_pool_mgr.request('POST', url, data).data
with vcr.use_cassette(str(tmpdir.join('verify_pool_mgr.yaml'))):
req2 = verify_pool_mgr.request('POST', url, data).data
assert req1 == req2
def test_redirects(tmpdir, scheme, verify_pool_mgr):
'''Ensure that we can handle redirects'''
url = scheme + '://httpbin.org/redirect-to?url=bytes/1024'
with vcr.use_cassette(str(tmpdir.join('verify_pool_mgr.yaml'))):
content = verify_pool_mgr.request('GET', url).data
with vcr.use_cassette(str(tmpdir.join('verify_pool_mgr.yaml'))) as cass:
assert content == verify_pool_mgr.request('GET', url).data
# Ensure that we've now cached *two* responses. One for the redirect
# and one for the final fetch
assert len(cass) == 2
assert cass.play_count == 2
def test_cross_scheme(tmpdir, scheme, verify_pool_mgr):
'''Ensure that requests between schemes are treated separately'''
# First fetch a url under http, and then again under https and then
# ensure that we haven't served anything out of cache, and we have two
# requests / response pairs in the cassette
with vcr.use_cassette(str(tmpdir.join('cross_scheme.yaml'))) as cass:
verify_pool_mgr.request('GET', 'https://httpbin.org/')
verify_pool_mgr.request('GET', 'http://httpbin.org/')
assert cass.play_count == 0
assert len(cass) == 2
def test_gzip(tmpdir, scheme, verify_pool_mgr):
'''
Ensure that requests (actually urllib3) is able to automatically decompress
the response body
'''
url = scheme + '://httpbin.org/gzip'
response = verify_pool_mgr.request('GET', url)
with vcr.use_cassette(str(tmpdir.join('gzip.yaml'))):
response = verify_pool_mgr.request('GET', url)
assert_is_json(response.data)
with vcr.use_cassette(str(tmpdir.join('gzip.yaml'))):
assert_is_json(response.data)
def test_https_with_cert_validation_disabled(tmpdir, pool_mgr):
with vcr.use_cassette(str(tmpdir.join('cert_validation_disabled.yaml'))):
pool_mgr.request('GET', 'https://httpbin.org')

View File

@@ -21,8 +21,8 @@ def test_headers():
('http://go.com/', 80), ('http://go.com/', 80),
('http://go.com:80/', 80), ('http://go.com:80/', 80),
('http://go.com:3000/', 3000), ('http://go.com:3000/', 3000),
('https://go.com/', 433), ('https://go.com/', 443),
('https://go.com:433/', 433), ('https://go.com:443/', 443),
('https://go.com:3000/', 3000), ('https://go.com:3000/', 3000),
]) ])
def test_port(uri, expected_port): def test_port(uri, expected_port):

View File

@@ -21,5 +21,7 @@ deps =
requests23: requests==2.3.0 requests23: requests==2.3.0
requests22: requests==2.2.1 requests22: requests==2.2.1
httplib2: httplib2 httplib2: httplib2
urllib3: urllib3==1.7.1 urllib317: urllib3==1.7.1
urllib319: urllib3==1.9.1
urllib3110: urllib3==1.10.2
boto: boto boto: boto

View File

@@ -58,7 +58,7 @@ PARTS = [
def build_uri(**parts): def build_uri(**parts):
port = parts['port'] port = parts['port']
scheme = parts['protocol'] scheme = parts['protocol']
default_port = {'https': 433, 'http': 80}[scheme] default_port = {'https': 443, 'http': 80}[scheme]
parts['port'] = ':{0}'.format(port) if port != default_port else '' parts['port'] = ':{0}'.format(port) if port != default_port else ''
return "{protocol}://{host}{port}{path}".format(**parts) return "{protocol}://{host}{port}{path}".format(**parts)

View File

@@ -92,15 +92,21 @@ class CassettePatcherBuilder(object):
def _recursively_apply_get_cassette_subclass(self, replacement_dict_or_obj): def _recursively_apply_get_cassette_subclass(self, replacement_dict_or_obj):
"""One of the subtleties of this class is that it does not directly """One of the subtleties of this class is that it does not directly
replace HTTPSConnection with VCRRequestsHTTPSConnection, but a replace HTTPSConnection with `VCRRequestsHTTPSConnection`, but a
subclass of this class that has cassette assigned to the subclass of the aforementioned class that has the `cassette`
appropriate value. This behavior is necessary to properly class attribute assigned to `self._cassette`. This behavior is
support nested cassette contexts necessary to properly support nested cassette contexts.
This function exists to ensure that we use the same class This function exists to ensure that we use the same class
object (reference) to patch everything that replaces object (reference) to patch everything that replaces
VCRRequestHTTP[S]Connection, but that we can talk about VCRRequestHTTP[S]Connection, but that we can talk about
patching them with the raw references instead. patching them with the raw references instead, and without
worrying about exactly where the subclass with the relevant
value for `cassette` is first created.
The function is recursive because it looks in to dictionaries
and replaces class values at any depth with the subclass
described in the previous paragraph.
""" """
if isinstance(replacement_dict_or_obj, dict): if isinstance(replacement_dict_or_obj, dict):
for key, replacement_obj in replacement_dict_or_obj.items(): for key, replacement_obj in replacement_dict_or_obj.items():
@@ -138,39 +144,8 @@ class CassettePatcherBuilder(object):
import requests.packages.urllib3.connectionpool as cpool import requests.packages.urllib3.connectionpool as cpool
except ImportError: # pragma: no cover except ImportError: # pragma: no cover
return () return ()
from .stubs.requests_stubs import VCRRequestsHTTPConnection, VCRRequestsHTTPSConnection from .stubs import requests_stubs
http_connection_remover = ConnectionRemover( return self._urllib3_patchers(cpool, requests_stubs)
self._get_cassette_subclass(VCRRequestsHTTPConnection)
)
https_connection_remover = ConnectionRemover(
self._get_cassette_subclass(VCRRequestsHTTPSConnection)
)
mock_triples = (
(cpool, 'VerifiedHTTPSConnection', VCRRequestsHTTPSConnection),
(cpool, 'VerifiedHTTPSConnection', VCRRequestsHTTPSConnection),
(cpool, 'HTTPConnection', VCRRequestsHTTPConnection),
(cpool, 'HTTPSConnection', VCRRequestsHTTPSConnection),
(cpool, 'is_connection_dropped', mock.Mock(return_value=False)), # Needed on Windows only
(cpool.HTTPConnectionPool, 'ConnectionCls', VCRRequestsHTTPConnection),
(cpool.HTTPSConnectionPool, 'ConnectionCls', VCRRequestsHTTPSConnection),
)
# These handle making sure that sessions only use the
# connections of the appropriate type.
mock_triples += ((cpool.HTTPConnectionPool, '_get_conn',
self._patched_get_conn(cpool.HTTPConnectionPool,
lambda : cpool.HTTPConnection)),
(cpool.HTTPSConnectionPool, '_get_conn',
self._patched_get_conn(cpool.HTTPSConnectionPool,
lambda : cpool.HTTPSConnection)),
(cpool.HTTPConnectionPool, '_new_conn',
self._patched_new_conn(cpool.HTTPConnectionPool,
http_connection_remover)),
(cpool.HTTPSConnectionPool, '_new_conn',
self._patched_new_conn(cpool.HTTPSConnectionPool,
https_connection_remover)))
return itertools.chain(self._build_patchers_from_mock_triples(mock_triples),
(http_connection_remover, https_connection_remover))
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
@@ -179,6 +154,12 @@ class CassettePatcherBuilder(object):
connection = get_conn(pool, timeout) connection = get_conn(pool, timeout)
connection_class = pool.ConnectionCls if hasattr(pool, 'ConnectionCls') \ connection_class = pool.ConnectionCls if hasattr(pool, 'ConnectionCls') \
else connection_class_getter() else connection_class_getter()
# We need to make sure that we are actually providing a
# patched version of the connection class. This might not
# always be the case because the pool keeps previously
# used connections (which might actually be of a different
# class) around. This while loop will terminate because
# eventually the pool will run out of connections.
while not isinstance(connection, connection_class): while not isinstance(connection, connection_class):
connection = get_conn(pool, timeout) connection = get_conn(pool, timeout)
return connection return connection
@@ -193,17 +174,13 @@ class CassettePatcherBuilder(object):
return new_connection return new_connection
return patched_new_conn return patched_new_conn
@_build_patchers_from_mock_triples_decorator
def _urllib3(self): def _urllib3(self):
try: try:
import urllib3.connectionpool as cpool import urllib3.connectionpool as cpool
except ImportError: # pragma: no cover except ImportError: # pragma: no cover
pass return ()
else: from .stubs import urllib3_stubs
from .stubs.urllib3_stubs import VCRVerifiedHTTPSConnection return self._urllib3_patchers(cpool, urllib3_stubs)
yield cpool, 'VerifiedHTTPSConnection', VCRVerifiedHTTPSConnection
yield cpool, 'HTTPConnection', VCRHTTPConnection
@_build_patchers_from_mock_triples_decorator @_build_patchers_from_mock_triples_decorator
def _httplib2(self): def _httplib2(self):
@@ -229,6 +206,40 @@ class CassettePatcherBuilder(object):
else: else:
from .stubs.boto_stubs import VCRCertValidatingHTTPSConnection from .stubs.boto_stubs import VCRCertValidatingHTTPSConnection
yield cpool, 'CertValidatingHTTPSConnection', VCRCertValidatingHTTPSConnection yield cpool, 'CertValidatingHTTPSConnection', VCRCertValidatingHTTPSConnection
def _urllib3_patchers(self, cpool, stubs):
http_connection_remover = ConnectionRemover(
self._get_cassette_subclass(stubs.VCRRequestsHTTPConnection)
)
https_connection_remover = ConnectionRemover(
self._get_cassette_subclass(stubs.VCRRequestsHTTPSConnection)
)
mock_triples = (
(cpool, 'VerifiedHTTPSConnection', stubs.VCRRequestsHTTPSConnection),
(cpool, 'VerifiedHTTPSConnection', stubs.VCRRequestsHTTPSConnection),
(cpool, 'HTTPConnection', stubs.VCRRequestsHTTPConnection),
(cpool, 'HTTPSConnection', stubs.VCRRequestsHTTPSConnection),
(cpool, 'is_connection_dropped', mock.Mock(return_value=False)), # Needed on Windows only
(cpool.HTTPConnectionPool, 'ConnectionCls', stubs.VCRRequestsHTTPConnection),
(cpool.HTTPSConnectionPool, 'ConnectionCls', stubs.VCRRequestsHTTPSConnection),
)
# These handle making sure that sessions only use the
# connections of the appropriate type.
mock_triples += ((cpool.HTTPConnectionPool, '_get_conn',
self._patched_get_conn(cpool.HTTPConnectionPool,
lambda : cpool.HTTPConnection)),
(cpool.HTTPSConnectionPool, '_get_conn',
self._patched_get_conn(cpool.HTTPSConnectionPool,
lambda : cpool.HTTPSConnection)),
(cpool.HTTPConnectionPool, '_new_conn',
self._patched_new_conn(cpool.HTTPConnectionPool,
http_connection_remover)),
(cpool.HTTPSConnectionPool, '_new_conn',
self._patched_new_conn(cpool.HTTPSConnectionPool,
https_connection_remover)))
return itertools.chain(self._build_patchers_from_mock_triples(mock_triples),
(http_connection_remover, https_connection_remover))
class ConnectionRemover(object): class ConnectionRemover(object):

View File

@@ -51,7 +51,7 @@ class Request(object):
parse_uri = urlparse(self.uri) parse_uri = urlparse(self.uri)
port = parse_uri.port port = parse_uri.port
if port is None: if port is None:
port = {'https': 433, 'http': 80}[parse_uri.scheme] port = {'https': 443, 'http': 80}[parse_uri.scheme]
return port return port
@property @property

View File

@@ -128,7 +128,7 @@ class VCRConnection(object):
Returns empty string for the default port and ':port' otherwise Returns empty string for the default port and ':port' otherwise
""" """
port = self.real_connection.port port = self.real_connection.port
default_port = {'https': 433, 'http': 80}[self._protocol] default_port = {'https': 443, 'http': 80}[self._protocol]
return ':{0}'.format(port) if port != default_port else '' return ':{0}'.format(port) if port != default_port else ''
def _uri(self, url): def _uri(self, url):

View File

@@ -1,8 +1,13 @@
'''Stubs for urllib3''' '''Stubs for urllib3'''
from urllib3.connectionpool import VerifiedHTTPSConnection from urllib3.connectionpool import HTTPConnection, VerifiedHTTPSConnection
from ..stubs import VCRHTTPSConnection from ..stubs import VCRHTTPConnection, VCRHTTPSConnection
# urllib3 defines its own HTTPConnection classes. It includes some polyfills
# for newer features missing in older pythons.
class VCRVerifiedHTTPSConnection(VCRHTTPSConnection, VerifiedHTTPSConnection): class VCRRequestsHTTPConnection(VCRHTTPConnection, HTTPConnection):
_baseclass = HTTPConnection
class VCRRequestsHTTPSConnection(VCRHTTPSConnection, VerifiedHTTPSConnection):
_baseclass = VerifiedHTTPSConnection _baseclass = VerifiedHTTPSConnection