]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
concurrent,auth: Add deprecation warnings to concurrent.return_future
authorBen Darnell <ben@bendarnell.com>
Sun, 18 Mar 2018 20:57:49 +0000 (16:57 -0400)
committerBen Darnell <ben@bendarnell.com>
Sun, 18 Mar 2018 21:24:44 +0000 (17:24 -0400)
tornado/auth.py
tornado/concurrent.py
tornado/test/concurrent_test.py
tornado/test/util.py
tornado/web.py

index bc14548aaa01eec15798fcdc3febe87bba08e75d..c9cec8d91ee31d492d49b1ca7ca8db74c5b71b42 100644 (file)
@@ -168,6 +168,11 @@ class OpenIdMixin(object):
            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)
@@ -349,16 +354,18 @@ class OAuthMixin(object):
         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")
@@ -604,6 +611,11 @@ class OAuth2Mixin(object):
            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,
@@ -755,6 +767,11 @@ class TwitterMixin(OAuthMixin):
         .. 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),
index aa38bb9968a21d0f713573690638970f264c574b..2245c0bd40d99519853ecef646d38017a8d60dcb 100644 (file)
@@ -33,6 +33,7 @@ import platform
 import textwrap
 import traceback
 import sys
+import warnings
 
 from tornado.log import app_log
 from tornado.stack_context import ExceptionStackContext, wrap
@@ -496,6 +497,15 @@ def return_future(f):
     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')
 
@@ -533,6 +543,9 @@ def return_future(f):
         # 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:
index b00b80ddf69e325bacac46503ddacbec5fe63385..dca66547e3e9efdb6e8614bde104f4c9a7d2dca0 100644 (file)
@@ -31,7 +31,7 @@ from tornado.log import app_log
 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:
@@ -99,7 +99,8 @@ class ReturnFutureTest(AsyncTestCase):
             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)
@@ -107,7 +108,8 @@ class ReturnFutureTest(AsyncTestCase):
     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)
@@ -154,20 +156,23 @@ class ReturnFutureTest(AsyncTestCase):
         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()
@@ -334,12 +339,14 @@ class ClientTestMixin(object):
         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):
index 63a9762f14affb81d80e41f4f7f60d079bbe6a34..7c9db84a661afce50bb9647b1aba07a129be5cfd 100644 (file)
@@ -6,6 +6,7 @@ import platform
 import socket
 import sys
 import textwrap
+import warnings
 
 from tornado.testing import bind_unused_port
 
@@ -107,3 +108,11 @@ def subTest(test, *args, **kwargs):
     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
index a1d2aa5f01b14dd293709cb9c76f50433f2394ee..8a9a8053444fee5223a51694e30e28d14dc1f177 100644 (file)
@@ -246,7 +246,7 @@ class RequestHandler(object):
         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.