Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: compatibility with urllib3 2.0 #294

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion cachecontrol/serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ def dumps(self, request, response, body=None):
u"status": response.status,
u"version": response.version,
u"reason": text_type(response.reason),
u"strict": response.strict,
u"decode_content": response.decode_content,
}
}
Expand Down
66 changes: 39 additions & 27 deletions tests/test_cache_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@
"""
Unit tests that verify our caching methods work correctly.
"""
import pytest
from mock import ANY, Mock
import time
from tempfile import mkdtemp

import pytest
from mock import ANY, Mock

from cachecontrol import CacheController
from cachecontrol.cache import DictCache
from cachecontrol.caches import SeparateBodyFileCache
from .utils import NullSerializer, DummyResponse, DummyRequest

TIME_FMT = "%a, %d %b %Y %H:%M:%S GMT"
from .utils import DummyRequest, DummyResponse, NullSerializer

TIME_FMT = "%a, %d %b %Y %H:%M:%S GMT"


class TestCacheControllerResponse(object):
Expand Down Expand Up @@ -126,13 +127,16 @@ def test_update_cached_response_no_local_cache(self):
cache = DictCache({})
cc = CacheController(cache)
req = DummyRequest(url="http://localhost/", headers={"if-match": "xyz"})
resp = DummyResponse(status=304, headers={
"ETag": "xyz",
"x-value": "b",
"Date": time.strftime(TIME_FMT, time.gmtime()),
"Cache-Control": "max-age=60",
"Content-Length": "200"
})
resp = DummyResponse(
status=304,
headers={
"ETag": "xyz",
"x-value": "b",
"Date": time.strftime(TIME_FMT, time.gmtime()),
"Cache-Control": "max-age=60",
"Content-Length": "200",
},
)
# First, ensure the response from update_cached_response() matches the
# cached one:
result = cc.update_cached_response(req, resp)
Expand Down Expand Up @@ -176,13 +180,16 @@ def update_cached_response_with_valid_headers_test(self, cache):
cc = CacheController(cache)
url = "http://localhost:123/x"
req = DummyRequest(url=url, headers={})
cached_resp = DummyResponse(status=200, headers={
"ETag": etag,
"x-value:": "a",
"Content-Length": "100",
"Cache-Control": "max-age=60",
"Date": time.strftime(TIME_FMT, time.gmtime()),
})
cached_resp = DummyResponse(
status=200,
headers={
"ETag": etag,
"x-value:": "a",
"Content-Length": "100",
"Cache-Control": "max-age=60",
"Date": time.strftime(TIME_FMT, time.gmtime()),
},
)
cc._cache_set(url, req, cached_resp, b"my body")

# Now we get another request, and it's a 304, with new value for
Expand All @@ -191,13 +198,16 @@ def update_cached_response_with_valid_headers_test(self, cache):
# Set our content length to 200. That would be a mistake in
# the server, but we'll handle it gracefully... for now.
req = DummyRequest(url=url, headers={"if-match": etag})
resp = DummyResponse(status=304, headers={
"ETag": etag,
"x-value": "b",
"Date": time.strftime(TIME_FMT, time.gmtime()),
"Cache-Control": "max-age=60",
"Content-Length": "200"
})
resp = DummyResponse(
status=304,
headers={
"ETag": etag,
"x-value": "b",
"Date": time.strftime(TIME_FMT, time.gmtime()),
"Cache-Control": "max-age=60",
"Content-Length": "200",
},
)
# First, ensure the response from update_cached_response() matches the
# cached one:
result = cc.update_cached_response(req, resp)
Expand All @@ -214,15 +224,17 @@ def update_cached_response_with_valid_headers_test(self, cache):
class TestCacheControlRequest(object):
url = "http://foo.com/bar"

def setup(self):
def setup_method(self):
self.c = CacheController(DictCache(), serializer=NullSerializer())

def req(self, headers):
mock_request = Mock(url=self.url, headers=headers)
return self.c.cached_request(mock_request)

def test_cache_request_no_headers(self):
cached_resp = Mock(headers={"ETag": "jfd9094r808", "Content-Length": 100}, status=200)
cached_resp = Mock(
headers={"ETag": "jfd9094r808", "Content-Length": 100}, status=200
)
self.c.cache = DictCache({self.url: cached_resp})
resp = self.req({})
assert not resp
Expand Down
7 changes: 3 additions & 4 deletions tests/test_etag.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
# SPDX-License-Identifier: Apache-2.0

import pytest

from mock import Mock, patch

import requests
from mock import Mock, patch

from cachecontrol import CacheControl
from cachecontrol.cache import DictCache
from cachecontrol.compat import urljoin

from .utils import NullSerializer


Expand Down Expand Up @@ -136,7 +135,7 @@ def test_not_modified_releases_connection(self, server, url):

# This is how the urllib3 response is created in
# requests.adapters
response_mod = "requests.adapters.HTTPResponse.from_httplib"
response_mod = "urllib3.HTTPConnectionPool.urlopen"

with patch(response_mod, Mock(return_value=resp)):
sess.get(etag_url)
Expand Down
41 changes: 17 additions & 24 deletions tests/test_expires_heuristics.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,27 @@

import calendar
import time

from email.utils import formatdate, parsedate
from datetime import datetime
from email.utils import formatdate, parsedate
from pprint import pprint

from mock import Mock
from requests import Session, get

from cachecontrol import CacheControl
from cachecontrol.heuristics import LastModified, ExpiresAfter, OneDayCache
from cachecontrol.heuristics import TIME_FMT
from cachecontrol.heuristics import BaseHeuristic
from .utils import DummyResponse
from cachecontrol.heuristics import (
TIME_FMT,
BaseHeuristic,
ExpiresAfter,
LastModified,
OneDayCache,
)

from pprint import pprint
from .utils import DummyResponse


class TestHeuristicWithoutWarning(object):

def setup(self):

def setup_method(self):
class NoopHeuristic(BaseHeuristic):
warning = Mock()

Expand All @@ -35,17 +36,14 @@ def update_headers(self, resp):

def test_no_header_change_means_no_warning_header(self, url):
the_url = url + "optional_cacheable_request"
resp = self.sess.get(the_url)
self.sess.get(the_url)

assert not self.heuristic.warning.called


class TestHeuristicWith3xxResponse(object):

def setup(self):

def setup_method(self):
class DummyHeuristic(BaseHeuristic):

def update_headers(self, resp):
return {"x-dummy-header": "foobar"}

Expand All @@ -63,16 +61,14 @@ def test_heuristic_applies_to_304(self, url):


class TestUseExpiresHeuristic(object):

def test_expires_heuristic_arg(self):
sess = Session()
cached_sess = CacheControl(sess, heuristic=Mock())
assert cached_sess


class TestOneDayCache(object):

def setup(self):
def setup_method(self):
self.sess = Session()
self.cached_sess = CacheControl(self.sess, heuristic=OneDayCache())

Expand All @@ -91,8 +87,7 @@ def test_cache_for_one_day(self, url):


class TestExpiresAfter(object):

def setup(self):
def setup_method(self):
self.sess = Session()
self.cache_sess = CacheControl(self.sess, heuristic=ExpiresAfter(days=1))

Expand All @@ -112,8 +107,7 @@ def test_expires_after_one_day(self, url):


class TestLastModified(object):

def setup(self):
def setup_method(self):
self.sess = Session()
self.cached_sess = CacheControl(self.sess, heuristic=LastModified())

Expand All @@ -136,11 +130,10 @@ def datetime_to_header(dt):


class TestModifiedUnitTests(object):

def last_modified(self, period):
return time.strftime(TIME_FMT, time.gmtime(self.time_now - period))

def setup(self):
def setup_method(self):
self.heuristic = LastModified()
self.time_now = time.time()
day_in_seconds = 86400
Expand Down
6 changes: 2 additions & 4 deletions tests/test_redirects.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@


class TestPermanentRedirects(object):

def setup(self):
def setup_method(self):
self.sess = CacheControl(requests.Session())

def test_redirect_response_is_cached(self, url):
Expand All @@ -33,8 +32,7 @@ def test_bust_cache_on_redirect(self, url):


class TestMultipleChoicesRedirects(object):

def setup(self):
def setup_method(self):
self.sess = CacheControl(requests.Session())

def test_multiple_choices_is_cacheable(self, url):
Expand Down
7 changes: 3 additions & 4 deletions tests/test_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


class TestSerializer(object):
def setup(self):
def setup_method(self):
self.serializer = Serializer()
self.response_data = {
u"response": {
Expand All @@ -27,7 +27,6 @@ def setup(self):
u"status": 200,
u"version": 11,
u"reason": u"",
u"strict": True,
u"decode_content": True,
}
}
Expand All @@ -46,7 +45,7 @@ def test_read_version_v1(self):

def test_read_version_v2(self):
req = Mock()
compressed_base64_json = b"x\x9c%O\xb9\n\x83@\x10\xfd\x97\xa9-\x92%E\x14R\xe4 +\x16\t\xe6\x10\xbb\xb0\xc7\xe0\x81\xb8\xb2\xbb*A\xfc\xf7\x8c\xa6|\xe7\xbc\x99\xc0\xa2\xebL\xeb\x10\xa2\t\xa4\xd1_\x88\xe0\xc93'\xf9\xbe\xc8X\xf8\x95<=@\x00\x1a\x95\xd1\xf8Q\xa6\xf5\xd8z\x88\xbc\xed1\x80\x12\x85F\xeb\x96h\xca\xc2^\xf3\xac\xd7\xe7\xed\x1b\xf3SC5\x04w\xfa\x1c\x8e\x92_;Y\x1c\x96\x9a\x94]k\xc1\xdf~u\xc7\xc9 \x8fDG\xa0\xe2\xac\x92\xbc\xa9\xc9\xf1\xc8\xcbQ\xe4I\xa3\xc6U\xb9_\x14\xbb\xbdh\xc2\x1c\xd0R\xe1LK$\xd9\x9c\x17\xbe\xa7\xc3l\xb3Y\x80\xad\x94\xff\x0b\x03\xed\xa9V\x17[2\x83\xb0\xf4\xd14\xcf?E\x03Im"
compressed_base64_json = b'x\x9c\x1d\x8fK\x0f\x820\x10\x84\xff\xcb\x9e9h\xe3A\x9ax\xf0\x11K8hPi\xb8\x99>6\n!\xd4\xd0\x02!\x84\xff\xee\xc2qg\xbe\x9d\x9d\x9d\xa0E\xffs\x8dG\xe0\x13hgG\xe0\xf0\x14\xd2k\xb1\xffH\x16\x8fZd\x07\x88\xc0\xa2q\x16\xdf\xc65\x01\x9b\x00<\xb4\x1dF\xf0Ee\xb1\xf5\xcbj\xc6\xe2\xce\n\xd9\xd9\xf36\xc7\xe2TS\x0c\x8d;{\x8e\x07-\xae?\xfd9,1\x19\xbbVJ\xe4a\xa5\x93\xb4\xd7G\x929\x98D\x96Z\xd4\x15\x11\x8f\xe2;\xa8"\xad\xcd\xb0:\xf7\x8ba\xb7\x17U\x98#j\xaa\xbckH$\xcc\x07\x15::\xcc6\x9b\x08z\xeaP\xae\x0e[\xb8^\xb5\xf4\xc54\xcf\x7f\xef\xc0E\xe6'
resp = self.serializer._loads_v2(req, compressed_base64_json)
# We have to decode our urllib3 data back into a unicode string.
assert resp.data == "Hello World".encode("utf-8")
Expand All @@ -72,7 +71,7 @@ def test_read_v1_serialized_with_py2_TypeError(self):
b"(dp1\nS'response'\np2\n(dp3\nS'body'\np4\nS'Hello World'\n",
b"p5\nsS'version'\np6\nS'2'\nsS'status'\np7\nI200\n",
b"sS'reason'\np8\nS''\nsS'decode_content'\np9\nI01\n",
b"sS'strict'\np10\nS''\nsS'headers'\np11\n(dp12\n",
b"sS'headers'\np11\n(dp12\n",
b"S'Content-Type'\np13\nS'text/plain'\np14\n",
b"sS'Cache-Control'\np15\nS'public'\np16\n",
b"sS'Expires'\np17\nS'87654'\np18\nsss.",
Expand Down
4 changes: 2 additions & 2 deletions tests/test_storage_redis.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
from datetime import datetime

from mock import Mock

from cachecontrol.caches import RedisCache


class TestRedisCache(object):

def setup(self):
def setup_method(self):
self.conn = Mock()
self.cache = RedisCache(self.conn)

Expand Down
1 change: 0 additions & 1 deletion tests/test_vary.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ def cached_equal(self, cached, resp):
cached.status == resp.raw.status,
cached.version == resp.raw.version,
cached.reason == resp.raw.reason,
cached.strict == resp.raw.strict,
cached.decode_content == resp.raw.decode_content,
]

Expand Down