apache/beam · error · DistutilsError

pyrefly exited with status

Error message

pyrefly exited with status %d

What it means

setup.py's pyrefly check command runs the external `pyrefly` type checker against the project path via subprocess.call and raises DistutilsError whenever pyrefly's exit status is nonzero, i.e. pyrefly reported type errors or failed to run. This blocks the packaging step so type errors cannot be silently released.

Solutions

  1. Run `pyrefly check .` locally and fix the reported type errors
  2. Install or upgrade pyrefly so the binary is on PATH (`pip install pyrefly`)
  3. Confirm the project path passed to check is correct in get_project_path()
  4. Temporarily skip the check target if you only need sdist/wheel without type gating

Example fix

# before
$ python setup.py pyrefly_check
DistutilsError: pyrefly exited with status 1
# after
$ pyrefly check .   # fix reported errors first
$ python setup.py pyrefly_check   # succeeds
Defensive patterns

Strategy: try-catch

Validate before calling

import shutil
if shutil.which('pyrefly') is None:
    raise RuntimeError('pyrefly not installed; pip install pyrefly')

Try / catch

try:
    result = subprocess.call(['pyrefly', 'check', project_path])
except DistutilsError as e:
    if 'pyrefly exited with status' in str(e):
        fix_type_errors_or_install_pyrefly()
    else:
        raise

Prevention

When it happens

Trigger: Running `python setup.py pyrefly_check` (or a build that invokes it) when pyrefly check finds type errors in apache_beam, or when the pyrefly binary is missing/old (subprocess.call returns a nonzero status or the shell returns 127).

Common situations: Developers adding code that fails pyrefly checks; pyrefly not installed on the machine (command not found yields nonzero status); CI pins an older pyrefly that doesn't support new syntax.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/1d580f291a16700e. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/setup.py:77

    """Abstract method that is required to be overwritten"""

  def get_project_path(self):
    self.run_command('egg_info')

    # Build extensions in-place
    self.reinitialize_command('build_ext', inplace=1)
    self.run_command('build_ext')

    ei_cmd = self.get_finalized_command("egg_info")

    project_path = normalize_path(ei_cmd.egg_base)
    return os.path.join(project_path, to_filename(ei_cmd.egg_name))

  def run(self):
    args = ['pyrefly', 'check', self.get_project_path()]
    result = subprocess.call(args)
    if result != 0:
      raise DistutilsError("pyrefly exited with status %d" % result)


def get_version():
  global_names = {}
  exec(  # pylint: disable=exec-used
      open(os.path.join(
          os.path.dirname(os.path.abspath(__file__)),
          'apache_beam/version.py')
          ).read(),
      global_names
  )
  return global_names['__version__']


PACKAGE_NAME = 'apache-beam'
PACKAGE_VERSION = get_version()
PACKAGE_DESCRIPTION = 'Apache Beam SDK for Python'
PACKAGE_URL = 'https://beam.apache.org'

View on GitHub (pinned to 12126d8942)