From: Ben Darnell Date: Mon, 4 Sep 2017 19:32:52 +0000 (-0400) Subject: Drop support for python 3.3, 3.5.[01] (#2116) X-Git-Tag: v5.0.0~58 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=34c43f4775971ab9b2b8ed43356f218add6387b2;p=thirdparty%2Ftornado.git Drop support for python 3.3, 3.5.[01] (#2116) * Drop support for python 3.3 In June 2017, Python 3.3 accounted for 0.2% of Tornado's downloads from pypi. * travis.yml: Use trusty, update pypy versions Get a py35-compatible version of pypy3. Plain "pypy" no longer seems to work in this environment, so specify a version. Drop testing of python 2.7.8, which no longer seems to be available. * gen,queues: Drop the "legacy aiter protocol" This protocol changed in Python 3.5.2 (after being introduced in 3.5.0). Async iteration now requires that version of Python (or newer). Closes #2107 * travis.yml: Only run doctests on one version of python 3 * Get tests passing on latest version of pypy3 --- diff --git a/.travis.yml b/.travis.yml index d2b549211..cae048f80 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,21 @@ # https://travis-ci.org/tornadoweb/tornado +dist: trusty + +# Use containers instead of full VMs for faster startup. +sudo: false + +matrix: + fast_finish: true + language: python python: - - 2.7.8 - 2.7 - - pypy - - 3.3 + - pypy-5.7.1 - 3.4 - 3.5 - 3.6 - nightly - - pypy3 + - pypy3.5-5.7.1-beta install: - if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then travis_retry pip install futures mock monotonic trollius; fi @@ -19,17 +25,16 @@ install: - if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then travis_retry pip install pycurl; fi # Twisted runs on 2.x and 3.3+, but is flaky on pypy. - if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then travis_retry pip install Twisted; fi - - if [[ $TRAVIS_PYTHON_VERSION == '2.7' || $TRAVIS_PYTHON_VERSION == '3.5' || $TRAVIS_PYTHON_VERSION == '3.6' ]]; then travis_retry pip install sphinx sphinx_rtd_theme; fi + - if [[ $TRAVIS_PYTHON_VERSION == '2.7' || $TRAVIS_PYTHON_VERSION == '3.6' ]]; then travis_retry pip install sphinx sphinx_rtd_theme; fi # On travis the extension should always be built - if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then export TORNADO_EXTENSION=1; fi - travis_retry python setup.py install - travis_retry pip install codecov virtualenv # Create a separate no-dependencies virtualenv to make sure all imports - # of optional-dependencies are guarded. (skipped on pypy3 because - # virtualenv no longer supports py32) - - if [[ $TRAVIS_PYTHON_VERSION != 'pypy3' ]]; then virtualenv ./nodeps; fi - - if [[ $TRAVIS_PYTHON_VERSION != 'pypy3' ]]; then ./nodeps/bin/python -VV; fi - - if [[ $TRAVIS_PYTHON_VERSION != 'pypy3' ]]; then ./nodeps/bin/python setup.py install; fi + # of optional-dependencies are guarded. + - virtualenv ./nodeps + - ./nodeps/bin/python -VV + - ./nodeps/bin/python setup.py install - curl-config --version; pip freeze script: @@ -71,17 +76,9 @@ script: # make coverage reports for Codecov to find - if [[ $TRAVIS_PYTHON_VERSION != nightly ]]; then coverage xml; fi - export TORNADO_EXTENSION=0 - - if [[ $TRAVIS_PYTHON_VERSION == '3.5' || $TRAVIS_PYTHON_VERSION == 3.6 ]]; then cd ../docs && mkdir sphinx-out && sphinx-build -E -n -W -b html . sphinx-out; fi - - if [[ $TRAVIS_PYTHON_VERSION == '2.7' || $TRAVIS_PYTHON_VERSION == '3.5' || $TRAVIS_PYTHON_VERSION == 3.6 ]]; then cd ../docs && mkdir sphinx-doctest-out && sphinx-build -E -n -b doctest . sphinx-out; fi + - if [[ $TRAVIS_PYTHON_VERSION == 3.6 ]]; then cd ../docs && mkdir sphinx-out && sphinx-build -E -n -W -b html . sphinx-out; fi + - if [[ $TRAVIS_PYTHON_VERSION == '2.7' || $TRAVIS_PYTHON_VERSION == 3.6 ]]; then cd ../docs && mkdir sphinx-doctest-out && sphinx-build -E -n -b doctest . sphinx-out; fi after_success: # call codecov from project root - if [[ $TRAVIS_PYTHON_VERSION != nightly ]]; then cd ../ && codecov; fi - -# This reportedly works around an issue downloading packages from pypi on -# travis. Consider removing this after the underlying issue is fixed. -# https://github.com/travis-ci/travis-ci/issues/2389 -sudo: false - -matrix: - fast_finish: true diff --git a/docs/index.rst b/docs/index.rst index 9905fe7d6..a5f166a3e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -66,7 +66,7 @@ installed in this way, so you may wish to download a copy of the source tarball or clone the `git repository `_ as well. -**Prerequisites**: Tornado runs on Python 2.7, and 3.3+ +**Prerequisites**: Tornado runs on Python 2.7, and 3.4+ For Python 2, version 2.7.9 or newer is *strongly* recommended for the improved SSL support. In addition to the requirements which will be installed automatically by ``pip`` or ``setup.py install``, @@ -86,7 +86,7 @@ the following optional packages may be useful: * `monotonic `_ or `Monotime `_ add support for a monotonic clock, which improves reliability in environments where - clock adjustements are frequent. No longer needed in Python 3.3. + clock adjustments are frequent. No longer needed in Python 3. **Platforms**: Tornado should run on any Unix-like platform, although for the best performance and scalability only Linux (with ``epoll``) diff --git a/maint/test/cython/tox.ini b/maint/test/cython/tox.ini index 0403df131..725e17044 100644 --- a/maint/test/cython/tox.ini +++ b/maint/test/cython/tox.ini @@ -1,6 +1,6 @@ [tox] # This currently segfaults on pypy. -envlist = py27,py33,py34,py35,py36 +envlist = py27,py34,py35,py36 [testenv] deps = @@ -13,7 +13,6 @@ commands = python -m unittest cythonapp_test # defaults for the others. basepython = py27: python2.7 - py33: python3.3 py34: python3.4 py35: python3.5 py36: python3.6 diff --git a/maint/vm/windows/bootstrap.py b/maint/vm/windows/bootstrap.py index 3f12aedb3..c69dc2864 100644 --- a/maint/vm/windows/bootstrap.py +++ b/maint/vm/windows/bootstrap.py @@ -29,7 +29,7 @@ TMPDIR = r'c:\tornado_bootstrap' PYTHON_VERSIONS = [ (r'c:\python27\python.exe', 'http://www.python.org/ftp/python/2.7.3/python-2.7.3.msi'), - (r'c:\python33\python.exe', 'http://www.python.org/ftp/python/3.3.0/python-3.3.0.msi'), + (r'c:\python36\python.exe', 'http://www.python.org/ftp/python/3.6.0/python-3.6.0.msi'), ] SCRIPTS_DIR = r'c:\python27\scripts' diff --git a/maint/vm/windows/tox.ini b/maint/vm/windows/tox.ini index 7a7ced31e..c3b1725cc 100644 --- a/maint/vm/windows/tox.ini +++ b/maint/vm/windows/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27-full, py27, py33, py27-opt, py33-monotonic +envlist = py27-full, py27, py36, py27-opt, py36-monotonic setupdir = e:\ toxworkdir = c:\tox-tornado @@ -12,12 +12,13 @@ deps = futures mock -[testenv:py33] +[testenv:py36] +# TODO: still needed? # tox's path mappings haven't been updated for py33 yet. -basepython = c:\python33\python.exe +basepython = c:\python36\python.exe -[testenv:py33-monotonic] -basepython = c:\python33\python.exe +[testenv:py36-monotonic] +basepython = c:\python36\python.exe commands = python -m tornado.test.runtests --ioloop_time_monotonic {posargs:} [testenv:py27-opt] diff --git a/setup.py b/setup.py index 4a94ed72b..72569a1f3 100644 --- a/setup.py +++ b/setup.py @@ -176,7 +176,6 @@ setup( 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', diff --git a/tornado/gen.py b/tornado/gen.py index 5558f986f..62fea303b 100644 --- a/tornado/gen.py +++ b/tornado/gen.py @@ -478,9 +478,8 @@ class WaitIterator(object): self.current_future = done self.current_index = self._unfinished.pop(done) - @coroutine def __aiter__(self): - raise Return(self) + return self def __anext__(self): if self.done(): diff --git a/tornado/netutil.py b/tornado/netutil.py index e58db35df..c054f625c 100644 --- a/tornado/netutil.py +++ b/tornado/netutil.py @@ -66,18 +66,6 @@ if hasattr(ssl, 'SSLContext'): ssl.Purpose.SERVER_AUTH) _server_ssl_defaults = ssl.create_default_context( ssl.Purpose.CLIENT_AUTH) - else: - # Python 3.2-3.3 - _client_ssl_defaults = ssl.SSLContext(ssl.PROTOCOL_SSLv23) - _client_ssl_defaults.verify_mode = ssl.CERT_REQUIRED - _client_ssl_defaults.load_verify_locations(certifi.where()) - _server_ssl_defaults = ssl.SSLContext(ssl.PROTOCOL_SSLv23) - if hasattr(ssl, 'OP_NO_COMPRESSION'): - # Disable TLS compression to avoid CRIME and related attacks. - # This constant wasn't added until python 3.3. - _client_ssl_defaults.options |= ssl.OP_NO_COMPRESSION - _server_ssl_defaults.options |= ssl.OP_NO_COMPRESSION - elif ssl: # Python 2.6-2.7.8 _client_ssl_defaults = dict(cert_reqs=ssl.CERT_REQUIRED, diff --git a/tornado/platform/asyncio.py b/tornado/platform/asyncio.py index 830ee1f3b..9d4d4f89d 100644 --- a/tornado/platform/asyncio.py +++ b/tornado/platform/asyncio.py @@ -3,9 +3,8 @@ .. versionadded:: 3.2 This module integrates Tornado with the ``asyncio`` module introduced -in Python 3.4 (and available `as a separate download -`_ for Python 3.3). This makes -it possible to combine the two libraries on the same event loop. +in Python 3.4. This makes it possible to combine the two libraries on +the same event loop. Most applications should use `AsyncIOMainLoop` to run Tornado on the default ``asyncio`` event loop. Applications that need to run event diff --git a/tornado/queues.py b/tornado/queues.py index 735896116..e6a99b15c 100644 --- a/tornado/queues.py +++ b/tornado/queues.py @@ -263,7 +263,6 @@ class Queue(object): """ return self._finished.wait(timeout) - @gen.coroutine def __aiter__(self): return _QueueIterator(self) diff --git a/tornado/test/iostream_test.py b/tornado/test/iostream_test.py index 030164479..751dfe2e1 100644 --- a/tornado/test/iostream_test.py +++ b/tornado/test/iostream_test.py @@ -9,7 +9,7 @@ from tornado.netutil import ssl_wrap_socket from tornado.stack_context import NullContext from tornado.tcpserver import TCPServer from tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, bind_unused_port, ExpectLog, gen_test -from tornado.test.util import unittest, skipIfNonUnix, refusing_port +from tornado.test.util import unittest, skipIfNonUnix, refusing_port, skipPypy3V58 from tornado.web import RequestHandler, Application import errno import logging @@ -538,6 +538,7 @@ class TestIOStreamMixin(object): client.close() @skipIfNonUnix + @skipPypy3V58 def test_inline_read_error(self): # An error on an inline read is raised without logging (on the # assumption that it will eventually be noticed or logged further @@ -556,6 +557,7 @@ class TestIOStreamMixin(object): server.close() client.close() + @skipPypy3V58 def test_async_read_error_logging(self): # Socket errors on asynchronous reads should be logged (but only # once). @@ -991,7 +993,7 @@ class TestIOStreamStartTLS(AsyncTestCase): server_future = self.server_start_tls(_server_ssl_options()) client_future = self.client_start_tls( ssl.create_default_context(), - server_hostname=b'127.0.0.1') + server_hostname='127.0.0.1') with ExpectLog(gen_log, "SSL Error"): with self.assertRaises(ssl.SSLError): # The client fails to connect with an SSL error. diff --git a/tornado/test/runtests.py b/tornado/test/runtests.py index 8c1b6a543..7cabbaf13 100644 --- a/tornado/test/runtests.py +++ b/tornado/test/runtests.py @@ -125,13 +125,6 @@ def main(): # Twisted 15.0.0 triggers some warnings on py3 with -bb. warnings.filterwarnings("ignore", category=BytesWarning, module=r"twisted\..*") - # The __aiter__ protocol changed in python 3.5.2. - # Silence the warning until we can drop 3.5.[01]. - warnings.filterwarnings("ignore", category=PendingDeprecationWarning, - message=".*legacy __aiter__ protocol") - # 3.5.2's PendingDeprecationWarning became a DeprecationWarning in 3.6. - warnings.filterwarnings("ignore", category=DeprecationWarning, - message=".*legacy __aiter__ protocol") logging.getLogger("tornado.access").setLevel(logging.CRITICAL) diff --git a/tornado/test/util.py b/tornado/test/util.py index 5f534e84e..19887c109 100644 --- a/tornado/test/util.py +++ b/tornado/test/util.py @@ -43,6 +43,14 @@ skipBefore35 = unittest.skipIf(sys.version_info < (3, 5), 'PEP 492 (async/await) skipNotCPython = unittest.skipIf(platform.python_implementation() != 'CPython', 'Not CPython implementation') +# Used for tests affected by +# https://bitbucket.org/pypy/pypy/issues/2616/incomplete-error-handling-in +# TODO: remove this after pypy3 5.8 is obsolete. +skipPypy3V58 = unittest.skipIf(platform.python_implementation() == 'PyPy' and + sys.version_info > (3,) and + sys.pypy_version_info < (5, 9), + 'pypy3 5.8 has buggy ssl module') + def refusing_port(): """Returns a local port number that will refuse all connections. diff --git a/tox.ini b/tox.ini index 409f025e7..11ba05725 100644 --- a/tox.ini +++ b/tox.ini @@ -15,8 +15,8 @@ envlist = # Basic configurations: Run the tests in both minimal installations # and with all optional dependencies. # (pypy3 doesn't have any optional deps yet) - {py27,pypy,py33,py34,py35,py36,pypy3}, - {py27,pypy,py33,py34,py35,py36}-full, + {py27,pypy,py34,py35,py36,pypy3}, + {py27,pypy,py34,py35,py36}-full, # Also run the tests with each possible replacement of a default # component. Run each test on both python 2 and 3 where possible. @@ -54,7 +54,6 @@ envlist = # defaults for the others. basepython = py27: python2.7 - py33: python3.3 py34: python3.4 py35: python3.5 py36: python3.6 @@ -70,20 +69,18 @@ deps = py3-unittest2: unittest2py3k # cpython-only deps: pycurl installs but curl_httpclient doesn't work; # twisted mostly works but is a bit flaky under pypy. - {py27,py33,py34,py35,py36}-full: pycurl + {py27,py34,py35,py36}-full: pycurl {py2,py3}: pycurl>=7.19.3.1 # twisted is cpython only. - {py27,py33,py34,py35,py36}-full: twisted + {py27,py34,py35,py36}-full: twisted {py2,py3}: twisted - # pycares installation currently fails on py33 - # (https://github.com/pypa/pip/pull/816) - {py2,py3,py27,py33,py34,py35,py36}-full: pycares + {py2,py3,py27,py34,py35,py36}-full: pycares # futures became standard in py32 {py2,py27,pypy}-full: futures # mock became standard in py33 - {py2,py27,pypy,py3,pypy3}-full: mock + {py2,py27,pypy,pypy3}-full: mock # singledispatch became standard in py34. - {py2,py27,pypy,py3,py33}-full: singledispatch + {py2,py27,pypy}-full: singledispatch trollius: trollius py2-monotonic: monotonic sphinx: sphinx @@ -91,7 +88,7 @@ deps = setenv = # The extension is mandatory on cpython. - {py2,py27,py3,py33,py34,py35,py36}: TORNADO_EXTENSION=1 + {py2,py27,py3,py34,py35,py36}: TORNADO_EXTENSION=1 # In python 3, opening files in text mode uses a # system-dependent encoding by default. Run the tests with "C" # (ascii) and "utf-8" locales to ensure we don't have hidden @@ -100,7 +97,7 @@ setenv = lang_utf8: LANG=en_US.utf-8 # tox's parser chokes if all the setenv entries are conditional. DUMMY=dummy - {py2,py27,py3,py33,py34,py35,py36}-no-ext: TORNADO_EXTENSION=0 + {py2,py27,py3,py34,py35,py36}-no-ext: TORNADO_EXTENSION=0 # All non-comment lines but the last must end in a backslash. # Tox filters line-by-line based on the environment name. @@ -108,7 +105,7 @@ commands = python \ # py3*: -b turns on an extra warning when calling # str(bytes), and -bb makes it an error. - {py3,py33,py34,py35,py36,pypy3}: -bb \ + {py3,py34,py35,py36,pypy3}: -bb \ # Python's optimized mode disables the assert statement, so # run the tests in this mode to ensure we haven't fallen into # the trap of relying on an assertion's side effects or using