Farewell, sweet Concorde!

Formally removing any remaining vestiges of Python 2 from Requests.
We'll also leave behind Python 3.6 while we're at it.
This commit is contained in:
Nate Prewitt
2022-03-25 10:50:33 -06:00
committed by GitHub
parent 79f60274f7
commit 8bce583b95
19 changed files with 139 additions and 178 deletions
+2 -5
View File
@@ -9,14 +9,11 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10"]
python-version: ["3.7", "3.8", "3.9", "3.10"]
os: [ubuntu-18.04, macOS-latest, windows-latest]
include:
# pypy3 on Mac OS currently fails trying to compile
# pypy-3.7 on Mac OS currently fails trying to compile
# brotlipy. Moving pypy3 to only test linux.
- python-version: pypy3
os: ubuntu-latest
experimental: false
- python-version: pypy-3.7
os: ubuntu-latest
experimental: false
+5
View File
@@ -11,6 +11,11 @@ dev
- Fixed urllib3 exception leak, wrapping `urllib3.exceptions.SSLError` with
`requests.exceptions.SSLError` for `content` and `iter_content`.
**Deprecations**
- ⚠️ Requests has officially dropped support for Python 2.7. ⚠️
- Requests has officially dropped support for Python 3.6 (including pypy3).
2.27.1 (2022-01-05)
-------------------
+1 -1
View File
@@ -33,7 +33,7 @@ Requests is available on PyPI:
$ python -m pip install requests
```
Requests officially supports Python 2.7 & 3.6+.
Requests officially supports Python 3.7+.
## Supported Features & BestPractices
+6 -9
View File
@@ -55,16 +55,16 @@ Chris Adams gave an excellent summary on
Python 3 Support?
-----------------
Yes! Requests officially supports Python 2.7 & 3.6+ and PyPy.
Yes! Requests officially supports Python 3.7+ and PyPy.
Python 2 Support?
-----------------
Yes! We understand that we have a large user base with varying needs. Through
**at least** Requests 2.27.x, we will be providing continued support for Python
2.7. However, this support is likely to end some time in 2022.
No! As of Requests 2.28.0, Requests no longer supports Python 2.7. Users who
have been unable to migrate should pin to `requests<2.28`. Full information
can be found in `psf/requests#6023 <https://github.com/psf/requests/issues/6023>`_.
It is *highly* recommended users migrate to Python 3.7+ now since Python
It is *highly* recommended users migrate to Python 3.8+ now since Python
2.7 is no longer receiving bug fixes or security updates as of January 1, 2020.
What are "hostname doesn't match" errors?
@@ -83,10 +83,7 @@ when servers are using `Virtual Hosting`_. When such servers are hosting
more than one SSL site they need to be able to return the appropriate
certificate based on the hostname the client is connecting to.
Python3 and Python 2.7.9+ include native support for SNI in their SSL modules.
For information on using SNI with Requests on Python < 2.7.9 refer to this
`Stack Overflow answer`_.
Python 3 already includes native support for SNI in their SSL modules.
.. _`Server-Name-Indication`: https://en.wikipedia.org/wiki/Server_Name_Indication
.. _`virtual hosting`: https://en.wikipedia.org/wiki/Virtual_hosting
.. _`Stack Overflow answer`: https://stackoverflow.com/questions/18578439/using-requests-with-tls-doesnt-give-sni-support/18579484#18579484
+1 -1
View File
@@ -72,7 +72,7 @@ Requests is ready for today's web.
- Chunked Requests
- ``.netrc`` Support
Requests officially supports Python 2.7 & 3.6+, and runs great on PyPy.
Requests officially supports Python 3.7+, and runs great on PyPy.
The User Guide
+2 -5
View File
@@ -8,7 +8,7 @@ Provides utility functions that are consumed internally by Requests
which depend on extremely few external helpers (such as compat)
"""
from .compat import is_py2, builtin_str, str
from .compat import builtin_str
def to_native_string(string, encoding='ascii'):
@@ -19,10 +19,7 @@ def to_native_string(string, encoding='ascii'):
if isinstance(string, builtin_str):
out = string
else:
if is_py2:
out = string.encode(encoding)
else:
out = string.decode(encoding)
out = string.decode(encoding)
return out
+1 -6
View File
@@ -477,12 +477,7 @@ class HTTPAdapter(BaseAdapter):
low_conn.send(b'0\r\n\r\n')
# Receive the response from the server
try:
# For Python 2.7, use buffering of HTTP responses
r = low_conn.getresponse(buffering=True)
except TypeError:
# For compatibility with Python 3.3+
r = low_conn.getresponse()
r = low_conn.getresponse()
resp = HTTPResponse.from_httplib(
r,
+24 -42
View File
@@ -4,8 +4,9 @@
requests.compat
~~~~~~~~~~~~~~~
This module handles import compatibility issues between Python 2 and
Python 3.
This module previously handled import compatibility issues
between Python 2 and Python 3. It remains for backwards
compatibility until the next major version.
"""
try:
@@ -28,6 +29,7 @@ is_py2 = (_ver[0] == 2)
#: Python 3.x?
is_py3 = (_ver[0] == 3)
# json/simplejson module import resolution
has_simplejson = False
try:
import simplejson as json
@@ -35,47 +37,27 @@ try:
except ImportError:
import json
if has_simplejson:
from simplejson import JSONDecodeError
else:
from json import JSONDecodeError
# ---------
# Specifics
# Legacy Imports
# ---------
from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag
from urllib.request import parse_http_list, getproxies, proxy_bypass, proxy_bypass_environment, getproxies_environment
from http import cookiejar as cookielib
from http.cookies import Morsel
from io import StringIO
if is_py2:
from urllib import (
quote, unquote, quote_plus, unquote_plus, urlencode, getproxies,
proxy_bypass, proxy_bypass_environment, getproxies_environment)
from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag
from urllib2 import parse_http_list
import cookielib
from Cookie import Morsel
from StringIO import StringIO
# Keep OrderedDict for backwards compatibility.
from collections import Callable, Mapping, MutableMapping, OrderedDict
# Keep OrderedDict for backwards compatibility.
from collections import OrderedDict
from collections.abc import Callable, Mapping, MutableMapping
builtin_str = str
bytes = str
str = unicode
basestring = basestring
numeric_types = (int, long, float)
integer_types = (int, long)
JSONDecodeError = ValueError
elif is_py3:
from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag
from urllib.request import parse_http_list, getproxies, proxy_bypass, proxy_bypass_environment, getproxies_environment
from http import cookiejar as cookielib
from http.cookies import Morsel
from io import StringIO
# Keep OrderedDict for backwards compatibility.
from collections import OrderedDict
from collections.abc import Callable, Mapping, MutableMapping
if has_simplejson:
from simplejson import JSONDecodeError
else:
from json import JSONDecodeError
builtin_str = str
str = str
bytes = bytes
basestring = (str, bytes)
numeric_types = (int, float)
integer_types = (int,)
builtin_str = str
str = str
bytes = bytes
basestring = (str, bytes)
numeric_types = (int, float)
integer_types = (int,)
+2 -2
View File
@@ -36,8 +36,8 @@ def _implementation():
"""Return a dict with the Python implementation and version.
Provide both the name and the version of the Python implementation
currently running. For example, on CPython 2.7.5 it will return
{'name': 'CPython', 'version': '2.7.5'}.
currently running. For example, on CPython 3.10.3 it will return
{'name': 'CPython', 'version': '3.10.3'}.
This function works best on CPython and PyPy: in particular, it probably
doesn't work for Jython or IronPython. Future investigation should be done
+4 -20
View File
@@ -8,7 +8,6 @@ This module contains the primary objects that power Requests.
"""
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,
@@ -45,8 +44,8 @@ from .utils import (
iter_slices, guess_json_utf, super_len, check_header_validity)
from .compat import (
Callable, Mapping,
cookielib, urlunparse, urlsplit, urlencode, str, bytes,
is_py2, chardet, builtin_str, basestring, JSONDecodeError)
cookielib, urlunparse, urlsplit, urlencode,
chardet, builtin_str, basestring, JSONDecodeError)
from .compat import json as complexjson
from .status_codes import codes
@@ -373,7 +372,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
if isinstance(url, bytes):
url = url.decode('utf8')
else:
url = unicode(url) if is_py2 else str(url)
url = str(url)
# Remove leading whitespaces from url
url = url.lstrip()
@@ -424,18 +423,6 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
if not path:
path = '/'
if is_py2:
if isinstance(scheme, str):
scheme = scheme.encode('utf-8')
if isinstance(netloc, str):
netloc = netloc.encode('utf-8')
if isinstance(path, str):
path = path.encode('utf-8')
if isinstance(query, str):
query = query.encode('utf-8')
if isinstance(fragment, str):
fragment = fragment.encode('utf-8')
if isinstance(params, (str, bytes)):
params = to_native_string(params)
@@ -919,10 +906,7 @@ class Response(object):
except JSONDecodeError as e:
# Catch JSON-related errors and raise as requests.JSONDecodeError
# This aliases json.JSONDecodeError and simplejson.JSONDecodeError
if is_py2: # e is a ValueError
raise RequestsJSONDecodeError(e.message)
else:
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
@property
def links(self):
+3 -7
View File
@@ -14,7 +14,7 @@ from datetime import timedelta
from collections import OrderedDict
from .auth import _basic_auth_str
from .compat import cookielib, is_py3, urljoin, urlparse, Mapping
from .compat import cookielib, urljoin, urlparse, Mapping
from .cookies import (
cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies)
from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT
@@ -39,10 +39,7 @@ from .models import REDIRECT_STATI
# Preferred clock, based on which one is more accurate on a given system.
if sys.platform == 'win32':
try: # Python 3.4+
preferred_clock = time.perf_counter
except AttributeError: # Earlier than Python 3.
preferred_clock = time.clock
preferred_clock = time.perf_counter
else:
preferred_clock = time.time
@@ -111,8 +108,7 @@ class SessionRedirectMixin(object):
# It is more likely to get UTF8 header rather than latin1.
# This causes incorrect handling of UTF8 encoded location headers.
# To solve this, we re-encode the location in latin1.
if is_py3:
location = location.encode('latin1')
location = location.encode('latin1')
return to_native_string(location, 'utf8')
return None
+3 -7
View File
@@ -30,7 +30,7 @@ from ._internal_utils import to_native_string
from .compat import parse_http_list as _parse_list_header
from .compat import (
quote, urlparse, bytes, str, unquote, getproxies,
proxy_bypass, urlunparse, basestring, integer_types, is_py3,
proxy_bypass, urlunparse, basestring, integer_types,
proxy_bypass_environment, getproxies_environment, Mapping)
from .cookies import cookiejar_from_dict
from .structures import CaseInsensitiveDict
@@ -54,10 +54,7 @@ if sys.platform == 'win32':
def proxy_bypass_registry(host):
try:
if is_py3:
import winreg
else:
import _winreg as winreg
import winreg
except ImportError:
return False
@@ -281,12 +278,11 @@ def extract_zipped_paths(path):
@contextlib.contextmanager
def atomic_open(filename):
"""Write a file to the disk in an atomic fashion"""
replacer = os.rename if sys.version_info[0] == 2 else os.replace
tmp_descriptor, tmp_name = tempfile.mkstemp(dir=os.path.dirname(filename))
try:
with os.fdopen(tmp_descriptor, 'wb') as tmp_handler:
yield tmp_handler
replacer(tmp_name, filename)
os.replace(tmp_name, filename)
except BaseException:
os.remove(tmp_name)
raise
+8 -3
View File
@@ -1,5 +1,10 @@
[bdist_wheel]
universal = 1
[metadata]
license_file = LICENSE
provides-extra =
socks
use_chardet_on_py3
requires-dist =
certifi>=2017.4.17
charset_normalizer~=2.0.0
idna>=2.5,<4
urllib3>=1.21.1,<1.27
+30 -17
View File
@@ -1,5 +1,4 @@
#!/usr/bin/env python
# Learn more: https://github.com/kennethreitz/setup.py
import os
import sys
@@ -8,7 +7,27 @@ from codecs import open
from setuptools import setup
from setuptools.command.test import test as TestCommand
here = os.path.abspath(os.path.dirname(__file__))
CURRENT_PYTHON = sys.version_info[:2]
REQUIRED_PYTHON = (3, 7)
if CURRENT_PYTHON < REQUIRED_PYTHON:
sys.stderr.write(
"""
==========================
Unsupported Python version
==========================
This version of Requests requires at least Python {}.{}, but
you're trying to install it on Python {}.{}. To resolve this,
consider upgrading to a supported Python version.
If you can't upgrade your Python version, you'll need to
pin to an older version of Requests (<2.28).
""".format(
*(REQUIRED_PYTHON + CURRENT_PYTHON)
)
)
sys.exit(1)
class PyTest(TestCommand):
user_options = [('pytest-args=', 'a', "Arguments to pass into py.test")]
@@ -38,16 +57,11 @@ if sys.argv[-1] == 'publish':
os.system('twine upload dist/*')
sys.exit()
packages = ['requests']
requires = [
'charset_normalizer~=2.0.0; python_version >= "3"',
'chardet>=3.0.2,<5; python_version < "3"',
'idna>=2.5,<3; python_version < "3"',
'idna>=2.5,<4; python_version >= "3"',
'charset_normalizer~=2.0.0',
'idna>=2.5,<4',
'urllib3>=1.21.1,<1.27',
'certifi>=2017.4.17'
'certifi>=2017.4.17',
]
test_requirements = [
'pytest-httpbin==0.0.7',
@@ -55,10 +69,11 @@ test_requirements = [
'pytest-mock',
'pytest-xdist',
'PySocks>=1.5.6, !=1.5.7',
'pytest>=3'
'pytest>=3',
]
about = {}
here = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(here, 'requests', '__version__.py'), 'r', 'utf-8') as f:
exec(f.read(), about)
@@ -74,11 +89,11 @@ setup(
author=about['__author__'],
author_email=about['__author_email__'],
url=about['__url__'],
packages=packages,
packages=['requests'],
package_data={'': ['LICENSE', 'NOTICE']},
package_dir={'requests': 'requests'},
include_package_data=True,
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*",
python_requires=">=3.7, <4",
install_requires=requires,
license=about['__license__'],
zip_safe=False,
@@ -90,14 +105,13 @@ setup(
'Natural Language :: English',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Internet :: WWW/HTTP',
@@ -108,7 +122,6 @@ setup(
extras_require={
'security': [],
'socks': ['PySocks>=1.5.6, !=1.5.7'],
'socks:sys_platform == "win32" and python_version == "2.7"': ['win_inet_pton'],
'use_chardet_on_py3': ['chardet>=3.0.2,<5']
},
project_urls={
+12 -9
View File
@@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
from requests.compat import is_py3
import warnings
try:
import StringIO
@@ -13,9 +11,14 @@ try:
except ImportError:
cStringIO = None
if is_py3:
def u(s):
return s
else:
def u(s):
return s.decode('unicode-escape')
def u(s):
warnings.warn(
(
"This helper function is no longer relevant in Python 3. "
"Usage of this alias should be discontinued as it will be "
"removed in a future release of Requests."
),
DeprecationWarning,
)
return s
+32 -36
View File
@@ -2,7 +2,6 @@
"""Tests for Requests."""
from __future__ import division
import json
import os
import pickle
@@ -18,7 +17,7 @@ import urllib3
from requests.adapters import HTTPAdapter
from requests.auth import HTTPDigestAuth, _basic_auth_str
from requests.compat import (
Morsel, cookielib, getproxies, str, urlparse,
Morsel, cookielib, getproxies, urlparse,
builtin_str)
from requests.cookies import (
cookiejar_from_dict, morsel_to_cookie)
@@ -47,9 +46,9 @@ from requests.structures import CaseInsensitiveDict
from requests.sessions import SessionRedirectMixin
from requests.models import urlencode
from requests.hooks import default_hooks
from requests.compat import JSONDecodeError, is_py3, MutableMapping
from requests.compat import JSONDecodeError, MutableMapping
from .compat import StringIO, u
from .compat import StringIO
from .utils import override_environ
from urllib3.util import Timeout as Urllib3Timeout
@@ -519,7 +518,7 @@ class TestRequests:
@pytest.mark.parametrize(
'username, password', (
('user', 'pass'),
(u'имя'.encode('utf-8'), u'пароль'.encode('utf-8')),
('имя'.encode('utf-8'), 'пароль'.encode('utf-8')),
(42, 42),
(None, None),
))
@@ -843,8 +842,6 @@ class TestRequests:
with open('requirements-dev.txt') as f:
with pytest.raises(ValueError):
requests.post(url, data='[{"some": "data"}]', files={'some': f})
with pytest.raises(ValueError):
requests.post(url, data=u('[{"some": "data"}]'), files={'some': f})
def test_request_ok_set(self, httpbin):
r = requests.get(httpbin('status', '404'))
@@ -989,8 +986,8 @@ class TestRequests:
@pytest.mark.parametrize(
'data', (
{'stuff': u('ëlïxr')},
{'stuff': u('ëlïxr').encode('utf-8')},
{'stuff': 'ëlïxr'},
{'stuff': 'ëlïxr'.encode('utf-8')},
{'stuff': 'elixr'},
{'stuff': 'elixr'.encode('utf-8')},
))
@@ -1013,13 +1010,13 @@ class TestRequests:
def test_unicode_method_name(self, httpbin):
files = {'file': open(__file__, 'rb')}
r = requests.request(
method=u('POST'), url=httpbin('post'), files=files)
method='POST', url=httpbin('post'), files=files)
assert r.status_code == 200
def test_unicode_method_name_with_request_object(self, httpbin):
files = {'file': open(__file__, 'rb')}
s = requests.Session()
req = requests.Request(u('POST'), httpbin('post'), files=files)
req = requests.Request('POST', httpbin('post'), files=files)
prep = s.prepare_request(req)
assert isinstance(prep.method, builtin_str)
assert prep.method == 'POST'
@@ -1029,7 +1026,7 @@ class TestRequests:
def test_non_prepared_request_error(self):
s = requests.Session()
req = requests.Request(u('POST'), '/')
req = requests.Request('POST', '/')
with pytest.raises(ValueError) as e:
s.send(req)
@@ -1336,8 +1333,8 @@ class TestRequests:
def test_response_reason_unicode(self):
# check for unicode HTTP status
r = requests.Response()
r.url = u'unicode URL'
r.reason = u'Komponenttia ei löydy'.encode('utf-8')
r.url = 'unicode URL'
r.reason = 'Komponenttia ei löydy'.encode('utf-8')
r.status_code = 404
r.encoding = None
assert not r.ok # old behaviour - crashes here
@@ -1346,7 +1343,7 @@ class TestRequests:
# check raise_status falls back to ISO-8859-1
r = requests.Response()
r.url = 'some url'
reason = u'Komponenttia ei löydy'
reason = 'Komponenttia ei löydy'
r.reason = reason.encode('latin-1')
r.status_code = 500
r.encoding = None
@@ -1593,7 +1590,7 @@ class TestRequests:
assert r.url == url
def test_header_keys_are_native(self, httpbin):
headers = {u('unicode'): 'blah', 'byte'.encode('ascii'): 'blah'}
headers = {'unicode': 'blah', 'byte'.encode('ascii'): 'blah'}
r = requests.Request('GET', httpbin('get'), headers=headers)
p = r.prepare()
@@ -1605,7 +1602,7 @@ class TestRequests:
def test_header_validation(self, httpbin):
"""Ensure prepare_headers regex isn't flagging valid header contents."""
headers_ok = {'foo': 'bar baz qux',
'bar': u'fbbq'.encode('utf8'),
'bar': 'fbbq'.encode('utf8'),
'baz': '',
'qux': '1'}
r = requests.get(httpbin('get'), headers=headers_ok)
@@ -1885,7 +1882,7 @@ class TestRequests:
@pytest.mark.parametrize(
'username, password, auth_str', (
('test', 'test', 'Basic dGVzdDp0ZXN0'),
(u'имя'.encode('utf-8'), u'пароль'.encode('utf-8'), 'Basic 0LjQvNGPOtC/0LDRgNC+0LvRjA=='),
('имя'.encode('utf-8'), 'пароль'.encode('utf-8'), 'Basic 0LjQvNGPOtC/0LDRgNC+0LvRjA=='),
))
def test_basic_auth_str_is_always_native(self, username, password, auth_str):
s = _basic_auth_str(username, password)
@@ -2469,7 +2466,7 @@ def test_data_argument_accepts_tuples(data):
},
{
'method': 'GET',
'url': u('http://www.example.com/üniçø∂é')
'url': 'http://www.example.com/üniçø∂é'
},
))
def test_prepared_copy(kwargs):
@@ -2507,39 +2504,39 @@ class TestPreparingURLs(object):
'url,expected',
(
('http://google.com', 'http://google.com/'),
(u'http://ジェーピーニック.jp', u'http://xn--hckqz9bzb1cyrb.jp/'),
(u'http://xn--n3h.net/', u'http://xn--n3h.net/'),
('http://ジェーピーニック.jp', 'http://xn--hckqz9bzb1cyrb.jp/'),
('http://xn--n3h.net/', 'http://xn--n3h.net/'),
(
u'http://ジェーピーニック.jp'.encode('utf-8'),
u'http://xn--hckqz9bzb1cyrb.jp/'
'http://ジェーピーニック.jp'.encode('utf-8'),
'http://xn--hckqz9bzb1cyrb.jp/'
),
(
u'http://straße.de/straße',
u'http://xn--strae-oqa.de/stra%C3%9Fe'
'http://straße.de/straße',
'http://xn--strae-oqa.de/stra%C3%9Fe'
),
(
u'http://straße.de/straße'.encode('utf-8'),
u'http://xn--strae-oqa.de/stra%C3%9Fe'
'http://straße.de/straße'.encode('utf-8'),
'http://xn--strae-oqa.de/stra%C3%9Fe'
),
(
u'http://Königsgäßchen.de/straße',
u'http://xn--knigsgchen-b4a3dun.de/stra%C3%9Fe'
'http://Königsgäßchen.de/straße',
'http://xn--knigsgchen-b4a3dun.de/stra%C3%9Fe'
),
(
u'http://Königsgäßchen.de/straße'.encode('utf-8'),
u'http://xn--knigsgchen-b4a3dun.de/stra%C3%9Fe'
'http://Königsgäßchen.de/straße'.encode('utf-8'),
'http://xn--knigsgchen-b4a3dun.de/stra%C3%9Fe'
),
(
b'http://xn--n3h.net/',
u'http://xn--n3h.net/'
'http://xn--n3h.net/'
),
(
b'http://[1200:0000:ab00:1234:0000:2552:7777:1313]:12345/',
u'http://[1200:0000:ab00:1234:0000:2552:7777:1313]:12345/'
'http://[1200:0000:ab00:1234:0000:2552:7777:1313]:12345/'
),
(
u'http://[1200:0000:ab00:1234:0000:2552:7777:1313]:12345/',
u'http://[1200:0000:ab00:1234:0000:2552:7777:1313]:12345/'
'http://[1200:0000:ab00:1234:0000:2552:7777:1313]:12345/',
'http://[1200:0000:ab00:1234:0000:2552:7777:1313]:12345/'
)
)
)
@@ -2664,7 +2661,6 @@ class TestPreparingURLs(object):
assert isinstance(excinfo.value, JSONDecodeError)
assert r.text not in str(excinfo.value)
@pytest.mark.skipif(not is_py3, reason="doc attribute is only present on py3")
def test_json_decode_persists_doc_attr(self, httpbin):
r = requests.get(httpbin('bytes/20'))
with pytest.raises(requests.exceptions.JSONDecodeError) as excinfo:
+1 -4
View File
@@ -749,10 +749,7 @@ def test_should_bypass_proxies_win_registry(url, expected, override,
"""
if override is None:
override = '192.168.*;127.0.0.1;localhost.localdomain;172.16.1.1'
if compat.is_py3:
import winreg
else:
import _winreg as winreg
import winreg
class RegHandle:
def Close(self):
+1 -3
View File
@@ -78,9 +78,7 @@ class Server(threading.Thread):
def _create_socket_and_bind(self):
sock = socket.socket()
sock.bind((self.host, self.port))
# NB: when Python 2.7 is no longer supported, the argument
# can be removed to use a default backlog size
sock.listen(5)
sock.listen()
return sock
def _close_server_sock_ignore_errors(self):
+1 -1
View File
@@ -1,5 +1,5 @@
[tox]
envlist = py{27,36,37,38,39}-{default,use_chardet_on_py3}
envlist = py{37,38,39,310}-{default, use_chardet_on_py3}
[testenv]
deps = -rrequirements-dev.txt