Revert "Revert #5423" (#5475)

Reverts xonsh/xonsh#5468

Closes #5466

Related #5423

---------

Co-authored-by: a <1@1.1>
This commit is contained in:
Andy Kipp 2024-06-02 14:53:00 +02:00 committed by GitHub
parent 6245e460a6
commit 850bd8f34b
Failed to generate hash of commit
5 changed files with 77 additions and 2 deletions

23
news/fix_redir.rst Normal file
View file

@ -0,0 +1,23 @@
**Added:**
* <news item>
**Changed:**
* <news item>
**Deprecated:**
* <news item>
**Removed:**
* <news item>
**Fixed:**
* Fixed redirect with python substitution e.g. ``echo 1 > @('/tmp/file')`` is working now.
**Security:**
* <news item>

View file

@ -353,6 +353,14 @@ def test_on_command_not_found_doesnt_fire_in_non_interactive_mode(xession):
assert not fired
def test_redirect_to_substitution(xession):
s = SubprocSpec.build(
# `echo hello > @('file')`
["echo", "hello", (">", ["file"])]
)
assert s.stdout.name == "file"
def test_partial_args_from_classmethod(xession):
class Class:
@classmethod

View file

@ -156,6 +156,34 @@ f e>o
"The Truth is Out There\n",
0,
),
# test redirecting to a python substitution
(
"""
def _f():
print('Wow Mom!')
aliases['f'] = _f
f > @('tttt')
with open('tttt') as tttt:
s = tttt.read().strip()
print('REDIRECTED OUTPUT: ' + s)
""",
"REDIRECTED OUTPUT: Wow Mom!\n",
0,
),
# test redirecting to a python substitution with p-string
(
"""
def _f():
print('Wow Mom!')
aliases['f'] = _f
f > @(p'tttt')
with open('tttt') as tttt:
s = tttt.read().strip()
print('REDIRECTED OUTPUT: ' + s)
""",
"REDIRECTED OUTPUT: Wow Mom!\n",
0,
),
# test system exit in function alias
(
"""

View file

@ -74,7 +74,6 @@ def patched_events(monkeypatch, xonsh_events, xonsh_session):
("!(echo hi | grep x)", "", "", ""),
),
)
@pytest.mark.flaky(reruns=3, reruns_delay=2)
def test_command_pipeline_capture(cmdline, stdout, stderr, raw_stdout, xonsh_execer):
pipeline: CommandPipeline = xonsh_execer.eval(cmdline)
assert pipeline.out == stdout

View file

@ -223,6 +223,9 @@ def _parse_redirects(r, loc=None):
def _redirect_streams(r, loc=None):
"""Returns stdin, stdout, stderr tuple of redirections."""
if isinstance(loc, list):
raise Exception(f"Unsupported redirect: {r!r} {loc!r}")
stdin = stdout = stderr = None
no_ampersand = r.replace("&", "")
# special case of redirecting stderr to stdout
@ -671,6 +674,20 @@ class SubprocSpec:
"""Weave a list of arguments into a command."""
resolved_cmd = []
for c in self.cmd:
if (
isinstance(c, tuple)
and len(c) == 2
and isinstance(c[1], list)
and len(c[1]) == 1
):
# Redirect case e.g. `> file`
resolved_cmd.append(
(
c[0],
c[1][0],
)
)
else:
resolved_cmd += c if isinstance(c, list) else [c]
self.cmd = resolved_cmd