diff --git a/cloudpickle/cloudpickle.py b/cloudpickle/cloudpickle.py index 1f122566..b4c9f44f 100644 --- a/cloudpickle/cloudpickle.py +++ b/cloudpickle/cloudpickle.py @@ -71,6 +71,7 @@ import types import typing import uuid +import warnings import weakref # The following import is required to be imported in the cloudpickle @@ -429,6 +430,26 @@ def _extract_class_dict(cls): return clsdict +def is_tornado_coroutine(func): + """Return whether `func` is a Tornado coroutine function. + + Running coroutines are not supported. + """ + warnings.warn( + "is_tornado_coroutine is deprecated in cloudpickle 3.0 and will be " + "removed in cloudpickle 4.0. Use tornado.gen.is_coroutine_function " + "directly instead.", + category=DeprecationWarning, + ) + if 'tornado.gen' not in sys.modules: + return False + gen = sys.modules['tornado.gen'] + if not hasattr(gen, "is_coroutine_function"): + # Tornado version is too old + return False + return gen.is_coroutine_function(func) + + def subimport(name): # We cannot do simply: `return __import__(name)`: Indeed, if ``name`` is # the name of a submodule, __import__ will return the top-level root module diff --git a/tests/cloudpickle_test.py b/tests/cloudpickle_test.py index bb2020f5..0d1d3240 100644 --- a/tests/cloudpickle_test.py +++ b/tests/cloudpickle_test.py @@ -991,6 +991,9 @@ def g(y): res = yield f(0.01, y) # noqa: F821 raise gen.Return(res + 1) + with pytest.warns(DeprecationWarning): + assert cloudpickle.is_tornado_coroutine(g) + data = cloudpickle.dumps([g, g], protocol=self.protocol) del f, g g2, g3 = pickle.loads(data)