]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Fix exceptions in the gen module to work correctly with tuple keys.
authorBen Darnell <ben@bendarnell.com>
Sun, 31 Mar 2013 22:34:48 +0000 (18:34 -0400)
committerBen Darnell <ben@bendarnell.com>
Sun, 31 Mar 2013 22:34:48 +0000 (18:34 -0400)
Previously this would result in a TypeError instead of the intended exception.

tornado/gen.py
tornado/test/gen_test.py

index 23b3c81c35fe59310492f133ad7971d55677fef8..885b604d33102d32bd409192b23daa5b1250ce8d 100644 (file)
@@ -147,7 +147,7 @@ def engine(func):
                         if value is not None:
                             raise ReturnValueIgnoredError(
                                 "@gen.engine functions cannot return values: "
-                                "%r" % result)
+                                "%r" % (value,))
                         assert value is None
                         deactivate()
                     runner = Runner(result, final_callback)
@@ -155,7 +155,8 @@ def engine(func):
                     return
             if result is not None:
                 raise ReturnValueIgnoredError(
-                    "@gen.engine functions cannot return values: %r" % result)
+                    "@gen.engine functions cannot return values: %r" %
+                    (result,))
             deactivate()
             # no yield, so we're done
     return wrapper
@@ -464,13 +465,13 @@ class Runner(object):
     def register_callback(self, key):
         """Adds ``key`` to the list of callbacks."""
         if key in self.pending_callbacks:
-            raise KeyReuseError("key %r is already pending" % key)
+            raise KeyReuseError("key %r is already pending" % (key,))
         self.pending_callbacks.add(key)
 
     def is_ready(self, key):
         """Returns true if a result is available for ``key``."""
         if key not in self.pending_callbacks:
-            raise UnknownKeyError("key %r is not pending" % key)
+            raise UnknownKeyError("key %r is not pending" % (key,))
         return key in self.results
 
     def set_result(self, key, result):
@@ -534,7 +535,8 @@ class Runner(object):
                     except Exception:
                         self.exc_info = sys.exc_info()
                 else:
-                    self.exc_info = (BadYieldError("yielded unknown object %r" % yielded),)
+                    self.exc_info = (BadYieldError(
+                            "yielded unknown object %r" % (yielded,)),)
         finally:
             self.running = False
 
index a9db7bcb612e3ba01d909f2249262d4570fb2962..b3dc004187a685063576b1347a3b8dc3e74f4f6d 100644 (file)
@@ -125,6 +125,15 @@ class GenEngineTest(AsyncTestCase):
             self.stop()
         self.run_gen(f)
 
+    def test_with_arg_tuple(self):
+        @gen.engine
+        def f():
+            (yield gen.Callback((1, 2)))((3, 4))
+            res = yield gen.Wait((1, 2))
+            self.assertEqual((3, 4), res)
+            self.stop()
+        self.run_gen(f)
+
     def test_key_reuse(self):
         @gen.engine
         def f():
@@ -133,6 +142,14 @@ class GenEngineTest(AsyncTestCase):
             self.stop()
         self.assertRaises(gen.KeyReuseError, self.run_gen, f)
 
+    def test_key_reuse_tuple(self):
+        @gen.engine
+        def f():
+            yield gen.Callback((1, 2))
+            yield gen.Callback((1, 2))
+            self.stop()
+        self.assertRaises(gen.KeyReuseError, self.run_gen, f)
+
     def test_key_mismatch(self):
         @gen.engine
         def f():
@@ -141,6 +158,14 @@ class GenEngineTest(AsyncTestCase):
             self.stop()
         self.assertRaises(gen.UnknownKeyError, self.run_gen, f)
 
+    def test_key_mismatch_tuple(self):
+        @gen.engine
+        def f():
+            yield gen.Callback((1, 2))
+            yield gen.Wait((2, 3))
+            self.stop()
+        self.assertRaises(gen.UnknownKeyError, self.run_gen, f)
+
     def test_leaked_callback(self):
         @gen.engine
         def f():
@@ -148,6 +173,13 @@ class GenEngineTest(AsyncTestCase):
             self.stop()
         self.assertRaises(gen.LeakedCallbackError, self.run_gen, f)
 
+    def test_leaked_callback_tuple(self):
+        @gen.engine
+        def f():
+            yield gen.Callback((1, 2))
+            self.stop()
+        self.assertRaises(gen.LeakedCallbackError, self.run_gen, f)
+
     def test_parallel_callback(self):
         @gen.engine
         def f():
@@ -167,6 +199,12 @@ class GenEngineTest(AsyncTestCase):
             yield 42
         self.assertRaises(gen.BadYieldError, self.run_gen, f)
 
+    def test_bogus_yield_tuple(self):
+        @gen.engine
+        def f():
+            yield (1, 2)
+        self.assertRaises(gen.BadYieldError, self.run_gen, f)
+
     def test_reuse(self):
         @gen.engine
         def f():
@@ -404,6 +442,14 @@ class GenEngineTest(AsyncTestCase):
         with self.assertRaises(gen.ReturnValueIgnoredError):
             self.run_gen(f)
 
+    def test_sync_raise_return_value_tuple(self):
+        @gen.engine
+        def f():
+            raise gen.Return((1, 2))
+
+        with self.assertRaises(gen.ReturnValueIgnoredError):
+            self.run_gen(f)
+
     def test_async_raise_return_value(self):
         @gen.engine
         def f():
@@ -413,6 +459,15 @@ class GenEngineTest(AsyncTestCase):
         with self.assertRaises(gen.ReturnValueIgnoredError):
             self.run_gen(f)
 
+    def test_async_raise_return_value_tuple(self):
+        @gen.engine
+        def f():
+            yield gen.Task(self.io_loop.add_callback)
+            raise gen.Return((1, 2))
+
+        with self.assertRaises(gen.ReturnValueIgnoredError):
+            self.run_gen(f)
+
     def test_return_value(self):
         # It is an error to apply @gen.engine to a function that returns
         # a value.
@@ -423,6 +478,16 @@ class GenEngineTest(AsyncTestCase):
         with self.assertRaises(gen.ReturnValueIgnoredError):
             self.run_gen(f)
 
+    def test_return_value_tuple(self):
+        # It is an error to apply @gen.engine to a function that returns
+        # a value.
+        @gen.engine
+        def f():
+            return (1, 2)
+
+        with self.assertRaises(gen.ReturnValueIgnoredError):
+            self.run_gen(f)
+
 
 class GenCoroutineTest(AsyncTestCase):
     def setUp(self):