Skip to content

Commit

Permalink
fix: use urllib3.connection where needed.
Browse files Browse the repository at this point in the history
Since urllib3 v2 the re-export of connection.HTTPConnection in
urllib3.connectionpool was removed.

In this commit we use urllib3.connection where needed. Some references
to connectionpool.HTTPConnection are still there for backward
compatibility.

Closes #688
  • Loading branch information
shifqu committed May 12, 2023
1 parent 14cef83 commit 2734f89
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 51 deletions.
2 changes: 1 addition & 1 deletion tests/integration/test_boto3.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def test_boto_vendored_stubs(tmpdir):
with vcr.use_cassette(str(tmpdir.join("boto3-stubs.yml"))):
# Perform the imports within the patched context so that
# HTTPConnection, VerifiedHTTPSConnection refers to the patched version.
from botocore.vendored.requests.packages.urllib3.connectionpool import (
from botocore.vendored.requests.packages.urllib3.connection import (
HTTPConnection,
VerifiedHTTPSConnection,
)
Expand Down
26 changes: 13 additions & 13 deletions tests/integration/test_urllib3.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,18 +145,18 @@ def test_https_with_cert_validation_disabled(tmpdir, httpbin_secure, pool_mgr):


def test_urllib3_force_reset():
cpool = urllib3.connectionpool
http_original = cpool.HTTPConnection
https_original = cpool.HTTPSConnection
verified_https_original = cpool.VerifiedHTTPSConnection
conn = urllib3.connection
http_original = conn.HTTPConnection
https_original = conn.HTTPSConnection
verified_https_original = conn.VerifiedHTTPSConnection
with vcr.use_cassette(path="test"):
first_cassette_HTTPConnection = cpool.HTTPConnection
first_cassette_HTTPSConnection = cpool.HTTPSConnection
first_cassette_VerifiedHTTPSConnection = cpool.VerifiedHTTPSConnection
first_cassette_HTTPConnection = conn.HTTPConnection
first_cassette_HTTPSConnection = conn.HTTPSConnection
first_cassette_VerifiedHTTPSConnection = conn.VerifiedHTTPSConnection
with force_reset():
assert cpool.HTTPConnection is http_original
assert cpool.HTTPSConnection is https_original
assert cpool.VerifiedHTTPSConnection is verified_https_original
assert cpool.HTTPConnection is first_cassette_HTTPConnection
assert cpool.HTTPSConnection is first_cassette_HTTPSConnection
assert cpool.VerifiedHTTPSConnection is first_cassette_VerifiedHTTPSConnection
assert conn.HTTPConnection is http_original
assert conn.HTTPSConnection is https_original
assert conn.VerifiedHTTPSConnection is verified_https_original
assert conn.HTTPConnection is first_cassette_HTTPConnection
assert conn.HTTPSConnection is first_cassette_HTTPSConnection
assert conn.VerifiedHTTPSConnection is first_cassette_VerifiedHTTPSConnection
75 changes: 43 additions & 32 deletions vcr/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,41 @@
from botocore.awsrequest import AWSHTTPConnection, AWSHTTPSConnection
except ImportError:
try:
import botocore.vendored.requests.packages.urllib3.connectionpool as cpool
from botocore.vendored.requests.packages.urllib3 import connection
except ImportError: # pragma: no cover
pass
else:
_Boto3VerifiedHTTPSConnection = cpool.VerifiedHTTPSConnection
_cpoolBoto3HTTPConnection = cpool.HTTPConnection
_cpoolBoto3HTTPSConnection = cpool.HTTPSConnection
_Boto3VerifiedHTTPSConnection = connection.VerifiedHTTPSConnection
_cpoolBoto3HTTPConnection = connection.HTTPConnection
_cpoolBoto3HTTPSConnection = connection.HTTPSConnection
else:
_Boto3VerifiedHTTPSConnection = AWSHTTPSConnection
_cpoolBoto3HTTPConnection = AWSHTTPConnection
_cpoolBoto3HTTPSConnection = AWSHTTPSConnection

cpool = None
conn = None
# Try to save the original types for urllib3
try:
import urllib3.connectionpool as cpool
import urllib3.connection as conn
except ImportError: # pragma: no cover
pass
else:
_VerifiedHTTPSConnection = cpool.VerifiedHTTPSConnection
_cpoolHTTPConnection = cpool.HTTPConnection
_cpoolHTTPSConnection = cpool.HTTPSConnection
_VerifiedHTTPSConnection = conn.VerifiedHTTPSConnection
_connHTTPConnection = conn.HTTPConnection
_connHTTPSConnection = conn.HTTPSConnection

# Try to save the original types for requests
try:
if not cpool:
import requests.packages.urllib3.connectionpool as cpool
if not conn:
import requests.packages.urllib3.connection as conn
except ImportError: # pragma: no cover
pass
else:
_VerifiedHTTPSConnection = cpool.VerifiedHTTPSConnection
_cpoolHTTPConnection = cpool.HTTPConnection
_cpoolHTTPSConnection = cpool.HTTPSConnection
_VerifiedHTTPSConnection = conn.VerifiedHTTPSConnection
_connHTTPConnection = conn.HTTPConnection
_connHTTPSConnection = conn.HTTPSConnection

# Try to save the original types for httplib2
try:
Expand Down Expand Up @@ -195,7 +197,7 @@ def _requests(self):
from .stubs import requests_stubs
except ImportError: # pragma: no cover
return ()
return self._urllib3_patchers(cpool, requests_stubs)
return self._urllib3_patchers(cpool, conn, requests_stubs)

@_build_patchers_from_mock_triples_decorator
def _boto3(self):
Expand All @@ -206,12 +208,13 @@ def _boto3(self):
try:
# botocore using vendored requests
import botocore.vendored.requests.packages.urllib3.connectionpool as cpool
import botocore.vendored.requests.packages.urllib3.connection as conn
except ImportError: # pragma: no cover
pass
else:
from .stubs import boto3_stubs

yield self._urllib3_patchers(cpool, boto3_stubs)
yield self._urllib3_patchers(cpool, conn, boto3_stubs)
else:
from .stubs import boto3_stubs

Expand Down Expand Up @@ -254,11 +257,12 @@ def patched_new_conn(pool):
def _urllib3(self):
try:
import urllib3.connectionpool as cpool
import urllib3.connection as conn
except ImportError: # pragma: no cover
return ()
from .stubs import urllib3_stubs

return self._urllib3_patchers(cpool, urllib3_stubs)
return self._urllib3_patchers(cpool, conn, urllib3_stubs)

@_build_patchers_from_mock_triples_decorator
def _httplib2(self):
Expand Down Expand Up @@ -335,17 +339,17 @@ def _httpx(self):
new_sync_client_send = sync_vcr_send(self._cassette, _HttpxSyncClient_send)
yield httpx.Client, "send", new_sync_client_send

def _urllib3_patchers(self, cpool, stubs):
def _urllib3_patchers(self, cpool, conn, 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, "HTTPConnection", stubs.VCRRequestsHTTPConnection),
(cpool, "HTTPSConnection", stubs.VCRRequestsHTTPSConnection),
(conn, "VerifiedHTTPSConnection", stubs.VCRRequestsHTTPSConnection),
(conn, "HTTPConnection", stubs.VCRRequestsHTTPConnection),
(conn, "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),
Expand Down Expand Up @@ -428,33 +432,37 @@ def reset_patchers():
# Note that this also means that now, requests.packages is never imported
# if requests 2.16.3 or greater is used with VCRPy.
import requests.packages.urllib3.connectionpool as cpool
import requests.packages.urllib3.connection as conn
else:
raise ImportError("Skip requests not vendored anymore")
except ImportError: # pragma: no cover
pass
else:
# unpatch requests v1.x
yield mock.patch.object(cpool, "VerifiedHTTPSConnection", _VerifiedHTTPSConnection)
yield mock.patch.object(cpool, "HTTPConnection", _cpoolHTTPConnection)
yield mock.patch.object(conn, "VerifiedHTTPSConnection", _VerifiedHTTPSConnection)
yield mock.patch.object(conn, "HTTPConnection", _connHTTPConnection)
yield mock.patch.object(conn, "HTTPSConnection", _connHTTPConnection)
# unpatch requests v2.x
if hasattr(cpool.HTTPConnectionPool, "ConnectionCls"):
yield mock.patch.object(cpool.HTTPConnectionPool, "ConnectionCls", _cpoolHTTPConnection)
yield mock.patch.object(cpool.HTTPSConnectionPool, "ConnectionCls", _cpoolHTTPSConnection)
yield mock.patch.object(cpool.HTTPConnectionPool, "ConnectionCls", _connHTTPConnection)
yield mock.patch.object(cpool.HTTPSConnectionPool, "ConnectionCls", _connHTTPSConnection)

# Leave this here for mocked httpsconnection from cpool (removed in urllib > 2)
if hasattr(cpool, "HTTPSConnection"):
yield mock.patch.object(cpool, "HTTPSConnection", _cpoolHTTPSConnection)
yield mock.patch.object(cpool, "HTTPSConnection", _connHTTPSConnection)

try:
import urllib3.connectionpool as cpool
import urllib3.connection as conn
except ImportError: # pragma: no cover
pass
else:
yield mock.patch.object(cpool, "VerifiedHTTPSConnection", _VerifiedHTTPSConnection)
yield mock.patch.object(cpool, "HTTPConnection", _cpoolHTTPConnection)
yield mock.patch.object(cpool, "HTTPSConnection", _cpoolHTTPSConnection)
yield mock.patch.object(conn, "VerifiedHTTPSConnection", _VerifiedHTTPSConnection)
yield mock.patch.object(conn, "HTTPConnection", _connHTTPConnection)
yield mock.patch.object(conn, "HTTPSConnection", _connHTTPSConnection)
if hasattr(cpool.HTTPConnectionPool, "ConnectionCls"):
yield mock.patch.object(cpool.HTTPConnectionPool, "ConnectionCls", _cpoolHTTPConnection)
yield mock.patch.object(cpool.HTTPSConnectionPool, "ConnectionCls", _cpoolHTTPSConnection)
yield mock.patch.object(cpool.HTTPConnectionPool, "ConnectionCls", _connHTTPConnection)
yield mock.patch.object(cpool.HTTPSConnectionPool, "ConnectionCls", _connHTTPSConnection)

try:
# unpatch botocore with awsrequest
Expand All @@ -463,19 +471,22 @@ def reset_patchers():
try:
# unpatch botocore with vendored requests
import botocore.vendored.requests.packages.urllib3.connectionpool as cpool
import botocore.vendored.requests.packages.urllib3.connection as conn
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)
yield mock.patch.object(conn, "VerifiedHTTPSConnection", _Boto3VerifiedHTTPSConnection)
yield mock.patch.object(conn, "HTTPConnection", _cpoolBoto3HTTPConnection)
yield mock.patch.object(conn, "HTTPSConnection", _cpoolBoto3HTTPSConnection)
# 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
)


