From 1da121356181844967fae02aedc17384e435581d Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Mon, 12 Dec 2016 13:47:18 -0700 Subject: [PATCH 001/104] add socket tests for 401 redirect and 401 failure --- tests/test_lowlevel.py | 113 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/tests/test_lowlevel.py b/tests/test_lowlevel.py index 126a3a3f..6bc948b4 100644 --- a/tests/test_lowlevel.py +++ b/tests/test_lowlevel.py @@ -5,7 +5,7 @@ import pytest import threading import requests -from tests.testserver.server import Server +from tests.testserver.server import Server, consume_socket_content from .utils import override_environ @@ -25,6 +25,117 @@ def test_chunked_upload(): assert r.request.headers['Transfer-Encoding'] == 'chunked' +def test_digestauth_401_count_reset_on_redirect(): + """Ensure we correctly reset num_401_calls after a successful digest auth, + followed by a 302 redirect to another digest auth prompt. + + See https://github.com/kennethreitz/requests/issues/1979. + """ + text_401 = (b'HTTP/1.1 401 UNAUTHORIZED\r\n' + b'Content-Length: 0\r\n' + b'WWW-Authenticate: Digest nonce="6bf5d6e4da1ce66918800195d6b9130d"' + b', opaque="372825293d1c26955496c80ed6426e9e", ' + b'realm="me@kennethreitz.com", qop=auth\r\n\r\n') + + text_302 = (b'HTTP/1.1 302 FOUND\r\n' + b'Content-Length: 0\r\n' + b'Location: /\r\n\r\n') + + text_200 = (b'HTTP/1.1 200 OK\r\n' + b'Content-Length: 0\r\n\r\n') + + expected_digest = (b'Authorization: Digest username="user", ' + b'realm="me@kennethreitz.com", ' + b'nonce="6bf5d6e4da1ce66918800195d6b9130d", uri="/"') + + auth = requests.auth.HTTPDigestAuth('user', 'pass') + + def digest_response_handler(sock): + # Respond to initial GET with a challenge. + request_content = consume_socket_content(sock, timeout=0.5) + assert request_content.startswith(b"GET / HTTP/1.1") + sock.send(text_401) + + # Verify we receive an Authorization header in response, then redirect. + request_content = consume_socket_content(sock, timeout=0.5) + assert expected_digest in request_content + sock.send(text_302) + + # Verify Authorization isn't sent to the redirected host, + # then send another challenge. + request_content = consume_socket_content(sock, timeout=0.5) + assert b'Authorization:' not in request_content + sock.send(text_401) + + # Verify Authorization is sent correctly again, and return 200 OK. + request_content = consume_socket_content(sock, timeout=0.5) + assert expected_digest in request_content + sock.send(text_200) + + return request_content + + close_server = threading.Event() + server = Server(digest_response_handler, wait_to_close_event=close_server) + + with server as (host, port): + url = 'http://{0}:{1}/'.format(host, port) + r = requests.get(url, auth=auth) + # Verify server succeeded in authenticating. + assert r.status_code == 200 + # Verify Authorization was sent in final request. + assert 'Authorization' in r.request.headers + assert r.request.headers['Authorization'].startswith('Digest ') + # Verify redirect happened as we expected. + assert r.history[0].status_code == 302 + close_server.set() + + +def test_digestauth_401_only_sent_once(): + """Ensure we correctly respond to a 401 challenge once, and then + stop responding if challenged again. + """ + text_401 = (b'HTTP/1.1 401 UNAUTHORIZED\r\n' + b'Content-Length: 0\r\n' + b'WWW-Authenticate: Digest nonce="6bf5d6e4da1ce66918800195d6b9130d"' + b', opaque="372825293d1c26955496c80ed6426e9e", ' + b'realm="me@kennethreitz.com", qop=auth\r\n\r\n') + + expected_digest = (b'Authorization: Digest username="user", ' + b'realm="me@kennethreitz.com", ' + b'nonce="6bf5d6e4da1ce66918800195d6b9130d", uri="/"') + + auth = requests.auth.HTTPDigestAuth('user', 'pass') + + def digest_failed_response_handler(sock): + # Respond to initial GET with a challenge. + request_content = consume_socket_content(sock, timeout=0.5) + assert request_content.startswith(b"GET / HTTP/1.1") + sock.send(text_401) + + # Verify we receive an Authorization header in response, then + # challenge again. + request_content = consume_socket_content(sock, timeout=0.5) + assert expected_digest in request_content + sock.send(text_401) + + # Verify the client didn't respond to second challenge. + request_content = consume_socket_content(sock, timeout=0.5) + assert request_content == b'' + + return request_content + + close_server = threading.Event() + server = Server(digest_failed_response_handler, wait_to_close_event=close_server) + + with server as (host, port): + url = 'http://{0}:{1}/'.format(host, port) + r = requests.get(url, auth=auth) + # Verify server didn't authenticate us. + assert r.status_code == 401 + assert r.history[0].status_code == 401 + close_server.set() + + _schemes_by_var_prefix = [ ('http', ['http']), ('https', ['https']), From 1285f576ae0a848de27af10d917c19b60940d1fa Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Wed, 14 Dec 2016 11:37:52 +0000 Subject: [PATCH 002/104] v2.12.4 --- HISTORY.rst | 9 +++++++++ requests/__init__.py | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 01ec2dd8..e377c405 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,6 +3,15 @@ Release History --------------- +2.12.4 (2016-12-14) ++++++++++++++++++++ + +**Bugfixes** + +- Fixed regression from 2.12.2 where non-string types were rejected in the + basic auth parameters. While support for this behaviour has been readded, + the behaviour is deprecated and will be removed in the future. + 2.12.3 (2016-12-01) +++++++++++++++++++ diff --git a/requests/__init__.py b/requests/__init__.py index c41c54f6..f4f1a042 100644 --- a/requests/__init__.py +++ b/requests/__init__.py @@ -41,8 +41,8 @@ is at . """ __title__ = 'requests' -__version__ = '2.12.3' -__build__ = 0x021203 +__version__ = '2.12.4' +__build__ = 0x021204 __author__ = 'Kenneth Reitz' __license__ = 'Apache 2.0' __copyright__ = 'Copyright 2016 Kenneth Reitz' From 30bcd55fb97523bf188f68b641ec9dc6eb4b6a75 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 20 Dec 2016 12:41:42 -0500 Subject: [PATCH 003/104] basic travis.yml file --- .travis.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..f1896428 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,13 @@ +language: python +python: + - "2.6" + - "2.7" + - "3.2" + - "3.3" + - "3.4" + - "3.5" + - "3.6-dev" # 3.6 development branch +# command to install dependencies +install: "pip install -r requirements.txt" +# command to run tests +script: make test \ No newline at end of file From e127ecab3f36b9a88c3a8e6ca169dabade41800a Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 20 Dec 2016 12:42:52 -0500 Subject: [PATCH 004/104] add pypy to travis.yml --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index f1896428..ac810ed3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,8 @@ python: - "3.4" - "3.5" - "3.6-dev" # 3.6 development branch + - "pypy" + - "pypy3" # command to install dependencies install: "pip install -r requirements.txt" # command to run tests From daebd6b807d45cc79e47d9d7f91b2ddb0f0aece3 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 20 Dec 2016 12:47:39 -0500 Subject: [PATCH 005/104] empty commit From 5a280a11bcfa822742a2914fa01a19ed4b45d034 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 20 Dec 2016 12:50:22 -0500 Subject: [PATCH 006/104] we don't support python 3.2 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ac810ed3..5ce184d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ language: python python: - "2.6" - "2.7" - - "3.2" - "3.3" - "3.4" - "3.5" From ddde5cd85b872cb09e865a9d52c810795ff64923 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 20 Dec 2016 12:54:00 -0500 Subject: [PATCH 007/104] travis and saythanks icons in readme --- README.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 57a4f334..a5916437 100644 --- a/README.rst +++ b/README.rst @@ -3,7 +3,15 @@ Requests: HTTP for Humans .. image:: https://img.shields.io/pypi/v/requests.svg :target: https://pypi.python.org/pypi/requests - + +.. image:: https://travis-ci.org/kennethreitz/requests.svg?branch=master + :target: https://travis-ci.org/kennethreitz/requests + +.. image:: https://img.shields.io/badge/SayThanks.io-☼-1EAEDB.svg + :target: https://saythanks.io/to/kennethreitz + + + Requests is the only *Non-GMO* HTTP library for Python, safe for human consumption. From ba6e948835ae16bbc460ca03fad6db4fbdb396da Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 20 Dec 2016 13:10:45 -0500 Subject: [PATCH 008/104] skipping pypy for now --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5ce184d6..089c6a99 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,8 @@ python: - "3.4" - "3.5" - "3.6-dev" # 3.6 development branch - - "pypy" - - "pypy3" + # - "pypy" -- appears to hang + # - "pypy3" # command to install dependencies install: "pip install -r requirements.txt" # command to run tests From 789f21807d4cc0eb939181494fea8399dfc5206a Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 20 Dec 2016 13:16:14 -0500 Subject: [PATCH 009/104] python 2.6 compatibiliby --- requests/auth.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requests/auth.py b/requests/auth.py index 701104d0..510846d6 100644 --- a/requests/auth.py +++ b/requests/auth.py @@ -39,7 +39,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 ({!r}) to " + "3.0.0. Please convert the object you've passed in ({0!r}) to " "a string or bytes object in the near future to avoid " "problems.".format(username), category=DeprecationWarning, @@ -49,7 +49,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 ({!r}) to " + "3.0.0. Please convert the object you've passed in ({0!r}) to " "a string or bytes object in the near future to avoid " "problems.".format(password), category=DeprecationWarning, From c3fb8e020b865a04afbc01e2c439fb3995feb702 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 20 Dec 2016 13:25:30 -0500 Subject: [PATCH 010/104] we support python 3.6 --- README.rst | 2 +- docs/index.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index a5916437..e1783b70 100644 --- a/README.rst +++ b/README.rst @@ -73,7 +73,7 @@ Requests is ready for today's web. - Chunked Requests - Thread-safety -Requests officially supports Python 2.6–2.7 & 3.3–3.5, and runs great on PyPy. +Requests officially supports Python 2.6–2.7 & 3.3–3.6, and runs great on PyPy. Installation ------------ diff --git a/docs/index.rst b/docs/index.rst index d8279a9c..1f323631 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -87,7 +87,7 @@ Requests is ready for today's web. - Chunked Requests - Thread-safety -Requests officially supports Python 2.6–2.7 & 3.3–3.5, and runs great on PyPy. +Requests officially supports Python 2.6–2.7 & 3.3–3.6, and runs great on PyPy. The User Guide From bc8b29099e67e7ce3b96739de0f5ba855aa6fba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20P=C5=82onka?= Date: Wed, 21 Dec 2016 17:59:34 +0200 Subject: [PATCH 011/104] updating idna.uts46data from upstream project (#3781) * updating idna.uts46data from upstream project * removing redundant find/sed in idna update * Revert "updating idna.uts46data from upstream project" This reverts commit 0150cee7057dbdcefa1a2fbe2e8617ad0cba5216. --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index d74b5aa1..f759fdf1 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,6 @@ idna: git checkout `git describe --abbrev=0 --tags` && \ cd .. && \ mv idna/idna requests/packages/ && \ - find requests/packages/idna -type f -exec sed -i "" "s/^from idna/from /" {} \; && \ rm -fr idna publish: From 5aa66615870beeb7b0ed3af27457f689db262ab3 Mon Sep 17 00:00:00 2001 From: John Dingee Date: Wed, 21 Dec 2016 13:08:45 -0500 Subject: [PATCH 012/104] fix urllib3 documentation link (#3785) --- requests/packages/urllib3/contrib/appengine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requests/packages/urllib3/contrib/appengine.py b/requests/packages/urllib3/contrib/appengine.py index c3249eeb..814b0222 100644 --- a/requests/packages/urllib3/contrib/appengine.py +++ b/requests/packages/urllib3/contrib/appengine.py @@ -111,7 +111,7 @@ class AppEngineManager(RequestMethods): warnings.warn( "urllib3 is using URLFetch on Google App Engine sandbox instead " "of sockets. To use sockets directly instead of URLFetch see " - "https://urllib3.readthedocs.io/en/latest/contrib.html.", + "https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html.", AppEnginePlatformWarning) RequestMethods.__init__(self, headers) From 8e0a532cad39e28dc6e74002f79513dbb509bad2 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Fri, 23 Dec 2016 13:08:49 -0500 Subject: [PATCH 013/104] wonder when 3.6 will be available on travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 089c6a99..de00235d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ python: - "3.3" - "3.4" - "3.5" - - "3.6-dev" # 3.6 development branch + - "3.6" # - "pypy" -- appears to hang # - "pypy3" # command to install dependencies From 1c34ac3ae66ef05820d781bde7ae8eda673eaa46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=93=D0=B5=D1=80=D0=B0=D1=81=D0=B8=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BA=D0=BE=20=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9?= Date: Thu, 29 Dec 2016 10:17:59 +0700 Subject: [PATCH 014/104] Fixed detection of utf-32-be by BOM. --- requests/utils.py | 2 +- tests/test_utils.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/requests/utils.py b/requests/utils.py index 4def3dba..47325090 100644 --- a/requests/utils.py +++ b/requests/utils.py @@ -714,7 +714,7 @@ def guess_json_utf(data): # easy as counting the nulls and from their location and count # determine the encoding. Also detect a BOM, if present. sample = data[:4] - if sample in (codecs.BOM_UTF32_LE, codecs.BOM32_BE): + if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE): return 'utf-32' # BOM included if sample[:3] == codecs.BOM_UTF8: return 'utf-8-sig' # BOM included, MS style (discouraged) diff --git a/tests/test_utils.py b/tests/test_utils.py index c92c7323..2b4401b0 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -274,6 +274,17 @@ class TestGuessJSONUTF: def test_bad_utf_like_encoding(self): assert guess_json_utf(b'\x00\x00\x00\x00') is None + @pytest.mark.parametrize( + ('encoding', 'expected'), ( + ('utf-16-be', 'utf-16'), + ('utf-16-le', 'utf-16'), + ('utf-32-be', 'utf-32'), + ('utf-32-le', 'utf-32') + )) + def test_guess_by_bom(self, encoding, expected): + data = '\ufeff{}'.encode(encoding) + assert guess_json_utf(data) == expected + USER = PASSWORD = "%!*'();:@&=+$,/?#[] " ENCODED_USER = compat.quote(USER, '') From 0cb6ddaecf8fe88f3c6ba9ae60aa6b9d063f0ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=93=D0=B5=D1=80=D0=B0=D1=81=D0=B8=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BA=D0=BE=20=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9?= Date: Thu, 29 Dec 2016 10:30:56 +0700 Subject: [PATCH 015/104] Fixed tests for python 2.x. --- tests/test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 2b4401b0..8d5ade9c 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -282,7 +282,7 @@ class TestGuessJSONUTF: ('utf-32-le', 'utf-32') )) def test_guess_by_bom(self, encoding, expected): - data = '\ufeff{}'.encode(encoding) + data = u'\ufeff{}'.encode(encoding) assert guess_json_utf(data) == expected From 33b29be8cf93572870415b04c21a895ca3edf3ce Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Fri, 30 Dec 2016 09:40:12 -0800 Subject: [PATCH 016/104] Require pytest-mock for the tests test_requests.py `test_session_close_proxy_clear` uses the `mocker` fixture, which is provided by pytest-mock. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c2406240..3e0f1555 100755 --- a/setup.py +++ b/setup.py @@ -47,7 +47,7 @@ packages = [ ] requires = [] -test_requirements = ['pytest>=2.8.0', 'pytest-httpbin==0.0.7', 'pytest-cov'] +test_requirements = ['pytest>=2.8.0', 'pytest-httpbin==0.0.7', 'pytest-cov', 'pytest-mock'] with open('requests/__init__.py', 'r') as fd: version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', From f5c5536916085ba4b6b9002ad723a6d7c7c08ed6 Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Wed, 4 Jan 2017 15:23:23 -0700 Subject: [PATCH 017/104] updating https demo urls --- docs/.api.rst.swo | Bin 16384 -> 0 bytes docs/user/advanced.rst | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 docs/.api.rst.swo diff --git a/docs/.api.rst.swo b/docs/.api.rst.swo deleted file mode 100644 index 76d80e7d66d897127ac0b0d9a2ef4159229981eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI3ZHOIL8OM)FeMz;oR-@EUCy92Gkez!sNl963Fx{pkHEH8!(}GR8J9p;Xy_20g zXF6x@?%otq!B1MPp9CwILIsspKPf0yvDGgYtDqp*_yQ_|;3pMYXrcOhX6C-+eY+qc z%)l?Rcjlbuobx|#&zy78Za#SQxIW@G$7yYGY>VShWJR z0<{9Q0<{9Q0<{9Q0<{9Q0{@o^PZe^=L;>iN@`ynnNL|BmYU zmde1;PW8CH)e6)K)C$xJ)C$xJ)C$xJ)C$xJ)C$xJ)C$xJ{0|iHL!~}My3ff10Q>*L z@Bi1{tJJITXZR)j0=^I5gC2YY{&2HWzlYz!%kU%kAq-#!n(#r`3UA(|)ZgG&@H~7C zJ_nzLbKoF@!*Cn?>pe>S9L|G-Prwx14j+XNz-HJ4|9rPn|9}hdQ}_wI2;YXM;LETE zJ}kl!n1LoVU@N?Fqf)QKui<(40ek^gpbtl22AZ%9ZiV;3-?u3B0(=P~=)w|o;55v` zCt)jGc$ZR7!+H2Bd>)>F&%k4F77oKL@X9-t`Yn7Nz6ejkr(h25hC}din1&C-ZSV$* zFR#OE@G86nFTxA(415Kig2%u?29H7tEw~?!!zTF4+o^l_6Z{5Vf}g>s;c++%0|;Oz z{P70b13U>Q;YQd3H^652@n+f>JOPiuY1jeV;T786w?Nw9v(gT)a%nw08ZvGDe%_6v zc1!z7IDWirvbM>rYk6w7K12`>mqdY|bF4&nP0V={r@Q`&(QRWA-OlVXH`~v3l;l=B zllqyT8{M;EKQ_+OCyh~JDUOF}=&rTPlSVSrvnwXlW-TyjuBS5NQkyt4)5WE zEbyJti;ISv+Tf$gPe+>YWXA9xsAT&yxd(8y^&c2*~LRR5d=8jzY;L zRXGxRRHKe6T|%yYn}biiM$Vb0I7&>B>Zo3$UTU*^6nm)pZb~~}HJKtpDVeC{qfH$9 z?bsBJJh3^CI3`6a&Ij6d_%&>76!qNrQX<-1AsDr*XxT<8kluhg5e>eh`{@$rvnZaY z3PBuFO6fzBOL2>^Jqa5|osP*&5};GthJULI+^Vi7Oo$uNT&!tiarupm6@icl6H#`V!8~2 zgzG2;ov_tUB568hhK60@`k9ibH0+|6mvO71_N_&AW!%6fIkU~ESTvWzm2v5WLz|bi zHW|jfBMS>B?unK-^>|1|^{chaQP>liT^p<~=-s}Hg6jvB5CmnqySNK0c`=?v-*OA} zLqC;SrYPc}^2f%FNDen@*%4w zA$`5!N0Z96ayQJ^hH_NRn`JMfDB>f~+2~{wB`^L|RUSrD?YQ-pP7X0Ahm!^7JA9~N ztG!~FdAywUgkv~N7^2q`bivx=elnP^Ms;`1^iRznlTtDMht~`z9kCpWt3G(e(p0%b zhwF!}#5`QMhs2oFTaBKUqo2=oG%;X@CdNY>=6B)+-c~RgB_^MbYhm)K<@ogF<2u9N z6`slvI2x=bjAZ2uqi`3@0FO=_;=G?F;yjgpV_?Lw5GP}{9OOoRjsDoMI~-iB+%`{% zPfhqr9yg_jiQymO-iTY+#_A~0kYDUDh``7iQ}f>%;TC!wn@@5llZab;CWxpr57I#o?_U*&s;5H z5A%zsl$r$R7pKXrkz_(VK1lF1nB4d1RWq_uI#W^!g{vjjhDu$O5PtLuBV{43N_`XL`=3w0;`%P% z_uqjCZifq1m~Tk9`l=PE6{r=c6{r=c6{r=c6{r=c6{r=c6{r>XFDanex?s(Ujf8TM zRGC$_IL)Q%fkeOk^8sC*fI@kdJB>Ui4mXX2xso(k5a1O7=5y*$V1e z)&yLhu@W8+Jbg5u!f42UMQ720g#mxXMj^I}4MX`VXX!xpod`uzQL$-KCet>UHEeP; zi>)o$oC#P%sCKT{+Iq0eF>4fJXK}GwZDzwqmdD8kO zvRFJ|D@>LYF)(0>> requests.get('https://kennethreitz.com', verify=False) + >>> requests.get('https://kennethreitz.org', verify=False) By default, ``verify`` is set to True. Option ``verify`` only applies to host certs. @@ -229,7 +229,7 @@ You can also specify a local cert to use as client side certificate, as a single file (containing the private key and the certificate) or as a tuple of both file's path:: - >>> requests.get('https://kennethreitz.com', cert=('/path/client.cert', '/path/client.key')) + >>> requests.get('https://kennethreitz.org', cert=('/path/client.cert', '/path/client.key')) or persistent:: @@ -239,7 +239,7 @@ or persistent:: If you specify a wrong path or an invalid cert, you'll get a SSLError:: - >>> requests.get('https://kennethreitz.com', cert='/wrong_path/client.pem') + >>> requests.get('https://kennethreitz.org', cert='/wrong_path/client.pem') SSLError: [Errno 336265225] _ssl.c:347: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib .. warning:: The private key to your local certificate *must* be unencrypted. From 2bcaff99eaffda691eadfa3298507db6ffe17ca9 Mon Sep 17 00:00:00 2001 From: Andrii Soldatenko Date: Mon, 9 Jan 2017 00:40:32 +0200 Subject: [PATCH 018/104] Added python 3.6.0 --- .travis.yml | 1 + AUTHORS.rst | 1 + README.rst | 4 +++- docs/community/faq.rst | 1 + docs/dev/todo.rst | 1 + setup.py | 1 + 6 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index de00235d..fffeab60 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ python: - "3.4" - "3.5" - "3.6" + - "3.7-dev" # - "pypy" -- appears to hang # - "pypy3" # command to install dependencies diff --git a/AUTHORS.rst b/AUTHORS.rst index 1dbd0409..c05befce 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -174,3 +174,4 @@ Patches and Suggestions - Philipp Konrad (`@gardiac2002 `_) - Hussain Tamboli (`@hussaintamboli `_) - Casey Davidson (`@davidsoncasey `_) +- Andrii Soldatenko (`@a_soldatenko `_) diff --git a/README.rst b/README.rst index e1783b70..43686998 100644 --- a/README.rst +++ b/README.rst @@ -10,7 +10,9 @@ Requests: HTTP for Humans .. image:: https://img.shields.io/badge/SayThanks.io-☼-1EAEDB.svg :target: https://saythanks.io/to/kennethreitz - +.. image:: https://codecov.io/github/kennethreitz/requests/coverage.svg?branch=master + :target: https://codecov.io/github/kennethreitz/requests + :alt: codecov.io Requests is the only *Non-GMO* HTTP library for Python, safe for human consumption. diff --git a/docs/community/faq.rst b/docs/community/faq.rst index c87687af..e835b122 100644 --- a/docs/community/faq.rst +++ b/docs/community/faq.rst @@ -59,6 +59,7 @@ supported: * Python 3.3 * Python 3.4 * Python 3.5 +* Python 3.6 * PyPy What are "hostname doesn't match" errors? diff --git a/docs/dev/todo.rst b/docs/dev/todo.rst index 79b95a21..14dafed3 100644 --- a/docs/dev/todo.rst +++ b/docs/dev/todo.rst @@ -41,6 +41,7 @@ Requests currently supports the following versions of Python: - Python 3.3 - Python 3.4 - Python 3.5 +- Python 3.6 - PyPy Google AppEngine is not officially supported although support is available diff --git a/setup.py b/setup.py index 3e0f1555..b1623489 100755 --- a/setup.py +++ b/setup.py @@ -88,6 +88,7 @@ setup( 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy' ), From ba7101e2cd790fde701b0d4942fb2f465f860ef7 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 8 Jan 2017 23:13:47 -0500 Subject: [PATCH 019/104] Update .travis.yml --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fffeab60..7abe7e4d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,4 +12,6 @@ python: # command to install dependencies install: "pip install -r requirements.txt" # command to run tests -script: make test \ No newline at end of file +script: make test +after_success: + - bash <(curl -s https://codecov.io/bash) From 4942b40496b5c1b7dc4b3e14360dd68e8633554a Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Tue, 10 Jan 2017 15:17:08 +1000 Subject: [PATCH 020/104] Improve discoverability of OAuth 2 support The previous summary gave the impression that requests-oauthlib only supports OAuth 1. This updates makes it clear that it also supports OAuth 2, and links directly to the use case specific authentication flow guides. --- docs/user/authentication.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/user/authentication.rst b/docs/user/authentication.rst index 58175623..dc15114d 100644 --- a/docs/user/authentication.rst +++ b/docs/user/authentication.rst @@ -76,6 +76,16 @@ For more information on how to OAuth flow works, please see the official `OAuth` For examples and documentation on requests-oauthlib, please see the `requests_oauthlib`_ repository on GitHub +OAuth 2 Authentication +---------------------- + +The ``requests-oauthlib`` library handles OAuth 2 in addition to OAuth 1. See their +documentation for details of the various OAuth 2 credential management flows: + +* `Web Application Flow`_ +* `Mobile Application Flow`_ +* `Legacy Application Flow`_ +* `Backend Application Flow`_ Other Authentication -------------------- @@ -123,6 +133,10 @@ Further examples can be found under the `Requests organization`_ and in the .. _OAuth: http://oauth.net/ .. _requests_oauthlib: https://github.com/requests/requests-oauthlib +.. _Web Application Flow: http://requests-oauthlib.readthedocs.io/en/latest/oauth2_workflow.html#web-application-flow +.. _Mobile Application Flow: http://requests-oauthlib.readthedocs.io/en/latest/oauth2_workflow.html#mobile-application-flow +.. _Legacy Application Flow: http://requests-oauthlib.readthedocs.io/en/latest/oauth2_workflow.html#legacy-application-flow +.. _Backend Application Flow: http://requests-oauthlib.readthedocs.io/en/latest/oauth2_workflow.html#backend-application-flow .. _Kerberos: https://github.com/requests/requests-kerberos .. _NTLM: https://github.com/requests/requests-ntlm .. _Requests organization: https://github.com/requests From 775d19ee052ecd89b6527f5e833cf936fb9dfbc6 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Tue, 10 Jan 2017 15:31:20 +1000 Subject: [PATCH 021/104] Explicitly mention OpenID Connect OAuth 2 is the authentication protocol underpinning OpenID Connect. Mention that explicitly for the benefit of folks looking for information on using requests with OpenID Connect that don't yet know that OAuth 2 is the relevant underlying authentication protocol. --- docs/user/authentication.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/user/authentication.rst b/docs/user/authentication.rst index dc15114d..2b7a8690 100644 --- a/docs/user/authentication.rst +++ b/docs/user/authentication.rst @@ -60,7 +60,7 @@ OAuth 1 Authentication ---------------------- A common form of authentication for several web APIs is OAuth. The ``requests-oauthlib`` -library allows Requests users to easily make OAuth authenticated requests:: +library allows Requests users to easily make OAuth 1 authenticated requests:: >>> import requests >>> from requests_oauthlib import OAuth1 @@ -76,11 +76,12 @@ For more information on how to OAuth flow works, please see the official `OAuth` For examples and documentation on requests-oauthlib, please see the `requests_oauthlib`_ repository on GitHub -OAuth 2 Authentication ----------------------- +OAuth 2 and OpenID Connect Authentication +----------------------------------------- -The ``requests-oauthlib`` library handles OAuth 2 in addition to OAuth 1. See their -documentation for details of the various OAuth 2 credential management flows: +The ``requests-oauthlib`` library also handles OAuth 2, the authentication mechanism +underpinning OpenID Connect. See the `requests-oauthlib OAuth2 documentation`_ for +details of the various OAuth 2 credential management flows: * `Web Application Flow`_ * `Mobile Application Flow`_ @@ -133,6 +134,7 @@ Further examples can be found under the `Requests organization`_ and in the .. _OAuth: http://oauth.net/ .. _requests_oauthlib: https://github.com/requests/requests-oauthlib +.. _requests-oauthlib OAuth2 documentation: http://requests-oauthlib.readthedocs.io/en/latest/oauth2_workflow.html .. _Web Application Flow: http://requests-oauthlib.readthedocs.io/en/latest/oauth2_workflow.html#web-application-flow .. _Mobile Application Flow: http://requests-oauthlib.readthedocs.io/en/latest/oauth2_workflow.html#mobile-application-flow .. _Legacy Application Flow: http://requests-oauthlib.readthedocs.io/en/latest/oauth2_workflow.html#legacy-application-flow From e8c0a99cb11c630b1e778a8c7e6b33b36d8088a7 Mon Sep 17 00:00:00 2001 From: winterJ Date: Wed, 11 Jan 2017 18:20:52 +0900 Subject: [PATCH 022/104] Remove unused module --- tests/test_requests.py | 3 +-- tests/test_utils.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/test_requests.py b/tests/test_requests.py index b0cb7d6b..b5705691 100755 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -20,7 +20,7 @@ from requests.compat import ( Morsel, cookielib, getproxies, str, urlparse, builtin_str, OrderedDict) from requests.cookies import ( - cookiejar_from_dict, morsel_to_cookie, merge_cookies) + cookiejar_from_dict, morsel_to_cookie) from requests.exceptions import ( ConnectionError, ConnectTimeout, InvalidSchema, InvalidURL, MissingSchema, ReadTimeout, Timeout, RetryError, TooManyRedirects, @@ -2293,4 +2293,3 @@ class TestPreparingURLs(object): r = requests.Request('GET', url=input, params=params) p = r.prepare() assert p.url == expected - diff --git a/tests/test_utils.py b/tests/test_utils.py index 8d5ade9c..1edf6218 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -4,7 +4,7 @@ from io import BytesIO import pytest from requests import compat -from requests.cookies import RequestsCookieJar, cookiejar_from_dict +from requests.cookies import RequestsCookieJar from requests.structures import CaseInsensitiveDict from requests.utils import ( address_in_network, dotted_netmask, From 2432dd62085629c775abc269ec92e7f13a63b73f Mon Sep 17 00:00:00 2001 From: Peter Inglesby Date: Thu, 12 Jan 2017 17:00:42 +0000 Subject: [PATCH 023/104] Add default value of allow_redirects to docs --- requests/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requests/api.py b/requests/api.py index 2bde58b1..16fd1e94 100644 --- a/requests/api.py +++ b/requests/api.py @@ -33,7 +33,7 @@ def request(method, url, **kwargs): before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple - :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. + :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``. :type allow_redirects: bool :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. :param verify: (optional) whether the SSL cert will be verified. A CA_BUNDLE path can also be provided. Defaults to ``True``. From fae3f92c34d8d7267de33ecb676b3d5600146257 Mon Sep 17 00:00:00 2001 From: Moin Date: Tue, 17 Jan 2017 20:34:15 +0530 Subject: [PATCH 024/104] lazily load idna library --- AUTHORS.rst | 1 + requests/models.py | 38 +++++++++++++++++++++++++---------- requests/packages/__init__.py | 6 ------ 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index c05befce..cc9e75f3 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -175,3 +175,4 @@ Patches and Suggestions - Hussain Tamboli (`@hussaintamboli `_) - Casey Davidson (`@davidsoncasey `_) - Andrii Soldatenko (`@a_soldatenko `_) +- Moinuddin Quadri (`@moin18 `_) diff --git a/requests/models.py b/requests/models.py index 91555b58..d1a9c868 100644 --- a/requests/models.py +++ b/requests/models.py @@ -9,6 +9,7 @@ This module contains the primary objects that power Requests. import collections import datetime +import sys # Import encoding now, to avoid implicit import later. # Implicit import within threads may cause LookupError when standard library is in a ZIP, @@ -21,7 +22,6 @@ from .structures import CaseInsensitiveDict from .auth import HTTPBasicAuth from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar -from .packages import idna from .packages.urllib3.fields import RequestField from .packages.urllib3.filepost import encode_multipart_formdata from .packages.urllib3.util import parse_url @@ -331,6 +331,22 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): if self.method is not None: self.method = to_native_string(self.method.upper()) + @staticmethod + def _get_idna_encoded_host(host): + try: + from .packages import idna + except ImportError: + # tolerate the possibility of downstream repackagers unvendoring `requests` + # For more information, read: packages/__init__.py + import idna + sys.modules['requests.packages.idna'] = idna + + try: + host = idna.encode(host, uts46=True).decode('utf-8') + except idna.IDNAError: + raise UnicodeError + return host + def prepare_url(self, url, params): """Prepares the given HTTP URL.""" #: Accept objects that have string representations. @@ -368,17 +384,17 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): if not host: raise InvalidURL("Invalid URL %r: No host supplied" % url) - # In general, we want to try IDNA encoding every hostname, as that - # allows users to automatically get the correct behaviour. However, - # we’re quite strict about IDNA encoding, so certain valid hostnames - # may fail to encode. On failure, we verify the hostname meets a - # minimum standard of only containing ASCII characters, and not starting - # with a wildcard (*), before allowing the unencoded hostname through. - try: - host = idna.encode(host, uts46=True).decode('utf-8') - except (UnicodeError, idna.IDNAError): - if not unicode_is_ascii(host) or host.startswith(u'*'): + # In general, we want to try IDNA encoding the hostname if the string contains + # non-ASCII characters. This allows users to automatically get the correct IDNA + # behaviour. For strings containing only ASCII characters, we need to also verify + # it doesn't start with a wildcard (*), before allowing the unencoded hostname. + if not unicode_is_ascii(host): + try: + host = self._get_idna_encoded_host(host) + except UnicodeError: raise InvalidURL('URL has an invalid label.') + elif host.startswith(u'*'): + raise InvalidURL('URL has an invalid label.') # Carefully reconstruct the network location netloc = auth or '' diff --git a/requests/packages/__init__.py b/requests/packages/__init__.py index 4077265e..971c2ad0 100644 --- a/requests/packages/__init__.py +++ b/requests/packages/__init__.py @@ -34,9 +34,3 @@ try: except ImportError: import chardet sys.modules['%s.chardet' % __name__] = chardet - -try: - from . import idna -except ImportError: - import idna - sys.modules['%s.idna' % __name__] = idna From a1d058c6b1258649c21396e1bfd79ed08401c285 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 17 Jan 2017 17:15:50 -0500 Subject: [PATCH 025/104] empty commit From 96fbe9e8c9ffad8c15358d1e53831c1a2922cb13 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 17 Jan 2017 17:34:33 -0500 Subject: [PATCH 026/104] get codecov to work --- .travis.yml | 5 +++-- Makefile | 2 +- requirements-to-freeze.txt | 3 ++- requirements.txt | 38 +++++++++++++++++++------------------- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7abe7e4d..a4576f96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ python: # command to install dependencies install: "pip install -r requirements.txt" # command to run tests -script: make test +script: + - make coverage after_success: - - bash <(curl -s https://codecov.io/bash) + - codecov diff --git a/Makefile b/Makefile index f759fdf1..331b957f 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ test: py.test tests coverage: - py.test --verbose --cov-report term --cov=requests tests + py.test --verbose --cov-report term --conv-report xml --cov=requests tests ci: init py.test --junitxml=junit.xml diff --git a/requirements-to-freeze.txt b/requirements-to-freeze.txt index e8b9e354..00b7e523 100644 --- a/requirements-to-freeze.txt +++ b/requirements-to-freeze.txt @@ -1,4 +1,5 @@ pytest pytest-cov pytest-httpbin -sphinx \ No newline at end of file +sphinx +codecov \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 7f12747c..dbe1da6c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,24 +1,24 @@ -alabaster==0.7.7 -Babel==2.2.0 -coverage==4.0.3 -decorator==4.0.9 -docutils==0.12 -Flask==0.10.1 +alabaster==0.7.9 +Babel==2.3.4 +click==6.7 +codecov==2.0.5 +coverage==4.3.4 +decorator==4.0.11 +docutils==0.13.1 +Flask==0.12 httpbin==0.5.0 +imagesize==0.7.1 itsdangerous==0.24 -Jinja2==2.8 +Jinja2==2.9.4 MarkupSafe==0.23 -py==1.4.31 -Pygments==2.1.1 -PySocks==1.5.6 -pytest==2.8.7 -pytest-cov==2.2.1 -pytest-httpbin==0.2.0 -pytest-mock==0.11.0 -pytz==2015.7 +py==1.4.32 +Pygments==2.1.3 +pytest==3.0.5 +pytest-cov==2.4.0 +pytest-httpbin==0.2.3 +pytz==2016.10 +requests==2.12.4 six==1.10.0 snowballstemmer==1.2.1 -Sphinx==1.3.5 -sphinx-rtd-theme==0.1.9 -Werkzeug==0.11.4 -wheel==0.29.0 +Sphinx==1.5.1 +Werkzeug==0.11.15 From 115b438e6a3b4e3d29c932cbf3da160b07591020 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 17 Jan 2017 17:37:21 -0500 Subject: [PATCH 027/104] typo --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 331b957f..0e232193 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ test: py.test tests coverage: - py.test --verbose --cov-report term --conv-report xml --cov=requests tests + py.test --verbose --cov-report term --cov-report xml --cov=requests tests ci: init py.test --junitxml=junit.xml From d374a182d997d6c07e519328ccdb8f2fec3ef7a6 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 17 Jan 2017 17:44:22 -0500 Subject: [PATCH 028/104] fixing build --- requirements-to-freeze.txt | 1 + requirements.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/requirements-to-freeze.txt b/requirements-to-freeze.txt index 00b7e523..adeb0032 100644 --- a/requirements-to-freeze.txt +++ b/requirements-to-freeze.txt @@ -1,5 +1,6 @@ pytest pytest-cov pytest-httpbin +PySocks sphinx codecov \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index dbe1da6c..fec3ba41 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,6 +13,7 @@ Jinja2==2.9.4 MarkupSafe==0.23 py==1.4.32 Pygments==2.1.3 +PySocks==1.6.5 pytest==3.0.5 pytest-cov==2.4.0 pytest-httpbin==0.2.3 From 65fb2a50c839ca5ae6496498efb0548054481d1e Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 17 Jan 2017 17:48:36 -0500 Subject: [PATCH 029/104] further fix the build --- requirements-to-freeze.txt | 1 + requirements.txt | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/requirements-to-freeze.txt b/requirements-to-freeze.txt index adeb0032..9a6a4384 100644 --- a/requirements-to-freeze.txt +++ b/requirements-to-freeze.txt @@ -1,6 +1,7 @@ pytest pytest-cov pytest-httpbin +pytest-mock PySocks sphinx codecov \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index fec3ba41..82af21cc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,17 +6,21 @@ coverage==4.3.4 decorator==4.0.11 docutils==0.13.1 Flask==0.12 +funcsigs==1.0.2 httpbin==0.5.0 imagesize==0.7.1 itsdangerous==0.24 Jinja2==2.9.4 MarkupSafe==0.23 +mock==2.0.0 +pbr==1.10.0 py==1.4.32 Pygments==2.1.3 PySocks==1.6.5 pytest==3.0.5 pytest-cov==2.4.0 pytest-httpbin==0.2.3 +pytest-mock==1.5.0 pytz==2016.10 requests==2.12.4 six==1.10.0 From a68f7169a5fa26e7f6bec646c86dfe128497b0bf Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 17 Jan 2017 17:56:19 -0500 Subject: [PATCH 030/104] omit coverage packages --- .coveragerc | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 00000000..e9b51ab1 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,2 @@ +[run] +omit = requests/packages/* \ No newline at end of file From 52b5ed18c12d4b0f8c0572b7433f60c0e42928c6 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 17 Jan 2017 18:03:23 -0500 Subject: [PATCH 031/104] cleanup makefile --- Makefile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 0e232193..d3dae053 100644 --- a/Makefile +++ b/Makefile @@ -9,10 +9,7 @@ test: py.test tests coverage: - py.test --verbose --cov-report term --cov-report xml --cov=requests tests - -ci: init - py.test --junitxml=junit.xml + py.test --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests certs: curl http://ci.kennethreitz.org/job/ca-bundle/lastSuccessfulBuild/artifact/cacerts.pem -o requests/cacert.pem From 23ac7256eaa7667d417ae91da7f9b90a5a07eb19 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 17 Jan 2017 18:07:10 -0500 Subject: [PATCH 032/104] Update README.rst --- README.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 43686998..dc5c9ea7 100644 --- a/README.rst +++ b/README.rst @@ -7,12 +7,14 @@ Requests: HTTP for Humans .. image:: https://travis-ci.org/kennethreitz/requests.svg?branch=master :target: https://travis-ci.org/kennethreitz/requests -.. image:: https://img.shields.io/badge/SayThanks.io-☼-1EAEDB.svg - :target: https://saythanks.io/to/kennethreitz - .. image:: https://codecov.io/github/kennethreitz/requests/coverage.svg?branch=master :target: https://codecov.io/github/kennethreitz/requests :alt: codecov.io + +.. image:: https://img.shields.io/badge/SayThanks.io-☼-1EAEDB.svg + :target: https://saythanks.io/to/kennethreitz + + Requests is the only *Non-GMO* HTTP library for Python, safe for human consumption. From 84ee1d4a42afb9b7baa4367f75323b1e187af7eb Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 17 Jan 2017 18:08:36 -0500 Subject: [PATCH 033/104] yes, 3.7 too --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index dc5c9ea7..1df00e0a 100644 --- a/README.rst +++ b/README.rst @@ -77,7 +77,7 @@ Requests is ready for today's web. - Chunked Requests - Thread-safety -Requests officially supports Python 2.6–2.7 & 3.3–3.6, and runs great on PyPy. +Requests officially supports Python 2.6–2.7 & 3.3–3.7, and runs great on PyPy. Installation ------------ From 525996654795a64c18e470b69cc75e240f47a87a Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 17 Jan 2017 18:09:09 -0500 Subject: [PATCH 034/104] yes 3.7 too --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 1f323631..b13860c7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -87,7 +87,7 @@ Requests is ready for today's web. - Chunked Requests - Thread-safety -Requests officially supports Python 2.6–2.7 & 3.3–3.6, and runs great on PyPy. +Requests officially supports Python 2.6–2.7 & 3.3–3.7, and runs great on PyPy. The User Guide From 8344b0b40979f11afbc1f76043f076f85f2e92dd Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 17 Jan 2017 18:09:47 -0500 Subject: [PATCH 035/104] link to twitter --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index b13860c7..5ea73778 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -56,7 +56,7 @@ Institutions that prefer to be unnamed claim to use Requests internally. **Daniel Greenfeld** Nuked a 1200 LOC spaghetti code library with 10 lines of code thanks to - @kennethreitz's request library. Today has been AWESOME. + `@kennethreitz `_'s request library. Today has been AWESOME. **Kenny Meyers** Python HTTP: When in doubt, or when not in doubt, use Requests. Beautiful, From 160d36450350cbb8948657a60aa4f0cbe18c601e Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 17 Jan 2017 18:10:25 -0500 Subject: [PATCH 036/104] RIP Readability --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 5ea73778..2aba9e35 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -43,7 +43,7 @@ User Testimonials The NSA, Her Majesty's Government, Amazon, Google, Twilio, Runscope, Mozilla, Heroku, PayPal, NPR, Obama for America, Transifex, Native Instruments, The Washington -Post, Twitter, SoundCloud, Kippt, Readability, Sony, and Federal U.S. +Post, Twitter, SoundCloud, Kippt, Sony, and Federal U.S. Institutions that prefer to be unnamed claim to use Requests internally. **Armin Ronacher** From 219d9a7297efc5673a8c77400204130d66bca311 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Wed, 18 Jan 2017 12:22:14 +0000 Subject: [PATCH 037/104] Prepare changelog for 2.12.5 --- HISTORY.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/HISTORY.rst b/HISTORY.rst index e377c405..8bad7eb0 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,6 +3,14 @@ Release History --------------- +2.12.5 (2017-01-18) ++++++++++++++++++++ + +**Bugfixes** + +- Fixed an issue with JSON encoding detection, specifically detecting + big-endian UTF-32 with BOM. + 2.12.4 (2016-12-14) +++++++++++++++++++ From 5dcc03945765a7e7b7044b5f41ff5ee8d707c49b Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Wed, 18 Jan 2017 12:41:46 +0000 Subject: [PATCH 038/104] v2.12.5 --- requests/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requests/__init__.py b/requests/__init__.py index f4f1a042..dac37c95 100644 --- a/requests/__init__.py +++ b/requests/__init__.py @@ -41,8 +41,8 @@ is at . """ __title__ = 'requests' -__version__ = '2.12.4' -__build__ = 0x021204 +__version__ = '2.12.5' +__build__ = 0x021205 __author__ = 'Kenneth Reitz' __license__ = 'Apache 2.0' __copyright__ = 'Copyright 2016 Kenneth Reitz' From c00783cd86b3de9592f498f4670a5ebad1e99e83 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 19:45:41 -0500 Subject: [PATCH 039/104] let's see if this works --- Makefile | 7 +++--- Pipfile | 12 ++++++++++ Pipfile.lock | 45 ++++++++++++++++++++++++++++++++++++++ requirements-to-freeze.txt | 7 ------ requirements.txt | 29 ------------------------ 5 files changed, 61 insertions(+), 39 deletions(-) create mode 100644 Pipfile create mode 100644 Pipfile.lock delete mode 100644 requirements-to-freeze.txt delete mode 100644 requirements.txt diff --git a/Makefile b/Makefile index d3dae053..f6d2adf8 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,16 @@ .PHONY: docs init: - pip install -r requirements.txt + pip install pipenv>=0.1.6 + pipenv install --dev test: # This runs all of the tests. To run an individual test, run py.test with # the -k flag, like "py.test -k test_path_is_not_double_encoded" - py.test tests + pipenv run py.test tests coverage: - py.test --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests + pipenv run py.test --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests certs: curl http://ci.kennethreitz.org/job/ca-bundle/lastSuccessfulBuild/artifact/cacerts.pem -o requests/cacert.pem diff --git a/Pipfile b/Pipfile new file mode 100644 index 00000000..0bb849e7 --- /dev/null +++ b/Pipfile @@ -0,0 +1,12 @@ +[[source]] +url = "https://pypi.org/" +verify_ssl = true + +[dev-packages] +sphinx = "*" +pytest-mock = "*" +pytest-cov = "*" +pytest = "*" +codecov = "*" +pytest-httpbin = "*" +PySocks = "*" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 00000000..b545c108 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,45 @@ +{ + "default": {}, + "develop": { + "Werkzeug": "==0.11.15", + "six": "==1.10.0", + "httpbin": "==0.5.0", + "codecov": "==2.0.5", + "Flask": "==0.12", + "Babel": "==2.3.4", + "alabaster": "==0.7.9", + "pytest-mock": "==1.5.0", + "MarkupSafe": "==0.23", + "pytz": "==2016.10", + "coverage": "==4.3.4", + "pytest-httpbin": "==0.2.3", + "funcsigs": "==1.0.2", + "click": "==6.7", + "decorator": "==4.0.11", + "imagesize": "==0.7.1", + "Pygments": "==2.1.3", + "sphinx": "*", + "pbr": "==1.10.0", + "snowballstemmer": "==1.2.1", + "py": "==1.4.32", + "pytest-cov": "==2.4.0", + "docutils": "==0.13.1", + "pytest": "==3.0.5", + "Jinja2": "==2.9.4", + "Sphinx": "==1.5.1", + "requests": "==2.12.5", + "itsdangerous": "==0.24", + "PySocks": "==1.6.5", + "mock": "==2.0.0" + }, + "_meta": { + "sources": [ + { + "url": "https://pypi.org/", + "verify_ssl": true + } + ], + "requires": {}, + "Pipfile-sha256": "f306fe105cc76e259ab1e5d2933ad2d0fe7a8b2d28686f64f7a94f767c0ce5d4" + } +} \ No newline at end of file diff --git a/requirements-to-freeze.txt b/requirements-to-freeze.txt deleted file mode 100644 index 9a6a4384..00000000 --- a/requirements-to-freeze.txt +++ /dev/null @@ -1,7 +0,0 @@ -pytest -pytest-cov -pytest-httpbin -pytest-mock -PySocks -sphinx -codecov \ No newline at end of file diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 82af21cc..00000000 --- a/requirements.txt +++ /dev/null @@ -1,29 +0,0 @@ -alabaster==0.7.9 -Babel==2.3.4 -click==6.7 -codecov==2.0.5 -coverage==4.3.4 -decorator==4.0.11 -docutils==0.13.1 -Flask==0.12 -funcsigs==1.0.2 -httpbin==0.5.0 -imagesize==0.7.1 -itsdangerous==0.24 -Jinja2==2.9.4 -MarkupSafe==0.23 -mock==2.0.0 -pbr==1.10.0 -py==1.4.32 -Pygments==2.1.3 -PySocks==1.6.5 -pytest==3.0.5 -pytest-cov==2.4.0 -pytest-httpbin==0.2.3 -pytest-mock==1.5.0 -pytz==2016.10 -requests==2.12.4 -six==1.10.0 -snowballstemmer==1.2.1 -Sphinx==1.5.1 -Werkzeug==0.11.15 From 0ad2792873d99451be4501ea010c8d0398460921 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 19:47:39 -0500 Subject: [PATCH 040/104] trying again --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a4576f96..26c159b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ python: # - "pypy" -- appears to hang # - "pypy3" # command to install dependencies -install: "pip install -r requirements.txt" +install: "pip install pipenv; pipenv install" # command to run tests script: - make coverage From efe0608cddabcc7cd40be69dfaaa6e04848c4b72 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 20:08:36 -0500 Subject: [PATCH 041/104] empty commit From bb6f5a1d93777df9244d09a33281ad0e95174466 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 20:12:15 -0500 Subject: [PATCH 042/104] --global --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 26c159b0..7ed55a2b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ python: # - "pypy" -- appears to hang # - "pypy3" # command to install dependencies -install: "pip install pipenv; pipenv install" +install: "pip install pipenv; pipenv install --global" # command to run tests script: - make coverage From 0938c9e985a7482ab1a131bf680b6b745978e87b Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 20:22:29 -0500 Subject: [PATCH 043/104] one more time --- .travis.yml | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7ed55a2b..02d98fca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ python: # - "pypy" -- appears to hang # - "pypy3" # command to install dependencies -install: "pip install pipenv; pipenv install --global" +install: "pip install pipenv; pipenv install --system" # command to run tests script: - make coverage diff --git a/Makefile b/Makefile index f6d2adf8..7da216b4 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ test: pipenv run py.test tests coverage: - pipenv run py.test --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests + py.test --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests certs: curl http://ci.kennethreitz.org/job/ca-bundle/lastSuccessfulBuild/artifact/cacerts.pem -o requests/cacert.pem From c6973d31ca5490b6901aa82abd65873b1a1dd187 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 20:27:33 -0500 Subject: [PATCH 044/104] last attempt --- .travis.yml | 2 +- requirements.txt | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 requirements.txt diff --git a/.travis.yml b/.travis.yml index 02d98fca..ec3325db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ python: # - "pypy" -- appears to hang # - "pypy3" # command to install dependencies -install: "pip install pipenv; pipenv install --system" +install: "pip install pipenv; pipenv install --dev --system" # command to run tests script: - make coverage diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..9ead0172 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,29 @@ +alabaster==0.7.9 +Babel==2.3.4 +click==6.7 +codecov==2.0.5 +coverage==4.3.4 +decorator==4.0.11 +docutils==0.13.1 +Flask==0.12 +funcsigs==1.0.2 +httpbin==0.5.0 +imagesize==0.7.1 +itsdangerous==0.24 +Jinja2==2.9.4 +MarkupSafe==0.23 +mock==2.0.0 +pbr==1.10.0 +py==1.4.32 +Pygments==2.1.3 +PySocks==1.6.5 +pytest==3.0.5 +pytest-cov==2.4.0 +pytest-httpbin==0.2.3 +pytest-mock==1.5.0 +pytz==2016.10 +requests==2.12.5 +six==1.10.0 +snowballstemmer==1.2.1 +Sphinx==1.5.1 +Werkzeug==0.11.15 From c619bea72259b37f4e8d770204232f36c83aaed3 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 20:45:00 -0500 Subject: [PATCH 045/104] empty commit From 8ae576193ccc9ba9b4ec6fa75d0d72354ce865e0 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 20:45:04 -0500 Subject: [PATCH 046/104] empty commit From 2a2dd1389b73f231ea1cf74da538174b7486808d Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 20:50:20 -0500 Subject: [PATCH 047/104] empty commit From 358bb766d02bfa99e17902aa37718642cc061e0b Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 20:53:21 -0500 Subject: [PATCH 048/104] empty commit From 73018f40a3c3869e7e747181c55bcc33c21fe5e5 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 20:57:48 -0500 Subject: [PATCH 049/104] empty commit From 62b014560ae8c282c761e413a9d31c727fe4a462 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 21:03:46 -0500 Subject: [PATCH 050/104] use git --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ec3325db..d7cbcc96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ python: # - "pypy" -- appears to hang # - "pypy3" # command to install dependencies -install: "pip install pipenv; pipenv install --dev --system" +install: "pip install git+https://github.com/kennethreitz/pipenv.git; pipenv install --dev --system" # command to run tests script: - make coverage From 5eb2df1acf60640a21165dc66a76167cae18d83c Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 21:06:29 -0500 Subject: [PATCH 051/104] empty commit From 8f6e990066876d70728218b39ef7b07edde7ccaf Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 21:09:29 -0500 Subject: [PATCH 052/104] empty commit From 5b801847c4c14760cf0d50e9ada172303c708962 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 21:12:03 -0500 Subject: [PATCH 053/104] empty commit From 03d96aa9f7f53783bbac5002b2349c7b0725b495 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 21:19:25 -0500 Subject: [PATCH 054/104] empty commit From 9c67691b9041f6a74e18ed5a04e11d2fd6ffbac7 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 21:28:50 -0500 Subject: [PATCH 055/104] empty commit From ab3c21cf969fcde73458fac6041f54492b7e60cd Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 21:32:27 -0500 Subject: [PATCH 056/104] empty commit From ed9004f30eb9a521ac10fcdae75a2748a1efba3b Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 21:36:00 -0500 Subject: [PATCH 057/104] no need for this anymore! --- requirements.txt | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 9ead0172..00000000 --- a/requirements.txt +++ /dev/null @@ -1,29 +0,0 @@ -alabaster==0.7.9 -Babel==2.3.4 -click==6.7 -codecov==2.0.5 -coverage==4.3.4 -decorator==4.0.11 -docutils==0.13.1 -Flask==0.12 -funcsigs==1.0.2 -httpbin==0.5.0 -imagesize==0.7.1 -itsdangerous==0.24 -Jinja2==2.9.4 -MarkupSafe==0.23 -mock==2.0.0 -pbr==1.10.0 -py==1.4.32 -Pygments==2.1.3 -PySocks==1.6.5 -pytest==3.0.5 -pytest-cov==2.4.0 -pytest-httpbin==0.2.3 -pytest-mock==1.5.0 -pytz==2016.10 -requests==2.12.5 -six==1.10.0 -snowballstemmer==1.2.1 -Sphinx==1.5.1 -Werkzeug==0.11.15 From 97b5bc21d1f95bf31d12bfe52267e62f88f82f9b Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 21 Jan 2017 21:41:16 -0500 Subject: [PATCH 058/104] fix broken tests --- tests/test_requests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_requests.py b/tests/test_requests.py index b5705691..fd35103b 100755 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -632,7 +632,7 @@ class TestRequests: post1 = requests.post(url, data={'some': 'data'}) assert post1.status_code == 200 - with open('requirements.txt') as f: + with open('Pipfile') as f: post2 = requests.post(url, files={'some': f}) assert post2.status_code == 200 @@ -692,7 +692,7 @@ class TestRequests: post1 = requests.post(url, data={'some': 'data'}) assert post1.status_code == 200 - with open('requirements.txt') as f: + with open('Pipfile') as f: post2 = requests.post(url, data={'some': 'data'}, files={'some': f}) assert post2.status_code == 200 @@ -729,7 +729,7 @@ class TestRequests: def test_conflicting_post_params(self, httpbin): url = httpbin('post') - with open('requirements.txt') as f: + with open('Pipfile') as f: pytest.raises(ValueError, "requests.post(url, data='[{\"some\": \"data\"}]', files={'some': f})") pytest.raises(ValueError, "requests.post(url, data=u('[{\"some\": \"data\"}]'), files={'some': f})") From e32e7108d03b8dea58f953e9f5ce517239fd08f1 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 22 Jan 2017 00:44:04 -0500 Subject: [PATCH 059/104] trying this --- .travis.yml | 2 +- Makefile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d7cbcc96..b3352c70 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ python: # - "pypy" -- appears to hang # - "pypy3" # command to install dependencies -install: "pip install git+https://github.com/kennethreitz/pipenv.git; pipenv install --dev --system" +install: "make" # command to run tests script: - make coverage diff --git a/Makefile b/Makefile index 7da216b4..86251957 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: docs init: - pip install pipenv>=0.1.6 + pip install 'pipenv>=0.1.6' pipenv install --dev test: @@ -10,7 +10,7 @@ test: pipenv run py.test tests coverage: - py.test --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests + pipenv run py.test --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests certs: curl http://ci.kennethreitz.org/job/ca-bundle/lastSuccessfulBuild/artifact/cacerts.pem -o requests/cacert.pem From c7a4819c84eef36e1f13191f95fe82abd39a62cf Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 22 Jan 2017 17:38:21 -0500 Subject: [PATCH 060/104] Update README.rst --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index 1df00e0a..b417cfdb 100644 --- a/README.rst +++ b/README.rst @@ -4,6 +4,9 @@ Requests: HTTP for Humans .. image:: https://img.shields.io/pypi/v/requests.svg :target: https://pypi.python.org/pypi/requests +.. image:: https://img.shields.io/pypi/pyversions/requests.svg + :target: https://pypi.python.org/pypi/requests + .. image:: https://travis-ci.org/kennethreitz/requests.svg?branch=master :target: https://travis-ci.org/kennethreitz/requests From 304e4cb5ee9cf47bbeb5822336789ac9f5111ce9 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 22 Jan 2017 17:42:04 -0500 Subject: [PATCH 061/104] Update README.rst --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index b417cfdb..bfa5ef63 100644 --- a/README.rst +++ b/README.rst @@ -4,6 +4,9 @@ Requests: HTTP for Humans .. image:: https://img.shields.io/pypi/v/requests.svg :target: https://pypi.python.org/pypi/requests +.. image:: https://img.shields.io/pypi/l/requests.svg + :target: https://pypi.python.org/pypi/requests + .. image:: https://img.shields.io/pypi/pyversions/requests.svg :target: https://pypi.python.org/pypi/requests From df56f38bb44b256eadcec267c42366fe6726462b Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 22 Jan 2017 17:44:28 -0500 Subject: [PATCH 062/104] Update README.rst --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index bfa5ef63..34505538 100644 --- a/README.rst +++ b/README.rst @@ -7,6 +7,9 @@ Requests: HTTP for Humans .. image:: https://img.shields.io/pypi/l/requests.svg :target: https://pypi.python.org/pypi/requests +.. image:: https://img.shields.io/pypi/wheel/requests.svg + :target: https://pypi.python.org/pypi/requests + .. image:: https://img.shields.io/pypi/pyversions/requests.svg :target: https://pypi.python.org/pypi/requests From b5704a63ca335fa5d513083909fb8cc4aab23a91 Mon Sep 17 00:00:00 2001 From: Ian Cordasco Date: Tue, 24 Jan 2017 06:16:54 -0600 Subject: [PATCH 063/104] Update urllib3 to 1.20.0 Further, fix the Makefile to pull urllib3 from the release branch. git-describe works based on the most recent commit but all of the nearest commits in the graph for urllib3 are on the release branch (since the release branch is never merged back to master). --- Makefile | 2 +- requests/packages/urllib3/__init__.py | 2 +- requests/packages/urllib3/connection.py | 5 +- requests/packages/urllib3/connectionpool.py | 68 ++- .../packages/urllib3/contrib/pyopenssl.py | 39 +- requests/packages/urllib3/contrib/socks.py | 10 + requests/packages/urllib3/exceptions.py | 5 + requests/packages/urllib3/poolmanager.py | 2 +- requests/packages/urllib3/util/__init__.py | 6 + requests/packages/urllib3/util/connection.py | 31 +- requests/packages/urllib3/util/request.py | 48 +- requests/packages/urllib3/util/retry.py | 19 +- requests/packages/urllib3/util/selectors.py | 524 ++++++++++++++++++ requests/packages/urllib3/util/timeout.py | 7 +- requests/packages/urllib3/util/wait.py | 40 ++ 15 files changed, 742 insertions(+), 66 deletions(-) create mode 100644 requests/packages/urllib3/util/selectors.py create mode 100644 requests/packages/urllib3/util/wait.py diff --git a/Makefile b/Makefile index 86251957..4e3a149e 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ certs: deps: urllib3 chardet idna urllib3: - git clone https://github.com/shazow/urllib3.git && \ + git clone -b release https://github.com/shazow/urllib3.git && \ rm -fr requests/packages/urllib3 && \ cd urllib3 && \ git checkout `git describe --abbrev=0 --tags` && \ diff --git a/requests/packages/urllib3/__init__.py b/requests/packages/urllib3/__init__.py index 6afd39b4..ac3ff838 100644 --- a/requests/packages/urllib3/__init__.py +++ b/requests/packages/urllib3/__init__.py @@ -32,7 +32,7 @@ except ImportError: __author__ = 'Andrey Petrov (andrey.petrov@shazow.net)' __license__ = 'MIT' -__version__ = '1.19.1' +__version__ = '1.20' __all__ = ( 'HTTPConnectionPool', diff --git a/requests/packages/urllib3/connection.py b/requests/packages/urllib3/connection.py index e24f5e32..9f06c395 100644 --- a/requests/packages/urllib3/connection.py +++ b/requests/packages/urllib3/connection.py @@ -56,7 +56,10 @@ port_by_scheme = { 'https': 443, } -RECENT_DATE = datetime.date(2014, 1, 1) +# When updating RECENT_DATE, move it to +# within two years of the current date, and no +# earlier than 6 months ago. +RECENT_DATE = datetime.date(2016, 1, 1) class DummyConnection(object): diff --git a/requests/packages/urllib3/connectionpool.py b/requests/packages/urllib3/connectionpool.py index 19d08f23..b4f1166a 100644 --- a/requests/packages/urllib3/connectionpool.py +++ b/requests/packages/urllib3/connectionpool.py @@ -25,7 +25,7 @@ from .exceptions import ( ) from .packages.ssl_match_hostname import CertificateError from .packages import six -from .packages.six.moves.queue import LifoQueue, Empty, Full +from .packages.six.moves import queue from .connection import ( port_by_scheme, DummyConnection, @@ -36,6 +36,7 @@ from .request import RequestMethods from .response import HTTPResponse from .util.connection import is_connection_dropped +from .util.request import set_file_position from .util.response import assert_header_parsing from .util.retry import Retry from .util.timeout import Timeout @@ -61,19 +62,13 @@ class ConnectionPool(object): """ scheme = None - QueueCls = LifoQueue + QueueCls = queue.LifoQueue def __init__(self, host, port=None): if not host: raise LocationValueError("No host specified.") - # httplib doesn't like it when we include brackets in ipv6 addresses - # Specifically, if we include brackets but also pass the port then - # httplib crazily doubles up the square brackets on the Host header. - # Instead, we need to make sure we never pass ``None`` as the port. - # However, for backward compatibility reasons we can't actually - # *assert* that. - self.host = host.strip('[]') + self.host = _ipv6_host(host).lower() self.port = port def __str__(self): @@ -154,7 +149,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): A dictionary with proxy headers, should not be used directly, instead, see :class:`urllib3.connectionpool.ProxyManager`" - :param \**conn_kw: + :param \\**conn_kw: Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`, :class:`urllib3.connection.HTTPSConnection` instances. """ @@ -235,7 +230,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): except AttributeError: # self.pool is None raise ClosedPoolError(self, "Pool is closed.") - except Empty: + except queue.Empty: if self.block: raise EmptyPoolError(self, "Pool reached maximum size and no more " @@ -274,7 +269,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): except AttributeError: # self.pool is None. pass - except Full: + except queue.Full: # This should never happen if self.block == True log.warning( "Connection pool is full, discarding connection: %s", @@ -424,7 +419,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): if conn: conn.close() - except Empty: + except queue.Empty: pass # Done. def is_same_host(self, url): @@ -438,6 +433,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): # TODO: Add optional support for socket.gethostbyname checking. scheme, host, port = get_host(url) + host = _ipv6_host(host).lower() + # Use explicit default port for comparison when none is given if self.port and not port: port = port_by_scheme.get(scheme) @@ -449,7 +446,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): def urlopen(self, method, url, body=None, headers=None, retries=None, redirect=True, assert_same_host=True, timeout=_Default, pool_timeout=None, release_conn=None, chunked=False, - **response_kw): + body_pos=None, **response_kw): """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all @@ -531,7 +528,12 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. - :param \**response_kw: + :param int body_pos: + Position to seek to in file-like body in the event of a retry or + redirect. Typically this won't need to be set because urllib3 will + auto-populate the value when needed. + + :param \\**response_kw: Additional parameters are passed to :meth:`urllib3.response.HTTPResponse.from_httplib` """ @@ -576,6 +578,10 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): # ensures we do proper cleanup in finally. clean_exit = False + # Rewind body position, if needed. Record current position + # for future rewinds in the event of a redirect/retry. + body_pos = set_file_position(body, body_pos) + try: # Request a connection from the queue. timeout_obj = self._get_timeout(timeout) @@ -612,7 +618,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): # Everything went great! clean_exit = True - except Empty: + except queue.Empty: # Timed out by queue. raise EmptyPoolError(self, "No pool connections are available.") @@ -668,7 +674,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): return self.urlopen(method, url, body, headers, retries, redirect, assert_same_host, timeout=timeout, pool_timeout=pool_timeout, - release_conn=release_conn, **response_kw) + release_conn=release_conn, body_pos=body_pos, + **response_kw) # Handle redirect? redirect_location = redirect and response.get_redirect_location() @@ -693,7 +700,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): retries=retries, redirect=redirect, assert_same_host=assert_same_host, timeout=timeout, pool_timeout=pool_timeout, - release_conn=release_conn, **response_kw) + release_conn=release_conn, body_pos=body_pos, + **response_kw) # Check if we should retry the HTTP response. has_retry_after = bool(response.getheader('Retry-After')) @@ -714,7 +722,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): retries=retries, redirect=redirect, assert_same_host=assert_same_host, timeout=timeout, pool_timeout=pool_timeout, - release_conn=release_conn, **response_kw) + release_conn=release_conn, + body_pos=body_pos, **response_kw) return response @@ -853,7 +862,7 @@ def connection_from_url(url, **kw): :param url: Absolute URL string that must include the scheme. Port is optional. - :param \**kw: + :param \\**kw: Passes additional parameters to the constructor of the appropriate :class:`.ConnectionPool`. Useful for specifying things like timeout, maxsize, headers, etc. @@ -869,3 +878,22 @@ def connection_from_url(url, **kw): return HTTPSConnectionPool(host, port=port, **kw) else: return HTTPConnectionPool(host, port=port, **kw) + + +def _ipv6_host(host): + """ + Process IPv6 address literals + """ + + # httplib doesn't like it when we include brackets in IPv6 addresses + # Specifically, if we include brackets but also pass the port then + # httplib crazily doubles up the square brackets on the Host header. + # Instead, we need to make sure we never pass ``None`` as the port. + # However, for backward compatibility reasons we can't actually + # *assert* that. See http://bugs.python.org/issue28539 + # + # Also if an IPv6 address literal has a zone identifier, the + # percent sign might be URIencoded, convert it back into ASCII + if host.startswith('[') and host.endswith(']'): + host = host.replace('%25', '%').strip('[]') + return host diff --git a/requests/packages/urllib3/contrib/pyopenssl.py b/requests/packages/urllib3/contrib/pyopenssl.py index c6db25d4..eb4d4765 100644 --- a/requests/packages/urllib3/contrib/pyopenssl.py +++ b/requests/packages/urllib3/contrib/pyopenssl.py @@ -43,7 +43,6 @@ set the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable. """ from __future__ import absolute_import -import idna import OpenSSL.SSL from cryptography import x509 from cryptography.hazmat.backends.openssl import backend as openssl_backend @@ -60,7 +59,6 @@ except ImportError: # Platform-specific: Python 3 import logging import ssl -import select import six import sys @@ -111,6 +109,8 @@ log = logging.getLogger(__name__) def inject_into_urllib3(): 'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.' + _validate_dependencies_met() + util.ssl_.SSLContext = PyOpenSSLContext util.HAS_SNI = HAS_SNI util.ssl_.HAS_SNI = HAS_SNI @@ -128,6 +128,26 @@ def extract_from_urllib3(): util.ssl_.IS_PYOPENSSL = False +def _validate_dependencies_met(): + """ + Verifies that PyOpenSSL's package-level dependencies have been met. + Throws `ImportError` if they are not met. + """ + # Method added in `cryptography==1.1`; not available in older versions + from cryptography.x509.extensions import Extensions + if getattr(Extensions, "get_extension_for_class", None) is None: + raise ImportError("'cryptography' module missing required functionality. " + "Try upgrading to v1.3.4 or newer.") + + # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509 + # attribute is only present on those versions. + from OpenSSL.crypto import X509 + x509 = X509() + if getattr(x509, "_x509", None) is None: + raise ImportError("'pyOpenSSL' module missing required functionality. " + "Try upgrading to v0.14 or newer.") + + def _dnsname_to_stdlib(name): """ Converts a dNSName SubjectAlternativeName field to the form used by the @@ -144,6 +164,8 @@ def _dnsname_to_stdlib(name): that we can't just safely call `idna.encode`: it can explode for wildcard names. This avoids that problem. """ + import idna + for prefix in [u'*.', u'.']: if name.startswith(prefix): name = name[len(prefix):] @@ -242,8 +264,7 @@ class WrappedSocket(object): else: raise except OpenSSL.SSL.WantReadError: - rd, wd, ed = select.select( - [self.socket], [], [], self.socket.gettimeout()) + rd = util.wait_for_read(self.socket, self.socket.gettimeout()) if not rd: raise timeout('The read operation timed out') else: @@ -265,8 +286,7 @@ class WrappedSocket(object): else: raise except OpenSSL.SSL.WantReadError: - rd, wd, ed = select.select( - [self.socket], [], [], self.socket.gettimeout()) + rd = util.wait_for_read(self.socket, self.socket.gettimeout()) if not rd: raise timeout('The read operation timed out') else: @@ -280,9 +300,8 @@ class WrappedSocket(object): try: return self.connection.send(data) except OpenSSL.SSL.WantWriteError: - _, wlist, _ = select.select([], [self.socket], [], - self.socket.gettimeout()) - if not wlist: + wr = util.wait_for_write(self.socket, self.socket.gettimeout()) + if not wr: raise timeout() continue @@ -416,7 +435,7 @@ class PyOpenSSLContext(object): try: cnx.do_handshake() except OpenSSL.SSL.WantReadError: - rd, _, _ = select.select([sock], [], [], sock.gettimeout()) + rd = util.wait_for_read(sock, sock.gettimeout()) if not rd: raise timeout('select timed out') continue diff --git a/requests/packages/urllib3/contrib/socks.py b/requests/packages/urllib3/contrib/socks.py index c8fa8409..39e92fde 100644 --- a/requests/packages/urllib3/contrib/socks.py +++ b/requests/packages/urllib3/contrib/socks.py @@ -83,6 +83,7 @@ class SOCKSConnection(HTTPConnection): proxy_port=self._socks_options['proxy_port'], proxy_username=self._socks_options['username'], proxy_password=self._socks_options['password'], + proxy_rdns=self._socks_options['rdns'], timeout=self.timeout, **extra_kw ) @@ -153,8 +154,16 @@ class SOCKSProxyManager(PoolManager): if parsed.scheme == 'socks5': socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = False + elif parsed.scheme == 'socks5h': + socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = True elif parsed.scheme == 'socks4': socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = False + elif parsed.scheme == 'socks4a': + socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = True else: raise ValueError( "Unable to determine SOCKS version from %s" % proxy_url @@ -168,6 +177,7 @@ class SOCKSProxyManager(PoolManager): 'proxy_port': parsed.port, 'username': username, 'password': password, + 'rdns': rdns } connection_pool_kw['_socks_options'] = socks_options diff --git a/requests/packages/urllib3/exceptions.py b/requests/packages/urllib3/exceptions.py index 8a091c17..6c4be581 100644 --- a/requests/packages/urllib3/exceptions.py +++ b/requests/packages/urllib3/exceptions.py @@ -239,3 +239,8 @@ class HeaderParsingError(HTTPError): def __init__(self, defects, unparsed_data): message = '%s, unparsed data: %r' % (defects or 'Unknown', unparsed_data) super(HeaderParsingError, self).__init__(message) + + +class UnrewindableBodyError(HTTPError): + "urllib3 encountered an error when trying to rewind a body" + pass diff --git a/requests/packages/urllib3/poolmanager.py b/requests/packages/urllib3/poolmanager.py index 276b54dd..cc5a00e4 100644 --- a/requests/packages/urllib3/poolmanager.py +++ b/requests/packages/urllib3/poolmanager.py @@ -93,7 +93,7 @@ class PoolManager(RequestMethods): Headers to include with all requests, unless other headers are given explicitly. - :param \**connection_pool_kw: + :param \\**connection_pool_kw: Additional parameters are used to create fresh :class:`urllib3.connectionpool.ConnectionPool` instances. diff --git a/requests/packages/urllib3/util/__init__.py b/requests/packages/urllib3/util/__init__.py index 4778cf99..5ced5a44 100644 --- a/requests/packages/urllib3/util/__init__.py +++ b/requests/packages/urllib3/util/__init__.py @@ -24,6 +24,10 @@ from .url import ( split_first, Url, ) +from .wait import ( + wait_for_read, + wait_for_write +) __all__ = ( 'HAS_SNI', @@ -43,4 +47,6 @@ __all__ = ( 'resolve_ssl_version', 'split_first', 'ssl_wrap_socket', + 'wait_for_read', + 'wait_for_write' ) diff --git a/requests/packages/urllib3/util/connection.py b/requests/packages/urllib3/util/connection.py index 3d608772..bf699cfd 100644 --- a/requests/packages/urllib3/util/connection.py +++ b/requests/packages/urllib3/util/connection.py @@ -1,13 +1,7 @@ from __future__ import absolute_import import socket -try: - from select import poll, POLLIN -except ImportError: # `poll` doesn't exist on OSX and other platforms - poll = False - try: - from select import select - except ImportError: # `select` doesn't exist on AppEngine. - select = False +from .wait import wait_for_read +from .selectors import HAS_SELECT, SelectorError def is_connection_dropped(conn): # Platform-specific @@ -26,22 +20,13 @@ def is_connection_dropped(conn): # Platform-specific if sock is None: # Connection already closed (such as by httplib). return True - if not poll: - if not select: # Platform-specific: AppEngine - return False + if not HAS_SELECT: + return False - try: - return select([sock], [], [], 0.0)[0] - except socket.error: - return True - - # This version is better on platforms that support it. - p = poll() - p.register(sock, POLLIN) - for (fno, ev) in p.poll(0.0): - if fno == sock.fileno(): - # Either data is buffered (bad), or the connection is dropped. - return True + try: + return bool(wait_for_read(sock, timeout=0.0)) + except SelectorError: + return True # This function is copied from socket.py in the Python 2.7 standard diff --git a/requests/packages/urllib3/util/request.py b/requests/packages/urllib3/util/request.py index 73779315..974fc40a 100644 --- a/requests/packages/urllib3/util/request.py +++ b/requests/packages/urllib3/util/request.py @@ -1,9 +1,11 @@ from __future__ import absolute_import from base64 import b64encode -from ..packages.six import b +from ..packages.six import b, integer_types +from ..exceptions import UnrewindableBodyError ACCEPT_ENCODING = 'gzip,deflate' +_FAILEDTELL = object() def make_headers(keep_alive=None, accept_encoding=None, user_agent=None, @@ -70,3 +72,47 @@ def make_headers(keep_alive=None, accept_encoding=None, user_agent=None, headers['cache-control'] = 'no-cache' return headers + + +def set_file_position(body, pos): + """ + If a position is provided, move file to that point. + Otherwise, we'll attempt to record a position for future use. + """ + if pos is not None: + rewind_body(body, pos) + elif getattr(body, 'tell', None) is not None: + try: + pos = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body. + pos = _FAILEDTELL + + return pos + + +def rewind_body(body, body_pos): + """ + Attempt to rewind body to a certain position. + Primarily used for request redirects and retries. + + :param body: + File-like object that supports seek. + + :param int pos: + Position to seek to in file. + """ + body_seek = getattr(body, 'seek', None) + if body_seek is not None and isinstance(body_pos, integer_types): + try: + body_seek(body_pos) + except (IOError, OSError): + raise UnrewindableBodyError("An error occured when rewinding request " + "body for redirect/retry.") + elif body_pos is _FAILEDTELL: + raise UnrewindableBodyError("Unable to record file position for rewinding " + "request body during a redirect/retry.") + else: + raise ValueError("body_pos must be of type integer, " + "instead it was %s." % type(body_pos)) diff --git a/requests/packages/urllib3/util/retry.py b/requests/packages/urllib3/util/retry.py index 47ad539a..c9e7d287 100644 --- a/requests/packages/urllib3/util/retry.py +++ b/requests/packages/urllib3/util/retry.py @@ -273,12 +273,25 @@ class Retry(object): """ return isinstance(err, (ReadTimeoutError, ProtocolError)) - def is_retry(self, method, status_code, has_retry_after=False): - """ Is this method/status code retryable? (Based on method/codes whitelists) + def _is_method_retryable(self, method): + """ Checks if a given HTTP method should be retried upon, depending if + it is included on the method whitelist. """ if self.method_whitelist and method.upper() not in self.method_whitelist: return False + return True + + def is_retry(self, method, status_code, has_retry_after=False): + """ Is this method/status code retryable? (Based on whitelists and control + variables such as the number of total retries to allow, whether to + respect the Retry-After header, whether this header is present, and + whether the returned status code is on the list of status codes to + be retried upon on the presence of the aforementioned header) + """ + if not self._is_method_retryable(method): + return False + if self.status_forcelist and status_code in self.status_forcelist: return True @@ -330,7 +343,7 @@ class Retry(object): elif error and self._is_read_error(error): # Read retry? - if read is False: + if read is False or not self._is_method_retryable(method): raise six.reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 diff --git a/requests/packages/urllib3/util/selectors.py b/requests/packages/urllib3/util/selectors.py new file mode 100644 index 00000000..51208b69 --- /dev/null +++ b/requests/packages/urllib3/util/selectors.py @@ -0,0 +1,524 @@ +# Backport of selectors.py from Python 3.5+ to support Python < 3.4 +# Also has the behavior specified in PEP 475 which is to retry syscalls +# in the case of an EINTR error. This module is required because selectors34 +# does not follow this behavior and instead returns that no dile descriptor +# events have occurred rather than retry the syscall. The decision to drop +# support for select.devpoll is made to maintain 100% test coverage. + +import errno +import math +import select +from collections import namedtuple, Mapping + +import time +try: + monotonic = time.monotonic +except (AttributeError, ImportError): # Python 3.3< + monotonic = time.time + +EVENT_READ = (1 << 0) +EVENT_WRITE = (1 << 1) + +HAS_SELECT = True # Variable that shows whether the platform has a selector. +_SYSCALL_SENTINEL = object() # Sentinel in case a system call returns None. + + +class SelectorError(Exception): + def __init__(self, errcode): + super(SelectorError, self).__init__() + self.errno = errcode + + def __repr__(self): + return "".format(self.errno) + + def __str__(self): + return self.__repr__() + + +def _fileobj_to_fd(fileobj): + """ Return a file descriptor from a file object. If + given an integer will simply return that integer back. """ + if isinstance(fileobj, int): + fd = fileobj + else: + try: + fd = int(fileobj.fileno()) + except (AttributeError, TypeError, ValueError): + raise ValueError("Invalid file object: {0!r}".format(fileobj)) + if fd < 0: + raise ValueError("Invalid file descriptor: {0}".format(fd)) + return fd + + +def _syscall_wrapper(func, recalc_timeout, *args, **kwargs): + """ Wrapper function for syscalls that could fail due to EINTR. + All functions should be retried if there is time left in the timeout + in accordance with PEP 475. """ + timeout = kwargs.get("timeout", None) + if timeout is None: + expires = None + recalc_timeout = False + else: + timeout = float(timeout) + if timeout < 0.0: # Timeout less than 0 treated as no timeout. + expires = None + else: + expires = monotonic() + timeout + + args = list(args) + if recalc_timeout and "timeout" not in kwargs: + raise ValueError( + "Timeout must be in args or kwargs to be recalculated") + + result = _SYSCALL_SENTINEL + while result is _SYSCALL_SENTINEL: + try: + result = func(*args, **kwargs) + # OSError is thrown by select.select + # IOError is thrown by select.epoll.poll + # select.error is thrown by select.poll.poll + # Aren't we thankful for Python 3.x rework for exceptions? + except (OSError, IOError, select.error) as e: + # select.error wasn't a subclass of OSError in the past. + errcode = None + if hasattr(e, "errno"): + errcode = e.errno + elif hasattr(e, "args"): + errcode = e.args[0] + + # Also test for the Windows equivalent of EINTR. + is_interrupt = (errcode == errno.EINTR or (hasattr(errno, "WSAEINTR") and + errcode == errno.WSAEINTR)) + + if is_interrupt: + if expires is not None: + current_time = monotonic() + if current_time > expires: + raise OSError(errno=errno.ETIMEDOUT) + if recalc_timeout: + if "timeout" in kwargs: + kwargs["timeout"] = expires - current_time + continue + if errcode: + raise SelectorError(errcode) + else: + raise + return result + + +SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data']) + + +class _SelectorMapping(Mapping): + """ Mapping of file objects to selector keys """ + + def __init__(self, selector): + self._selector = selector + + def __len__(self): + return len(self._selector._fd_to_key) + + def __getitem__(self, fileobj): + try: + fd = self._selector._fileobj_lookup(fileobj) + return self._selector._fd_to_key[fd] + except KeyError: + raise KeyError("{0!r} is not registered.".format(fileobj)) + + def __iter__(self): + return iter(self._selector._fd_to_key) + + +class BaseSelector(object): + """ Abstract Selector class + + A selector supports registering file objects to be monitored + for specific I/O events. + + A file object is a file descriptor or any object with a + `fileno()` method. An arbitrary object can be attached to the + file object which can be used for example to store context info, + a callback, etc. + + A selector can use various implementations (select(), poll(), epoll(), + and kqueue()) depending on the platform. The 'DefaultSelector' class uses + the most efficient implementation for the current platform. + """ + def __init__(self): + # Maps file descriptors to keys. + self._fd_to_key = {} + + # Read-only mapping returned by get_map() + self._map = _SelectorMapping(self) + + def _fileobj_lookup(self, fileobj): + """ Return a file descriptor from a file object. + This wraps _fileobj_to_fd() to do an exhaustive + search in case the object is invalid but we still + have it in our map. Used by unregister() so we can + unregister an object that was previously registered + even if it is closed. It is also used by _SelectorMapping + """ + try: + return _fileobj_to_fd(fileobj) + except ValueError: + + # Search through all our mapped keys. + for key in self._fd_to_key.values(): + if key.fileobj is fileobj: + return key.fd + + # Raise ValueError after all. + raise + + def register(self, fileobj, events, data=None): + """ Register a file object for a set of events to monitor. """ + if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)): + raise ValueError("Invalid events: {0!r}".format(events)) + + key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data) + + if key.fd in self._fd_to_key: + raise KeyError("{0!r} (FD {1}) is already registered" + .format(fileobj, key.fd)) + + self._fd_to_key[key.fd] = key + return key + + def unregister(self, fileobj): + """ Unregister a file object from being monitored. """ + try: + key = self._fd_to_key.pop(self._fileobj_lookup(fileobj)) + except KeyError: + raise KeyError("{0!r} is not registered".format(fileobj)) + return key + + def modify(self, fileobj, events, data=None): + """ Change a registered file object monitored events and data. """ + # NOTE: Some subclasses optimize this operation even further. + try: + key = self._fd_to_key[self._fileobj_lookup(fileobj)] + except KeyError: + raise KeyError("{0!r} is not registered".format(fileobj)) + + if events != key.events: + self.unregister(fileobj) + key = self.register(fileobj, events, data) + + elif data != key.data: + # Use a shortcut to update the data. + key = key._replace(data=data) + self._fd_to_key[key.fd] = key + + return key + + def select(self, timeout=None): + """ Perform the actual selection until some monitored file objects + are ready or the timeout expires. """ + raise NotImplementedError() + + def close(self): + """ Close the selector. This must be called to ensure that all + underlying resources are freed. """ + self._fd_to_key.clear() + self._map = None + + def get_key(self, fileobj): + """ Return the key associated with a registered file object. """ + mapping = self.get_map() + if mapping is None: + raise RuntimeError("Selector is closed") + try: + return mapping[fileobj] + except KeyError: + raise KeyError("{0!r} is not registered".format(fileobj)) + + def get_map(self): + """ Return a mapping of file objects to selector keys """ + return self._map + + def _key_from_fd(self, fd): + """ Return the key associated to a given file descriptor + Return None if it is not found. """ + try: + return self._fd_to_key[fd] + except KeyError: + return None + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + +# Almost all platforms have select.select() +if hasattr(select, "select"): + class SelectSelector(BaseSelector): + """ Select-based selector. """ + def __init__(self): + super(SelectSelector, self).__init__() + self._readers = set() + self._writers = set() + + def register(self, fileobj, events, data=None): + key = super(SelectSelector, self).register(fileobj, events, data) + if events & EVENT_READ: + self._readers.add(key.fd) + if events & EVENT_WRITE: + self._writers.add(key.fd) + return key + + def unregister(self, fileobj): + key = super(SelectSelector, self).unregister(fileobj) + self._readers.discard(key.fd) + self._writers.discard(key.fd) + return key + + def _select(self, r, w, timeout=None): + """ Wrapper for select.select because timeout is a positional arg """ + return select.select(r, w, [], timeout) + + def select(self, timeout=None): + # Selecting on empty lists on Windows errors out. + if not len(self._readers) and not len(self._writers): + return [] + + timeout = None if timeout is None else max(timeout, 0.0) + ready = [] + r, w, _ = _syscall_wrapper(self._select, True, self._readers, + self._writers, timeout) + r = set(r) + w = set(w) + for fd in r | w: + events = 0 + if fd in r: + events |= EVENT_READ + if fd in w: + events |= EVENT_WRITE + + key = self._key_from_fd(fd) + if key: + ready.append((key, events & key.events)) + return ready + + +if hasattr(select, "poll"): + class PollSelector(BaseSelector): + """ Poll-based selector """ + def __init__(self): + super(PollSelector, self).__init__() + self._poll = select.poll() + + def register(self, fileobj, events, data=None): + key = super(PollSelector, self).register(fileobj, events, data) + event_mask = 0 + if events & EVENT_READ: + event_mask |= select.POLLIN + if events & EVENT_WRITE: + event_mask |= select.POLLOUT + self._poll.register(key.fd, event_mask) + return key + + def unregister(self, fileobj): + key = super(PollSelector, self).unregister(fileobj) + self._poll.unregister(key.fd) + return key + + def _wrap_poll(self, timeout=None): + """ Wrapper function for select.poll.poll() so that + _syscall_wrapper can work with only seconds. """ + if timeout is not None: + if timeout <= 0: + timeout = 0 + else: + # select.poll.poll() has a resolution of 1 millisecond, + # round away from zero to wait *at least* timeout seconds. + timeout = math.ceil(timeout * 1e3) + + result = self._poll.poll(timeout) + return result + + def select(self, timeout=None): + ready = [] + fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout) + for fd, event_mask in fd_events: + events = 0 + if event_mask & ~select.POLLIN: + events |= EVENT_WRITE + if event_mask & ~select.POLLOUT: + events |= EVENT_READ + + key = self._key_from_fd(fd) + if key: + ready.append((key, events & key.events)) + + return ready + + +if hasattr(select, "epoll"): + class EpollSelector(BaseSelector): + """ Epoll-based selector """ + def __init__(self): + super(EpollSelector, self).__init__() + self._epoll = select.epoll() + + def fileno(self): + return self._epoll.fileno() + + def register(self, fileobj, events, data=None): + key = super(EpollSelector, self).register(fileobj, events, data) + events_mask = 0 + if events & EVENT_READ: + events_mask |= select.EPOLLIN + if events & EVENT_WRITE: + events_mask |= select.EPOLLOUT + _syscall_wrapper(self._epoll.register, False, key.fd, events_mask) + return key + + def unregister(self, fileobj): + key = super(EpollSelector, self).unregister(fileobj) + try: + _syscall_wrapper(self._epoll.unregister, False, key.fd) + except SelectorError: + # This can occur when the fd was closed since registry. + pass + return key + + def select(self, timeout=None): + if timeout is not None: + if timeout <= 0: + timeout = 0.0 + else: + # select.epoll.poll() has a resolution of 1 millisecond + # but luckily takes seconds so we don't need a wrapper + # like PollSelector. Just for better rounding. + timeout = math.ceil(timeout * 1e3) * 1e-3 + timeout = float(timeout) + else: + timeout = -1.0 # epoll.poll() must have a float. + + # We always want at least 1 to ensure that select can be called + # with no file descriptors registered. Otherwise will fail. + max_events = max(len(self._fd_to_key), 1) + + ready = [] + fd_events = _syscall_wrapper(self._epoll.poll, True, + timeout=timeout, + maxevents=max_events) + for fd, event_mask in fd_events: + events = 0 + if event_mask & ~select.EPOLLIN: + events |= EVENT_WRITE + if event_mask & ~select.EPOLLOUT: + events |= EVENT_READ + + key = self._key_from_fd(fd) + if key: + ready.append((key, events & key.events)) + return ready + + def close(self): + self._epoll.close() + super(EpollSelector, self).close() + + +if hasattr(select, "kqueue"): + class KqueueSelector(BaseSelector): + """ Kqueue / Kevent-based selector """ + def __init__(self): + super(KqueueSelector, self).__init__() + self._kqueue = select.kqueue() + + def fileno(self): + return self._kqueue.fileno() + + def register(self, fileobj, events, data=None): + key = super(KqueueSelector, self).register(fileobj, events, data) + if events & EVENT_READ: + kevent = select.kevent(key.fd, + select.KQ_FILTER_READ, + select.KQ_EV_ADD) + + _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0) + + if events & EVENT_WRITE: + kevent = select.kevent(key.fd, + select.KQ_FILTER_WRITE, + select.KQ_EV_ADD) + + _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0) + + return key + + def unregister(self, fileobj): + key = super(KqueueSelector, self).unregister(fileobj) + if key.events & EVENT_READ: + kevent = select.kevent(key.fd, + select.KQ_FILTER_READ, + select.KQ_EV_DELETE) + try: + _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0) + except SelectorError: + pass + if key.events & EVENT_WRITE: + kevent = select.kevent(key.fd, + select.KQ_FILTER_WRITE, + select.KQ_EV_DELETE) + try: + _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0) + except SelectorError: + pass + + return key + + def select(self, timeout=None): + if timeout is not None: + timeout = max(timeout, 0) + + max_events = len(self._fd_to_key) * 2 + ready_fds = {} + + kevent_list = _syscall_wrapper(self._kqueue.control, True, + None, max_events, timeout) + + for kevent in kevent_list: + fd = kevent.ident + event_mask = kevent.filter + events = 0 + if event_mask == select.KQ_FILTER_READ: + events |= EVENT_READ + if event_mask == select.KQ_FILTER_WRITE: + events |= EVENT_WRITE + + key = self._key_from_fd(fd) + if key: + if key.fd not in ready_fds: + ready_fds[key.fd] = (key, events & key.events) + else: + old_events = ready_fds[key.fd][1] + ready_fds[key.fd] = (key, (events | old_events) & key.events) + + return list(ready_fds.values()) + + def close(self): + self._kqueue.close() + super(KqueueSelector, self).close() + + +# Choose the best implementation, roughly: +# kqueue == epoll > poll > select. Devpoll not supported. (See above) +# select() also can't accept a FD > FD_SETSIZE (usually around 1024) +if 'KqueueSelector' in globals(): # Platform-specific: Mac OS and BSD + DefaultSelector = KqueueSelector +elif 'EpollSelector' in globals(): # Platform-specific: Linux + DefaultSelector = EpollSelector +elif 'PollSelector' in globals(): # Platform-specific: Linux + DefaultSelector = PollSelector +elif 'SelectSelector' in globals(): # Platform-specific: Windows + DefaultSelector = SelectSelector +else: # Platform-specific: AppEngine + def no_selector(_): + raise ValueError("Platform does not have a selector") + DefaultSelector = no_selector + HAS_SELECT = False diff --git a/requests/packages/urllib3/util/timeout.py b/requests/packages/urllib3/util/timeout.py index 1eaa6a35..cec817e6 100644 --- a/requests/packages/urllib3/util/timeout.py +++ b/requests/packages/urllib3/util/timeout.py @@ -11,11 +11,8 @@ from ..exceptions import TimeoutStateError _Default = object() -def current_time(): - """ - Retrieve the current time. This function is mocked out in unit testing. - """ - return time.time() +# Use time.monotonic if available. +current_time = getattr(time, "monotonic", time.time) class Timeout(object): diff --git a/requests/packages/urllib3/util/wait.py b/requests/packages/urllib3/util/wait.py new file mode 100644 index 00000000..cb396e50 --- /dev/null +++ b/requests/packages/urllib3/util/wait.py @@ -0,0 +1,40 @@ +from .selectors import ( + HAS_SELECT, + DefaultSelector, + EVENT_READ, + EVENT_WRITE +) + + +def _wait_for_io_events(socks, events, timeout=None): + """ Waits for IO events to be available from a list of sockets + or optionally a single socket if passed in. Returns a list of + sockets that can be interacted with immediately. """ + if not HAS_SELECT: + raise ValueError('Platform does not have a selector') + if not isinstance(socks, list): + # Probably just a single socket. + if hasattr(socks, "fileno"): + socks = [socks] + # Otherwise it might be a non-list iterable. + else: + socks = list(socks) + with DefaultSelector() as selector: + for sock in socks: + selector.register(sock, events) + return [key[0].fileobj for key in + selector.select(timeout) if key[1] & events] + + +def wait_for_read(socks, timeout=None): + """ Waits for reading to be available from a list of sockets + or optionally a single socket if passed in. Returns a list of + sockets that can be read from immediately. """ + return _wait_for_io_events(socks, EVENT_READ, timeout) + + +def wait_for_write(socks, timeout=None): + """ Waits for writing to be available from a list of sockets + or optionally a single socket if passed in. Returns a list of + sockets that can be written to immediately. """ + return _wait_for_io_events(socks, EVENT_WRITE, timeout) From af1b542e200047c1285f74192e3977c616d9e72f Mon Sep 17 00:00:00 2001 From: Ian Cordasco Date: Tue, 24 Jan 2017 06:20:44 -0600 Subject: [PATCH 064/104] Update idna to v2.2.0 --- requests/packages/idna/uts46data.py | 368 +++++++++++++++++++++++++++- 1 file changed, 367 insertions(+), 1 deletion(-) diff --git a/requests/packages/idna/uts46data.py b/requests/packages/idna/uts46data.py index 64e2c687..48da8408 100644 --- a/requests/packages/idna/uts46data.py +++ b/requests/packages/idna/uts46data.py @@ -3,7 +3,9 @@ """IDNA Mapping Table from UTS46.""" -uts46data = ( + +def _seg_0(): + return [ (0x0, '3'), (0x1, '3'), (0x2, '3'), @@ -104,6 +106,10 @@ uts46data = ( (0x61, 'V'), (0x62, 'V'), (0x63, 'V'), + ] + +def _seg_1(): + return [ (0x64, 'V'), (0x65, 'V'), (0x66, 'V'), @@ -204,6 +210,10 @@ uts46data = ( (0xC5, 'M', u'å'), (0xC6, 'M', u'æ'), (0xC7, 'M', u'ç'), + ] + +def _seg_2(): + return [ (0xC8, 'M', u'è'), (0xC9, 'M', u'é'), (0xCA, 'M', u'ê'), @@ -304,6 +314,10 @@ uts46data = ( (0x129, 'V'), (0x12A, 'M', u'ī'), (0x12B, 'V'), + ] + +def _seg_3(): + return [ (0x12C, 'M', u'ĭ'), (0x12D, 'V'), (0x12E, 'M', u'į'), @@ -404,6 +418,10 @@ uts46data = ( (0x191, 'M', u'ƒ'), (0x192, 'V'), (0x193, 'M', u'ɠ'), + ] + +def _seg_4(): + return [ (0x194, 'M', u'ɣ'), (0x195, 'V'), (0x196, 'M', u'ɩ'), @@ -504,6 +522,10 @@ uts46data = ( (0x20A, 'M', u'ȋ'), (0x20B, 'V'), (0x20C, 'M', u'ȍ'), + ] + +def _seg_5(): + return [ (0x20D, 'V'), (0x20E, 'M', u'ȏ'), (0x20F, 'V'), @@ -604,6 +626,10 @@ uts46data = ( (0x375, 'V'), (0x376, 'M', u'ͷ'), (0x377, 'V'), + ] + +def _seg_6(): + return [ (0x378, 'X'), (0x37A, '3', u' ι'), (0x37B, 'V'), @@ -704,6 +730,10 @@ uts46data = ( (0x401, 'M', u'ё'), (0x402, 'M', u'ђ'), (0x403, 'M', u'ѓ'), + ] + +def _seg_7(): + return [ (0x404, 'M', u'є'), (0x405, 'M', u'ѕ'), (0x406, 'M', u'і'), @@ -804,6 +834,10 @@ uts46data = ( (0x49C, 'M', u'ҝ'), (0x49D, 'V'), (0x49E, 'M', u'ҟ'), + ] + +def _seg_8(): + return [ (0x49F, 'V'), (0x4A0, 'M', u'ҡ'), (0x4A1, 'V'), @@ -904,6 +938,10 @@ uts46data = ( (0x501, 'V'), (0x502, 'M', u'ԃ'), (0x503, 'V'), + ] + +def _seg_9(): + return [ (0x504, 'M', u'ԅ'), (0x505, 'V'), (0x506, 'M', u'ԇ'), @@ -1004,6 +1042,10 @@ uts46data = ( (0x678, 'M', u'يٴ'), (0x679, 'V'), (0x6DD, 'X'), + ] + +def _seg_10(): + return [ (0x6DE, 'V'), (0x70E, 'X'), (0x710, 'V'), @@ -1104,6 +1146,10 @@ uts46data = ( (0xA5D, 'X'), (0xA5E, 'M', u'ਫ਼'), (0xA5F, 'X'), + ] + +def _seg_11(): + return [ (0xA66, 'V'), (0xA76, 'X'), (0xA81, 'V'), @@ -1204,6 +1250,10 @@ uts46data = ( (0xC2A, 'V'), (0xC34, 'X'), (0xC35, 'V'), + ] + +def _seg_12(): + return [ (0xC3A, 'X'), (0xC3D, 'V'), (0xC45, 'X'), @@ -1304,6 +1354,10 @@ uts46data = ( (0xE84, 'V'), (0xE85, 'X'), (0xE87, 'V'), + ] + +def _seg_13(): + return [ (0xE89, 'X'), (0xE8A, 'V'), (0xE8B, 'X'), @@ -1404,6 +1458,10 @@ uts46data = ( (0x1250, 'V'), (0x1257, 'X'), (0x1258, 'V'), + ] + +def _seg_14(): + return [ (0x1259, 'X'), (0x125A, 'V'), (0x125E, 'X'), @@ -1504,6 +1562,10 @@ uts46data = ( (0x1A8A, 'X'), (0x1A90, 'V'), (0x1A9A, 'X'), + ] + +def _seg_15(): + return [ (0x1AA0, 'V'), (0x1AAE, 'X'), (0x1B00, 'V'), @@ -1604,6 +1666,10 @@ uts46data = ( (0x1DA7, 'M', u'ᵻ'), (0x1DA8, 'M', u'ʝ'), (0x1DA9, 'M', u'ɭ'), + ] + +def _seg_16(): + return [ (0x1DAA, 'M', u'ᶅ'), (0x1DAB, 'M', u'ʟ'), (0x1DAC, 'M', u'ɱ'), @@ -1704,6 +1770,10 @@ uts46data = ( (0x1E48, 'M', u'ṉ'), (0x1E49, 'V'), (0x1E4A, 'M', u'ṋ'), + ] + +def _seg_17(): + return [ (0x1E4B, 'V'), (0x1E4C, 'M', u'ṍ'), (0x1E4D, 'V'), @@ -1804,6 +1874,10 @@ uts46data = ( (0x1EB1, 'V'), (0x1EB2, 'M', u'ẳ'), (0x1EB3, 'V'), + ] + +def _seg_18(): + return [ (0x1EB4, 'M', u'ẵ'), (0x1EB5, 'V'), (0x1EB6, 'M', u'ặ'), @@ -1904,6 +1978,10 @@ uts46data = ( (0x1F2B, 'M', u'ἣ'), (0x1F2C, 'M', u'ἤ'), (0x1F2D, 'M', u'ἥ'), + ] + +def _seg_19(): + return [ (0x1F2E, 'M', u'ἦ'), (0x1F2F, 'M', u'ἧ'), (0x1F30, 'V'), @@ -2004,6 +2082,10 @@ uts46data = ( (0x1FAC, 'M', u'ὤι'), (0x1FAD, 'M', u'ὥι'), (0x1FAE, 'M', u'ὦι'), + ] + +def _seg_20(): + return [ (0x1FAF, 'M', u'ὧι'), (0x1FB0, 'V'), (0x1FB2, 'M', u'ὰι'), @@ -2104,6 +2186,10 @@ uts46data = ( (0x204A, 'V'), (0x2057, 'M', u'′′′′'), (0x2058, 'V'), + ] + +def _seg_21(): + return [ (0x205F, '3', u' '), (0x2060, 'I'), (0x2061, 'X'), @@ -2204,6 +2290,10 @@ uts46data = ( (0x2133, 'M', u'm'), (0x2134, 'M', u'o'), (0x2135, 'M', u'א'), + ] + +def _seg_22(): + return [ (0x2136, 'M', u'ב'), (0x2137, 'M', u'ג'), (0x2138, 'M', u'ד'), @@ -2304,6 +2394,10 @@ uts46data = ( (0x2469, 'M', u'10'), (0x246A, 'M', u'11'), (0x246B, 'M', u'12'), + ] + +def _seg_23(): + return [ (0x246C, 'M', u'13'), (0x246D, 'M', u'14'), (0x246E, 'M', u'15'), @@ -2404,6 +2498,10 @@ uts46data = ( (0x24E0, 'M', u'q'), (0x24E1, 'M', u'r'), (0x24E2, 'M', u's'), + ] + +def _seg_24(): + return [ (0x24E3, 'M', u't'), (0x24E4, 'M', u'u'), (0x24E5, 'M', u'v'), @@ -2504,6 +2602,10 @@ uts46data = ( (0x2C80, 'M', u'ⲁ'), (0x2C81, 'V'), (0x2C82, 'M', u'ⲃ'), + ] + +def _seg_25(): + return [ (0x2C83, 'V'), (0x2C84, 'M', u'ⲅ'), (0x2C85, 'V'), @@ -2604,6 +2706,10 @@ uts46data = ( (0x2CEB, 'M', u'ⳬ'), (0x2CEC, 'V'), (0x2CED, 'M', u'ⳮ'), + ] + +def _seg_26(): + return [ (0x2CEE, 'V'), (0x2CF2, 'M', u'ⳳ'), (0x2CF3, 'V'), @@ -2704,6 +2810,10 @@ uts46data = ( (0x2F37, 'M', u'弋'), (0x2F38, 'M', u'弓'), (0x2F39, 'M', u'彐'), + ] + +def _seg_27(): + return [ (0x2F3A, 'M', u'彡'), (0x2F3B, 'M', u'彳'), (0x2F3C, 'M', u'心'), @@ -2804,6 +2914,10 @@ uts46data = ( (0x2F9B, 'M', u'走'), (0x2F9C, 'M', u'足'), (0x2F9D, 'M', u'身'), + ] + +def _seg_28(): + return [ (0x2F9E, 'M', u'車'), (0x2F9F, 'M', u'辛'), (0x2FA0, 'M', u'辰'), @@ -2904,6 +3018,10 @@ uts46data = ( (0x3142, 'M', u'ᄇ'), (0x3143, 'M', u'ᄈ'), (0x3144, 'M', u'ᄡ'), + ] + +def _seg_29(): + return [ (0x3145, 'M', u'ᄉ'), (0x3146, 'M', u'ᄊ'), (0x3147, 'M', u'ᄋ'), @@ -3004,6 +3122,10 @@ uts46data = ( (0x3202, '3', u'(ᄃ)'), (0x3203, '3', u'(ᄅ)'), (0x3204, '3', u'(ᄆ)'), + ] + +def _seg_30(): + return [ (0x3205, '3', u'(ᄇ)'), (0x3206, '3', u'(ᄉ)'), (0x3207, '3', u'(ᄋ)'), @@ -3104,6 +3226,10 @@ uts46data = ( (0x326D, 'M', u'ᄒ'), (0x326E, 'M', u'가'), (0x326F, 'M', u'나'), + ] + +def _seg_31(): + return [ (0x3270, 'M', u'다'), (0x3271, 'M', u'라'), (0x3272, 'M', u'마'), @@ -3204,6 +3330,10 @@ uts46data = ( (0x32D1, 'M', u'イ'), (0x32D2, 'M', u'ウ'), (0x32D3, 'M', u'エ'), + ] + +def _seg_32(): + return [ (0x32D4, 'M', u'オ'), (0x32D5, 'M', u'カ'), (0x32D6, 'M', u'キ'), @@ -3304,6 +3434,10 @@ uts46data = ( (0x3335, 'M', u'フラン'), (0x3336, 'M', u'ヘクタール'), (0x3337, 'M', u'ペソ'), + ] + +def _seg_33(): + return [ (0x3338, 'M', u'ペニヒ'), (0x3339, 'M', u'ヘルツ'), (0x333A, 'M', u'ペンス'), @@ -3404,6 +3538,10 @@ uts46data = ( (0x3399, 'M', u'fm'), (0x339A, 'M', u'nm'), (0x339B, 'M', u'μm'), + ] + +def _seg_34(): + return [ (0x339C, 'M', u'mm'), (0x339D, 'M', u'cm'), (0x339E, 'M', u'km'), @@ -3504,6 +3642,10 @@ uts46data = ( (0x33FD, 'M', u'30日'), (0x33FE, 'M', u'31日'), (0x33FF, 'M', u'gal'), + ] + +def _seg_35(): + return [ (0x3400, 'V'), (0x4DB6, 'X'), (0x4DC0, 'V'), @@ -3604,6 +3746,10 @@ uts46data = ( (0xA72F, 'V'), (0xA732, 'M', u'ꜳ'), (0xA733, 'V'), + ] + +def _seg_36(): + return [ (0xA734, 'M', u'ꜵ'), (0xA735, 'V'), (0xA736, 'M', u'ꜷ'), @@ -3704,6 +3850,10 @@ uts46data = ( (0xA7AA, 'M', u'ɦ'), (0xA7AB, 'X'), (0xA7F8, 'M', u'ħ'), + ] + +def _seg_37(): + return [ (0xA7F9, 'M', u'œ'), (0xA7FA, 'V'), (0xA82C, 'X'), @@ -3804,6 +3954,10 @@ uts46data = ( (0xF92B, 'M', u'狼'), (0xF92C, 'M', u'郎'), (0xF92D, 'M', u'來'), + ] + +def _seg_38(): + return [ (0xF92E, 'M', u'冷'), (0xF92F, 'M', u'勞'), (0xF930, 'M', u'擄'), @@ -3904,6 +4058,10 @@ uts46data = ( (0xF98F, 'M', u'憐'), (0xF990, 'M', u'戀'), (0xF991, 'M', u'撚'), + ] + +def _seg_39(): + return [ (0xF992, 'M', u'漣'), (0xF993, 'M', u'煉'), (0xF994, 'M', u'璉'), @@ -4004,6 +4162,10 @@ uts46data = ( (0xF9F3, 'M', u'麟'), (0xF9F4, 'M', u'林'), (0xF9F5, 'M', u'淋'), + ] + +def _seg_40(): + return [ (0xF9F6, 'M', u'臨'), (0xF9F7, 'M', u'立'), (0xF9F8, 'M', u'笠'), @@ -4104,6 +4266,10 @@ uts46data = ( (0xFA5C, 'M', u'臭'), (0xFA5D, 'M', u'艹'), (0xFA5F, 'M', u'著'), + ] + +def _seg_41(): + return [ (0xFA60, 'M', u'褐'), (0xFA61, 'M', u'視'), (0xFA62, 'M', u'謁'), @@ -4204,6 +4370,10 @@ uts46data = ( (0xFAC2, 'M', u'輸'), (0xFAC3, 'M', u'遲'), (0xFAC4, 'M', u'醙'), + ] + +def _seg_42(): + return [ (0xFAC5, 'M', u'鉶'), (0xFAC6, 'M', u'陼'), (0xFAC7, 'M', u'難'), @@ -4304,6 +4474,10 @@ uts46data = ( (0xFB7A, 'M', u'چ'), (0xFB7E, 'M', u'ڇ'), (0xFB82, 'M', u'ڍ'), + ] + +def _seg_43(): + return [ (0xFB84, 'M', u'ڌ'), (0xFB86, 'M', u'ڎ'), (0xFB88, 'M', u'ڈ'), @@ -4404,6 +4578,10 @@ uts46data = ( (0xFC3C, 'M', u'كم'), (0xFC3D, 'M', u'كى'), (0xFC3E, 'M', u'كي'), + ] + +def _seg_44(): + return [ (0xFC3F, 'M', u'لج'), (0xFC40, 'M', u'لح'), (0xFC41, 'M', u'لخ'), @@ -4504,6 +4682,10 @@ uts46data = ( (0xFCA0, 'M', u'به'), (0xFCA1, 'M', u'تج'), (0xFCA2, 'M', u'تح'), + ] + +def _seg_45(): + return [ (0xFCA3, 'M', u'تخ'), (0xFCA4, 'M', u'تم'), (0xFCA5, 'M', u'ته'), @@ -4604,6 +4786,10 @@ uts46data = ( (0xFD04, 'M', u'خي'), (0xFD05, 'M', u'صى'), (0xFD06, 'M', u'صي'), + ] + +def _seg_46(): + return [ (0xFD07, 'M', u'ضى'), (0xFD08, 'M', u'ضي'), (0xFD09, 'M', u'شج'), @@ -4704,6 +4890,10 @@ uts46data = ( (0xFD87, 'M', u'لمح'), (0xFD89, 'M', u'محج'), (0xFD8A, 'M', u'محم'), + ] + +def _seg_47(): + return [ (0xFD8B, 'M', u'محي'), (0xFD8C, 'M', u'مجح'), (0xFD8D, 'M', u'مجم'), @@ -4804,6 +4994,10 @@ uts46data = ( (0xFE3C, 'M', u'】'), (0xFE3D, 'M', u'《'), (0xFE3E, 'M', u'》'), + ] + +def _seg_48(): + return [ (0xFE3F, 'M', u'〈'), (0xFE40, 'M', u'〉'), (0xFE41, 'M', u'「'), @@ -4904,6 +5098,10 @@ uts46data = ( (0xFF00, 'X'), (0xFF01, '3', u'!'), (0xFF02, '3', u'"'), + ] + +def _seg_49(): + return [ (0xFF03, '3', u'#'), (0xFF04, '3', u'$'), (0xFF05, '3', u'%'), @@ -5004,6 +5202,10 @@ uts46data = ( (0xFF64, 'M', u'、'), (0xFF65, 'M', u'・'), (0xFF66, 'M', u'ヲ'), + ] + +def _seg_50(): + return [ (0xFF67, 'M', u'ァ'), (0xFF68, 'M', u'ィ'), (0xFF69, 'M', u'ゥ'), @@ -5104,6 +5306,10 @@ uts46data = ( (0xFFCB, 'M', u'ᅨ'), (0xFFCC, 'M', u'ᅩ'), (0xFFCD, 'M', u'ᅪ'), + ] + +def _seg_51(): + return [ (0xFFCE, 'M', u'ᅫ'), (0xFFCF, 'M', u'ᅬ'), (0xFFD0, 'X'), @@ -5204,6 +5410,10 @@ uts46data = ( (0x1041B, 'M', u'𐑃'), (0x1041C, 'M', u'𐑄'), (0x1041D, 'M', u'𐑅'), + ] + +def _seg_52(): + return [ (0x1041E, 'M', u'𐑆'), (0x1041F, 'M', u'𐑇'), (0x10420, 'M', u'𐑈'), @@ -5304,6 +5514,10 @@ uts46data = ( (0x12474, 'X'), (0x13000, 'V'), (0x1342F, 'X'), + ] + +def _seg_53(): + return [ (0x16800, 'V'), (0x16A39, 'X'), (0x16F00, 'V'), @@ -5404,6 +5618,10 @@ uts46data = ( (0x1D43A, 'M', u'g'), (0x1D43B, 'M', u'h'), (0x1D43C, 'M', u'i'), + ] + +def _seg_54(): + return [ (0x1D43D, 'M', u'j'), (0x1D43E, 'M', u'k'), (0x1D43F, 'M', u'l'), @@ -5504,6 +5722,10 @@ uts46data = ( (0x1D49E, 'M', u'c'), (0x1D49F, 'M', u'd'), (0x1D4A0, 'X'), + ] + +def _seg_55(): + return [ (0x1D4A2, 'M', u'g'), (0x1D4A3, 'X'), (0x1D4A5, 'M', u'j'), @@ -5604,6 +5826,10 @@ uts46data = ( (0x1D505, 'M', u'b'), (0x1D506, 'X'), (0x1D507, 'M', u'd'), + ] + +def _seg_56(): + return [ (0x1D508, 'M', u'e'), (0x1D509, 'M', u'f'), (0x1D50A, 'M', u'g'), @@ -5704,6 +5930,10 @@ uts46data = ( (0x1D56C, 'M', u'a'), (0x1D56D, 'M', u'b'), (0x1D56E, 'M', u'c'), + ] + +def _seg_57(): + return [ (0x1D56F, 'M', u'd'), (0x1D570, 'M', u'e'), (0x1D571, 'M', u'f'), @@ -5804,6 +6034,10 @@ uts46data = ( (0x1D5D0, 'M', u'w'), (0x1D5D1, 'M', u'x'), (0x1D5D2, 'M', u'y'), + ] + +def _seg_58(): + return [ (0x1D5D3, 'M', u'z'), (0x1D5D4, 'M', u'a'), (0x1D5D5, 'M', u'b'), @@ -5904,6 +6138,10 @@ uts46data = ( (0x1D634, 'M', u's'), (0x1D635, 'M', u't'), (0x1D636, 'M', u'u'), + ] + +def _seg_59(): + return [ (0x1D637, 'M', u'v'), (0x1D638, 'M', u'w'), (0x1D639, 'M', u'x'), @@ -6004,6 +6242,10 @@ uts46data = ( (0x1D698, 'M', u'o'), (0x1D699, 'M', u'p'), (0x1D69A, 'M', u'q'), + ] + +def _seg_60(): + return [ (0x1D69B, 'M', u'r'), (0x1D69C, 'M', u's'), (0x1D69D, 'M', u't'), @@ -6104,6 +6346,10 @@ uts46data = ( (0x1D6FE, 'M', u'γ'), (0x1D6FF, 'M', u'δ'), (0x1D700, 'M', u'ε'), + ] + +def _seg_61(): + return [ (0x1D701, 'M', u'ζ'), (0x1D702, 'M', u'η'), (0x1D703, 'M', u'θ'), @@ -6204,6 +6450,10 @@ uts46data = ( (0x1D764, 'M', u'ο'), (0x1D765, 'M', u'π'), (0x1D766, 'M', u'ρ'), + ] + +def _seg_62(): + return [ (0x1D767, 'M', u'θ'), (0x1D768, 'M', u'σ'), (0x1D769, 'M', u'τ'), @@ -6304,6 +6554,10 @@ uts46data = ( (0x1D7CA, 'M', u'ϝ'), (0x1D7CC, 'X'), (0x1D7CE, 'M', u'0'), + ] + +def _seg_63(): + return [ (0x1D7CF, 'M', u'1'), (0x1D7D0, 'M', u'2'), (0x1D7D1, 'M', u'3'), @@ -6404,6 +6658,10 @@ uts46data = ( (0x1EE30, 'M', u'ف'), (0x1EE31, 'M', u'ص'), (0x1EE32, 'M', u'ق'), + ] + +def _seg_64(): + return [ (0x1EE33, 'X'), (0x1EE34, 'M', u'ش'), (0x1EE35, 'M', u'ت'), @@ -6504,6 +6762,10 @@ uts46data = ( (0x1EEA2, 'M', u'ج'), (0x1EEA3, 'M', u'د'), (0x1EEA4, 'X'), + ] + +def _seg_65(): + return [ (0x1EEA5, 'M', u'و'), (0x1EEA6, 'M', u'ز'), (0x1EEA7, 'M', u'ح'), @@ -6604,6 +6866,10 @@ uts46data = ( (0x1F140, 'M', u'q'), (0x1F141, 'M', u'r'), (0x1F142, 'M', u's'), + ] + +def _seg_66(): + return [ (0x1F143, 'M', u't'), (0x1F144, 'M', u'u'), (0x1F145, 'M', u'v'), @@ -6704,6 +6970,10 @@ uts46data = ( (0x1F400, 'V'), (0x1F43F, 'X'), (0x1F440, 'V'), + ] + +def _seg_67(): + return [ (0x1F441, 'X'), (0x1F442, 'V'), (0x1F4F8, 'X'), @@ -6804,6 +7074,10 @@ uts46data = ( (0x2F84B, 'M', u'圖'), (0x2F84C, 'M', u'嘆'), (0x2F84D, 'M', u'圗'), + ] + +def _seg_68(): + return [ (0x2F84E, 'M', u'噑'), (0x2F84F, 'M', u'噴'), (0x2F850, 'M', u'切'), @@ -6904,6 +7178,10 @@ uts46data = ( (0x2F8B2, 'M', u'成'), (0x2F8B3, 'M', u'戛'), (0x2F8B4, 'M', u'扝'), + ] + +def _seg_69(): + return [ (0x2F8B5, 'M', u'抱'), (0x2F8B6, 'M', u'拔'), (0x2F8B7, 'M', u'捐'), @@ -7004,6 +7282,10 @@ uts46data = ( (0x2F916, 'M', u'㶖'), (0x2F917, 'M', u'灊'), (0x2F918, 'M', u'災'), + ] + +def _seg_70(): + return [ (0x2F919, 'M', u'灷'), (0x2F91A, 'M', u'炭'), (0x2F91B, 'M', u'𠔥'), @@ -7104,6 +7386,10 @@ uts46data = ( (0x2F97D, 'M', u'聠'), (0x2F97E, 'M', u'𦖨'), (0x2F97F, 'M', u'聰'), + ] + +def _seg_71(): + return [ (0x2F980, 'M', u'𣍟'), (0x2F981, 'M', u'䏕'), (0x2F982, 'M', u'育'), @@ -7204,6 +7490,10 @@ uts46data = ( (0x2F9E1, 'M', u'𨗭'), (0x2F9E2, 'M', u'邔'), (0x2F9E3, 'M', u'郱'), + ] + +def _seg_72(): + return [ (0x2F9E4, 'M', u'鄑'), (0x2F9E5, 'M', u'𨜮'), (0x2F9E6, 'M', u'鄛'), @@ -7264,4 +7554,80 @@ uts46data = ( (0x2FA1E, 'X'), (0xE0100, 'I'), (0xE01F0, 'X'), + ] + +uts46data = tuple( + _seg_0() + + _seg_1() + + _seg_2() + + _seg_3() + + _seg_4() + + _seg_5() + + _seg_6() + + _seg_7() + + _seg_8() + + _seg_9() + + _seg_10() + + _seg_11() + + _seg_12() + + _seg_13() + + _seg_14() + + _seg_15() + + _seg_16() + + _seg_17() + + _seg_18() + + _seg_19() + + _seg_20() + + _seg_21() + + _seg_22() + + _seg_23() + + _seg_24() + + _seg_25() + + _seg_26() + + _seg_27() + + _seg_28() + + _seg_29() + + _seg_30() + + _seg_31() + + _seg_32() + + _seg_33() + + _seg_34() + + _seg_35() + + _seg_36() + + _seg_37() + + _seg_38() + + _seg_39() + + _seg_40() + + _seg_41() + + _seg_42() + + _seg_43() + + _seg_44() + + _seg_45() + + _seg_46() + + _seg_47() + + _seg_48() + + _seg_49() + + _seg_50() + + _seg_51() + + _seg_52() + + _seg_53() + + _seg_54() + + _seg_55() + + _seg_56() + + _seg_57() + + _seg_58() + + _seg_59() + + _seg_60() + + _seg_61() + + _seg_62() + + _seg_63() + + _seg_64() + + _seg_65() + + _seg_66() + + _seg_67() + + _seg_68() + + _seg_69() + + _seg_70() + + _seg_71() + + _seg_72() ) From 4d00d47a5a7eec2dc8e145dc2d9c2a6f68270496 Mon Sep 17 00:00:00 2001 From: Ian Cordasco Date: Tue, 24 Jan 2017 06:22:58 -0600 Subject: [PATCH 065/104] Use twine for publishing Requests --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 4e3a149e..0fb26321 100644 --- a/Makefile +++ b/Makefile @@ -45,9 +45,10 @@ idna: rm -fr idna publish: - python setup.py register - python setup.py sdist upload - python setup.py bdist_wheel --universal upload + pip install 'twine>=1.5.0' + python setup.py sdist + python setup.py bdist_wheel --universal + twine upload dist/* rm -fr build dist .egg requests.egg-info From b2289cd2d5d21bd31cf4a818a4e0ff6951b2317a Mon Sep 17 00:00:00 2001 From: Ian Cordasco Date: Tue, 24 Jan 2017 06:32:12 -0600 Subject: [PATCH 066/104] Bump version for 2.13.0 Add release notes for 2.13.0 --- HISTORY.rst | 13 +++++++++++++ requests/__init__.py | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 8bad7eb0..5ec8bb21 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,6 +3,19 @@ Release History --------------- +2.13.0 (2017-01-24) ++++++++++++++++++++ + +**Features** + +- Only load the ``idna`` library when we've determined we need it. This will + save some memory for users. + +**Miscellaneous** + +- Updated bundled urllib3 to 1.20. +- Updated bundled idna to 2.2. + 2.12.5 (2017-01-18) +++++++++++++++++++ diff --git a/requests/__init__.py b/requests/__init__.py index dac37c95..1665d4b9 100644 --- a/requests/__init__.py +++ b/requests/__init__.py @@ -41,8 +41,8 @@ is at . """ __title__ = 'requests' -__version__ = '2.12.5' -__build__ = 0x021205 +__version__ = '2.13.0' +__build__ = 0x021300 __author__ = 'Kenneth Reitz' __license__ = 'Apache 2.0' __copyright__ = 'Copyright 2016 Kenneth Reitz' From 32548e2bb67f5645785554a5762e42603e09985c Mon Sep 17 00:00:00 2001 From: Ian Cordasco Date: Tue, 24 Jan 2017 06:45:29 -0600 Subject: [PATCH 067/104] Pin pipenv to fix CI --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0fb26321..bcc6b74a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: docs init: - pip install 'pipenv>=0.1.6' + pip install 'pipenv===0.2.0' pipenv install --dev test: From 6a415a02cf0fafc34be212befb95136bc037f565 Mon Sep 17 00:00:00 2001 From: Ian Cordasco Date: Tue, 24 Jan 2017 06:55:23 -0600 Subject: [PATCH 068/104] Blacklist known bad version of pipenv We pinned pipenv to release v2.13.0 but in reality, we could have just blacklisted the known bad version. For future us, we now blacklist it. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bcc6b74a..707839fe 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: docs init: - pip install 'pipenv===0.2.0' + pip install 'pipenv>=0.1.6,!=0.2.6,!=0.2.7,!=0.2.8' pipenv install --dev test: From fee0e94a76b4ed561897b341f8e88c046b483129 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 24 Jan 2017 13:27:38 -0500 Subject: [PATCH 069/104] empty commit From b12272d7d158c080494181610c2cc648e9a35026 Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Tue, 24 Jan 2017 16:05:33 -0700 Subject: [PATCH 070/104] updating Pipfile source to a useable pypi endpoint --- Makefile | 2 +- Pipfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 707839fe..0fb26321 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: docs init: - pip install 'pipenv>=0.1.6,!=0.2.6,!=0.2.7,!=0.2.8' + pip install 'pipenv>=0.1.6' pipenv install --dev test: diff --git a/Pipfile b/Pipfile index 0bb849e7..7a05b862 100644 --- a/Pipfile +++ b/Pipfile @@ -1,5 +1,5 @@ [[source]] -url = "https://pypi.org/" +url = "https://pypi.python.org/simple" verify_ssl = true [dev-packages] From 9a2a316f0832ace4d74a1f0c74a6fb26a3da1600 Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Tue, 24 Jan 2017 16:05:46 -0700 Subject: [PATCH 071/104] updating Pipfile.lock --- Pipfile.lock | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index b545c108..6558addd 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -9,23 +9,28 @@ "Babel": "==2.3.4", "alabaster": "==0.7.9", "pytest-mock": "==1.5.0", + "packaging": "==16.8", "MarkupSafe": "==0.23", "pytz": "==2016.10", "coverage": "==4.3.4", "pytest-httpbin": "==0.2.3", "funcsigs": "==1.0.2", + "pyparsing": "==2.1.10", "click": "==6.7", "decorator": "==4.0.11", "imagesize": "==0.7.1", + "argparse": "==1.4.0", "Pygments": "==2.1.3", "sphinx": "*", "pbr": "==1.10.0", "snowballstemmer": "==1.2.1", + "ordereddict": "==1.1", "py": "==1.4.32", "pytest-cov": "==2.4.0", "docutils": "==0.13.1", "pytest": "==3.0.5", "Jinja2": "==2.9.4", + "appdirs": "==1.4.0", "Sphinx": "==1.5.1", "requests": "==2.12.5", "itsdangerous": "==0.24", @@ -35,11 +40,11 @@ "_meta": { "sources": [ { - "url": "https://pypi.org/", + "url": "https://pypi.python.org/simple", "verify_ssl": true } ], "requires": {}, - "Pipfile-sha256": "f306fe105cc76e259ab1e5d2933ad2d0fe7a8b2d28686f64f7a94f767c0ce5d4" + "Pipfile-sha256": "f626e302e0f052b9f5e407a0b998407906b4272b4fe45503d3ea1dcd5e8e5029" } } \ No newline at end of file From 600ee2bf2b4c9e8ae7e8de11e4e999e514f9cd15 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 24 Jan 2017 20:59:26 -0500 Subject: [PATCH 072/104] updated lockfile --- Pipfile.lock | 167 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 138 insertions(+), 29 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index b545c108..736fb687 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,36 +1,145 @@ { "default": {}, "develop": { - "Werkzeug": "==0.11.15", - "six": "==1.10.0", - "httpbin": "==0.5.0", - "codecov": "==2.0.5", - "Flask": "==0.12", - "Babel": "==2.3.4", - "alabaster": "==0.7.9", - "pytest-mock": "==1.5.0", - "MarkupSafe": "==0.23", - "pytz": "==2016.10", - "coverage": "==4.3.4", - "pytest-httpbin": "==0.2.3", - "funcsigs": "==1.0.2", - "click": "==6.7", - "decorator": "==4.0.11", - "imagesize": "==0.7.1", - "Pygments": "==2.1.3", + "Werkzeug": { + "version": "==0.11.15", + "hash": "sha256:c6f6f89124df0514d886782c658c3e12f2caaa94da34cee3fd82eebf4ebf052b" + }, + "six": { + "version": "==1.10.0", + "hash": "sha256:0ff78c403d9bccf5a425a6d31a12aa6b47f1c21ca4dc2573a7e2f32a97335eb1" + }, + "httpbin": { + "version": "==0.5.0", + "hash": "sha256:710069973216d4bbf9ab6757f1e9a1f3be05832ce77da023adce0a98dfeecfee" + }, + "codecov": { + "version": "==2.0.5", + "hash": "sha256:9fb0cd4a43fe538b4ea229607d0a7d65b00f9bfb37bb6af60a17f4ac33707334" + }, + "Flask": { + "version": "==0.12", + "hash": "sha256:7f03bb2c255452444f7265eddb51601806e5447b6f8a2d50bbc77a654a14c118" + }, + "Babel": { + "version": "==2.3.4", + "hash": "sha256:3318ed2960240d61cbc6558858ee00c10eed77a6508c4d1ed8e6f7f48399c975" + }, + "alabaster": { + "version": "==0.7.9", + "hash": "sha256:d3e64a74919373d6d4d1d36bd717206584cb64cbb0532dfce3bc2081cba6817b" + }, + "pytest-mock": "*", + "pytest_mock": { + "version": "==1.5.0", + "hash": "sha256:8e0fd43280c717f36920b60356bd713291b81a61704c94bc13aae9a12ef7fbd8" + }, + "packaging": { + "version": "==16.8", + "hash": "sha256:99276dc6e3a7851f32027a68f1095cd3f77c148091b092ea867a351811cfe388" + }, + "MarkupSafe": { + "version": "==0.23", + "hash": "sha256:a4ec1aff59b95a14b45eb2e23761a0179e98319da5a7eb76b56ea8cdc7b871c3" + }, + "pytz": { + "version": "==2016.10", + "hash": "sha256:a1ea35e87a63c7825846d5b5c81d23d668e8a102d3b1b465ce95afe1b3a2e065" + }, + "coverage": { + "version": "==4.3.4", + "hash": "sha256:36407249a0b6669c6ad4425b0f29685579df745480c03afa70f101f09f4eead3" + }, + "pytest-httpbin": { + "version": "==0.2.3", + "hash": "sha256:c5b698dfa474ffc9caebcb35e34346b753eb226aea5c2e1b69fefedbcf161bf8" + }, + "funcsigs": { + "version": "==1.0.2", + "hash": "sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca" + }, + "pyparsing": { + "version": "==2.1.10", + "hash": "sha256:67101d7acee692962f33dd30b5dce079ff532dd9aa99ff48d52a3dad51d2fe84" + }, + "click": { + "version": "==6.7", + "hash": "sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d" + }, + "decorator": { + "version": "==4.0.11", + "hash": "sha256:73cbaadb8bc4e3c65fe1100773d56331a2d756cc0f5c7b9d8d5d5223fe04f600" + }, + "imagesize": { + "version": "==0.7.1", + "hash": "sha256:6ebdc9e0ad188f9d1b2cdd9bc59cbe42bf931875e829e7a595e6b3abdc05cdfb" + }, + "argparse": { + "version": "==1.4.0", + "hash": "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314" + }, + "Pygments": { + "version": "==2.2.0", + "hash": "sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d" + }, "sphinx": "*", - "pbr": "==1.10.0", - "snowballstemmer": "==1.2.1", - "py": "==1.4.32", - "pytest-cov": "==2.4.0", - "docutils": "==0.13.1", - "pytest": "==3.0.5", - "Jinja2": "==2.9.4", - "Sphinx": "==1.5.1", - "requests": "==2.12.5", - "itsdangerous": "==0.24", - "PySocks": "==1.6.5", - "mock": "==2.0.0" + "pbr": { + "version": "==1.10.0", + "hash": "sha256:f5cf7265a80636ecff66806d13494cbf9d77a3758a65fd8b4d4d4bee81b0c375" + }, + "snowballstemmer": { + "version": "==1.2.1", + "hash": "sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89" + }, + "py": { + "version": "==1.4.32", + "hash": "sha256:2d4bba2e25fff58140e6bdce1e485e89bb59776adbe01d490baa6b1f37a3dd6b" + }, + "pytest-cov": "*", + "pytest_cov": { + "version": "==2.4.0", + "hash": "sha256:10e37e876f49ddec80d6c83a54b657157f1387ebc0f7755285f8c156130014a1" + }, + "docutils": { + "version": "==0.13.1", + "hash": "sha256:de454f1015958450b72641165c08afe7023cd7e3944396448f2fb1b0ccba9d77" + }, + "pytest": { + "version": "==3.0.6", + "hash": "sha256:da0ab50c7eec0683bc24f1c1137db1f4111752054ecdad63125e7ec71316b813" + }, + "Jinja2": { + "version": "==2.9.4", + "hash": "sha256:93b97a811b575998899b293fdb2144c536aeb7d6ee13464b0cf8e86ae64eb56b" + }, + "appdirs": { + "version": "==1.4.0", + "hash": "sha256:85e58578db8f29538f3109c11250c2a5514a2fcdc9890d9b2fe777eb55517736" + }, + "setuptools": { + "version": "==34.0.2", + "hash": "sha256:f9ac44de8b36a13ce35d2989052a295a548c9fe5a161fb066dff53592200aa12" + }, + "Sphinx": { + "version": "==1.5.2", + "hash": "sha256:57c8636e1d23f6c01fb19911a8f255f1b4934ba69feb55bd4dd0f097ebb04f05" + }, + "requests": { + "version": "==2.13.0", + "hash": "sha256:1a720e8862a41aa22e339373b526f508ef0c8988baf48b84d3fc891a8e237efb" + }, + "itsdangerous": { + "version": "==0.24", + "hash": "sha256:cbb3fcf8d3e33df861709ecaf89d9e6629cff0a217bc2848f1b41cd30d360519" + }, + "PySocks": { + "version": "==1.6.5", + "hash": "sha256:7962f4d7c76e8414ae168c677a77f19cf8926143911f7e8d37a5d4c4eb910c6f" + }, + "mock": { + "version": "==2.0.0", + "hash": "sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1" + } }, "_meta": { "sources": [ From 7cad64ac5a5e4cdf446f7fe7370ce27be5003122 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 24 Jan 2017 21:02:06 -0500 Subject: [PATCH 073/104] use proper names --- Pipfile | 6 +++--- Pipfile.lock | 51 ++++++++++++++++++++++++--------------------------- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/Pipfile b/Pipfile index 0bb849e7..e6ddc258 100644 --- a/Pipfile +++ b/Pipfile @@ -3,9 +3,9 @@ url = "https://pypi.org/" verify_ssl = true [dev-packages] -sphinx = "*" -pytest-mock = "*" -pytest-cov = "*" +Sphinx = "*" +pytest_mock = "*" +pytest_cov = "*" pytest = "*" codecov = "*" pytest-httpbin = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 736fb687..7bf637ad 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -5,13 +5,13 @@ "version": "==0.11.15", "hash": "sha256:c6f6f89124df0514d886782c658c3e12f2caaa94da34cee3fd82eebf4ebf052b" }, - "six": { - "version": "==1.10.0", - "hash": "sha256:0ff78c403d9bccf5a425a6d31a12aa6b47f1c21ca4dc2573a7e2f32a97335eb1" + "py": { + "version": "==1.4.32", + "hash": "sha256:2d4bba2e25fff58140e6bdce1e485e89bb59776adbe01d490baa6b1f37a3dd6b" }, - "httpbin": { - "version": "==0.5.0", - "hash": "sha256:710069973216d4bbf9ab6757f1e9a1f3be05832ce77da023adce0a98dfeecfee" + "Sphinx": { + "version": "==1.5.2", + "hash": "sha256:57c8636e1d23f6c01fb19911a8f255f1b4934ba69feb55bd4dd0f097ebb04f05" }, "codecov": { "version": "==2.0.5", @@ -29,11 +29,6 @@ "version": "==0.7.9", "hash": "sha256:d3e64a74919373d6d4d1d36bd717206584cb64cbb0532dfce3bc2081cba6817b" }, - "pytest-mock": "*", - "pytest_mock": { - "version": "==1.5.0", - "hash": "sha256:8e0fd43280c717f36920b60356bd713291b81a61704c94bc13aae9a12ef7fbd8" - }, "packaging": { "version": "==16.8", "hash": "sha256:99276dc6e3a7851f32027a68f1095cd3f77c148091b092ea867a351811cfe388" @@ -42,6 +37,10 @@ "version": "==0.23", "hash": "sha256:a4ec1aff59b95a14b45eb2e23761a0179e98319da5a7eb76b56ea8cdc7b871c3" }, + "funcsigs": { + "version": "==1.0.2", + "hash": "sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca" + }, "pytz": { "version": "==2016.10", "hash": "sha256:a1ea35e87a63c7825846d5b5c81d23d668e8a102d3b1b465ce95afe1b3a2e065" @@ -54,9 +53,9 @@ "version": "==0.2.3", "hash": "sha256:c5b698dfa474ffc9caebcb35e34346b753eb226aea5c2e1b69fefedbcf161bf8" }, - "funcsigs": { - "version": "==1.0.2", - "hash": "sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca" + "httpbin": { + "version": "==0.5.0", + "hash": "sha256:710069973216d4bbf9ab6757f1e9a1f3be05832ce77da023adce0a98dfeecfee" }, "pyparsing": { "version": "==2.1.10", @@ -82,24 +81,26 @@ "version": "==2.2.0", "hash": "sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d" }, - "sphinx": "*", - "pbr": { - "version": "==1.10.0", - "hash": "sha256:f5cf7265a80636ecff66806d13494cbf9d77a3758a65fd8b4d4d4bee81b0c375" + "pytest_mock": { + "version": "==1.5.0", + "hash": "sha256:8e0fd43280c717f36920b60356bd713291b81a61704c94bc13aae9a12ef7fbd8" }, "snowballstemmer": { "version": "==1.2.1", "hash": "sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89" }, - "py": { - "version": "==1.4.32", - "hash": "sha256:2d4bba2e25fff58140e6bdce1e485e89bb59776adbe01d490baa6b1f37a3dd6b" + "pbr": { + "version": "==1.10.0", + "hash": "sha256:f5cf7265a80636ecff66806d13494cbf9d77a3758a65fd8b4d4d4bee81b0c375" }, - "pytest-cov": "*", "pytest_cov": { "version": "==2.4.0", "hash": "sha256:10e37e876f49ddec80d6c83a54b657157f1387ebc0f7755285f8c156130014a1" }, + "six": { + "version": "==1.10.0", + "hash": "sha256:0ff78c403d9bccf5a425a6d31a12aa6b47f1c21ca4dc2573a7e2f32a97335eb1" + }, "docutils": { "version": "==0.13.1", "hash": "sha256:de454f1015958450b72641165c08afe7023cd7e3944396448f2fb1b0ccba9d77" @@ -120,10 +121,6 @@ "version": "==34.0.2", "hash": "sha256:f9ac44de8b36a13ce35d2989052a295a548c9fe5a161fb066dff53592200aa12" }, - "Sphinx": { - "version": "==1.5.2", - "hash": "sha256:57c8636e1d23f6c01fb19911a8f255f1b4934ba69feb55bd4dd0f097ebb04f05" - }, "requests": { "version": "==2.13.0", "hash": "sha256:1a720e8862a41aa22e339373b526f508ef0c8988baf48b84d3fc891a8e237efb" @@ -149,6 +146,6 @@ } ], "requires": {}, - "Pipfile-sha256": "f306fe105cc76e259ab1e5d2933ad2d0fe7a8b2d28686f64f7a94f767c0ce5d4" + "Pipfile-sha256": "544b292495d731a3cd2f48f38401c26b1f1c5f6f72e23b22b12d42f7dbedfdac" } } \ No newline at end of file From c008465d244e1ade1f007a04037eac96a4ad67e3 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 24 Jan 2017 21:09:21 -0500 Subject: [PATCH 074/104] pypi/simple --- Pipfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pipfile b/Pipfile index e6ddc258..862e4c4d 100644 --- a/Pipfile +++ b/Pipfile @@ -1,5 +1,5 @@ [[source]] -url = "https://pypi.org/" +url = "https://pypi.python.org/simple" verify_ssl = true [dev-packages] From efa030eae3cfa1eccb292a75ed958e00bb231631 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 24 Jan 2017 21:13:18 -0500 Subject: [PATCH 075/104] proper pipfile.lock --- Pipfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 7bf637ad..7a3c9a3f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -141,11 +141,11 @@ "_meta": { "sources": [ { - "url": "https://pypi.org/", + "url": "https://pypi.python.org/simple", "verify_ssl": true } ], "requires": {}, - "Pipfile-sha256": "544b292495d731a3cd2f48f38401c26b1f1c5f6f72e23b22b12d42f7dbedfdac" + "Pipfile-sha256": "54439fbdf043a2efe430cc27886cb6cbcc3f5642e7c93da6b96198c473153684" } } \ No newline at end of file From 9e681a4a9f4e85083ce76e763eef55b0e1f3185c Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 24 Jan 2017 21:22:16 -0500 Subject: [PATCH 076/104] fix makefle --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 707839fe..20783359 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: docs init: - pip install 'pipenv>=0.1.6,!=0.2.6,!=0.2.7,!=0.2.8' + pip install 'pipenv' pipenv install --dev test: From cf07efa534e150241a097f4300bb8cf5f78970fc Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 24 Jan 2017 22:51:24 -0500 Subject: [PATCH 077/104] give up --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 20783359..3fe1e1f4 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,9 @@ .PHONY: docs init: - pip install 'pipenv' - pipenv install --dev + pip install pipenv + pipenv install --dev --requirements > requirements.txt + pip install -r requirements.txt test: # This runs all of the tests. To run an individual test, run py.test with @@ -10,7 +11,7 @@ test: pipenv run py.test tests coverage: - pipenv run py.test --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests + py.test --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests certs: curl http://ci.kennethreitz.org/job/ca-bundle/lastSuccessfulBuild/artifact/cacerts.pem -o requests/cacert.pem From 1da52c04d47bf1339f563203b01719ac1875ea5e Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 24 Jan 2017 23:04:25 -0500 Subject: [PATCH 078/104] attempted fix for travis --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 3fe1e1f4..d3822803 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,8 @@ init: pip install pipenv - pipenv install --dev --requirements > requirements.txt - pip install -r requirements.txt + pipenv lock + pipenv install --dev test: # This runs all of the tests. To run an individual test, run py.test with @@ -11,7 +11,7 @@ test: pipenv run py.test tests coverage: - py.test --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests + pipenv run py.test --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests certs: curl http://ci.kennethreitz.org/job/ca-bundle/lastSuccessfulBuild/artifact/cacerts.pem -o requests/cacert.pem From b92058b6fe68a3b114b872d1dba072c115af413b Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 24 Jan 2017 23:08:27 -0500 Subject: [PATCH 079/104] empty commit From 795106c1885f19c84cefe037914a12d37ddd6248 Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Tue, 24 Jan 2017 21:28:14 -0700 Subject: [PATCH 080/104] fixing codecov with pipenv --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b3352c70..0887ad29 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,4 @@ install: "make" script: - make coverage after_success: - - codecov + - pipenv run codecov From 808e4c62dc54ec7a10197038d56fb70f738b19cf Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Fri, 27 Jan 2017 13:42:22 -0700 Subject: [PATCH 081/104] pin pipenv until kennethreitz/pipenv#90 is resolved --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d3822803..8c1e25b8 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: docs init: - pip install pipenv + pip install pipenv==3.1.9 pipenv lock pipenv install --dev From 8a58427d8aa73d6af81b6e5f6fd934b3386ef3de Mon Sep 17 00:00:00 2001 From: Matthew Medal Date: Fri, 27 Jan 2017 12:56:50 -0800 Subject: [PATCH 082/104] Only send HTTPDigestAuth on 4xx challenges Resolves: #3772 --- requests/auth.py | 6 ++++++ tests/test_lowlevel.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/requests/auth.py b/requests/auth.py index 510846d6..762ac7e2 100644 --- a/requests/auth.py +++ b/requests/auth.py @@ -227,6 +227,12 @@ class HTTPDigestAuth(AuthBase): :rtype: requests.Response """ + # If response is not 4xx, do not auth + # See https://github.com/kennethreitz/requests/issues/3772 + if not 400 <= r.status_code < 500: + self._thread_local.num_401_calls = 1 + return r + if self._thread_local.pos is not None: # Rewind the file position indicator of the body to where # it was to resend the request. diff --git a/tests/test_lowlevel.py b/tests/test_lowlevel.py index 6bc948b4..c8de1b1b 100644 --- a/tests/test_lowlevel.py +++ b/tests/test_lowlevel.py @@ -136,6 +136,43 @@ def test_digestauth_401_only_sent_once(): close_server.set() +def test_digestauth_only_on_4xx(): + """Ensure we only send digestauth on 4xx challenges. + + See https://github.com/kennethreitz/requests/issues/3772. + """ + text_200_chal = (b'HTTP/1.1 200 OK\r\n' + b'Content-Length: 0\r\n' + b'WWW-Authenticate: Digest nonce="6bf5d6e4da1ce66918800195d6b9130d"' + b', opaque="372825293d1c26955496c80ed6426e9e", ' + b'realm="me@kennethreitz.com", qop=auth\r\n\r\n') + + auth = requests.auth.HTTPDigestAuth('user', 'pass') + + def digest_response_handler(sock): + # Respond to GET with a 200 containing www-authenticate header. + request_content = consume_socket_content(sock, timeout=0.5) + assert request_content.startswith(b"GET / HTTP/1.1") + sock.send(text_200_chal) + + # Verify the client didn't respond with auth. + request_content = consume_socket_content(sock, timeout=0.5) + assert request_content == b'' + + return request_content + + close_server = threading.Event() + server = Server(digest_response_handler, wait_to_close_event=close_server) + + with server as (host, port): + url = 'http://{0}:{1}/'.format(host, port) + r = requests.get(url, auth=auth) + # Verify server didn't receive auth from us. + assert r.status_code == 200 + assert len(r.history) == 0 + close_server.set() + + _schemes_by_var_prefix = [ ('http', ['http']), ('https', ['https']), From 1a4ba6c833f16283103d4eac488bd46640280bdf Mon Sep 17 00:00:00 2001 From: TetraEtc Date: Tue, 31 Jan 2017 13:03:12 +1000 Subject: [PATCH 083/104] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 8c1dd448..db78ea69 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2016 Kenneth Reitz +Copyright 2017 Kenneth Reitz Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 036b5d34fd2d25a8c9acfe09cebbf6306c60ff40 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 2 Feb 2017 14:05:07 -0500 Subject: [PATCH 084/104] better sidebar for docs --- docs/_templates/sidebarintro.html | 2 +- docs/_templates/sidebarlogo.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_templates/sidebarintro.html b/docs/_templates/sidebarintro.html index 3ddd01ff..9c44fea4 100644 --- a/docs/_templates/sidebarintro.html +++ b/docs/_templates/sidebarintro.html @@ -31,10 +31,10 @@
  • pep8.org
  • httpbin.org
  • The Python Guide
  • +
  • Maya: Datetimes for Humans
  • Records: SQL for Humans
  • Legit: Git for Humans
  • Tablib: Tabular Datasets
  • -
  • Markdown, Please!
  • diff --git a/docs/_templates/sidebarlogo.html b/docs/_templates/sidebarlogo.html index b9cc5991..d71a0d88 100644 --- a/docs/_templates/sidebarlogo.html +++ b/docs/_templates/sidebarlogo.html @@ -35,10 +35,10 @@
  • pep8.org
  • httpbin.org
  • The Python Guide
  • +
  • Maya: Datetimes for Humans
  • Records: SQL for Humans
  • Legit: Git for Humans
  • Tablib: Tabular Datasets
  • -
  • Markdown, Please!
  • From 5ac53c69c78703e7eb782758b4a66c087bacd5f3 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 2 Feb 2017 14:09:31 -0500 Subject: [PATCH 085/104] 11,000,000! --- README.rst | 8 ++++---- docs/index.rst | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 34505538..02d52d86 100644 --- a/README.rst +++ b/README.rst @@ -6,10 +6,10 @@ Requests: HTTP for Humans .. image:: https://img.shields.io/pypi/l/requests.svg :target: https://pypi.python.org/pypi/requests - + .. image:: https://img.shields.io/pypi/wheel/requests.svg :target: https://pypi.python.org/pypi/requests - + .. image:: https://img.shields.io/pypi/pyversions/requests.svg :target: https://pypi.python.org/pypi/requests @@ -19,7 +19,7 @@ Requests: HTTP for Humans .. image:: https://codecov.io/github/kennethreitz/requests/coverage.svg?branch=master :target: https://codecov.io/github/kennethreitz/requests :alt: codecov.io - + .. image:: https://img.shields.io/badge/SayThanks.io-☼-1EAEDB.svg :target: https://saythanks.io/to/kennethreitz @@ -61,7 +61,7 @@ are 100% automatic, powered by `urllib3 `_, which is embedded within Requests. Besides, all the cool kids are doing it. Requests is one of the most -downloaded Python packages of all time, pulling in over 7,000,000 downloads +downloaded Python packages of all time, pulling in over 11,000,000 downloads every month. You don't want to be left out! Feature Support diff --git a/docs/index.rst b/docs/index.rst index 2aba9e35..cf0bebef 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -63,7 +63,7 @@ Institutions that prefer to be unnamed claim to use Requests internally. simple, Pythonic. Requests is one of the most downloaded Python packages of all time, pulling in -over 7,000,000 downloads every month. All the cool kids are doing it! +over 11,000,000 downloads every month. All the cool kids are doing it! Supported Features ------------------ From 260763a83d26d829c5308dfc937793a302a70f7a Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 2 Feb 2017 15:06:54 -0500 Subject: [PATCH 086/104] better say thanks icon --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 02d52d86..9b5f7aa9 100644 --- a/README.rst +++ b/README.rst @@ -20,7 +20,7 @@ Requests: HTTP for Humans :target: https://codecov.io/github/kennethreitz/requests :alt: codecov.io -.. image:: https://img.shields.io/badge/SayThanks.io-☼-1EAEDB.svg +.. image:: https://img.shields.io/badge/Say%20Thanks!-🦉-1EAEDB.svg :target: https://saythanks.io/to/kennethreitz From 6bd091ca7046585e4dc4cdb7bc33d7f29022834e Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 2 Feb 2017 15:18:24 -0500 Subject: [PATCH 087/104] improved homepage --- docs/index.rst | 46 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index cf0bebef..7a5568e3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -8,14 +8,36 @@ Requests: HTTP for Humans Release v\ |version|. (:ref:`Installation `) -Requests is the only *Non-GMO* HTTP library for Python, safe for human +.. image:: https://img.shields.io/pypi/l/requests.svg + :target: https://pypi.python.org/pypi/requests + +.. image:: https://img.shields.io/pypi/wheel/requests.svg + :target: https://pypi.python.org/pypi/requests + +.. image:: https://img.shields.io/pypi/pyversions/requests.svg + :target: https://pypi.python.org/pypi/requests + +.. image:: https://travis-ci.org/kennethreitz/requests.svg?branch=master + :target: https://travis-ci.org/kennethreitz/requests + +.. image:: https://codecov.io/github/kennethreitz/requests/coverage.svg?branch=master + :target: https://codecov.io/github/kennethreitz/requests + :alt: codecov.io + +.. image:: https://img.shields.io/badge/Say%20Thanks!-🦉-1EAEDB.svg + :target: https://saythanks.io/to/kennethreitz + + +**Requests** is the only *Non-GMO* HTTP library for Python, safe for human consumption. -**Warning:** Recreational use of other HTTP libraries may result in dangerous side-effects, +*Warning: Recreational use of other HTTP libraries may result in dangerous side-effects, including: security vulnerabilities, verbose code, reinventing the wheel, -constantly reading documentation, depression, headaches, or even death. +constantly reading documentation, depression, headaches, or even death.* -Behold, the power of Requests:: +------------------- + +**Behold, the power of Requests**:: >>> r = requests.get('https://api.github.com/user', auth=('user', 'pass')) >>> r.status_code @@ -32,7 +54,7 @@ Behold, the power of Requests:: See `similar code, sans Requests `_. -Requests allows you to send *organic, grass-fed* HTTP/1.1 requests, without the +**Requests** allows you to send *organic, grass-fed* HTTP/1.1 requests, without the need for manual labor. There's no need to manually add query strings to your URLs, or to form-encode your POST data. Keep-alive and HTTP connection pooling are 100% automatic, powered by `urllib3 `_, @@ -65,26 +87,26 @@ Institutions that prefer to be unnamed claim to use Requests internally. Requests is one of the most downloaded Python packages of all time, pulling in over 11,000,000 downloads every month. All the cool kids are doing it! -Supported Features ------------------- +Beloved Features +---------------- Requests is ready for today's web. -- International Domains and URLs - Keep-Alive & Connection Pooling +- International Domains and URLs - Sessions with Cookie Persistence - Browser-style SSL Verification +- Automatic Content Decoding - Basic/Digest Authentication - Elegant Key/Value Cookies - Automatic Decompression -- Automatic Content Decoding - Unicode Response Bodies -- Multipart File Uploads - HTTP(S) Proxy Support -- Connection Timeouts +- Multipart File Uploads - Streaming Downloads -- ``.netrc`` Support +- Connection Timeouts - Chunked Requests +- ``.netrc`` Support - Thread-safety Requests officially supports Python 2.6–2.7 & 3.3–3.7, and runs great on PyPy. From abaeeb8807fe8f3cfdac656a992c08c096fe8f5d Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 2 Feb 2017 15:19:31 -0500 Subject: [PATCH 088/104] improved sidebar --- docs/_templates/sidebarintro.html | 1 + docs/_templates/sidebarlogo.html | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/_templates/sidebarintro.html b/docs/_templates/sidebarintro.html index 9c44fea4..457688d9 100644 --- a/docs/_templates/sidebarintro.html +++ b/docs/_templates/sidebarintro.html @@ -28,6 +28,7 @@

    More Kenneth Reitz projects:

      +
    • pipenv
    • pep8.org
    • httpbin.org
    • The Python Guide
    • diff --git a/docs/_templates/sidebarlogo.html b/docs/_templates/sidebarlogo.html index d71a0d88..798f8091 100644 --- a/docs/_templates/sidebarlogo.html +++ b/docs/_templates/sidebarlogo.html @@ -32,6 +32,7 @@

      More Kenneth Reitz projects:

        +
      • pipenv
      • pep8.org
      • httpbin.org
      • The Python Guide
      • From c2c523ba9e327adf5810165d115136397f8190f7 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 2 Feb 2017 15:22:01 -0500 Subject: [PATCH 089/104] docs --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 7a5568e3..c1d78c87 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -73,7 +73,7 @@ Institutions that prefer to be unnamed claim to use Requests internally. right level of abstraction. **Matt DeBoard** - I'm going to get @kennethreitz's Python requests module tattooed + I'm going to get `@kennethreitz `_'s Python requests module tattooed on my body, somehow. The whole thing. **Daniel Greenfeld** From f278344e010e0d3fed5ba1c3bef8d9f16cab693f Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 2 Feb 2017 16:12:29 -0500 Subject: [PATCH 090/104] updated pipfile --- Pipfile | 8 ++-- Pipfile.lock | 112 ++++++++++++++++++++++++++------------------------- 2 files changed, 61 insertions(+), 59 deletions(-) diff --git a/Pipfile b/Pipfile index 862e4c4d..2e7ec08d 100644 --- a/Pipfile +++ b/Pipfile @@ -3,10 +3,10 @@ url = "https://pypi.python.org/simple" verify_ssl = true [dev-packages] -Sphinx = "*" -pytest_mock = "*" -pytest_cov = "*" pytest = "*" codecov = "*" pytest-httpbin = "*" -PySocks = "*" +sphinx = "*" +pytest-mock = "*" +pytest-cov = "*" +pysocks = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 7a3c9a3f..d522ed2f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,34 +1,38 @@ { "default": {}, "develop": { + "snowballstemmer": { + "version": "==1.2.1", + "hash": "sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89" + }, "Werkzeug": { "version": "==0.11.15", "hash": "sha256:c6f6f89124df0514d886782c658c3e12f2caaa94da34cee3fd82eebf4ebf052b" }, - "py": { - "version": "==1.4.32", - "hash": "sha256:2d4bba2e25fff58140e6bdce1e485e89bb59776adbe01d490baa6b1f37a3dd6b" + "six": { + "version": "==1.10.0", + "hash": "sha256:0ff78c403d9bccf5a425a6d31a12aa6b47f1c21ca4dc2573a7e2f32a97335eb1" }, - "Sphinx": { - "version": "==1.5.2", - "hash": "sha256:57c8636e1d23f6c01fb19911a8f255f1b4934ba69feb55bd4dd0f097ebb04f05" + "funcsigs": { + "version": "==1.0.2", + "hash": "sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca" }, - "codecov": { - "version": "==2.0.5", - "hash": "sha256:9fb0cd4a43fe538b4ea229607d0a7d65b00f9bfb37bb6af60a17f4ac33707334" + "coverage": { + "version": "==4.3.4", + "hash": "sha256:36407249a0b6669c6ad4425b0f29685579df745480c03afa70f101f09f4eead3" }, "Flask": { "version": "==0.12", "hash": "sha256:7f03bb2c255452444f7265eddb51601806e5447b6f8a2d50bbc77a654a14c118" }, - "Babel": { - "version": "==2.3.4", - "hash": "sha256:3318ed2960240d61cbc6558858ee00c10eed77a6508c4d1ed8e6f7f48399c975" - }, "alabaster": { "version": "==0.7.9", "hash": "sha256:d3e64a74919373d6d4d1d36bd717206584cb64cbb0532dfce3bc2081cba6817b" }, + "pytest-mock": { + "version": "==1.5.0", + "hash": "sha256:8e0fd43280c717f36920b60356bd713291b81a61704c94bc13aae9a12ef7fbd8" + }, "packaging": { "version": "==16.8", "hash": "sha256:99276dc6e3a7851f32027a68f1095cd3f77c148091b092ea867a351811cfe388" @@ -37,17 +41,13 @@ "version": "==0.23", "hash": "sha256:a4ec1aff59b95a14b45eb2e23761a0179e98319da5a7eb76b56ea8cdc7b871c3" }, - "funcsigs": { - "version": "==1.0.2", - "hash": "sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca" - }, "pytz": { "version": "==2016.10", "hash": "sha256:a1ea35e87a63c7825846d5b5c81d23d668e8a102d3b1b465ce95afe1b3a2e065" }, - "coverage": { - "version": "==4.3.4", - "hash": "sha256:36407249a0b6669c6ad4425b0f29685579df745480c03afa70f101f09f4eead3" + "codecov": { + "version": "==2.0.5", + "hash": "sha256:9fb0cd4a43fe538b4ea229607d0a7d65b00f9bfb37bb6af60a17f4ac33707334" }, "pytest-httpbin": { "version": "==0.2.3", @@ -65,9 +65,9 @@ "version": "==6.7", "hash": "sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d" }, - "decorator": { - "version": "==4.0.11", - "hash": "sha256:73cbaadb8bc4e3c65fe1100773d56331a2d756cc0f5c7b9d8d5d5223fe04f600" + "appdirs": { + "version": "==1.4.0", + "hash": "sha256:85e58578db8f29538f3109c11250c2a5514a2fcdc9890d9b2fe777eb55517736" }, "imagesize": { "version": "==0.7.1", @@ -77,49 +77,49 @@ "version": "==1.4.0", "hash": "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314" }, - "Pygments": { - "version": "==2.2.0", - "hash": "sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d" - }, - "pytest_mock": { - "version": "==1.5.0", - "hash": "sha256:8e0fd43280c717f36920b60356bd713291b81a61704c94bc13aae9a12ef7fbd8" - }, - "snowballstemmer": { - "version": "==1.2.1", - "hash": "sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89" + "sphinx": { + "version": "==1.5.2", + "hash": "sha256:57c8636e1d23f6c01fb19911a8f255f1b4934ba69feb55bd4dd0f097ebb04f05" }, "pbr": { "version": "==1.10.0", "hash": "sha256:f5cf7265a80636ecff66806d13494cbf9d77a3758a65fd8b4d4d4bee81b0c375" }, - "pytest_cov": { + "babel": { + "version": "==2.3.4", + "hash": "sha256:3318ed2960240d61cbc6558858ee00c10eed77a6508c4d1ed8e6f7f48399c975" + }, + "py": { + "version": "==1.4.32", + "hash": "sha256:2d4bba2e25fff58140e6bdce1e485e89bb59776adbe01d490baa6b1f37a3dd6b" + }, + "pytest-cov": { "version": "==2.4.0", "hash": "sha256:10e37e876f49ddec80d6c83a54b657157f1387ebc0f7755285f8c156130014a1" }, - "six": { - "version": "==1.10.0", - "hash": "sha256:0ff78c403d9bccf5a425a6d31a12aa6b47f1c21ca4dc2573a7e2f32a97335eb1" - }, - "docutils": { - "version": "==0.13.1", - "hash": "sha256:de454f1015958450b72641165c08afe7023cd7e3944396448f2fb1b0ccba9d77" - }, "pytest": { "version": "==3.0.6", "hash": "sha256:da0ab50c7eec0683bc24f1c1137db1f4111752054ecdad63125e7ec71316b813" }, - "Jinja2": { - "version": "==2.9.4", - "hash": "sha256:93b97a811b575998899b293fdb2144c536aeb7d6ee13464b0cf8e86ae64eb56b" + "docutils": { + "version": "==0.13.1", + "hash": "sha256:de454f1015958450b72641165c08afe7023cd7e3944396448f2fb1b0ccba9d77" }, - "appdirs": { - "version": "==1.4.0", - "hash": "sha256:85e58578db8f29538f3109c11250c2a5514a2fcdc9890d9b2fe777eb55517736" + "Pygments": { + "version": "==2.2.0", + "hash": "sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d" + }, + "Jinja2": { + "version": "==2.9.5", + "hash": "sha256:a7b7438120dbe76a8e735ef7eba6048eaf4e0b7dbc530e100812f8ec462a4d50" + }, + "decorator": { + "version": "==4.0.11", + "hash": "sha256:73cbaadb8bc4e3c65fe1100773d56331a2d756cc0f5c7b9d8d5d5223fe04f600" }, "setuptools": { - "version": "==34.0.2", - "hash": "sha256:f9ac44de8b36a13ce35d2989052a295a548c9fe5a161fb066dff53592200aa12" + "version": "==34.1.0", + "hash": "sha256:edd9d39782fe38b9c533002b2e6fdf06498793cbd29266accdcc519431d4b7ba" }, "requests": { "version": "==2.13.0", @@ -129,9 +129,9 @@ "version": "==0.24", "hash": "sha256:cbb3fcf8d3e33df861709ecaf89d9e6629cff0a217bc2848f1b41cd30d360519" }, - "PySocks": { - "version": "==1.6.5", - "hash": "sha256:7962f4d7c76e8414ae168c677a77f19cf8926143911f7e8d37a5d4c4eb910c6f" + "pysocks": { + "version": "==1.6.6", + "hash": "sha256:02419a225ff5dcfc3c9695ef8fc9b4d8cc99658e650c6d4718d4c8f451e63f41" }, "mock": { "version": "==2.0.0", @@ -146,6 +146,8 @@ } ], "requires": {}, - "Pipfile-sha256": "54439fbdf043a2efe430cc27886cb6cbcc3f5642e7c93da6b96198c473153684" + "hash": { + "sha256": "0b4728fe74b683054ddde5b9dba7dd674ce17b6726764407a9779b4fdd0afd47" + } } } \ No newline at end of file From 62176a1ca7207db37273365b4691ed599203b828 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 2 Feb 2017 16:12:33 -0500 Subject: [PATCH 091/104] 2017 --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index fb8a01e0..41bc6066 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -59,7 +59,7 @@ master_doc = 'index' # General information about the project. project = u'Requests' -copyright = u'2016. A Kenneth Reitz Project' +copyright = u'2017. A Kenneth Reitz Project' author = u'Kenneth Reitz' # The version info for the project you're documenting, acts as replacement for From f521a25970140e187d43458efc2bdea37dc93f17 Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Fri, 3 Feb 2017 09:29:13 -0700 Subject: [PATCH 092/104] remove pin --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8c1e25b8..d3822803 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: docs init: - pip install pipenv==3.1.9 + pip install pipenv pipenv lock pipenv install --dev From 593734b77092439b533e8e0599be6d204867b751 Mon Sep 17 00:00:00 2001 From: Marcos Dione Date: Mon, 6 Feb 2017 17:27:16 +0100 Subject: [PATCH 093/104] do not convert /o\ into /O\ --- requests/status_codes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requests/status_codes.py b/requests/status_codes.py index db2986bb..a7980ca5 100644 --- a/requests/status_codes.py +++ b/requests/status_codes.py @@ -87,5 +87,5 @@ codes = LookupDict(name='status_codes') for code, titles in _codes.items(): for title in titles: setattr(codes, title, code) - if not title.startswith('\\'): + if not title.startswith('\\') and not title.strartswith('/'): setattr(codes, title.upper(), code) From b00d8bf474cf5e2850ba83a11b7e372dad4bf119 Mon Sep 17 00:00:00 2001 From: Marcos Dione Date: Mon, 6 Feb 2017 21:44:28 +0100 Subject: [PATCH 094/104] Proper version, no bugs, shorter. --- requests/status_codes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requests/status_codes.py b/requests/status_codes.py index a7980ca5..79e5c4e3 100644 --- a/requests/status_codes.py +++ b/requests/status_codes.py @@ -87,5 +87,5 @@ codes = LookupDict(name='status_codes') for code, titles in _codes.items(): for title in titles: setattr(codes, title, code) - if not title.startswith('\\') and not title.strartswith('/'): + if not if not title.startswith(('\\', '/')): setattr(codes, title.upper(), code) From 571d2c2cd7495e6fb81f656abdd2b3d3f593f1f0 Mon Sep 17 00:00:00 2001 From: Marcos Dione Date: Tue, 7 Feb 2017 16:57:17 +0100 Subject: [PATCH 095/104] Fix syntax error I can only wonder how I managed to write it like that... --- requests/status_codes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requests/status_codes.py b/requests/status_codes.py index 79e5c4e3..dee89190 100644 --- a/requests/status_codes.py +++ b/requests/status_codes.py @@ -87,5 +87,5 @@ codes = LookupDict(name='status_codes') for code, titles in _codes.items(): for title in titles: setattr(codes, title, code) - if not if not title.startswith(('\\', '/')): + if not title.startswith(('\\', '/')): setattr(codes, title.upper(), code) From 08ce652b8b42c64ad904133ceb3e4f71df90c03c Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Wed, 8 Feb 2017 11:54:32 +0000 Subject: [PATCH 096/104] Say that we use a dictionary of strings. --- docs/user/quickstart.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/user/quickstart.rst b/docs/user/quickstart.rst index 232760f4..60cc73fb 100644 --- a/docs/user/quickstart.rst +++ b/docs/user/quickstart.rst @@ -57,8 +57,8 @@ Passing Parameters In URLs You often want to send some sort of data in the URL's query string. If you were constructing the URL by hand, this data would be given as key/value pairs in the URL after a question mark, e.g. ``httpbin.org/get?key=val``. -Requests allows you to provide these arguments as a dictionary, using the -``params`` keyword argument. As an example, if you wanted to pass +Requests allows you to provide these arguments as a dictionary of strings, +using the ``params`` keyword argument. As an example, if you wanted to pass ``key1=value1`` and ``key2=value2`` to ``httpbin.org/get``, you would use the following code:: From e63dd1a66b1bedbf14ee730c5b7b093e0451ce3c Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 9 Feb 2017 21:31:14 -0500 Subject: [PATCH 097/104] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 9b5f7aa9..30a032a8 100644 --- a/README.rst +++ b/README.rst @@ -20,7 +20,7 @@ Requests: HTTP for Humans :target: https://codecov.io/github/kennethreitz/requests :alt: codecov.io -.. image:: https://img.shields.io/badge/Say%20Thanks!-🦉-1EAEDB.svg +.. image:: https://img.shields.io/badge/SayThanks-!-1EAEDB.svg :target: https://saythanks.io/to/kennethreitz From 84749f08bc80caa2987efb8217a1ce10db237232 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 9 Feb 2017 21:31:38 -0500 Subject: [PATCH 098/104] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 30a032a8..d276e42a 100644 --- a/README.rst +++ b/README.rst @@ -20,7 +20,7 @@ Requests: HTTP for Humans :target: https://codecov.io/github/kennethreitz/requests :alt: codecov.io -.. image:: https://img.shields.io/badge/SayThanks-!-1EAEDB.svg +.. image:: https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg :target: https://saythanks.io/to/kennethreitz From a0b97253c2f29022c55cfef2453068437f523d56 Mon Sep 17 00:00:00 2001 From: mattkohl Date: Fri, 10 Feb 2017 10:45:06 +0000 Subject: [PATCH 099/104] Removed docs-init (depended on missing docs/requirements.txt) --- Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Makefile b/Makefile index d3822803..ee737f9e 100644 --- a/Makefile +++ b/Makefile @@ -52,10 +52,6 @@ publish: twine upload dist/* rm -fr build dist .egg requests.egg-info - -docs-init: - pip install -r docs/requirements.txt - docs: cd docs && make html @echo "\033[95m\n\nBuild successful! View the docs homepage at docs/_build/html/index.html.\n\033[0m" From 7b190acf82e41f8203143ad08eb8c76aaffc2f14 Mon Sep 17 00:00:00 2001 From: mattkohl Date: Fri, 10 Feb 2017 10:46:35 +0000 Subject: [PATCH 100/104] Updated Pipfile to reflect version specs in setup.py; added Sphinx --- Pipfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Pipfile b/Pipfile index 2e7ec08d..0f528f0d 100644 --- a/Pipfile +++ b/Pipfile @@ -3,10 +3,12 @@ url = "https://pypi.python.org/simple" verify_ssl = true [dev-packages] -pytest = "*" +pytest = ">=2.8.0" codecov = "*" -pytest-httpbin = "*" +pytest-httpbin = "==0.0.7" sphinx = "*" pytest-mock = "*" pytest-cov = "*" pysocks = "*" +sphinx = "*" +alabaster = "*" From a3e671d717d575b579b7a4fdd710e0d3a63b2bbf Mon Sep 17 00:00:00 2001 From: mattkohl Date: Fri, 10 Feb 2017 10:47:40 +0000 Subject: [PATCH 101/104] Updated test instructions for Pipenv --- docs/dev/todo.rst | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/docs/dev/todo.rst b/docs/dev/todo.rst index 14dafed3..d4862fbb 100644 --- a/docs/dev/todo.rst +++ b/docs/dev/todo.rst @@ -23,13 +23,23 @@ Development Dependencies You'll need to install py.test in order to run the Requests' test suite:: - $ pip install -r requirements.txt - $ py.test - platform darwin -- Python 2.7.3 -- pytest-2.3.4 - collected 25 items + $ pip install pipenv + $ pipenv lock + $ pipenv install --dev + $ pipenv run py.test tests + ============================= test session starts ============================== + platform darwin -- Python 3.4.4, pytest-3.0.6, py-1.4.32, pluggy-0.4.0 + ... + collected 445 items - test_requests.py ......................... - 25 passed in 3.50 seconds + tests/test_hooks.py ... + tests/test_lowlevel.py ............ + tests/test_requests.py ........................................................... + tests/test_structures.py .................... + tests/test_testserver.py ........... + tests/test_utils.py ..s........................................................... + + ============== 442 passed, 1 skipped, 2 xpassed in 46.48 seconds =============== Runtime Environments -------------------- From b41bb9ecb2d8e633ea693f36776930098f0584e4 Mon Sep 17 00:00:00 2001 From: mattkohl Date: Fri, 10 Feb 2017 10:48:15 +0000 Subject: [PATCH 102/104] Added name & github link --- AUTHORS.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.rst b/AUTHORS.rst index cc9e75f3..d29fa812 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -176,3 +176,4 @@ Patches and Suggestions - Casey Davidson (`@davidsoncasey `_) - Andrii Soldatenko (`@a_soldatenko `_) - Moinuddin Quadri (`@moin18 `_) +- Matt Kohl (`@mattkohl `_) From c134388a43eef18b2dcb3b9a515898cea9a091e5 Mon Sep 17 00:00:00 2001 From: mattkohl Date: Fri, 10 Feb 2017 10:51:14 +0000 Subject: [PATCH 103/104] Removed requirements.txt from MANIFEST.in --- MANIFEST.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 439de496..46ef0b46 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1 @@ -include README.rst LICENSE NOTICE HISTORY.rst test_requests.py requirements.txt requests/cacert.pem +include README.rst LICENSE NOTICE HISTORY.rst test_requests.py requests/cacert.pem From 57659e5987e7a9649dd3d59b256cd8e917d2b2e1 Mon Sep 17 00:00:00 2001 From: mattkohl Date: Fri, 10 Feb 2017 11:46:59 +0000 Subject: [PATCH 104/104] Removed duplicate key in Pipfile --- Pipfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Pipfile b/Pipfile index 0f528f0d..617c7ffa 100644 --- a/Pipfile +++ b/Pipfile @@ -10,5 +10,4 @@ sphinx = "*" pytest-mock = "*" pytest-cov = "*" pysocks = "*" -sphinx = "*" alabaster = "*"