Skip to content

OutStream.close raises if watchfd=False #867

@mdickinson

Description

@mdickinson

Closing an OutStream instance via its close method fails if that OutStream instance is created with watchfd=False, with an exception AttributeError: 'OutStream' object has no attribute 'watch_fd_thread'.

Here's a full traceback from some Envisage tests. We're creating a kernel app with kernel = IPKernelApp.instance(capture_fd_output=False), and then later shutting that kernel down. Only the last two lines are directly relevant for ipykernel. I'll see if I can come up with a more self-contained reproducer.

======================================================================
ERROR: test_ipython_util_io_globals_restored (envisage.plugins.ipython_kernel.tests.test_internal_ipkernel.TestInternalIPKernel)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/mdickinson/Enthought/ETS/envisage/envisage/plugins/ipython_kernel/tests/test_internal_ipkernel.py", line 162, in test_ipython_util_io_globals_restored
    self.create_and_destroy_kernel()
  File "/Users/mdickinson/Enthought/ETS/envisage/envisage/plugins/ipython_kernel/tests/test_internal_ipkernel.py", line 319, in create_and_destroy_kernel
    kernel.shutdown()
  File "/Users/mdickinson/Enthought/ETS/envisage/envisage/plugins/ipython_kernel/internal_ipkernel.py", line 133, in shutdown
    self.ipkernel.close()
  File "/Users/mdickinson/Enthought/ETS/envisage/envisage/plugins/ipython_kernel/kernelapp.py", line 202, in close
    self.close_io()
  File "/Users/mdickinson/Enthought/ETS/envisage/envisage/plugins/ipython_kernel/kernelapp.py", line 296, in close_io
    sys.stderr.close()
  File "/Users/mdickinson/.venvs/envisage/lib/python3.10/site-packages/ipykernel/iostream.py", line 429, in close
    self.watch_fd_thread.join()
AttributeError: 'OutStream' object has no attribute 'watch_fd_thread'

----------------------------------------------------------------------
Ran 1 test in 0.161s

FAILED (errors=1)

From the source, the cause looks fairly clear: at OutStream creation time, the _should_watch and watch_fd_thread attributes are only created if watchfd=True, but the close method assumes that both attributes exist unconditionally. (Well, at least on Linux and macOS, anyway.)

ipykernel version: 6.9.1
Python version: 3.10.2
OS + hardware: macOS 11.6.3 (Big Sur), Intel MacBook Pro

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions