From 89ab030cdb83a728a30e172bc65d27ba214d2eda Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Sun, 4 Jun 2017 14:12:08 -0300 Subject: [PATCH 1/4] Use comprehensions whenever possible --- requests/adapters.py | 3 +-- requests/cookies.py | 29 +++++++++++++++-------------- requests/hooks.py | 4 ++-- requests/models.py | 5 +---- requests/sessions.py | 2 +- tests/test_requests.py | 2 +- tests/test_utils.py | 2 +- 7 files changed, 22 insertions(+), 25 deletions(-) diff --git a/requests/adapters.py b/requests/adapters.py index f2639150..09d5eb80 100644 --- a/requests/adapters.py +++ b/requests/adapters.py @@ -129,8 +129,7 @@ class HTTPAdapter(BaseAdapter): self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) def __getstate__(self): - return dict((attr, getattr(self, attr, None)) for attr in - self.__attrs__) + return {attr: getattr(self, attr, None) for attr in self.__attrs__} def __setstate__(self, state): # Can't handle by adding 'proxy_manager' to self.__attrs__ because diff --git a/requests/cookies.py b/requests/cookies.py index 72e94be8..56fccd9c 100644 --- a/requests/cookies.py +++ b/requests/cookies.py @@ -444,20 +444,21 @@ def create_cookie(name, value, **kwargs): By default, the pair of `name` and `value` will be set for the domain '' and sent on every request (this is sometimes called a "supercookie"). """ - result = dict( - version=0, - name=name, - value=value, - port=None, - domain='', - path='/', - secure=False, - expires=None, - discard=True, - comment=None, - comment_url=None, - rest={'HttpOnly': None}, - rfc2109=False,) + result = { + 'version': 0, + 'name': name, + 'value': value, + 'port': None, + 'domain': '', + 'path': '/', + 'secure': False, + 'expires': None, + 'discard': True, + 'comment': None, + 'comment_url': None, + 'rest': {'HttpOnly': None}, + 'rfc2109': False, + } badargs = set(kwargs) - set(result) if badargs: diff --git a/requests/hooks.py b/requests/hooks.py index 32b32de7..7a51f212 100644 --- a/requests/hooks.py +++ b/requests/hooks.py @@ -15,14 +15,14 @@ HOOKS = ['response'] def default_hooks(): - return dict((event, []) for event in HOOKS) + return {event: [] for event in HOOKS} # TODO: response is the only one def dispatch_hook(key, hooks, hook_data, **kwargs): """Dispatches a hook dictionary on a given piece of data.""" - hooks = hooks or dict() + hooks = hooks or {} hooks = hooks.get(key) if hooks: if hasattr(hooks, '__call__'): diff --git a/requests/models.py b/requests/models.py index 4c8d631c..3dded57e 100644 --- a/requests/models.py +++ b/requests/models.py @@ -652,10 +652,7 @@ class Response(object): if not self._content_consumed: self.content - return dict( - (attr, getattr(self, attr, None)) - for attr in self.__attrs__ - ) + return {attr: getattr(self, attr, None) for attr in self.__attrs__} def __setstate__(self, state): for name, value in state.items(): diff --git a/requests/sessions.py b/requests/sessions.py index b124d793..a448bd83 100644 --- a/requests/sessions.py +++ b/requests/sessions.py @@ -738,7 +738,7 @@ class Session(SessionRedirectMixin): self.adapters[key] = self.adapters.pop(key) def __getstate__(self): - state = dict((attr, getattr(self, attr, None)) for attr in self.__attrs__) + state = {attr: getattr(self, attr, None) for attr in self.__attrs__} return state def __setstate__(self, state): diff --git a/tests/test_requests.py b/tests/test_requests.py index b4ee9f94..d972f002 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -864,7 +864,7 @@ class TestRequests: def test_urlencoded_get_query_multivalued_param(self, httpbin): - r = requests.get(httpbin('get'), params=dict(test=['foo', 'baz'])) + r = requests.get(httpbin('get'), params={'test': ['foo', 'baz']}) assert r.status_code == 200 assert r.url == httpbin('get?test=foo&test=baz') diff --git a/tests/test_utils.py b/tests/test_utils.py index f34c630f..59b0b0ef 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -665,7 +665,7 @@ def test_add_dict_to_cookiejar(cookiejar): cookiedict = {'test': 'cookies', 'good': 'cookies'} cj = add_dict_to_cookiejar(cookiejar, cookiedict) - cookies = dict((cookie.name, cookie.value) for cookie in cj) + cookies = {cookie.name: cookie.value for cookie in cj} assert cookiedict == cookies From 6ae8a2189235b62d7c5b2a6b95528750f046097c Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Tue, 30 May 2017 19:28:16 -0300 Subject: [PATCH 2/4] Add myself to AUTHORS (Or rather, just update my email) --- AUTHORS.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index 9f22c9e2..f0ee696b 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -125,7 +125,7 @@ Patches and Suggestions - Bryce Boe (`@bboe `_) - Colin Dunklau (`@cdunklau `_) - Bob Carroll (`@rcarz `_) -- Hugo Osvaldo Barrera (`@hobarrera `_) +- Hugo Osvaldo Barrera (`@hobarrera `_) - Ɓukasz Langa - Dave Shawley - James Clarke (`@jam `_) From 7fd9267b3bab1d45f5e4ac0953629c5531ecbc55 Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Tue, 16 Oct 2018 12:57:11 -0700 Subject: [PATCH 3/4] remove final remnants from 2.6 --- requests/__init__.py | 11 +++-------- requests/adapters.py | 13 ++++++------- requests/auth.py | 4 ++-- requests/compat.py | 3 +-- requests/help.py | 3 +-- requests/utils.py | 11 +++-------- setup.py | 12 +++--------- tests/test_help.py | 9 --------- tests/test_lowlevel.py | 28 ++++++++++++++-------------- tests/test_requests.py | 10 +++++----- tests/test_testserver.py | 6 +++--- tox.ini | 2 +- 12 files changed, 42 insertions(+), 70 deletions(-) diff --git a/requests/__init__.py b/requests/__init__.py index 098c21f0..18da1f26 100644 --- a/requests/__init__.py +++ b/requests/__init__.py @@ -79,14 +79,14 @@ def _check_cryptography(cryptography_version): return if cryptography_version < [1, 3, 4]: - warning = 'Old version of cryptography ({0}) may cause slowdown.'.format(cryptography_version) + warning = 'Old version of cryptography ({}) may cause slowdown.'.format(cryptography_version) warnings.warn(warning, RequestsDependencyWarning) # Check imported dependencies for compatibility. try: check_compatibility(urllib3.__version__, chardet.__version__) except (AssertionError, ValueError): - warnings.warn("urllib3 ({0}) or chardet ({1}) doesn't match a supported " + warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported " "version!".format(urllib3.__version__, chardet.__version__), RequestsDependencyWarning) @@ -123,12 +123,7 @@ from .exceptions import ( # Set default logging handler to avoid "No handler found" warnings. import logging -try: # Python 2.7+ - from logging import NullHandler -except ImportError: - class NullHandler(logging.Handler): - def emit(self, record): - pass +from logging import NullHandler logging.getLogger(__name__).addHandler(NullHandler()) diff --git a/requests/adapters.py b/requests/adapters.py index 09d5eb80..fa4d9b3c 100644 --- a/requests/adapters.py +++ b/requests/adapters.py @@ -225,7 +225,7 @@ class HTTPAdapter(BaseAdapter): if not cert_loc or not os.path.exists(cert_loc): raise IOError("Could not find a suitable TLS CA certificate bundle, " - "invalid path: {0}".format(cert_loc)) + "invalid path: {}".format(cert_loc)) conn.cert_reqs = 'CERT_REQUIRED' @@ -247,10 +247,10 @@ class HTTPAdapter(BaseAdapter): conn.key_file = None if conn.cert_file and not os.path.exists(conn.cert_file): raise IOError("Could not find the TLS certificate file, " - "invalid path: {0}".format(conn.cert_file)) + "invalid path: {}".format(conn.cert_file)) if conn.key_file and not os.path.exists(conn.key_file): raise IOError("Could not find the TLS key file, " - "invalid path: {0}".format(conn.key_file)) + "invalid path: {}".format(conn.key_file)) def build_response(self, req, resp): """Builds a :class:`Response ` object from a urllib3 @@ -425,7 +425,7 @@ class HTTPAdapter(BaseAdapter): timeout = TimeoutSauce(connect=connect, read=read) except ValueError as e: # this may raise a string formatting error. - err = ("Invalid timeout {0}. Pass a (connect, read) " + err = ("Invalid timeout {}. Pass a (connect, read) " "timeout tuple, or a single float to set " "both timeouts to the same value".format(timeout)) raise ValueError(err) @@ -475,11 +475,10 @@ class HTTPAdapter(BaseAdapter): # Receive the response from the server try: - # For Python 2.7+ versions, use buffering of HTTP - # responses + # For Python 2.7, use buffering of HTTP responses r = low_conn.getresponse(buffering=True) except TypeError: - # For compatibility with Python 2.6 versions and back + # For compatibility with Python 3.3+ r = low_conn.getresponse() resp = HTTPResponse.from_httplib( diff --git a/requests/auth.py b/requests/auth.py index 4ae45947..bdde51c7 100644 --- a/requests/auth.py +++ b/requests/auth.py @@ -38,7 +38,7 @@ def _basic_auth_str(username, password): if not isinstance(username, basestring): warnings.warn( "Non-string usernames will no longer be supported in Requests " - "3.0.0. Please convert the object you've passed in ({0!r}) to " + "3.0.0. Please convert the object you've passed in ({!r}) to " "a string or bytes object in the near future to avoid " "problems.".format(username), category=DeprecationWarning, @@ -48,7 +48,7 @@ def _basic_auth_str(username, password): if not isinstance(password, basestring): warnings.warn( "Non-string passwords will no longer be supported in Requests " - "3.0.0. Please convert the object you've passed in ({0!r}) to " + "3.0.0. Please convert the object you've passed in ({!r}) to " "a string or bytes object in the near future to avoid " "problems.".format(password), category=DeprecationWarning, diff --git a/requests/compat.py b/requests/compat.py index 6b9c6fac..c44b35ef 100644 --- a/requests/compat.py +++ b/requests/compat.py @@ -43,9 +43,8 @@ if is_py2: import cookielib from Cookie import Morsel from StringIO import StringIO - from collections import Callable, Mapping, MutableMapping + from collections import Callable, Mapping, MutableMapping, OrderedDict - from urllib3.packages.ordered_dict import OrderedDict builtin_str = str bytes = str diff --git a/requests/help.py b/requests/help.py index 06e06b2a..e53d35ef 100644 --- a/requests/help.py +++ b/requests/help.py @@ -89,8 +89,7 @@ def info(): 'version': getattr(idna, '__version__', ''), } - # OPENSSL_VERSION_NUMBER doesn't exist in the Python 2.6 ssl module. - system_ssl = getattr(ssl, 'OPENSSL_VERSION_NUMBER', None) + system_ssl = ssl.OPENSSL_VERSION_NUMBER system_ssl_info = { 'version': '%x' % system_ssl if system_ssl is not None else '' } diff --git a/requests/utils.py b/requests/utils.py index 67197312..0ce7fe11 100644 --- a/requests/utils.py +++ b/requests/utils.py @@ -173,7 +173,7 @@ def get_netrc_auth(url, raise_errors=False): for f in NETRC_FILES: try: - loc = os.path.expanduser('~/{0}'.format(f)) + loc = os.path.expanduser('~/{}'.format(f)) except KeyError: # os.path.expanduser can fail when $HOME is undefined and # getpwuid fails. See https://bugs.python.org/issue20164 & @@ -729,7 +729,7 @@ def should_bypass_proxies(url, no_proxy): else: host_with_port = parsed.hostname if parsed.port: - host_with_port += ':{0}'.format(parsed.port) + host_with_port += ':{}'.format(parsed.port) for host in no_proxy: if parsed.hostname.endswith(host) or host_with_port.endswith(host): @@ -737,13 +737,8 @@ def should_bypass_proxies(url, no_proxy): # to apply the proxies on this URL. return True - # If the system proxy settings indicate that this URL should be bypassed, - # don't proxy. - # The proxy_bypass function is incredibly buggy on OS X in early versions - # of Python 2.6, so allow this call to fail. Only catch the specific - # exceptions we've seen, though: this call failing in other ways can reveal - # legitimate problems. with set_environ('no_proxy', no_proxy_arg): + # parsed.hostname can be `None` in cases such as a file URI. try: bypass = proxy_bypass(parsed.hostname) except (TypeError, socket.gaierror): diff --git a/setup.py b/setup.py index 4a56bb9f..ec5542a2 100755 --- a/setup.py +++ b/setup.py @@ -39,12 +39,6 @@ if sys.argv[-1] == 'publish': os.system('twine upload dist/*') sys.exit() -# pyOpenSSL version 18.0.0 dropped support for Python 2.6 -if sys.version_info < (2, 7): - PYOPENSSL_VERSION = 'pyOpenSSL >= 0.14, < 18.0.0' -else: - PYOPENSSL_VERSION = 'pyOpenSSL >= 0.14' - packages = ['requests'] requires = [ @@ -85,7 +79,7 @@ setup( package_data={'': ['LICENSE', 'NOTICE'], 'requests': ['*.pem']}, package_dir={'requests': 'requests'}, include_package_data=True, - python_requires=">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", + python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", install_requires=requires, license=about['__license__'], zip_safe=False, @@ -108,8 +102,8 @@ setup( cmdclass={'test': PyTest}, tests_require=test_requirements, extras_require={ - 'security': [PYOPENSSL_VERSION, 'cryptography>=1.3.4', 'idna>=2.0.0'], + 'security': ['pyOpenSSL >= 0.14', 'cryptography>=1.3.4', 'idna>=2.0.0'], 'socks': ['PySocks>=1.5.6, !=1.5.7'], - 'socks:sys_platform == "win32" and (python_version == "2.7" or python_version == "2.6")': ['win_inet_pton'], + 'socks:sys_platform == "win32" and python_version == "2.7"': ['win_inet_pton'], }, ) diff --git a/tests/test_help.py b/tests/test_help.py index c11d43f3..3beb65f3 100644 --- a/tests/test_help.py +++ b/tests/test_help.py @@ -7,15 +7,6 @@ import pytest from requests.help import info -@pytest.mark.skipif(sys.version_info[:2] != (2,6), reason="Only run on Python 2.6") -def test_system_ssl_py26(): - """OPENSSL_VERSION_NUMBER isn't provided in Python 2.6, verify we don't - blow up in this case. - """ - assert info()['system_ssl'] == {'version': ''} - - -@pytest.mark.skipif(sys.version_info < (2,7), reason="Only run on Python 2.7+") def test_system_ssl(): """Verify we're actually setting system_ssl when it should be available.""" assert info()['system_ssl']['version'] != '' diff --git a/tests/test_lowlevel.py b/tests/test_lowlevel.py index e3789a47..82c3b25a 100644 --- a/tests/test_lowlevel.py +++ b/tests/test_lowlevel.py @@ -16,7 +16,7 @@ def test_chunked_upload(): data = iter([b'a', b'b', b'c']) with server as (host, port): - url = 'http://{0}:{1}/'.format(host, port) + url = 'http://{}:{}/'.format(host, port) r = requests.post(url, data=data, stream=True) close_server.set() # release server block @@ -77,7 +77,7 @@ def test_digestauth_401_count_reset_on_redirect(): server = Server(digest_response_handler, wait_to_close_event=close_server) with server as (host, port): - url = 'http://{0}:{1}/'.format(host, port) + url = 'http://{}:{}/'.format(host, port) r = requests.get(url, auth=auth) # Verify server succeeded in authenticating. assert r.status_code == 200 @@ -127,7 +127,7 @@ def test_digestauth_401_only_sent_once(): server = Server(digest_failed_response_handler, wait_to_close_event=close_server) with server as (host, port): - url = 'http://{0}:{1}/'.format(host, port) + url = 'http://{}:{}/'.format(host, port) r = requests.get(url, auth=auth) # Verify server didn't authenticate us. assert r.status_code == 401 @@ -164,7 +164,7 @@ def test_digestauth_only_on_4xx(): server = Server(digest_response_handler, wait_to_close_event=close_server) with server as (host, port): - url = 'http://{0}:{1}/'.format(host, port) + url = 'http://{}:{}/'.format(host, port) r = requests.get(url, auth=auth) # Verify server didn't receive auth from us. assert r.status_code == 200 @@ -181,17 +181,17 @@ _schemes_by_var_prefix = [ _proxy_combos = [] for prefix, schemes in _schemes_by_var_prefix: for scheme in schemes: - _proxy_combos.append(("{0}_proxy".format(prefix), scheme)) + _proxy_combos.append(("{}_proxy".format(prefix), scheme)) _proxy_combos += [(var.upper(), scheme) for var, scheme in _proxy_combos] @pytest.mark.parametrize("var,scheme", _proxy_combos) def test_use_proxy_from_environment(httpbin, var, scheme): - url = "{0}://httpbin.org".format(scheme) + url = "{}://httpbin.org".format(scheme) fake_proxy = Server() # do nothing with the requests; just close the socket with fake_proxy as (host, port): - proxy_url = "socks5://{0}:{1}".format(host, port) + proxy_url = "socks5://{}:{}".format(host, port) kwargs = {var: proxy_url} with override_environ(**kwargs): # fake proxy's lack of response will cause a ConnectionError @@ -212,7 +212,7 @@ def test_redirect_rfc1808_to_non_ascii_location(): def redirect_resp_handler(sock): consume_socket_content(sock, timeout=0.5) - location = u'//{0}:{1}/{2}'.format(host, port, path) + location = u'//{}:{}/{}'.format(host, port, path) sock.send( b'HTTP/1.1 301 Moved Permanently\r\n' b'Content-Length: 0\r\n' @@ -226,13 +226,13 @@ def test_redirect_rfc1808_to_non_ascii_location(): server = Server(redirect_resp_handler, wait_to_close_event=close_server) with server as (host, port): - url = u'http://{0}:{1}'.format(host, port) + url = u'http://{}:{}'.format(host, port) r = requests.get(url=url, allow_redirects=True) assert r.status_code == 200 assert len(r.history) == 1 assert r.history[0].status_code == 301 assert redirect_request[0].startswith(b'GET /' + expected_path + b' HTTP/1.1') - assert r.url == u'{0}/{1}'.format(url, expected_path.decode('ascii')) + assert r.url == u'{}/{}'.format(url, expected_path.decode('ascii')) close_server.set() @@ -250,7 +250,7 @@ def test_fragment_not_sent_with_request(): server = Server(response_handler, wait_to_close_event=close_server) with server as (host, port): - url = 'http://{0}:{1}/path/to/thing/#view=edit&token=hunter2'.format(host, port) + url = 'http://{}:{}/path/to/thing/#view=edit&token=hunter2'.format(host, port) r = requests.get(url) raw_request = r.content @@ -293,7 +293,7 @@ def test_fragment_update_on_redirect(): server = Server(response_handler, wait_to_close_event=close_server) with server as (host, port): - url = 'http://{0}:{1}/path/to/thing/#view=edit&token=hunter2'.format(host, port) + url = 'http://{}:{}/path/to/thing/#view=edit&token=hunter2'.format(host, port) r = requests.get(url) raw_request = r.content @@ -302,8 +302,8 @@ def test_fragment_update_on_redirect(): assert r.history[0].request.url == url # Verify we haven't overwritten the location with our previous fragment. - assert r.history[1].request.url == 'http://{0}:{1}/get#relevant-section'.format(host, port) + assert r.history[1].request.url == 'http://{}:{}/get#relevant-section'.format(host, port) # Verify previous fragment is used and not the original. - assert r.url == 'http://{0}:{1}/final-url/#relevant-section'.format(host, port) + assert r.url == 'http://{}:{}/final-url/#relevant-section'.format(host, port) close_server.set() diff --git a/tests/test_requests.py b/tests/test_requests.py index d972f002..4cf5c973 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -158,7 +158,7 @@ class TestRequests: url = scheme + parts.netloc + parts.path r = requests.Request('GET', url) r = s.send(r.prepare()) - assert r.status_code == 200, 'failed for scheme {0}'.format(scheme) + assert r.status_code == 200, 'failed for scheme {}'.format(scheme) def test_HTTP_200_OK_GET_ALTERNATIVE(self, httpbin): r = requests.Request('GET', httpbin('get')) @@ -816,17 +816,17 @@ class TestRequests: INVALID_PATH = '/garbage' with pytest.raises(IOError) as e: requests.get(httpbin_secure(), verify=INVALID_PATH) - assert str(e.value) == 'Could not find a suitable TLS CA certificate bundle, invalid path: {0}'.format(INVALID_PATH) + assert str(e.value) == 'Could not find a suitable TLS CA certificate bundle, invalid path: {}'.format(INVALID_PATH) def test_invalid_ssl_certificate_files(self, httpbin_secure): INVALID_PATH = '/garbage' with pytest.raises(IOError) as e: requests.get(httpbin_secure(), cert=INVALID_PATH) - assert str(e.value) == 'Could not find the TLS certificate file, invalid path: {0}'.format(INVALID_PATH) + assert str(e.value) == 'Could not find the TLS certificate file, invalid path: {}'.format(INVALID_PATH) with pytest.raises(IOError) as e: requests.get(httpbin_secure(), cert=('.', INVALID_PATH)) - assert str(e.value) == 'Could not find the TLS key file, invalid path: {0}'.format(INVALID_PATH) + assert str(e.value) == 'Could not find the TLS key file, invalid path: {}'.format(INVALID_PATH) def test_http_with_certificate(self, httpbin): r = requests.get(httpbin(), cert='.') @@ -1458,7 +1458,7 @@ class TestRequests: assert r.json()['args'] == {'foo': 'bar', 'FOO': 'bar'} def test_long_authinfo_in_url(self): - url = 'http://{0}:{1}@{2}:9000/path?query#frag'.format( + url = 'http://{}:{}@{}:9000/path?query#frag'.format( 'E8A3BE87-9E3F-4620-8858-95478E385B5B', 'EA770032-DA4D-4D84-8CE9-29C6D910BF1E', 'exactly-------------sixty-----------three------------characters', diff --git a/tests/test_testserver.py b/tests/test_testserver.py index 3c770759..aac52926 100644 --- a/tests/test_testserver.py +++ b/tests/test_testserver.py @@ -50,7 +50,7 @@ class TestTestServer: ) with server as (host, port): - r = requests.get('http://{0}:{1}'.format(host, port)) + r = requests.get('http://{}:{}'.format(host, port)) assert r.status_code == 200 assert r.text == u'roflol' @@ -59,7 +59,7 @@ class TestTestServer: def test_basic_response(self): """the basic response server returns an empty http response""" with Server.basic_response_server() as (host, port): - r = requests.get('http://{0}:{1}'.format(host, port)) + r = requests.get('http://{}:{}'.format(host, port)) assert r.status_code == 200 assert r.text == u'' assert r.headers['Content-Length'] == '0' @@ -83,7 +83,7 @@ class TestTestServer: server = Server.basic_response_server(requests_to_handle=requests_to_handle) with server as (host, port): - server_url = 'http://{0}:{1}'.format(host, port) + server_url = 'http://{}:{}'.format(host, port) for _ in range(requests_to_handle): r = requests.get(server_url) assert r.status_code == 200 diff --git a/tox.ini b/tox.ini index 38bf3ac4..47b68ba5 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py26,py27,py34,py35,py36 +envlist = py27,py34,py35,py36 [testenv] From bd840450c0d1e9db3bf62382c15d96378cc3a056 Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Tue, 16 Oct 2018 13:06:29 -0700 Subject: [PATCH 4/4] v2.20.0 --- HISTORY.md | 19 ++++++++++++++++++- requests/__init__.py | 4 ++-- requests/__version__.py | 4 ++-- setup.py | 2 +- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 116a6399..09a09eee 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,12 +6,29 @@ dev **Bugfixes** +- \[Short description of non-trivial change.\] + +2.20.0 (2018-10-18) +------------------- + +**Bugfixes** + - Content-Type header parsing is now case-insensitive (e.g. charset=utf8 v Charset=utf8). - Fixed exception leak where certain redirect urls would raise uncaught urllib3 exceptions. +- Requests removes Authorization header from requests redirected + from https to http on the same hostname. (CVE-2018-18074) +- `should_bypass_proxies` now handles URIs without hostnames (e.g. + files). -- \[Short description of non-trivial change.\] +**Dependencies** + +- Requests now supports urllib3 v1.24. + +**Deprecations** + +- Requests has officially stopped support for Python 2.6. 2.19.1 (2018-06-14) ------------------- diff --git a/requests/__init__.py b/requests/__init__.py index 18da1f26..bc168ee5 100644 --- a/requests/__init__.py +++ b/requests/__init__.py @@ -57,10 +57,10 @@ def check_compatibility(urllib3_version, chardet_version): # Check urllib3 for compatibility. major, minor, patch = urllib3_version # noqa: F811 major, minor, patch = int(major), int(minor), int(patch) - # urllib3 >= 1.21.1, <= 1.23 + # urllib3 >= 1.21.1, <= 1.24 assert major == 1 assert minor >= 21 - assert minor <= 23 + assert minor <= 24 # Check chardet for compatibility. major, minor, patch = chardet_version.split('.')[:3] diff --git a/requests/__version__.py b/requests/__version__.py index ef61ec0f..be8a45fe 100644 --- a/requests/__version__.py +++ b/requests/__version__.py @@ -5,8 +5,8 @@ __title__ = 'requests' __description__ = 'Python HTTP for Humans.' __url__ = 'http://python-requests.org' -__version__ = '2.19.1' -__build__ = 0x021901 +__version__ = '2.20.0' +__build__ = 0x022000 __author__ = 'Kenneth Reitz' __author_email__ = 'me@kennethreitz.org' __license__ = 'Apache 2.0' diff --git a/setup.py b/setup.py index ec5542a2..4e2ad936 100755 --- a/setup.py +++ b/setup.py @@ -44,7 +44,7 @@ packages = ['requests'] requires = [ 'chardet>=3.0.2,<3.1.0', 'idna>=2.5,<2.8', - 'urllib3>=1.21.1,<1.24', + 'urllib3>=1.21.1,<1.25', 'certifi>=2017.4.17' ]