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::
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:
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
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
<BaseIOStream.write>` while the connection is pending, in
)
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
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',
"""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):
def mockable(self) -> "_Mockable":
"""Returns a wrapper around self that is compatible with
- `mock.patch <unittest.mock.patch>`.
+ `unittest.mock.patch`.
- The `mock.patch <unittest.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
- <unittest.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 <unittest.mock.patch.object>` to modify option values::
with mock.patch.object(options.mockable(), 'name', value):
assert options.name == value
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:
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,
"""Shim to allow python -m tornado.test.
-
-This only works in python 2.7+.
"""
from tornado.test.runtests import all, main
@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
@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(
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=/'),
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):