From 05d4817fe3b44832356890b6ebdba6ce67b7058f Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Mon, 10 May 2021 18:41:33 +0530 Subject: [PATCH 1/3] Add output streaming --- zx.py | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/zx.py b/zx.py index 7f4a6a2..438f0d4 100644 --- a/zx.py +++ b/zx.py @@ -27,7 +27,7 @@ import subprocess import sys import traceback -from typing import Union +from typing import Optional, Union def cli() -> None: @@ -54,10 +54,26 @@ def cli() -> None: run_zxpy(filename, module) -def run_shell(command: str) -> str: +def run_shell(command: str, print_it: bool = False) -> Optional[str]: """This is indirectly run when doing ~'...'""" - output = subprocess.getoutput(command) - return output + process = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + shell=True + ) + assert process.stdout is not None + + output = b'' + + while char := process.stdout.read(1): + if print_it: + sys.stdout.buffer.write(char) + sys.stdout.flush() + else: + output += char + + return None if print_it else output.decode() def run_zxpy(filename: str, module: ast.Module) -> None: @@ -116,12 +132,12 @@ def print_shell_outputs(expr_statement: ast.Expr) -> None: and isinstance(expr.func, ast.Name) and expr.func.id == 'run_shell' ): - new_expr = ast.Call( - func=ast.Name(id='print', ctx=ast.Load()), - args=[expr], - keywords=[], - ) - expr_statement.value = new_expr + expr.keywords = [ + ast.keyword( + arg='print_it', + value=ast.Constant(value=True), + ) + ] def setup_zxpy_repl() -> None: From 4321d5b0196c8378192091ff732b3e0fbf0ab21b Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Mon, 10 May 2021 18:45:31 +0530 Subject: [PATCH 2/3] Add early return to run_shell --- zx.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/zx.py b/zx.py index 438f0d4..fe907de 100644 --- a/zx.py +++ b/zx.py @@ -64,16 +64,15 @@ def run_shell(command: str, print_it: bool = False) -> Optional[str]: ) assert process.stdout is not None - output = b'' + if not print_it: + return process.stdout.read().decode() while char := process.stdout.read(1): if print_it: sys.stdout.buffer.write(char) sys.stdout.flush() - else: - output += char - return None if print_it else output.decode() + return None def run_zxpy(filename: str, module: ast.Module) -> None: From 9cf1c27192a1d1dc788616dbb2220c51d5dc8982 Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Mon, 10 May 2021 18:47:11 +0530 Subject: [PATCH 3/3] Update docstring --- zx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zx.py b/zx.py index fe907de..ac6c1af 100644 --- a/zx.py +++ b/zx.py @@ -124,7 +124,7 @@ def visit_Assign(self, assign: ast.Assign) -> ast.Assign: def print_shell_outputs(expr_statement: ast.Expr) -> None: - """Wrap every top level run_shell call with print() to get output""" + """Set print_it to True on every top level run_shell""" expr = expr_statement.value if ( isinstance(expr, ast.Call)