From 2bb49ff386deab4e67e199450085720c1521411a Mon Sep 17 00:00:00 2001
From: Matt Sweeney
Date: Tue, 25 Sep 2012 15:35:30 -0700
Subject: [PATCH 01/15] Handle encoding of `None` when decoding unicode
If encoding is None, decoding will throw the following TypeError:
TypeError: unicode() argument 2 must be string, not None
If this is the case, attempt to run without any set encoding
---
requests/models.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/requests/models.py b/requests/models.py
index f33c3c3e..305e615e 100644
--- a/requests/models.py
+++ b/requests/models.py
@@ -834,6 +834,11 @@ class Response(object):
#
# So we try blindly encoding.
content = str(self.content, errors='replace')
+ except TypeError:
+ # A TypeError can be raised if encoding is None
+ #
+ # So we try blindly encoding.
+ content = str(self.content, errors='replace')
return content
From eb6a6b1a234e520d9ef6263fc1f35758ca1b662a Mon Sep 17 00:00:00 2001
From: Matt Sweeney
Date: Wed, 26 Sep 2012 12:38:36 -0700
Subject: [PATCH 02/15] Simplify error handling when decoding unicode
---
requests/models.py | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/requests/models.py b/requests/models.py
index 305e615e..2193c6e5 100644
--- a/requests/models.py
+++ b/requests/models.py
@@ -828,13 +828,10 @@ class Response(object):
# Decode unicode from given encoding.
try:
content = str(self.content, encoding, errors='replace')
- except LookupError:
+ except (LookupError, TypeError):
# A LookupError is raised if the encoding was not found which could
# indicate a misspelling or similar mistake.
#
- # So we try blindly encoding.
- content = str(self.content, errors='replace')
- except TypeError:
# A TypeError can be raised if encoding is None
#
# So we try blindly encoding.
From e656222188475369ec3493cdeb37d398a7e7e1c5 Mon Sep 17 00:00:00 2001
From: yegle
Date: Sat, 29 Sep 2012 18:28:53 -0400
Subject: [PATCH 03/15] Python 3.3 compatible update
httplib.cookiejar.DefaultCookiePolicy changed its implementation of
set_ok_verifiability.
---
requests/cookies.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/requests/cookies.py b/requests/cookies.py
index bd2d6654..83f6bb60 100644
--- a/requests/cookies.py
+++ b/requests/cookies.py
@@ -67,6 +67,10 @@ class MockRequest(object):
def get_new_headers(self):
return self._new_headers
+ def __getattr__(self, name):
+ if name == 'unverifiable':
+ return self.is_unverifiable()
+
class MockResponse(object):
"""Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`.
From 4f9e5521480e5b9fa760e0f19274441c363aca5e Mon Sep 17 00:00:00 2001
From: Kunal Mehta
Date: Sun, 30 Sep 2012 19:24:56 -0500
Subject: [PATCH 04/15] Use __iter__ rather than the inefficient nested for
loops
---
requests/utils.py | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/requests/utils.py b/requests/utils.py
index eb146000..63b281a2 100644
--- a/requests/utils.py
+++ b/requests/utils.py
@@ -311,11 +311,8 @@ def dict_from_cookiejar(cj):
cookie_dict = {}
- for _, cookies in list(cj._cookies.items()):
- for _, cookies in list(cookies.items()):
- for cookie in list(cookies.values()):
- # print cookie
- cookie_dict[cookie.name] = cookie.value
+ for cookie in cj:
+ cookie_dict[cookie.name] = cookie.value
return cookie_dict
From 22fdecba521610466f4316ad4a22c6f25870b46f Mon Sep 17 00:00:00 2001
From: yegle
Date: Mon, 1 Oct 2012 13:13:12 -0400
Subject: [PATCH 05/15] Update: @property decorator instead of __getattr__
---
requests/cookies.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/requests/cookies.py b/requests/cookies.py
index 83f6bb60..101e617d 100644
--- a/requests/cookies.py
+++ b/requests/cookies.py
@@ -67,9 +67,9 @@ class MockRequest(object):
def get_new_headers(self):
return self._new_headers
- def __getattr__(self, name):
- if name == 'unverifiable':
- return self.is_unverifiable()
+ @property
+ def unverifiable(self):
+ return self.is_unverifiable()
class MockResponse(object):
From ed8a3f319958844870bb071db7a185fb66d25171 Mon Sep 17 00:00:00 2001
From: Kenneth Reitz
Date: Mon, 1 Oct 2012 13:29:38 -0400
Subject: [PATCH 06/15] v0.14.1
---
HISTORY.rst | 8 ++++++++
requests/__init__.py | 4 ++--
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/HISTORY.rst b/HISTORY.rst
index 1416c463..0a83006b 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -3,6 +3,14 @@
History
-------
+0.14.1 (2012-10-01)
++++++++++++++++++++
+
+- Python 3.3 Compatibility
+- Simply default accept-encoding
+- Bugfixes
+
+
0.14.0 (2012-09-02)
++++++++++++++++++++
diff --git a/requests/__init__.py b/requests/__init__.py
index 50953f86..2e33412b 100644
--- a/requests/__init__.py
+++ b/requests/__init__.py
@@ -42,8 +42,8 @@ is at .
"""
__title__ = 'requests'
-__version__ = '0.14.0'
-__build__ = 0x001400
+__version__ = '0.14.1'
+__build__ = 0x001401
__author__ = 'Kenneth Reitz'
__license__ = 'ISC'
__copyright__ = 'Copyright 2012 Kenneth Reitz'
From 46fd297c3ac903793a99fd9712f04d747a027538 Mon Sep 17 00:00:00 2001
From: Kenneth Reitz
Date: Mon, 1 Oct 2012 13:30:41 -0400
Subject: [PATCH 07/15] new classifiers for 3.2+
---
setup.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/setup.py b/setup.py
index 35c87cef..9844ab1b 100755
--- a/setup.py
+++ b/setup.py
@@ -65,6 +65,8 @@ setup(
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.0',
'Programming Language :: Python :: 3.1',
+ 'Programming Language :: Python :: 3.2',
+ 'Programming Language :: Python :: 3.3',
),
)
From 4e6cf21d8231b28a9bbfdd94392137255e434033 Mon Sep 17 00:00:00 2001
From: Ian Cordasco
Date: Mon, 1 Oct 2012 13:09:02 -0400
Subject: [PATCH 08/15] Only register callable items in lists
Prior to this, you could sneak a list of anything to register_hook and it
would accept it. This will check if the items in the list are callable before
registering them. Also added a regression test to make sure if this gets
changed it will be noticed.
---
requests/models.py | 6 +++---
tests/test_requests.py | 4 ++++
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/requests/models.py b/requests/models.py
index 2193c6e5..78311491 100644
--- a/requests/models.py
+++ b/requests/models.py
@@ -462,10 +462,10 @@ class Request(object):
def register_hook(self, event, hook):
"""Properly register a hook."""
- if isinstance(hook, (list, tuple, set)):
- self.hooks[event].extend(hook)
- else:
+ if callable(hook):
self.hooks[event].append(hook)
+ elif hasattr(hook, '__iter__'):
+ self.hooks[event].extend(h for h in hook if callable(h))
def deregister_hook(self, event, hook):
"""Deregister a previously registered hook.
diff --git a/tests/test_requests.py b/tests/test_requests.py
index 0f67618a..3d6f49c2 100755
--- a/tests/test_requests.py
+++ b/tests/test_requests.py
@@ -778,6 +778,10 @@ class RequestsTestSuite(TestSetup, TestBaseMixin, unittest.TestCase):
r = requests.models.Request(hooks={'args': hooks})
assert_hooks_are_callable(r.hooks)
+ hooks.append('string that should not be registered')
+ r = requests.models.Request(hooks={'args': hooks})
+ assert_hooks_are_callable(r.hooks)
+
def test_session_persistent_cookies(self):
s = requests.session()
From 582a53f3f4b7cf539dfa61e83994ca9f2b5ef2ff Mon Sep 17 00:00:00 2001
From: Kenneth Reitz
Date: Tue, 2 Oct 2012 00:43:21 -0400
Subject: [PATCH 09/15] why not
---
docs/_templates/sidebarintro.html | 6 ++++++
docs/_templates/sidebarlogo.html | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/docs/_templates/sidebarintro.html b/docs/_templates/sidebarintro.html
index 4d341223..14987f78 100644
--- a/docs/_templates/sidebarintro.html
+++ b/docs/_templates/sidebarintro.html
@@ -20,6 +20,12 @@
If you love Requests, consider supporting the author on Gittip:
+
+ Or, if your company uses Requests, consider purchasing a copy:
+
+ Requests
+
+
+
+ Or, if your company uses Requests, consider purchasing a copy:
+
+ Requests
+
+
- Or, if your company uses Requests, consider purchasing a copy:
+ If your organization uses Requests, consider financial support:
- Requests
+
+ Requests Pro
Feedback
diff --git a/docs/_templates/sidebarlogo.html b/docs/_templates/sidebarlogo.html
index 8a427b9c..21a2a6b3 100644
--- a/docs/_templates/sidebarlogo.html
+++ b/docs/_templates/sidebarlogo.html
@@ -25,10 +25,8 @@
- Or, if your company uses Requests, consider purchasing a copy:
-
-
+ If your organization uses Requests, consider financial support:
- Requests
+ Requests Pro
From 3e3019691734a8867370bb6dee54559b4a747679 Mon Sep 17 00:00:00 2001
From: Kenneth Reitz
Date: Tue, 2 Oct 2012 01:02:32 -0400
Subject: [PATCH 13/15] update
---
docs/_templates/sidebarintro.html | 5 +++--
docs/_templates/sidebarlogo.html | 4 +++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/docs/_templates/sidebarintro.html b/docs/_templates/sidebarintro.html
index 1fa949bb..f2b0d7a0 100644
--- a/docs/_templates/sidebarintro.html
+++ b/docs/_templates/sidebarintro.html
@@ -30,8 +30,9 @@
If your organization uses Requests, consider financial support:
-
- Requests Pro
+
+ Requests Pro
+
Feedback
diff --git a/docs/_templates/sidebarlogo.html b/docs/_templates/sidebarlogo.html
index 21a2a6b3..34b9d421 100644
--- a/docs/_templates/sidebarlogo.html
+++ b/docs/_templates/sidebarlogo.html
@@ -29,4 +29,6 @@
- Requests Pro
+
+ Requests Pro
+
From 5ec2c96f0298d2bbac523396683cfb9f3ce971f9 Mon Sep 17 00:00:00 2001
From: tokuda109
Date: Tue, 2 Oct 2012 23:26:10 +0900
Subject: [PATCH 14/15] declare the encoding
---
requests/cookies.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/requests/cookies.py b/requests/cookies.py
index 101e617d..241ca679 100644
--- a/requests/cookies.py
+++ b/requests/cookies.py
@@ -1,3 +1,5 @@
+# -*- coding: utf-8 -*-
+
"""
Compatibility code to be able to use `cookielib.CookieJar` with requests.
From 820dfb0495ef379f140ad3c78c30e0a16c7e9fa8 Mon Sep 17 00:00:00 2001
From: Radu Voicilas
Date: Tue, 9 Oct 2012 00:41:42 +0300
Subject: [PATCH 15/15] Making the code more PEP8 compliant
---
requests/auth.py | 2 +-
requests/compat.py | 2 +-
requests/cookies.py | 10 ++++------
requests/hooks.py | 1 -
requests/models.py | 2 +-
requests/utils.py | 5 ++++-
tests/informal/test_leaked_connections.py | 6 +++++-
tests/test_proxies.py | 12 +++++++-----
tests/test_requests.py | 5 +++--
tests/test_requests_ext.py | 3 ++-
tests/test_requests_https.py | 4 ++--
11 files changed, 30 insertions(+), 22 deletions(-)
diff --git a/requests/auth.py b/requests/auth.py
index 6c5264e4..65568f52 100644
--- a/requests/auth.py
+++ b/requests/auth.py
@@ -94,7 +94,7 @@ class OAuth1(AuthBase):
# to preserve body.
r.url, r.headers, _ = self.client.sign(
unicode(r.full_url), unicode(r.method), None, r.headers)
- elif decoded_body != None and contenttype in (CONTENT_TYPE_FORM_URLENCODED, ''):
+ elif decoded_body is not None and contenttype in (CONTENT_TYPE_FORM_URLENCODED, ''):
# Normal signing
if not contenttype:
r.headers['Content-Type'] = CONTENT_TYPE_FORM_URLENCODED
diff --git a/requests/compat.py b/requests/compat.py
index 351b7c6e..69dd25c5 100644
--- a/requests/compat.py
+++ b/requests/compat.py
@@ -115,5 +115,5 @@ elif is_py3:
builtin_str = str
str = str
bytes = bytes
- basestring = (str,bytes)
+ basestring = (str, bytes)
numeric_types = (int, float)
diff --git a/requests/cookies.py b/requests/cookies.py
index 241ca679..c3c2debb 100644
--- a/requests/cookies.py
+++ b/requests/cookies.py
@@ -235,7 +235,7 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
Python dict of name-value pairs of cookies that meet the requirements."""
dictionary = {}
for cookie in iter(self):
- if (domain == None or cookie.domain == domain) and (path == None
+ if (domain is None or cookie.domain == domain) and (path is None
or cookie.path == path):
dictionary[cookie.name] = cookie.value
return dictionary
@@ -279,7 +279,7 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
if cookie.name == name:
if domain is None or cookie.domain == domain:
if path is None or cookie.path == path:
- if toReturn != None: # if there are multiple cookies that meet passed in criteria
+ if toReturn is not None: # if there are multiple cookies that meet passed in criteria
raise CookieConflictError('There are multiple cookies with name, %r' % (name))
toReturn = cookie.value # we will eventually return this as long as no cookie conflict
@@ -324,8 +324,7 @@ def create_cookie(name, value, **kwargs):
comment=None,
comment_url=None,
rest={'HttpOnly': None},
- rfc2109=False,
- )
+ rfc2109=False,)
badargs = set(kwargs) - set(result)
if badargs:
@@ -360,8 +359,7 @@ def morsel_to_cookie(morsel):
comment=morsel['comment'],
comment_url=bool(morsel['comment']),
rest={'HttpOnly': morsel['httponly']},
- rfc2109=False,
- )
+ rfc2109=False,)
return c
diff --git a/requests/hooks.py b/requests/hooks.py
index 9e0ce346..9a35fb16 100644
--- a/requests/hooks.py
+++ b/requests/hooks.py
@@ -45,5 +45,4 @@ def dispatch_hook(key, hooks, hook_data):
if _hook_data is not None:
hook_data = _hook_data
-
return hook_data
diff --git a/requests/models.py b/requests/models.py
index 78311491..f02cec33 100644
--- a/requests/models.py
+++ b/requests/models.py
@@ -111,7 +111,7 @@ class Request(object):
# Dictionary mapping protocol to the URL of the proxy (e.g. {'http': 'foo.bar:3128'})
self.proxies = dict(proxies or [])
- for proxy_type,uri_ref in list(self.proxies.items()):
+ for proxy_type, uri_ref in list(self.proxies.items()):
if not uri_ref:
del self.proxies[proxy_type]
diff --git a/requests/utils.py b/requests/utils.py
index 63b281a2..7c895c4b 100644
--- a/requests/utils.py
+++ b/requests/utils.py
@@ -378,13 +378,15 @@ def stream_decode_response_unicode(iterator, r):
if rv:
yield rv
+
def iter_slices(string, slice_length):
"""Iterate over slices of a string."""
pos = 0
while pos < len(string):
- yield string[pos:pos+slice_length]
+ yield string[pos:pos + slice_length]
pos += slice_length
+
def get_unicode_from_response(r):
"""Returns the requested content back in unicode.
@@ -543,6 +545,7 @@ def default_user_agent():
'%s/%s' % (platform.system(), platform.release()),
])
+
def parse_header_links(value):
"""Return a dict of parsed link headers proxies.
diff --git a/tests/informal/test_leaked_connections.py b/tests/informal/test_leaked_connections.py
index 438a6cee..37d964cf 100644
--- a/tests/informal/test_leaked_connections.py
+++ b/tests/informal/test_leaked_connections.py
@@ -4,7 +4,11 @@ it verifies that Requests does not leak connections when
the body of the request is not read.
"""
-import gc, os, subprocess, requests, sys
+import gc
+import os
+import requests
+import subprocess
+import sys
def main():
diff --git a/tests/test_proxies.py b/tests/test_proxies.py
index 8ab124b2..5aa5bf36 100644
--- a/tests/test_proxies.py
+++ b/tests/test_proxies.py
@@ -1,7 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-import sys, os, unittest
+import os
+import sys
+import unittest
# Path hack.
sys.path.insert(0, os.path.abspath('..'))
@@ -14,13 +16,13 @@ class HTTPSProxyTest(unittest.TestCase):
smoke_url = "https://github.com"
def test_empty_https_proxy(self):
- proxy = {"https" : "" }
- result = requests.get(self.smoke_url, verify=False, proxies = proxy)
+ proxy = {"https": ""}
+ result = requests.get(self.smoke_url, verify=False, proxies=proxy)
self.assertEqual(result.status_code, 200)
def test_empty_http_proxy(self):
- proxy = {"http" : "" }
- result = requests.get(self.smoke_url, proxies = proxy)
+ proxy = {"http": ""}
+ result = requests.get(self.smoke_url, proxies=proxy)
self.assertEqual(result.status_code, 200)
if __name__ == '__main__':
diff --git a/tests/test_requests.py b/tests/test_requests.py
index 3d6f49c2..9ed4ad03 100755
--- a/tests/test_requests.py
+++ b/tests/test_requests.py
@@ -51,6 +51,7 @@ class TestSetup(object):
# time.sleep(1)
_httpbin = True
+
class TestBaseMixin(object):
def assertCookieHas(self, cookie, **kwargs):
@@ -60,6 +61,7 @@ class TestBaseMixin(object):
message = 'Failed comparison for %s: %s != %s' % (attr, cookie_attr, expected_value)
self.assertEqual(cookie_attr, expected_value, message)
+
class RequestsTestSuite(TestSetup, TestBaseMixin, unittest.TestCase):
"""Requests test cases."""
@@ -903,7 +905,7 @@ class RequestsTestSuite(TestSetup, TestBaseMixin, unittest.TestCase):
def test_connection_error_with_safe_mode(self):
config = {'safe_mode': True}
r = get('http://localhost:1/nope', allow_redirects=False, config=config)
- assert r.content == None
+ assert r.content is None
# def test_invalid_content(self):
# # WARNING: if you're using a terrible DNS provider (comcast),
@@ -1038,7 +1040,6 @@ class RequestsTestSuite(TestSetup, TestBaseMixin, unittest.TestCase):
s.config['danger_mode'] = True
s.get(httpbin('redirect', '4'))
-
def test_empty_response(self):
r = requests.get(httpbin('status', '404'))
r.text
diff --git a/tests/test_requests_ext.py b/tests/test_requests_ext.py
index 208803a7..e3cdd04e 100644
--- a/tests/test_requests_ext.py
+++ b/tests/test_requests_ext.py
@@ -2,7 +2,8 @@
# -*- coding: utf-8 -*-
# Path hack.
-import sys, os
+import os
+import sys
sys.path.insert(0, os.path.abspath('..'))
import unittest
diff --git a/tests/test_requests_https.py b/tests/test_requests_https.py
index 1691a8c0..2da09824 100755
--- a/tests/test_requests_https.py
+++ b/tests/test_requests_https.py
@@ -1,8 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-import sys, os
-import json
+import os
+import sys
import unittest
# Path hack.