summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo <hugovk@users.noreply.github.com>2018-08-23 20:36:25 +0300
committerSeth M. Larson <sethmichaellarson@gmail.com>2018-08-23 12:36:25 -0500
commitcb2159878f8b47c5b4bc6d159ae2857b85c0a197 (patch)
tree92a2a27fd324e0e40aed98eac759581f25c4de9f
parent85e376a16d61a01d9c943870c48f3be8b8957223 (diff)
downloadurllib3-cb2159878f8b47c5b4bc6d159ae2857b85c0a197.tar.gz
Drop support for Python 2.6 (#1429)
-rw-r--r--.travis.yml5
-rwxr-xr-x_travis/install.sh8
-rw-r--r--dev-requirements.txt11
-rw-r--r--docs/contributing.rst7
-rw-r--r--dummyserver/testcase.py7
-rw-r--r--setup.cfg7
-rwxr-xr-xsetup.py12
-rw-r--r--src/urllib3/__init__.py7
-rw-r--r--src/urllib3/_collections.py5
-rw-r--r--src/urllib3/connection.py14
-rw-r--r--src/urllib3/connectionpool.py16
-rw-r--r--src/urllib3/contrib/ntlmpool.py3
-rw-r--r--src/urllib3/packages/backports/makefile.py2
-rw-r--r--src/urllib3/packages/ordered_dict.py259
-rw-r--r--src/urllib3/request.py2
-rw-r--r--src/urllib3/util/ssl_.py29
-rw-r--r--test/__init__.py36
-rw-r--r--test/contrib/test_pyopenssl.py4
-rw-r--r--test/contrib/test_socks.py8
-rw-r--r--test/test_no_ssl.py12
-rw-r--r--test/test_poolmanager.py5
-rw-r--r--test/with_dummyserver/test_chunked_transfer.py6
-rw-r--r--test/with_dummyserver/test_connectionpool.py25
-rw-r--r--test/with_dummyserver/test_https.py31
-rw-r--r--test/with_dummyserver/test_no_ssl.py2
-rw-r--r--test/with_dummyserver/test_poolmanager.py4
-rw-r--r--test/with_dummyserver/test_proxy_poolmanager.py24
-rw-r--r--test/with_dummyserver/test_socketlevel.py15
-rw-r--r--tox.ini8
29 files changed, 82 insertions, 492 deletions
diff --git a/.travis.yml b/.travis.yml
index 38b0ac69..ff2a839d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -23,8 +23,6 @@ env:
# https://github.com/travis-ci/travis-ci/issues/4794
matrix:
include:
- - python: 2.6
- env: TOXENV=py26
- python: 2.7
env: TOXENV=py27
- python: 3.4
@@ -39,9 +37,6 @@ matrix:
env: TOXENV=pypy
- language: generic
os: osx
- env: TOXENV=py26
- - language: generic
- os: osx
env: TOXENV=py27
- language: generic
os: osx
diff --git a/_travis/install.sh b/_travis/install.sh
index dac22049..76bd226b 100755
--- a/_travis/install.sh
+++ b/_travis/install.sh
@@ -17,18 +17,10 @@ if [[ "$(uname -s)" == 'Darwin' ]]; then
eval "$(pyenv init -)"
case "${TOXENV}" in
- py26)
- pyenv install 2.6.9
- pyenv global 2.6.9
- ;;
py27)
pyenv install 2.7.14
pyenv global 2.7.14
;;
- py33)
- pyenv install 3.3.6
- pyenv global 3.3.6
- ;;
py34)
pyenv install 3.4.7
pyenv global 3.4.7
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 356b84d4..9a2a962a 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -3,12 +3,9 @@ coverage==4.5.1
tox==2.9.1
twine==1.11.0
wheel==0.30.0
-tornado==5.0.2; python_version>"2.6"
-tornado==4.2.1; python_version<="2.6"
+tornado==5.0.2
PySocks==1.6.8
pkginfo==1.4.2
-pytest-timeout==1.3.1; python_version>"2.6"
-pytest-timeout==1.2.0; python_version<="2.6"
-pytest==3.6.4; python_version>"2.6"
-pytest==3.2.5; python_version<="2.6"
-gcp-devrel-py-tools==0.0.15; python_version>"2.6"
+pytest-timeout==1.3.1
+pytest==3.6.4
+gcp-devrel-py-tools==0.0.15 \ No newline at end of file
diff --git a/docs/contributing.rst b/docs/contributing.rst
index 206f640f..13ea6c8b 100644
--- a/docs/contributing.rst
+++ b/docs/contributing.rst
@@ -55,11 +55,12 @@ suite::
$ make test-all
[... tox creates a virtualenv for every platform and runs tests inside of each]
- py26: commands succeeded
py27: commands succeeded
- py32: commands succeeded
- py33: commands succeeded
py34: commands succeeded
+ py35: commands succeeded
+ py36: commands succeeded
+ py37: commands succeeded
+ pypy: commands succeeded
Our test suite `runs continuously on Travis CI
<https://travis-ci.org/urllib3/urllib3>`_ with every pull request.
diff --git a/dummyserver/testcase.py b/dummyserver/testcase.py
index d9ff8cf4..ebd0bcb8 100644
--- a/dummyserver/testcase.py
+++ b/dummyserver/testcase.py
@@ -1,5 +1,5 @@
-import sys
import threading
+import unittest
import pytest
from tornado import ioloop, web
@@ -14,11 +14,6 @@ from dummyserver.server import (
from dummyserver.handlers import TestingApp
from dummyserver.proxy import ProxyHandler
-if sys.version_info >= (2, 7):
- import unittest
-else:
- import unittest2 as unittest
-
def consume_socket(sock, chunks=65536):
while not sock.recv(chunks).endswith(b'\r\n\r\n'):
diff --git a/setup.cfg b/setup.cfg
index 91c59cb6..efb26b86 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -11,10 +11,9 @@ provides-extra =
secure
socks
requires-dist =
- pyOpenSSL>=0.14,<18.0.0; python_version=="2.6" and extra == 'secure'
pyOpenSSL>=0.14; python_version=="2.7" and extra == 'secure'
- cryptography>=1.3.4; python_version<="2.7" and extra == 'secure'
- idna>=2.0.0; python_version<="2.7" and extra == 'secure'
+ cryptography>=1.3.4; python_version=="2.7" and extra == 'secure'
+ idna>=2.0.0; python_version=="2.7" and extra == 'secure'
certifi; extra == 'secure'
- ipaddress; python_version<="2.7" and extra == 'secure'
+ ipaddress; python_version=="2.7" and extra == 'secure'
PySocks>=1.5.6,<2.0,!=1.5.7; extra == 'socks'
diff --git a/setup.py b/setup.py
index 17f33776..28441648 100755
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,6 @@
from setuptools import setup
import os
-import sys
import re
import codecs
@@ -20,12 +19,6 @@ with codecs.open('CHANGES.rst', encoding='utf-8') as fp:
changes = fp.read()
version = VERSION
-# pyOpenSSL version 18.0.0 dropped support for Python 2.6
-if sys.version_info < (2, 7):
- PYOPENSSL_VERSION = 'pyOpenSSL >= 0.14, < 18.0.0'
-else:
- PYOPENSSL_VERSION = 'pyOpenSSL >= 0.14'
-
setup(name='urllib3',
version=version,
description="HTTP library with thread-safe connection pooling, file post, and more.",
@@ -37,7 +30,6 @@ setup(name='urllib3',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
@@ -60,7 +52,7 @@ setup(name='urllib3',
],
package_dir={'': 'src'},
requires=[],
- python_requires=">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4",
+ python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4",
tests_require=[
# These are a less-specific subset of dev-requirements.txt, for the
# convenience of distro package maintainers.
@@ -71,7 +63,7 @@ setup(name='urllib3',
test_suite='test',
extras_require={
'secure': [
- PYOPENSSL_VERSION,
+ 'pyOpenSSL >= 0.14',
'cryptography>=1.3.4',
'idna>=2.0.0',
'certifi',
diff --git a/src/urllib3/__init__.py b/src/urllib3/__init__.py
index 0cd5e342..f010fc4e 100644
--- a/src/urllib3/__init__.py
+++ b/src/urllib3/__init__.py
@@ -22,12 +22,7 @@ from .util.retry import Retry
# Set default logging handler to avoid "No handler found" warnings.
import logging
-try: # Python 2.7+
- from logging import NullHandler
-except ImportError:
- class NullHandler(logging.Handler):
- def emit(self, record):
- pass
+from logging import NullHandler
__author__ = 'Andrey Petrov (andrey.petrov@shazow.net)'
__license__ = 'MIT'
diff --git a/src/urllib3/_collections.py b/src/urllib3/_collections.py
index 6e36b84e..34f23811 100644
--- a/src/urllib3/_collections.py
+++ b/src/urllib3/_collections.py
@@ -14,10 +14,7 @@ except ImportError: # Platform-specific: No threads available
pass
-try: # Python 2.7+
- from collections import OrderedDict
-except ImportError:
- from .packages.ordered_dict import OrderedDict
+from collections import OrderedDict
from .exceptions import InvalidHeader
from .packages.six import iterkeys, itervalues, PY3
diff --git a/src/urllib3/connection.py b/src/urllib3/connection.py
index 4f662b0d..7c9a9f3b 100644
--- a/src/urllib3/connection.py
+++ b/src/urllib3/connection.py
@@ -2,7 +2,6 @@ from __future__ import absolute_import
import datetime
import logging
import os
-import sys
import socket
from socket import error as SocketError, timeout as SocketTimeout
import warnings
@@ -78,9 +77,6 @@ class HTTPConnection(_HTTPConnection, object):
- ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool`
- ``source_address``: Set the source address for the current connection.
-
- .. note:: This is ignored for Python 2.6. It is only applied for 2.7 and 3.x
-
- ``socket_options``: Set specific options on the underlying socket. If not specified, then
defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling
Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy.
@@ -108,21 +104,13 @@ class HTTPConnection(_HTTPConnection, object):
if six.PY3: # Python 3
kw.pop('strict', None)
- # Pre-set source_address in case we have an older Python like 2.6.
+ # Pre-set source_address.
self.source_address = kw.get('source_address')
- if sys.version_info < (2, 7): # Python 2.6
- # _HTTPConnection on Python 2.6 will balk at this keyword arg, but
- # not newer versions. We can still use it when creating a
- # connection though, so we pop it *after* we have saved it as
- # self.source_address.
- kw.pop('source_address', None)
-
#: The socket options provided by the user. If no options are
#: provided, we use the default options.
self.socket_options = kw.pop('socket_options', self.default_socket_options)
- # Superclass also sets self.source_address in Python 2.7+.
_HTTPConnection.__init__(self, *args, **kw)
@property
diff --git a/src/urllib3/connectionpool.py b/src/urllib3/connectionpool.py
index 8fcb0bce..8e58fa74 100644
--- a/src/urllib3/connectionpool.py
+++ b/src/urllib3/connectionpool.py
@@ -89,7 +89,7 @@ class ConnectionPool(object):
# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252
-_blocking_errnos = set([errno.EAGAIN, errno.EWOULDBLOCK])
+_blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK}
class HTTPConnectionPool(ConnectionPool, RequestMethods):
@@ -375,7 +375,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
try:
try: # Python 2.7, use buffering of HTTP responses
httplib_response = conn.getresponse(buffering=True)
- except TypeError: # Python 2.6 and older, Python 3
+ except TypeError: # Python 3
try:
httplib_response = conn.getresponse()
except Exception as e:
@@ -801,17 +801,7 @@ class HTTPSConnectionPool(HTTPConnectionPool):
Establish tunnel connection early, because otherwise httplib
would improperly set Host: header to proxy's IP:port.
"""
- # Python 2.7+
- try:
- set_tunnel = conn.set_tunnel
- except AttributeError: # Platform-specific: Python 2.6
- set_tunnel = conn._set_tunnel
-
- if sys.version_info <= (2, 6, 4) and not self.proxy_headers: # Python 2.6.4 and older
- set_tunnel(self._proxy_host, self.port)
- else:
- set_tunnel(self._proxy_host, self.port, self.proxy_headers)
-
+ conn.set_tunnel(self._proxy_host, self.port, self.proxy_headers)
conn.connect()
def _new_conn(self):
diff --git a/src/urllib3/contrib/ntlmpool.py b/src/urllib3/contrib/ntlmpool.py
index 642e99ed..8ea127c5 100644
--- a/src/urllib3/contrib/ntlmpool.py
+++ b/src/urllib3/contrib/ntlmpool.py
@@ -43,8 +43,7 @@ class NTLMConnectionPool(HTTPSConnectionPool):
log.debug('Starting NTLM HTTPS connection no. %d: https://%s%s',
self.num_connections, self.host, self.authurl)
- headers = {}
- headers['Connection'] = 'Keep-Alive'
+ headers = {'Connection': 'Keep-Alive'}
req_header = 'Authorization'
resp_header = 'www-authenticate'
diff --git a/src/urllib3/packages/backports/makefile.py b/src/urllib3/packages/backports/makefile.py
index 75b80dcf..740db377 100644
--- a/src/urllib3/packages/backports/makefile.py
+++ b/src/urllib3/packages/backports/makefile.py
@@ -16,7 +16,7 @@ def backport_makefile(self, mode="r", buffering=None, encoding=None,
"""
Backport of ``socket.makefile`` from Python 3.5.
"""
- if not set(mode) <= set(["r", "w", "b"]):
+ if not set(mode) <= {"r", "w", "b"}:
raise ValueError(
"invalid mode %r (only r, w, b allowed)" % (mode,)
)
diff --git a/src/urllib3/packages/ordered_dict.py b/src/urllib3/packages/ordered_dict.py
deleted file mode 100644
index 4479363c..00000000
--- a/src/urllib3/packages/ordered_dict.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy.
-# Passes Python2.7's test suite and incorporates all the latest updates.
-# Copyright 2009 Raymond Hettinger, released under the MIT License.
-# http://code.activestate.com/recipes/576693/
-try:
- from thread import get_ident as _get_ident
-except ImportError:
- from dummy_thread import get_ident as _get_ident
-
-try:
- from _abcoll import KeysView, ValuesView, ItemsView
-except ImportError:
- pass
-
-
-class OrderedDict(dict):
- 'Dictionary that remembers insertion order'
- # An inherited dict maps keys to values.
- # The inherited dict provides __getitem__, __len__, __contains__, and get.
- # The remaining methods are order-aware.
- # Big-O running times for all methods are the same as for regular dictionaries.
-
- # The internal self.__map dictionary maps keys to links in a doubly linked list.
- # The circular doubly linked list starts and ends with a sentinel element.
- # The sentinel element never gets deleted (this simplifies the algorithm).
- # Each link is stored as a list of length three: [PREV, NEXT, KEY].
-
- def __init__(self, *args, **kwds):
- '''Initialize an ordered dictionary. Signature is the same as for
- regular dictionaries, but keyword arguments are not recommended
- because their insertion order is arbitrary.
-
- '''
- if len(args) > 1:
- raise TypeError('expected at most 1 arguments, got %d' % len(args))
- try:
- self.__root
- except AttributeError:
- self.__root = root = [] # sentinel node
- root[:] = [root, root, None]
- self.__map = {}
- self.__update(*args, **kwds)
-
- def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
- 'od.__setitem__(i, y) <==> od[i]=y'
- # Setting a new item creates a new link which goes at the end of the linked
- # list, and the inherited dictionary is updated with the new key/value pair.
- if key not in self:
- root = self.__root
- last = root[0]
- last[1] = root[0] = self.__map[key] = [last, root, key]
- dict_setitem(self, key, value)
-
- def __delitem__(self, key, dict_delitem=dict.__delitem__):
- 'od.__delitem__(y) <==> del od[y]'
- # Deleting an existing item uses self.__map to find the link which is
- # then removed by updating the links in the predecessor and successor nodes.
- dict_delitem(self, key)
- link_prev, link_next, key = self.__map.pop(key)
- link_prev[1] = link_next
- link_next[0] = link_prev
-
- def __iter__(self):
- 'od.__iter__() <==> iter(od)'
- root = self.__root
- curr = root[1]
- while curr is not root:
- yield curr[2]
- curr = curr[1]
-
- def __reversed__(self):
- 'od.__reversed__() <==> reversed(od)'
- root = self.__root
- curr = root[0]
- while curr is not root:
- yield curr[2]
- curr = curr[0]
-
- def clear(self):
- 'od.clear() -> None. Remove all items from od.'
- try:
- for node in self.__map.itervalues():
- del node[:]
- root = self.__root
- root[:] = [root, root, None]
- self.__map.clear()
- except AttributeError:
- pass
- dict.clear(self)
-
- def popitem(self, last=True):
- '''od.popitem() -> (k, v), return and remove a (key, value) pair.
- Pairs are returned in LIFO order if last is true or FIFO order if false.
-
- '''
- if not self:
- raise KeyError('dictionary is empty')
- root = self.__root
- if last:
- link = root[0]
- link_prev = link[0]
- link_prev[1] = root
- root[0] = link_prev
- else:
- link = root[1]
- link_next = link[1]
- root[1] = link_next
- link_next[0] = root
- key = link[2]
- del self.__map[key]
- value = dict.pop(self, key)
- return key, value
-
- # -- the following methods do not depend on the internal structure --
-
- def keys(self):
- 'od.keys() -> list of keys in od'
- return list(self)
-
- def values(self):
- 'od.values() -> list of values in od'
- return [self[key] for key in self]
-
- def items(self):
- 'od.items() -> list of (key, value) pairs in od'
- return [(key, self[key]) for key in self]
-
- def iterkeys(self):
- 'od.iterkeys() -> an iterator over the keys in od'
- return iter(self)
-
- def itervalues(self):
- 'od.itervalues -> an iterator over the values in od'
- for k in self:
- yield self[k]
-
- def iteritems(self):
- 'od.iteritems -> an iterator over the (key, value) items in od'
- for k in self:
- yield (k, self[k])
-
- def update(*args, **kwds):
- '''od.update(E, **F) -> None. Update od from dict/iterable E and F.
-
- If E is a dict instance, does: for k in E: od[k] = E[k]
- If E has a .keys() method, does: for k in E.keys(): od[k] = E[k]
- Or if E is an iterable of items, does: for k, v in E: od[k] = v
- In either case, this is followed by: for k, v in F.items(): od[k] = v
-
- '''
- if len(args) > 2:
- raise TypeError('update() takes at most 2 positional '
- 'arguments (%d given)' % (len(args),))
- elif not args:
- raise TypeError('update() takes at least 1 argument (0 given)')
- self = args[0]
- # Make progressively weaker assumptions about "other"
- other = ()
- if len(args) == 2:
- other = args[1]
- if isinstance(other, dict):
- for key in other:
- self[key] = other[key]
- elif hasattr(other, 'keys'):
- for key in other.keys():
- self[key] = other[key]
- else:
- for key, value in other:
- self[key] = value
- for key, value in kwds.items():
- self[key] = value
-
- __update = update # let subclasses override update without breaking __init__
-
- __marker = object()
-
- def pop(self, key, default=__marker):
- '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value.
- If key is not found, d is returned if given, otherwise KeyError is raised.
-
- '''
- if key in self:
- result = self[key]
- del self[key]
- return result
- if default is self.__marker:
- raise KeyError(key)
- return default
-
- def setdefault(self, key, default=None):
- 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
- if key in self:
- return self[key]
- self[key] = default
- return default
-
- def __repr__(self, _repr_running={}):
- 'od.__repr__() <==> repr(od)'
- call_key = id(self), _get_ident()
- if call_key in _repr_running:
- return '...'
- _repr_running[call_key] = 1
- try:
- if not self:
- return '%s()' % (self.__class__.__name__,)
- return '%s(%r)' % (self.__class__.__name__, self.items())
- finally:
- del _repr_running[call_key]
-
- def __reduce__(self):
- 'Return state information for pickling'
- items = [[k, self[k]] for k in self]
- inst_dict = vars(self).copy()
- for k in vars(OrderedDict()):
- inst_dict.pop(k, None)
- if inst_dict:
- return (self.__class__, (items,), inst_dict)
- return self.__class__, (items,)
-
- def copy(self):
- 'od.copy() -> a shallow copy of od'
- return self.__class__(self)
-
- @classmethod
- def fromkeys(cls, iterable, value=None):
- '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
- and values equal to v (which defaults to None).
-
- '''
- d = cls()
- for key in iterable:
- d[key] = value
- return d
-
- def __eq__(self, other):
- '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
- while comparison to a regular mapping is order-insensitive.
-
- '''
- if isinstance(other, OrderedDict):
- return len(self)==len(other) and self.items() == other.items()
- return dict.__eq__(self, other)
-
- def __ne__(self, other):
- return not self == other
-
- # -- the following methods are only used in Python 2.7 --
-
- def viewkeys(self):
- "od.viewkeys() -> a set-like object providing a view on od's keys"
- return KeysView(self)
-
- def viewvalues(self):
- "od.viewvalues() -> an object providing a view on od's values"
- return ValuesView(self)
-
- def viewitems(self):
- "od.viewitems() -> a set-like object providing a view on od's items"
- return ItemsView(self)
diff --git a/src/urllib3/request.py b/src/urllib3/request.py
index 1be33341..8f2f44bb 100644
--- a/src/urllib3/request.py
+++ b/src/urllib3/request.py
@@ -36,7 +36,7 @@ class RequestMethods(object):
explicitly.
"""
- _encode_url_methods = set(['DELETE', 'GET', 'HEAD', 'OPTIONS'])
+ _encode_url_methods = {'DELETE', 'GET', 'HEAD', 'OPTIONS'}
def __init__(self, headers=None):
self.headers = headers or {}
diff --git a/src/urllib3/util/ssl_.py b/src/urllib3/util/ssl_.py
index 2893752a..9ca08bf6 100644
--- a/src/urllib3/util/ssl_.py
+++ b/src/urllib3/util/ssl_.py
@@ -56,9 +56,8 @@ except ImportError:
OP_NO_COMPRESSION = 0x20000
-# Python 2.7 and earlier didn't have inet_pton on non-Linux
-# so we fallback on inet_aton in those cases. This means that
-# we can only detect IPv4 addresses in this case.
+# Python 2.7 doesn't have inet_pton on non-Linux so we fallback on inet_aton in
+# those cases. This means that we can only detect IPv4 addresses in this case.
if hasattr(socket, 'inet_pton'):
inet_pton = socket.inet_pton
else:
@@ -115,9 +114,8 @@ try:
except ImportError:
import sys
- class SSLContext(object): # Platform-specific: Python 2 & 3.1
- supports_set_ciphers = ((2, 7) <= sys.version_info < (3,) or
- (3, 2) <= sys.version_info)
+ class SSLContext(object): # Platform-specific: Python 2
+ supports_set_ciphers = True
def __init__(self, protocol_version):
self.protocol = protocol_version
@@ -141,12 +139,6 @@ except ImportError:
raise SSLError("CA directories not supported in older Pythons")
def set_ciphers(self, cipher_suite):
- if not self.supports_set_ciphers:
- raise TypeError(
- 'Your version of Python does not support setting '
- 'a custom cipher suite. Please upgrade to Python '
- '2.7, 3.2, or later if you need this functionality.'
- )
self.ciphers = cipher_suite
def wrap_socket(self, socket, server_hostname=None, server_side=False):
@@ -167,10 +159,7 @@ except ImportError:
'ssl_version': self.protocol,
'server_side': server_side,
}
- if self.supports_set_ciphers: # Platform-specific: Python 2.7+
- return wrap_socket(socket, ciphers=self.ciphers, **kwargs)
- else: # Platform-specific: Python 2.6
- return wrap_socket(socket, **kwargs)
+ return wrap_socket(socket, ciphers=self.ciphers, **kwargs)
def assert_fingerprint(cert, fingerprint):
@@ -291,9 +280,6 @@ def create_urllib3_context(ssl_version=None, cert_reqs=None,
context.options |= options
- if getattr(context, 'supports_set_ciphers', True): # Platform-specific: Python 2.6
- context.set_ciphers(ciphers or DEFAULT_CIPHERS)
-
context.verify_mode = cert_reqs
if getattr(context, 'check_hostname', None) is not None: # Platform-specific: Python 3.2
# We do our own verification, including fingerprints and alternative
@@ -316,8 +302,7 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
A pre-made :class:`SSLContext` object. If none is provided, one will
be created using :func:`create_urllib3_context`.
:param ciphers:
- A string of ciphers we wish the client to support. This is not
- supported on Python 2.6 as the ssl module does not support it.
+ A string of ciphers we wish the client to support.
:param ca_cert_dir:
A directory containing CA certificates in multiple separate files, as
supported by OpenSSL's -CApath flag or the capath argument to
@@ -334,7 +319,7 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
if ca_certs or ca_cert_dir:
try:
context.load_verify_locations(ca_certs, ca_cert_dir)
- except IOError as e: # Platform-specific: Python 2.6, 2.7, 3.2
+ except IOError as e: # Platform-specific: Python 2.7
raise SSLError(e)
# Py33 raises FileNotFoundError which subclasses OSError
# These are not equivalent unless we check the errno attribute
diff --git a/test/__init__.py b/test/__init__.py
index 39eddd79..1db7cd59 100644
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -4,7 +4,6 @@ import errno
import functools
import logging
import socket
-import platform
import pytest
@@ -37,30 +36,6 @@ def setUp():
warnings.simplefilter('ignore', HTTPWarning)
-def onlyPy26OrOlder(test):
- """Skips this test unless you are on Python2.6.x or earlier."""
-
- @functools.wraps(test)
- def wrapper(*args, **kwargs):
- msg = "{name} only runs on Python2.6.x or older".format(name=test.__name__)
- if sys.version_info >= (2, 7):
- pytest.skip(msg)
- return test(*args, **kwargs)
- return wrapper
-
-
-def onlyPy27OrNewer(test):
- """Skips this test unless you are on Python 2.7.x or later."""
-
- @functools.wraps(test)
- def wrapper(*args, **kwargs):
- msg = "{name} requires Python 2.7.x+ to run".format(name=test.__name__)
- if sys.version_info < (2, 7):
- pytest.skip(msg)
- return test(*args, **kwargs)
- return wrapper
-
-
def onlyPy279OrNewer(test):
"""Skips this test unless you are on Python 2.7.9 or later."""
@@ -109,17 +84,6 @@ def notSecureTransport(test):
return wrapper
-def onlyPy27OrNewerOrNonWindows(test):
- """Skips this test unless you are on Python2.7+ or non-Windows"""
- @functools.wraps(test)
- def wrapper(*args, **kwargs):
- msg = "{name} requires Python2.7+ or non-Windows to run".format(name=test.__name__)
- if sys.version_info < (2, 7) and platform.system() == 'Windows':
- pytest.skip(msg)
- return test(*args, **kwargs)
- return wrapper
-
-
_requires_network_has_route = None
diff --git a/test/contrib/test_pyopenssl.py b/test/contrib/test_pyopenssl.py
index 20f80607..7fc296f3 100644
--- a/test/contrib/test_pyopenssl.py
+++ b/test/contrib/test_pyopenssl.py
@@ -82,5 +82,5 @@ class TestPyOpenSSLHelpers(unittest.TestCase):
self.assertEqual(get_subj_alt_name(cert), [])
self.assertEqual(mock_warning.call_count, 1)
- self.assertTrue(isinstance(mock_warning.call_args[0][1],
- x509.DuplicateExtension))
+ self.assertIsInstance(mock_warning.call_args[0][1],
+ x509.DuplicateExtension)
diff --git a/test/contrib/test_socks.py b/test/contrib/test_socks.py
index 67228cbe..ce016452 100644
--- a/test/contrib/test_socks.py
+++ b/test/contrib/test_socks.py
@@ -288,7 +288,7 @@ class TestSocks5Proxy(IPV4SocketDummyServerTestCase):
break
self.assertTrue(buf.startswith(b'GET / HTTP/1.1'))
- self.assertTrue(b'Host: example.com' in buf)
+ self.assertIn(b'Host: example.com', buf)
sock.sendall(b'HTTP/1.1 200 OK\r\n'
b'Server: SocksTestServer\r\n'
@@ -455,7 +455,7 @@ class TestSocks5Proxy(IPV4SocketDummyServerTestCase):
try:
pm.request('GET', 'http://example.com', retries=False)
except NewConnectionError as e:
- self.assertTrue("SOCKS5 authentication failed" in str(e))
+ self.assertIn("SOCKS5 authentication failed", str(e))
else:
self.fail("Did not raise")
@@ -584,7 +584,7 @@ class TestSOCKS4Proxy(IPV4SocketDummyServerTestCase):
break
self.assertTrue(buf.startswith(b'GET / HTTP/1.1'))
- self.assertTrue(b'Host: example.com' in buf)
+ self.assertIn(b'Host: example.com', buf)
sock.sendall(b'HTTP/1.1 200 OK\r\n'
b'Server: SocksTestServer\r\n'
@@ -670,7 +670,7 @@ class TestSOCKS4Proxy(IPV4SocketDummyServerTestCase):
try:
pm.request('GET', 'http://example.com', retries=False)
except NewConnectionError as e:
- self.assertTrue("different user-ids" in str(e))
+ self.assertIn("different user-ids", str(e))
else:
self.fail("Did not raise")
diff --git a/test/test_no_ssl.py b/test/test_no_ssl.py
index 3f04cd8b..4b4eb559 100644
--- a/test/test_no_ssl.py
+++ b/test/test_no_ssl.py
@@ -6,10 +6,7 @@ Test what happens if Python was built without SSL
"""
import sys
-if sys.version_info >= (2, 7):
- import unittest
-else:
- import unittest2 as unittest
+import unittest
class ImportBlocker(object):
@@ -80,13 +77,8 @@ class TestWithoutSSL(unittest.TestCase):
class TestImportWithoutSSL(TestWithoutSSL):
def test_cannot_import_ssl(self):
- # python26 has neither contextmanagers (for assertRaises) nor
- # importlib.
- # 'import' inside 'lambda' is invalid syntax.
- def import_ssl():
+ with self.assertRaises(ImportError):
import ssl # noqa: F401
- self.assertRaises(ImportError, import_ssl)
-
def test_import_urllib3(self):
import urllib3 # noqa: F401
diff --git a/test/test_poolmanager.py b/test/test_poolmanager.py
index a233f013..6ed695df 100644
--- a/test/test_poolmanager.py
+++ b/test/test_poolmanager.py
@@ -188,10 +188,7 @@ class TestPoolManager(object):
'ssl_version': 'SSLv23_METHOD',
}
p = PoolManager(5, **ssl_kw)
- conns = []
- conns.append(
- p.connection_from_host('example.com', 443, scheme='https')
- )
+ conns = [p.connection_from_host('example.com', 443, scheme='https')]
for k in ssl_kw:
p.connection_pool_kw[k] = 'newval'
diff --git a/test/with_dummyserver/test_chunked_transfer.py b/test/with_dummyserver/test_chunked_transfer.py
index ba5251b4..11fedec2 100644
--- a/test/with_dummyserver/test_chunked_transfer.py
+++ b/test/with_dummyserver/test_chunked_transfer.py
@@ -31,7 +31,7 @@ class TestChunkedTransfer(SocketDummyServerTestCase):
pool.urlopen('GET', '/', chunks, headers=dict(DNT='1'), chunked=True)
self.addCleanup(pool.close)
- self.assertTrue(b'Transfer-Encoding' in self.buffer)
+ self.assertIn(b'Transfer-Encoding', self.buffer)
body = self.buffer.split(b'\r\n\r\n', 1)[1]
lines = body.split(b'\r\n')
# Empty chunks should have been skipped, as this could not be distinguished
@@ -48,10 +48,10 @@ class TestChunkedTransfer(SocketDummyServerTestCase):
pool.urlopen('GET', '/', data, chunked=True)
header, body = self.buffer.split(b'\r\n\r\n', 1)
- self.assertTrue(b'Transfer-Encoding: chunked' in header.split(b'\r\n'))
+ self.assertIn(b'Transfer-Encoding: chunked', header.split(b'\r\n'))
if data:
bdata = data if isinstance(data, six.binary_type) else data.encode('utf-8')
- self.assertTrue(b'\r\n' + bdata + b'\r\n' in body)
+ self.assertIn(b'\r\n' + bdata + b'\r\n', body)
self.assertTrue(body.endswith(b'\r\n0\r\n\r\n'))
len_str = body.split(b'\r\n', 1)[0]
diff --git a/test/with_dummyserver/test_connectionpool.py b/test/with_dummyserver/test_connectionpool.py
index eb17b400..5faa0638 100644
--- a/test/with_dummyserver/test_connectionpool.py
+++ b/test/with_dummyserver/test_connectionpool.py
@@ -120,7 +120,7 @@ class TestConnectionPoolTimeouts(SocketDummyServerTestCase):
block_event.set() # Release request
message = "timeout was pool-level LONG_TIMEOUT rather than request-level SHORT_TIMEOUT"
- self.assertTrue(delta < LONG_TIMEOUT, message)
+ self.assertLess(delta, LONG_TIMEOUT, message)
pool._put_conn(conn)
wait_for_socket(ready_event)
@@ -129,7 +129,7 @@ class TestConnectionPoolTimeouts(SocketDummyServerTestCase):
delta = time.time() - now
message = "timeout was pool-level LONG_TIMEOUT rather than request-level SHORT_TIMEOUT"
- self.assertTrue(delta < LONG_TIMEOUT, message)
+ self.assertLess(delta, LONG_TIMEOUT, message)
block_event.set() # Release request
# Timeout int/float passed directly to request and _make_request should
@@ -388,10 +388,7 @@ class TestConnectionPool(HTTPDummyServerTestCase):
self.addCleanup(pool.close)
conn = pool._get_conn()
self.addCleanup(conn.close)
- try:
- conn.set_tunnel(self.host, self.port)
- except AttributeError: # python 2.6
- conn._set_tunnel(self.host, self.port)
+ conn.set_tunnel(self.host, self.port)
conn._tunnel = mock.Mock(return_value=None)
pool._make_request(conn, 'GET', '/')
@@ -406,7 +403,7 @@ class TestConnectionPool(HTTPDummyServerTestCase):
conn._tunnel = mock.Mock(return_value=None)
pool._make_request(conn, 'GET', '/')
- self.assertEqual(conn._tunnel.called, False)
+ self.assertFalse(conn._tunnel.called)
def test_redirect(self):
r = self.pool.request('GET', '/redirect', fields={'target': '/'}, redirect=False)
@@ -454,7 +451,7 @@ class TestConnectionPool(HTTPDummyServerTestCase):
# because _get_conn() is where the check & reset occurs
# pylint: disable-msg=W0212
conn = pool.pool.get()
- self.assertEqual(conn.sock, None)
+ self.assertIsNone(conn.sock)
pool._put_conn(conn)
# Now with keep-alive
@@ -466,7 +463,7 @@ class TestConnectionPool(HTTPDummyServerTestCase):
# The dummyserver responded with Connection:keep-alive, the connection
# persists.
conn = pool.pool.get()
- self.assertNotEqual(conn.sock, None)
+ self.assertIsNotNone(conn.sock)
pool._put_conn(conn)
# Another request asking the server to close the connection. This one
@@ -479,7 +476,7 @@ class TestConnectionPool(HTTPDummyServerTestCase):
self.assertEqual(r.status, 200)
conn = pool.pool.get()
- self.assertEqual(conn.sock, None)
+ self.assertIsNone(conn.sock)
pool._put_conn(conn)
# Next request
@@ -932,14 +929,14 @@ class TestRetryAfter(HTTPDummyServerTestCase):
r = self.pool.request('GET', '/redirect_after')
self.assertEqual(r.status, 200)
delta = time.time() - t
- self.assertTrue(delta >= 1)
+ self.assertGreaterEqual(delta, 1)
t = time.time()
timestamp = t + 2
r = self.pool.request('GET', '/redirect_after?date=' + str(timestamp))
self.assertEqual(r.status, 200)
delta = time.time() - t
- self.assertTrue(delta >= 1)
+ self.assertGreaterEqual(delta, 1)
# Retry-After is past
t = time.time()
@@ -947,7 +944,7 @@ class TestRetryAfter(HTTPDummyServerTestCase):
r = self.pool.request('GET', '/redirect_after?date=' + str(timestamp))
delta = time.time() - t
self.assertEqual(r.status, 200)
- self.assertTrue(delta < 1)
+ self.assertLess(delta, 1)
class TestFileBodiesOnRetryOrRedirect(HTTPDummyServerTestCase):
@@ -1005,7 +1002,7 @@ class TestFileBodiesOnRetryOrRedirect(HTTPDummyServerTestCase):
self.pool.urlopen('PUT', url, headers=headers, body=body)
self.fail('PUT successful despite failed rewind.')
except UnrewindableBodyError as e:
- self.assertTrue('Unable to record file position for' in str(e))
+ self.assertIn('Unable to record file position for', str(e))
class TestRetryPoolSize(HTTPDummyServerTestCase):
diff --git a/test/with_dummyserver/test_https.py b/test/with_dummyserver/test_https.py
index 9078151e..41c1d5a7 100644
--- a/test/with_dummyserver/test_https.py
+++ b/test/with_dummyserver/test_https.py
@@ -20,10 +20,8 @@ from dummyserver.server import (DEFAULT_CA, DEFAULT_CA_BAD, DEFAULT_CERTS,
IP_SAN_CERTS)
from test import (
- onlyPy26OrOlder,
onlyPy279OrNewer,
notSecureTransport,
- onlyPy27OrNewerOrNonWindows,
requires_network,
TARPIT_HOST,
)
@@ -232,9 +230,9 @@ class TestHTTPS(HTTPSDummyServerTestCase):
self.fail("Didn't raise SSL error with bad CA certs")
except MaxRetryError as e:
self.assertIsInstance(e.reason, SSLError)
- self.assertTrue('certificate verify failed' in str(e.reason),
- "Expected 'certificate verify failed',"
- "instead got: %r" % e.reason)
+ self.assertIn('certificate verify failed', str(e.reason),
+ "Expected 'certificate verify failed',"
+ "instead got: %r" % e.reason)
def test_verified_without_ca_certs(self):
# default is cert_reqs=None which is ssl.CERT_NONE
@@ -476,26 +474,11 @@ class TestHTTPS(HTTPSDummyServerTestCase):
self.addCleanup(https_pool.close)
conn = https_pool._new_conn()
self.addCleanup(conn.close)
- try:
- conn.set_tunnel(self.host, self.port)
- except AttributeError: # python 2.6
- conn._set_tunnel(self.host, self.port)
+ conn.set_tunnel(self.host, self.port)
conn._tunnel = mock.Mock()
https_pool._make_request(conn, 'GET', '/')
conn._tunnel.assert_called_once_with()
- @onlyPy26OrOlder
- def test_tunnel_old_python(self):
- """HTTPSConnection can still make connections if _tunnel_host isn't set
-
- The _tunnel_host attribute was added in 2.6.3 - because our test runners
- generally use the latest Python 2.6, we simulate the old version by
- deleting the attribute from the HTTPSConnection.
- """
- conn = self._pool._new_conn()
- del conn._tunnel_host
- self._pool._make_request(conn, 'GET', '/')
-
@requires_network
def test_enhanced_timeout(self):
def new_pool(timeout, cert_reqs='CERT_REQUIRED'):
@@ -556,7 +539,7 @@ class TestHTTPS(HTTPSDummyServerTestCase):
warning = w[0]
self.assertEqual(SystemTimeWarning, warning.category)
- self.assertTrue(str(RECENT_DATE) in warning.message.args[0])
+ self.assertIn(str(RECENT_DATE), warning.message.args[0])
def _request_without_resource_warnings(self, method, url):
with warnings.catch_warnings(record=True) as w:
@@ -574,11 +557,7 @@ class TestHTTPS_TLSv1(HTTPSDummyServerTestCase):
self._pool = HTTPSConnectionPool(self.host, self.port)
self.addCleanup(self._pool.close)
- @onlyPy27OrNewerOrNonWindows
def test_discards_connection_on_sslerror(self):
- # This test is skipped on Windows for Python 2.6 because we suspect there
- # is an issue with the OpenSSL for Python 2.6 on Windows.
-
self._pool.cert_reqs = 'CERT_REQUIRED'
with self.assertRaises(MaxRetryError) as cm:
self._pool.request('GET', '/', retries=0)
diff --git a/test/with_dummyserver/test_no_ssl.py b/test/with_dummyserver/test_no_ssl.py
index 956ebe83..282c9faa 100644
--- a/test/with_dummyserver/test_no_ssl.py
+++ b/test/with_dummyserver/test_no_ssl.py
@@ -26,4 +26,4 @@ class TestHTTPSWithoutSSL(HTTPSDummyServerTestCase, TestWithoutSSL):
try:
pool.request('GET', '/')
except urllib3.exceptions.SSLError as e:
- self.assertTrue('SSL module is not available' in str(e))
+ self.assertIn('SSL module is not available', str(e))
diff --git a/test/with_dummyserver/test_poolmanager.py b/test/with_dummyserver/test_poolmanager.py
index 448525f6..2a13722c 100644
--- a/test/with_dummyserver/test_poolmanager.py
+++ b/test/with_dummyserver/test_poolmanager.py
@@ -240,12 +240,12 @@ class TestPoolManager(HTTPDummyServerTestCase):
r = http.request_encode_url('GET', '%s/headers' % self.base_url, headers={'Baz': 'quux'})
returned_headers = json.loads(r.data.decode())
- self.assertEqual(returned_headers.get('Foo'), None)
+ self.assertIsNone(returned_headers.get('Foo'))
self.assertEqual(returned_headers.get('Baz'), 'quux')
r = http.request_encode_body('GET', '%s/headers' % self.base_url, headers={'Baz': 'quux'})
returned_headers = json.loads(r.data.decode())
- self.assertEqual(returned_headers.get('Foo'), None)
+ self.assertIsNone(returned_headers.get('Foo'))
self.assertEqual(returned_headers.get('Baz'), 'quux')
def test_http_with_ssl_keywords(self):
diff --git a/test/with_dummyserver/test_proxy_poolmanager.py b/test/with_dummyserver/test_proxy_poolmanager.py
index 0e1d04bb..225f5c45 100644
--- a/test/with_dummyserver/test_proxy_poolmanager.py
+++ b/test/with_dummyserver/test_proxy_poolmanager.py
@@ -86,9 +86,9 @@ class TestHTTPProxyManager(HTTPDummyProxyTestCase):
self.fail("Didn't raise SSL error with wrong CA")
except MaxRetryError as e:
self.assertIsInstance(e.reason, SSLError)
- self.assertTrue('certificate verify failed' in str(e.reason),
- "Expected 'certificate verify failed',"
- "instead got: %r" % e.reason)
+ self.assertIn('certificate verify failed', str(e.reason),
+ "Expected 'certificate verify failed',"
+ "instead got: %r" % e.reason)
http = proxy_from_url(self.proxy_url, cert_reqs='REQUIRED',
ca_certs=DEFAULT_CA)
@@ -108,7 +108,7 @@ class TestHTTPProxyManager(HTTPDummyProxyTestCase):
self.fail("Didn't raise SSL invalid common name")
except MaxRetryError as e:
self.assertIsInstance(e.reason, SSLError)
- self.assertTrue("doesn't match" in str(e.reason))
+ self.assertIn("doesn't match", str(e.reason))
def test_redirect(self):
http = proxy_from_url(self.proxy_url)
@@ -186,14 +186,14 @@ class TestHTTPProxyManager(HTTPDummyProxyTestCase):
r = http.request_encode_url('GET', '%s/headers' % self.https_url)
returned_headers = json.loads(r.data.decode())
self.assertEqual(returned_headers.get('Foo'), 'bar')
- self.assertEqual(returned_headers.get('Hickory'), None)
+ self.assertIsNone(returned_headers.get('Hickory'))
self.assertEqual(returned_headers.get('Host'),
'%s:%s' % (self.https_host, self.https_port))
r = http.request_encode_url('GET', '%s/headers' % self.https_url_alt)
returned_headers = json.loads(r.data.decode())
self.assertEqual(returned_headers.get('Foo'), 'bar')
- self.assertEqual(returned_headers.get('Hickory'), None)
+ self.assertIsNone(returned_headers.get('Hickory'))
self.assertEqual(returned_headers.get('Host'),
'%s:%s' % (self.https_host_alt, self.https_port))
@@ -206,7 +206,7 @@ class TestHTTPProxyManager(HTTPDummyProxyTestCase):
r = http.request_encode_url('GET', '%s/headers' % self.http_url, headers={'Baz': 'quux'})
returned_headers = json.loads(r.data.decode())
- self.assertEqual(returned_headers.get('Foo'), None)
+ self.assertIsNone(returned_headers.get('Foo'))
self.assertEqual(returned_headers.get('Baz'), 'quux')
self.assertEqual(returned_headers.get('Hickory'), 'dickory')
self.assertEqual(returned_headers.get('Host'),
@@ -214,15 +214,15 @@ class TestHTTPProxyManager(HTTPDummyProxyTestCase):
r = http.request_encode_url('GET', '%s/headers' % self.https_url, headers={'Baz': 'quux'})
returned_headers = json.loads(r.data.decode())
- self.assertEqual(returned_headers.get('Foo'), None)
+ self.assertIsNone(returned_headers.get('Foo'))
self.assertEqual(returned_headers.get('Baz'), 'quux')
- self.assertEqual(returned_headers.get('Hickory'), None)
+ self.assertIsNone(returned_headers.get('Hickory'))
self.assertEqual(returned_headers.get('Host'),
'%s:%s' % (self.https_host, self.https_port))
r = http.request_encode_body('GET', '%s/headers' % self.http_url, headers={'Baz': 'quux'})
returned_headers = json.loads(r.data.decode())
- self.assertEqual(returned_headers.get('Foo'), None)
+ self.assertIsNone(returned_headers.get('Foo'))
self.assertEqual(returned_headers.get('Baz'), 'quux')
self.assertEqual(returned_headers.get('Hickory'), 'dickory')
self.assertEqual(returned_headers.get('Host'),
@@ -230,9 +230,9 @@ class TestHTTPProxyManager(HTTPDummyProxyTestCase):
r = http.request_encode_body('GET', '%s/headers' % self.https_url, headers={'Baz': 'quux'})
returned_headers = json.loads(r.data.decode())
- self.assertEqual(returned_headers.get('Foo'), None)
+ self.assertIsNone(returned_headers.get('Foo'))
self.assertEqual(returned_headers.get('Baz'), 'quux')
- self.assertEqual(returned_headers.get('Hickory'), None)
+ self.assertIsNone(returned_headers.get('Hickory'))
self.assertEqual(returned_headers.get('Host'),
'%s:%s' % (self.https_host, self.https_port))
diff --git a/test/with_dummyserver/test_socketlevel.py b/test/with_dummyserver/test_socketlevel.py
index 3135d371..a1896cfd 100644
--- a/test/with_dummyserver/test_socketlevel.py
+++ b/test/with_dummyserver/test_socketlevel.py
@@ -14,7 +14,7 @@ from urllib3.response import httplib
from urllib3.util.ssl_ import HAS_SNI
from urllib3.util.timeout import Timeout
from urllib3.util.retry import Retry
-from urllib3._collections import HTTPHeaderDict, OrderedDict
+from urllib3._collections import HTTPHeaderDict
from dummyserver.testcase import SocketDummyServerTestCase, consume_socket
from dummyserver.server import (
@@ -27,6 +27,7 @@ try:
except ImportError:
class MimeToolMessage(object):
pass
+from collections import OrderedDict
from threading import Event
import select
import socket
@@ -81,8 +82,8 @@ class TestSNI(SocketDummyServerTestCase):
except MaxRetryError: # We are violating the protocol
pass
done_receiving.wait()
- self.assertTrue(self.host.encode('ascii') in self.buf,
- "missing hostname in SSL handshake")
+ self.assertIn(self.host.encode('ascii'), self.buf,
+ "missing hostname in SSL handshake")
class TestClientCerts(SocketDummyServerTestCase):
@@ -737,12 +738,12 @@ class TestSocketClosing(SocketDummyServerTestCase):
# should be in the pool. We opened two though.
self.assertEqual(pool.num_connections, 2)
self.assertEqual(pool.pool.qsize(), 0)
- self.assertTrue(response.connection is not None)
+ self.assertIsNotNone(response.connection)
# Consume the data. This should put the connection back.
response.read()
self.assertEqual(pool.pool.qsize(), 1)
- self.assertTrue(response.connection is None)
+ self.assertIsNone(response.connection)
class TestProxyManager(SocketDummyServerTestCase):
@@ -814,7 +815,7 @@ class TestProxyManager(SocketDummyServerTestCase):
# FIXME: The order of the headers is not predictable right now. We
# should fix that someday (maybe when we migrate to
# OrderedDict/MultiDict).
- self.assertTrue(b'For The Proxy: YEAH!\r\n' in r.data)
+ self.assertIn(b'For The Proxy: YEAH!\r\n', r.data)
def test_retries(self):
close_event = Event()
@@ -1433,7 +1434,7 @@ class TestBadContentLength(SocketDummyServerTestCase):
next(data)
self.assertFail()
except ProtocolError as e:
- self.assertTrue('12 bytes read, 10 more expected' in str(e))
+ self.assertIn('12 bytes read, 10 more expected', str(e))
done_event.set()
diff --git a/tox.ini b/tox.ini
index d52d8730..5f65ab9f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = flake8-py3, py26, py27, py34, py35, py36, py37, pypy
+envlist = flake8-py3, py27, py34, py35, py36, py37, pypy
[testenv]
deps= -r{toxinidir}/dev-requirements.txt
@@ -20,12 +20,6 @@ setenv =
PYTHONWARNINGS=always::DeprecationWarning
passenv = CFLAGS LDFLAGS TRAVIS APPVEYOR CRYPTOGRAPHY_OSX_NO_LINK_FLAGS
-[testenv:py26]
-# Additional dependency on unittest2 for Python 2.6
-deps=
- {[testenv]deps}
- unittest2
-
[testenv:gae]
basepython = python2.7
deps=