apache/beam · info
is_tornado_coroutine is deprecated in cloudpickle 3.0 and…
Error message
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.
What it means
Beam's vendored cloudpickle copy emits a DeprecationWarning when is_tornado_coroutine is called: the helper is deprecated in cloudpickle 3.0 and will be removed in 4.0; callers should use tornado.gen.is_coroutine_function directly. It still works, returning whether the function is a Tornado coroutine.
Solutions
- No action required — Beam vendors its own cloudpickle and will update before 4.0.
- If the warning is noisy, filter it: warnings.filterwarnings('ignore', category=DeprecationWarning, module='apache_beam.internal.cloudpickle').
- In your own code, replace calls to is_tornado_coroutine with tornado.gen.is_coroutine_function.
- Avoid pickling raw Tornado coroutines in DoFns; pass plain functions or instantiate inside the DoFn.
Example fix
# before import apache_beam.internal.cloudpickle.cloudpickle as cp is_coro = cp.is_tornado_coroutine(func) # after import tornado.gen is_coro = tornado.gen.is_coroutine_function(func)
Defensive patterns
Strategy: fallback
Validate before calling
import sys, warnings
deprecated = 'apache_beam.internal.cloudpickle' in getattr(warnings, '__warningregistry__', {}) or 'tornado.gen' in sys.modules
# prefer direct API:
import tornado.gen
coro = tornado.gen.is_coroutine_function(func) if 'tornado.gen' in sys.modules else False Type guard
def is_tornado_coroutine_safe(func) -> bool:
import sys
if 'tornado.gen' not in sys.modules:
return False
import tornado.gen
return tornado.gen.is_coroutine_function(func) Try / catch
import warnings
with warnings.catch_warnings():
warnings.filterwarnings('ignore', category=DeprecationWarning,
module='apache_beam.internal.cloudpickle')
result = do_pickle(func) Prevention
- Never call Beam's vendored is_tornado_coroutine in user code; use tornado.gen.is_coroutine_function.
- Avoid pickling Tornado coroutine objects inside DoFns.
- Filter DeprecationWarnings from vendored modules in production logging configs.
- Track Beam releases so vendored cloudpickle updates are picked up before cloudpickle 4.0.
When it happens
Trigger: Cloudpickling Tornado coroutine functions (e.g. Tornado-based I/O callbacks inside a Beam pipeline) with cloudpickle 3.x, which invokes the deprecated helper during pickle dispatch.
Common situations: Pipelines that serialize Tornado coroutines or tornado.gen-based callables; upgrading cloudpickle from 2.x to 3.x and suddenly seeing DeprecationWarnings in worker logs.
Understand the failure class
Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.
Related errors
- Artifact not found at
- cannot check importability of
- Cannot find default Beam SDK tar file
- Cannot pickle files that do not map to an actual file
- chunk_to_dict_fn is deprecated, use embeddable_to_dict_fn
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/cea16661d357b897.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/internal/cloudpickle/cloudpickle.py:551
to_remove = []
for name, value in clsdict.items():
try:
base_value = inherited_dict[name]
if value is base_value:
to_remove.append(name)
except KeyError:
pass
for name in to_remove:
clsdict.pop(name)
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
# of this submodule. For instance, __import__('os.path') returns the `os`View on GitHub (pinned to 12126d8942)