Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CliRunner terminates with io.UnsupportedOperation when using faulthandler #2865

Open
ThomasLoke opened this issue Mar 4, 2025 · 0 comments

Comments

@ThomasLoke
Copy link

It looks like the output redirection for CliRunner doesn't play nicely with Python's faulthandler library, as it terminates prematurely with the following backtrace (slightly modified to hide local filesystem details):

Traceback (most recent call last):
  File "$CONDA_PREFIX/lib/python3.11/site-packages/click/testing.py", line 408, in invoke
    return_value = cli.main(args=args or (), prog_name=prog_name, **extra)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "$CONDA_PREFIX/lib/python3.11/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "$CONDA_PREFIX/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "$CONDA_PREFIX/lib/python3.11/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "./test_click.py", line 12, in main
    faulthandler.enable()
io.UnsupportedOperation: fileno

Code for test_click.py that replicates the problem:

import click
from click.testing import CliRunner
import faulthandler
import traceback

@click.command()
@click.option('--flag', type=bool, default=True)
def main(flag):
    print("Executing main function...")
    if flag:
      print("Registering faulthandler")
      faulthandler.enable()
    print("Finished executing main function.")

if __name__ == '__main__':
    flag_value = True
    runner = CliRunner()
    result = runner.invoke(main, ["--flag", flag_value])
    print("Exit code = %d; contents of stdout:\n%s" % (result.exit_code, result.stdout))
    if result.exit_code != 0:
        traceback.print_exception(result.exc_info[1])

The code was then executed by running python test_click.py

I assume the problem is that the CliRunner redirected stderr doesn't implement some details that are required by the faulthandler signal handler registration. Ideally, it should just work; or at least, it should avoid crashing and just do nothing (and perhaps be documented somewhere).

Environment:

  • Python version: 3.11.10
  • Click version: 8.1.7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant