-
-
Notifications
You must be signed in to change notification settings - Fork 630
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
343ea33
commit 8df1c3c
Showing
5 changed files
with
155 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import contextlib | ||
|
||
import pytest | ||
|
||
from xonsh.procs import async_proc as ap | ||
import sys | ||
|
||
from xonsh.procs.specs import run_subproc | ||
|
||
|
||
def test_ls(xession): | ||
proc = ap.AsyncProc(["ls"], stdout=sys.stdout, stderr=sys.stderr) | ||
assert proc.proc.pid | ||
|
||
|
||
@pytest.fixture | ||
def run_proc(tmp_path): | ||
def factory(cmds: "list[str]", captured): | ||
out_file = tmp_path / "stdout" | ||
with out_file.open("wb") as fw: | ||
with contextlib.redirect_stdout(fw): | ||
return_val = run_subproc([cmds], captured) | ||
return return_val, out_file.read_text() | ||
|
||
return factory | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"captured,exp_out,exp_rtn", | ||
[ | ||
pytest.param(False, "hello", None, id="$[]"), | ||
pytest.param("stdout", "", "hello", id="$()"), | ||
], | ||
) | ||
def test_run_subproc(xession, run_proc, captured, exp_out, exp_rtn): | ||
xession.env["XONSH_SHOW_TRACEBACK"] = True | ||
cmds = ["echo", "hello"] | ||
|
||
rtn, out = run_proc(cmds, captured) | ||
|
||
assert rtn == exp_rtn | ||
assert out.strip() == exp_out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import asyncio | ||
import asyncio.subprocess as asp | ||
import sys | ||
|
||
|
||
class SubProcStreamProtocol(asp.SubprocessStreamProtocol): | ||
"""store writes to streams""" | ||
|
||
|
||
class XonshProcBase: | ||
"""attributes and methods that are expected from a xonshProc implementation""" | ||
|
||
@property | ||
def pid(self): | ||
raise NotImplementedError | ||
|
||
|
||
class AsyncProc(XonshProcBase): | ||
def __init__( | ||
self, | ||
args: "list[str]", | ||
loop=None, | ||
universal_newlines=False, | ||
stdin=None, | ||
stdout=None, | ||
stderr=None, | ||
**kwargs, | ||
): | ||
# todo: check if unbuffered read work all the time | ||
kwargs["bufsize"] = 0 | ||
|
||
self.is_text = universal_newlines | ||
if loop is None: | ||
loop = asyncio.get_event_loop_policy().get_event_loop() | ||
self.loop = loop | ||
self.stdin = stdin | ||
self.stdout = sys.stdout if stdout is None else stdout | ||
self.stderr = sys.stdout if stderr is None else stderr | ||
|
||
self.proc: asp.Process = self.loop.run_until_complete( | ||
self.get_proc(*args, **kwargs) | ||
) | ||
|
||
async def get_proc( | ||
self, | ||
program: str, | ||
*args, | ||
limit=2 ** 16, | ||
**kwargs, | ||
): | ||
"""wrap ``create_subprocess_exec`` call""" | ||
protocol_factory = lambda: SubProcStreamProtocol(limit=limit, loop=self.loop) | ||
transport, protocol = await self.loop.subprocess_exec( | ||
protocol_factory, | ||
program, | ||
*args, | ||
stdin=self.stdin, | ||
stdout=self.stdout, | ||
stderr=self.stderr, | ||
**kwargs, | ||
) | ||
return asp.Process(transport, protocol, self.loop) | ||
|
||
@property | ||
def pid(self): | ||
return self.proc.pid | ||
|
||
def wait(self): | ||
if self.proc: | ||
self.loop.run_until_complete(self.proc.wait()) | ||
|
||
@property | ||
def returncode(self): | ||
return self.proc.returncode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters