diff --git a/ipykernel/iostream.py b/ipykernel/iostream.py index ce69334d8..e37840be2 100644 --- a/ipykernel/iostream.py +++ b/ipykernel/iostream.py @@ -320,7 +320,7 @@ def _watch_pipe_fd(self): self._exc = sys.exc_info() def __init__( - self, session, pub_thread, name, pipe=None, echo=None, *, watchfd=True + self, session, pub_thread, name, pipe=None, echo=None, *, watchfd=True, isatty=False, ): """ Parameters @@ -333,6 +333,8 @@ def __init__( the file descriptor by its number. It will spawn a watching thread, that will swap the give file descriptor for a pipe, read from the pipe, and insert this into the current Stream. + isatty : bool (default, False) + Indication of whether this stream has termimal capabilities (e.g. can handle colors) """ if pipe is not None: @@ -364,6 +366,7 @@ def __init__( self._io_loop = pub_thread.io_loop self._new_buffer() self.echo = None + self._isatty = bool(isatty) if ( watchfd @@ -381,6 +384,14 @@ def __init__( else: raise ValueError("echo argument must be a file like object") + def isatty(self): + """Return a bool indicating whether this is an 'interactive' stream. + + Returns: + Boolean + """ + return self._isatty + def _setup_stream_redirects(self, name): pr, pw = os.pipe() fno = getattr(sys, name).fileno() diff --git a/ipykernel/tests/test_io.py b/ipykernel/tests/test_io.py index c0e7021af..cf68b88ea 100644 --- a/ipykernel/tests/test_io.py +++ b/ipykernel/tests/test_io.py @@ -38,3 +38,13 @@ def test_io_api(): stream.seek(0) with nt.assert_raises(io.UnsupportedOperation): stream.tell() + +def test_io_isatty(): + session = Session() + ctx = zmq.Context() + pub = ctx.socket(zmq.PUB) + thread = IOPubThread(pub) + thread.start() + + stream = OutStream(session, thread, 'stdout', isatty=True) + assert stream.isatty()