Skip to content

Commit 13976c1

Browse files
Carreaumeeseeksmachine
authored andcommitted
Backport PR ipython#14695: Read script output/error streams as they become available
1 parent 327e784 commit 13976c1

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

IPython/core/magics/script.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ def in_thread(coro):
220220

221221
async def _readchunk(stream):
222222
try:
223-
return await stream.readuntil(b"\n")
223+
return await stream.read(100)
224224
except asyncio.exceptions.IncompleteReadError as e:
225225
return e.partial
226226
except asyncio.exceptions.LimitOverrunError as e:

IPython/core/tests/test_magic.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
from importlib import invalidate_caches
1313
from io import StringIO
1414
from pathlib import Path
15+
from time import sleep
16+
from threading import Thread
1517
from subprocess import CalledProcessError
1618
from textwrap import dedent
1719
from time import sleep
@@ -1259,6 +1261,37 @@ def test_script_defaults():
12591261
assert cmd in ip.magics_manager.magics["cell"]
12601262

12611263

1264+
async def test_script_streams_continiously(capsys):
1265+
ip = get_ipython()
1266+
# Windows is slow to start up a thread on CI
1267+
is_windows = os.name == "nt"
1268+
step = 3 if is_windows else 1
1269+
code = dedent(
1270+
f"""\
1271+
import time
1272+
for _ in range(3):
1273+
time.sleep({step})
1274+
print(".", flush=True, end="")
1275+
"""
1276+
)
1277+
1278+
def print_numbers():
1279+
for i in range(3):
1280+
sleep(step)
1281+
print(i, flush=True, end="")
1282+
1283+
thread = Thread(target=print_numbers)
1284+
thread.start()
1285+
sleep(step / 2)
1286+
ip.run_cell_magic("script", f"{sys.executable}", code)
1287+
thread.join()
1288+
1289+
captured = capsys.readouterr()
1290+
# If the streaming was line-wise or broken
1291+
# we would get `012...`
1292+
assert captured.out == "0.1.2."
1293+
1294+
12621295
@magics_class
12631296
class FooFoo(Magics):
12641297
"""class with both %foo and %%foo magics"""

0 commit comments

Comments
 (0)