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

  1. No action required — Beam vendors its own cloudpickle and will update before 4.0.
  2. If the warning is noisy, filter it: warnings.filterwarnings('ignore', category=DeprecationWarning, module='apache_beam.internal.cloudpickle').
  3. In your own code, replace calls to is_tornado_coroutine with tornado.gen.is_coroutine_function.
  4. 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

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


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)