not strictly necessary as this method is synchronous,
but they are supplied for consistency with
`OAuthMixin.authorize_redirect`.
+
+ .. deprecated:: 5.1
+
+ The ``callback`` argument and returned awaitable will be removed
+ in Tornado 6.0; this will be an ordinary synchronous function.
"""
callback_uri = callback_uri or self.request.uri
args = self._openid_args(callback_uri, ax_attrs=ax_attrs)
subsequently used (and cleared) in `get_authenticated_user` for
security purposes.
- Note that this method is asynchronous, although it calls
- `.RequestHandler.finish` for you so it may not be necessary
- to pass a callback or use the `.Future` it returns. However,
- if this method is called from a function decorated with
- `.gen.coroutine`, you must call it with ``yield`` to keep the
- response from being closed prematurely.
+ This method is asynchronous and must be called with ``await``
+ or ``yield``. It calls `.RequestHandler.finish` for you so you
+ should not write any other response after it returns.
.. versionchanged:: 3.1
Now returns a `.Future` and takes an optional callback, for
compatibility with `.gen.coroutine`.
+
+ .. deprecated:: 5.1
+
+ The ``callback`` argument is deprecated and will be removed in 6.0.
+ Use the returned awaitable object instead.
"""
if callback_uri and getattr(self, "_OAUTH_NO_CALLBACKS", False):
raise Exception("This service does not support oauth_callback")
not strictly necessary as this method is synchronous,
but they are supplied for consistency with
`OAuthMixin.authorize_redirect`.
+
+ .. deprecated:: 5.1
+
+ The ``callback`` argument and returned awaitable will be removed
+ in Tornado 6.0; this will be an ordinary synchronous function.
"""
args = {
"redirect_uri": redirect_uri,
.. versionchanged:: 3.1
Now returns a `.Future` and takes an optional callback, for
compatibility with `.gen.coroutine`.
+
+ .. deprecated:: 5.1
+
+ The ``callback`` argument is deprecated and will be removed in 6.0.
+ Use the returned awaitable object instead.
"""
http = self.get_auth_http_client()
http.fetch(self._oauth_request_token_url(callback_uri=callback_uri),
import textwrap
import traceback
import sys
+import warnings
from tornado.log import app_log
from tornado.stack_context import ExceptionStackContext, wrap
same function, provided ``@return_future`` appears first. However,
consider using ``@gen.coroutine`` instead of this combination.
+ .. versionchanged:: 5.1
+
+ Now raises a `.DeprecationWarning` if a callback argument is passed to
+ the decorated function and deprecation warnings are enabled.
+
+ .. deprecated:: 5.1
+
+ New code should use coroutines directly instead of wrapping
+ callback-based code with this decorator.
"""
replacer = ArgReplacer(f, 'callback')
# immediate exception, and again when the future resolves and
# the callback triggers its exception by calling future.result()).
if callback is not None:
+ warnings.warn("callback arguments are deprecated, use the returned Future instead",
+ DeprecationWarning)
+
def run_callback(future):
result = future.result()
if result is _NO_RESULT:
from tornado import stack_context
from tornado.tcpserver import TCPServer
from tornado.testing import AsyncTestCase, ExpectLog, bind_unused_port, gen_test
-from tornado.test.util import unittest, skipBefore35, exec_test
+from tornado.test.util import unittest, skipBefore35, exec_test, ignore_deprecation
try:
self.return_value(callback=self.stop)
def test_callback_kw(self):
- future = self.sync_future(callback=self.stop)
+ with ignore_deprecation():
+ future = self.sync_future(callback=self.stop)
result = self.wait()
self.assertEqual(result, 42)
self.assertEqual(future.result(), 42)
def test_callback_positional(self):
# When the callback is passed in positionally, future_wrap shouldn't
# add another callback in the kwargs.
- future = self.sync_future(self.stop)
+ with ignore_deprecation():
+ future = self.sync_future(self.stop)
result = self.wait()
self.assertEqual(result, 42)
self.assertEqual(future.result(), 42)
self.assertEqual(future.result(), 42)
def test_error_in_callback(self):
- self.sync_future(callback=lambda future: 1 / 0)
+ with ignore_deprecation():
+ self.sync_future(callback=lambda future: 1 / 0)
# The exception gets caught by our StackContext and will be re-raised
# when we wait.
self.assertRaises(ZeroDivisionError, self.wait)
def test_no_result_future(self):
- future = self.no_result_future(self.stop)
+ with ignore_deprecation():
+ future = self.no_result_future(self.stop)
result = self.wait()
self.assertIs(result, None)
# result of this future is undefined, but not an error
future.result()
def test_no_result_future_callback(self):
- future = self.no_result_future(callback=lambda: self.stop())
+ with ignore_deprecation():
+ future = self.no_result_future(callback=lambda: self.stop())
result = self.wait()
self.assertIs(result, None)
future.result()
super(ClientTestMixin, self).tearDown() # type: ignore
def test_callback(self):
- self.client.capitalize("hello", callback=self.stop)
+ with ignore_deprecation():
+ self.client.capitalize("hello", callback=self.stop)
result = self.wait()
self.assertEqual(result, "HELLO")
def test_callback_error(self):
- self.client.capitalize("HELLO", callback=self.stop)
+ with ignore_deprecation():
+ self.client.capitalize("HELLO", callback=self.stop)
self.assertRaisesRegexp(CapError, "already capitalized", self.wait)
def test_future(self):
import socket
import sys
import textwrap
+import warnings
from tornado.testing import bind_unused_port
except AttributeError:
subTest = contextlib.contextmanager(lambda *a, **kw: (yield))
return subTest(*args, **kwargs)
+
+
+@contextlib.contextmanager
+def ignore_deprecation():
+ """Context manager to ignore deprecation warnings."""
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore', DeprecationWarning)
+ yield
of the request method.
Asynchronous support: Decorate this method with `.gen.coroutine`
- or `.return_future` to make it asynchronous (the
+ or use ``async def`` to make it asynchronous (the
`asynchronous` decorator cannot be used on `prepare`).
If this method returns a `.Future` execution will not proceed
until the `.Future` is done.