From 00110e1602c516d2dcb371c5b9aa92b522ee7c48 Mon Sep 17 00:00:00 2001 From: Ben Darnell Date: Thu, 11 Jul 2024 15:43:32 -0400 Subject: [PATCH] *: Remove references to old python versions Mainly in docs that say things like "you can only use this if you're using python 3.2". --- tornado/gen.py | 15 ++++++--------- tornado/iostream.py | 9 +-------- tornado/netutil.py | 18 ++++++------------ tornado/options.py | 17 ++++++----------- tornado/tcpserver.py | 2 +- tornado/test/__main__.py | 2 -- tornado/test/gen_test.py | 1 - tornado/test/iostream_test.py | 2 -- tornado/test/web_test.py | 10 +++------- 9 files changed, 23 insertions(+), 53 deletions(-) diff --git a/tornado/gen.py b/tornado/gen.py index 51fa4c19..d12f32fb 100644 --- a/tornado/gen.py +++ b/tornado/gen.py @@ -275,6 +275,10 @@ def is_coroutine_function(func: Any) -> bool: class Return(Exception): """Special exception to return a value from a `coroutine`. + This exception exists for compatibility with older versions of + Python (before 3.3). In newer code use the ``return`` statement + instead. + If this exception is raised, its value argument is used as the result of the coroutine:: @@ -283,14 +287,7 @@ class Return(Exception): response = yield AsyncHTTPClient().fetch(url) raise gen.Return(json_decode(response.body)) - In Python 3.3, this exception is no longer necessary: the ``return`` - statement can be used directly to return a value (previously - ``yield`` and ``return`` with a value could not be combined in the - same function). - - By analogy with the return statement, the value argument is optional, - but it is never necessary to ``raise gen.Return()``. The ``return`` - statement can be used with no arguments instead. + By analogy with the return statement, the value argument is optional. """ def __init__(self, value: Any = None) -> None: @@ -337,7 +334,7 @@ class WaitIterator: arguments were used in the construction of the `WaitIterator`, ``current_index`` will use the corresponding keyword). - On Python 3.5, `WaitIterator` implements the async iterator + `WaitIterator` implements the async iterator protocol, so it can be used with the ``async for`` statement (note that in this version the entire iteration is aborted if any value raises an exception, while the previous example can continue past diff --git a/tornado/iostream.py b/tornado/iostream.py index 40b4f8d4..dd2111e3 100644 --- a/tornado/iostream.py +++ b/tornado/iostream.py @@ -1147,8 +1147,7 @@ class IOStream(BaseIOStream): In SSL mode, the ``server_hostname`` parameter will be used for certificate validation (unless disabled in the - ``ssl_options``) and SNI (if supported; requires Python - 2.7.9+). + ``ssl_options``) and SNI. Note that it is safe to call `IOStream.write ` while the connection is pending, in @@ -1381,12 +1380,6 @@ class SSLIOStream(IOStream): ) return self.close(exc_info=err) raise - except ssl.CertificateError as err: - # CertificateError can happen during handshake (hostname - # verification) and should be passed to user. Starting - # in Python 3.7, this error is a subclass of SSLError - # and will be handled by the previous block instead. - return self.close(exc_info=err) except OSError as err: # Some port scans (e.g. nmap in -sT mode) have been known # to cause do_handshake to raise EBADF and ENOTCONN, so make diff --git a/tornado/netutil.py b/tornado/netutil.py index b6772086..3ec76af7 100644 --- a/tornado/netutil.py +++ b/tornado/netutil.py @@ -501,10 +501,6 @@ class BlockingResolver(ExecutorResolver): class ThreadedResolver(ExecutorResolver): """Multithreaded non-blocking `Resolver` implementation. - Requires the `concurrent.futures` package to be installed - (available in the standard library since Python 3.2, - installable with ``pip install futures`` in older versions). - The thread pool size can be configured with:: Resolver.configure('tornado.netutil.ThreadedResolver', @@ -598,17 +594,15 @@ def ssl_options_to_context( """Try to convert an ``ssl_options`` dictionary to an `~ssl.SSLContext` object. - The ``ssl_options`` dictionary contains keywords to be passed to - ``ssl.SSLContext.wrap_socket``. In Python 2.7.9+, `ssl.SSLContext` objects can - be used instead. This function converts the dict form to its - `~ssl.SSLContext` equivalent, and may be used when a component which - accepts both forms needs to upgrade to the `~ssl.SSLContext` version - to use features like SNI or NPN. + The ``ssl_options`` argument may be either an `ssl.SSLContext` object or a dictionary containing + keywords to be passed to ``ssl.SSLContext.wrap_socket``. This function converts the dict form + to its `~ssl.SSLContext` equivalent, and may be used when a component which accepts both forms + needs to upgrade to the `~ssl.SSLContext` version to use features like SNI or ALPN. .. versionchanged:: 6.2 - Added server_side argument. Omitting this argument will - result in a DeprecationWarning on Python 3.10. + Added server_side argument. Omitting this argument will result in a DeprecationWarning on + Python 3.10. """ if isinstance(ssl_options, ssl.SSLContext): diff --git a/tornado/options.py b/tornado/options.py index d02a730c..b6578bb9 100644 --- a/tornado/options.py +++ b/tornado/options.py @@ -482,15 +482,11 @@ class OptionParser: def mockable(self) -> "_Mockable": """Returns a wrapper around self that is compatible with - `mock.patch `. + `unittest.mock.patch`. - The `mock.patch ` function (included in - the standard library `unittest.mock` package since Python 3.3, - or in the third-party ``mock`` package for older versions of - Python) is incompatible with objects like ``options`` that - override ``__getattr__`` and ``__setattr__``. This function - returns an object that can be used with `mock.patch.object - ` to modify option values:: + The `unittest.mock.patch` function is incompatible with objects like ``options`` that + override ``__getattr__`` and ``__setattr__``. This function returns an object that can be + used with `mock.patch.object ` to modify option values:: with mock.patch.object(options.mockable(), 'name', value): assert options.name == value @@ -664,9 +660,8 @@ class _Option: num = float(m.group(1)) units = m.group(2) or "seconds" units = self._TIMEDELTA_ABBREV_DICT.get(units, units) - # This line confuses mypy when setup.py sets python_version=3.6 - # https://github.com/python/mypy/issues/9676 - sum += datetime.timedelta(**{units: num}) # type: ignore + + sum += datetime.timedelta(**{units: num}) start = m.end() return sum except Exception: diff --git a/tornado/tcpserver.py b/tornado/tcpserver.py index a9ae88de..6d74224b 100644 --- a/tornado/tcpserver.py +++ b/tornado/tcpserver.py @@ -339,7 +339,7 @@ class TCPServer: def _handle_connection(self, connection: socket.socket, address: Any) -> None: if self.ssl_options is not None: - assert ssl, "Python 2.6+ and OpenSSL required for SSL" + assert ssl, "OpenSSL required for SSL" try: connection = ssl_wrap_socket( connection, diff --git a/tornado/test/__main__.py b/tornado/test/__main__.py index 890bd505..65b794d9 100644 --- a/tornado/test/__main__.py +++ b/tornado/test/__main__.py @@ -1,6 +1,4 @@ """Shim to allow python -m tornado.test. - -This only works in python 2.7+. """ from tornado.test.runtests import all, main diff --git a/tornado/test/gen_test.py b/tornado/test/gen_test.py index ec3a6c8e..71fdceb1 100644 --- a/tornado/test/gen_test.py +++ b/tornado/test/gen_test.py @@ -441,7 +441,6 @@ class GenCoroutineTest(AsyncTestCase): @gen_test def test_async_return_no_value(self): - # Without a return value we don't need python 3.3. @gen.coroutine def f(): yield gen.moment diff --git a/tornado/test/iostream_test.py b/tornado/test/iostream_test.py index 09191ecf..d55485c7 100644 --- a/tornado/test/iostream_test.py +++ b/tornado/test/iostream_test.py @@ -1078,8 +1078,6 @@ class TestIOStreamStartTLS(AsyncTestCase): @gen_test def test_check_hostname(self): # Test that server_hostname parameter to start_tls is being used. - # The check_hostname functionality is only available in python 2.7 and - # up and in python 3.4 and up. server_future = self.server_start_tls(_server_ssl_options()) with ExpectLog(gen_log, "SSL Error"): client_future = self.client_start_tls( diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py index 32a12bad..7e1278e6 100644 --- a/tornado/test/web_test.py +++ b/tornado/test/web_test.py @@ -367,7 +367,7 @@ class CookieTest(WebTestCase): self.assertEqual(len(headers), 3) self.assertEqual(headers[0], 'equals="a=b"; Path=/') self.assertEqual(headers[1], 'quote="a\\"b"; Path=/') - # python 2.7 octal-escapes the semicolon; older versions leave it alone + # Semicolons are octal-escaped self.assertIn( headers[2], ('semicolon="a;b"; Path=/', 'semicolon="a\\073b"; Path=/'), @@ -1888,12 +1888,8 @@ class ClearAllCookiesTest(SimpleHandlerTestCase): response = self.fetch("/", headers={"Cookie": "foo=bar; baz=xyzzy"}) set_cookies = sorted(response.headers.get_list("Set-Cookie")) # Python 3.5 sends 'baz="";'; older versions use 'baz=;' - self.assertTrue( - set_cookies[0].startswith("baz=;") or set_cookies[0].startswith('baz="";') - ) - self.assertTrue( - set_cookies[1].startswith("foo=;") or set_cookies[1].startswith('foo="";') - ) + self.assertTrue(set_cookies[0].startswith('baz="";')) + self.assertTrue(set_cookies[1].startswith('foo="";')) class PermissionError(Exception): -- 2.47.2