# Leave this here for mocked httpsconnection from cpool (removed in urllib > 2)
if hasattr(cpool, "HTTPSConnection"):
yield mock.patch.object(cpool, "HTTPSConnection", _cpoolBoto3HTTPSConnection)
else:
Expand Down
4 changes: 2 additions & 2 deletions vcr/stubs/boto3_stubs.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
# 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
from urllib3.connection import HTTPConnection, VerifiedHTTPSConnection
except ImportError: # pragma: nocover
from requests.packages.urllib3.connectionpool import HTTPConnection, VerifiedHTTPSConnection
from requests.packages.urllib3.connection import HTTPConnection, VerifiedHTTPSConnection

from ..stubs import VCRHTTPConnection, VCRHTTPSConnection

Expand Down
4 changes: 2 additions & 2 deletions vcr/stubs/requests_stubs.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"""Stubs for requests"""

try:
from urllib3.connectionpool import HTTPConnection, VerifiedHTTPSConnection
from urllib3.connection import HTTPConnection, VerifiedHTTPSConnection
except ImportError:
from requests.packages.urllib3.connectionpool import HTTPConnection, VerifiedHTTPSConnection
from requests.packages.urllib3.connection import HTTPConnection, VerifiedHTTPSConnection

from ..stubs import VCRHTTPConnection, VCRHTTPSConnection

Expand Down
2 changes: 1 addition & 1 deletion vcr/stubs/urllib3_stubs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Stubs for urllib3"""

from urllib3.connectionpool import HTTPConnection, VerifiedHTTPSConnection
from urllib3.connection import HTTPConnection, VerifiedHTTPSConnection

from ..stubs import VCRHTTPConnection, VCRHTTPSConnection

Expand Down

0 comments on commit 2734f89

Please sign in to comment.