Revert partial_proxy (#5445)

In #5366 we removed partial_proxy. But @doronz88 [found the
case](https://xonsh.zulipchat.com/#narrow/stream/435525-xonsh-xontrib/topic/.E2.9C.94.20xontrib-z.20and.20maybe.20other.20break.20in.20master)
where this functionality is good and needed. In xontrib-z there is a
[handler](a40abb4d8b/xontrib/z.py (L225-L227))
that requires partial_proxy. So I bring partial_proxy back because it
looks useful.

## For community
⬇️ **Please click the 👍 reaction instead of leaving a `+1` or 👍
comment**

---------

Co-authored-by: a <1@1.1>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Andy Kipp 2024-05-27 18:00:15 +02:00 committed by GitHub
parent 2d966fb1b5
commit 120bcb3559
Failed to generate hash of commit
4 changed files with 39 additions and 6 deletions

View file

@ -308,3 +308,15 @@ def test_redirect_to_substitution(xession):
["echo", "hello", (">", ["file"])] ["echo", "hello", (">", ["file"])]
) )
assert s.stdout.name == "file" assert s.stdout.name == "file"
def test_partial_args_from_classmethod(xession):
class Class:
@classmethod
def alias(cls, args, stdin, stdout):
print("ok", file=stdout)
return 0
xession.aliases["alias_with_partial_args"] = Class.alias
out = run_subproc([["alias_with_partial_args"]], captured="stdout")
assert out == "ok"

View file

@ -340,7 +340,7 @@ def test_parser_show(args, session, slice, numerate, reverse, mocker, hist, xess
from xonsh.history import main as mod from xonsh.history import main as mod
main = HistoryAlias() main = HistoryAlias()
spy = mocker.spy(mod.xcli, "_dispatch_func") spy = mocker.spy(mod.xcli, "run_with_partial_args")
# action # action
main(shlex.split(args)) main(shlex.split(args))

View file

@ -366,8 +366,8 @@ class ArgParser(ap.ArgumentParser):
return super()._parse_known_args(arg_strings, namespace) return super()._parse_known_args(arg_strings, namespace)
def _dispatch_func(func: tp.Callable, ns: dict[str, tp.Any]): def run_with_partial_args(func: tp.Callable, ns: dict[str, tp.Any]):
"""Final dispatch to the function based on signature.""" """Run function based on signature. Filling the arguments will be based on the values in ``ns``."""
sign = inspect.signature(func) sign = inspect.signature(func)
kwargs = {} kwargs = {}
for name, param in sign.parameters.items(): for name, param in sign.parameters.items():
@ -408,7 +408,7 @@ def dispatch(parser: ap.ArgumentParser, args=None, lenient=False, **ns):
if _FUNC_NAME in ns: if _FUNC_NAME in ns:
func = ns[_FUNC_NAME] func = ns[_FUNC_NAME]
return _dispatch_func(func, ns) return run_with_partial_args(func, ns)
class ArgparseCompleter: class ArgparseCompleter:

View file

@ -20,6 +20,7 @@ import xonsh.lazyimps as xli
import xonsh.platform as xp import xonsh.platform as xp
import xonsh.tools as xt import xonsh.tools as xt
from xonsh.built_ins import XSH from xonsh.built_ins import XSH
from xonsh.cli_utils import run_with_partial_args
from xonsh.procs.readers import safe_fdclose from xonsh.procs.readers import safe_fdclose
@ -466,7 +467,17 @@ class ProcProxyThread(threading.Thread):
xt.redirect_stderr(STDERR_DISPATCHER), xt.redirect_stderr(STDERR_DISPATCHER),
XSH.env.swap(self.env, __ALIAS_STACK=alias_stack), XSH.env.swap(self.env, __ALIAS_STACK=alias_stack),
): ):
r = self.f(self.args, sp_stdin, sp_stdout, sp_stderr, spec, spec.stack) r = run_with_partial_args(
self.f,
{
"args": self.args,
"stdin": sp_stdin,
"stdout": sp_stdout,
"stderr": sp_stderr,
"spec": spec,
"stack": spec.stack,
},
)
except SystemExit as e: except SystemExit as e:
r = e.code if isinstance(e.code, int) else int(bool(e.code)) r = e.code if isinstance(e.code, int) else int(bool(e.code))
except OSError: except OSError:
@ -767,7 +778,17 @@ class ProcProxy:
# run the actual function # run the actual function
try: try:
with XSH.env.swap(self.env): with XSH.env.swap(self.env):
r = self.f(self.args, stdin, stdout, stderr, spec, spec.stack) r = run_with_partial_args(
self.f,
{
"args": self.args,
"stdin": stdin,
"stdout": stdout,
"stderr": stderr,
"spec": spec,
"stack": spec.stack,
},
)
except Exception: except Exception:
xt.print_exception(source_msg="Exception in " + get_proc_proxy_name(self)) xt.print_exception(source_msg="Exception in " + get_proc_proxy_name(self))
r = 1 r = 1