mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 08:24:40 +01:00
spec modifier: rename to decorator alias (#5579)
* rename * rename * rename * rename * rename * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * rename * rename * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * rename * rename * rename * rename * rename * rename * rename * rename * rename * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix * fix --------- 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:
parent
96c2c0af14
commit
233e407b52
7 changed files with 98 additions and 77 deletions
|
@ -1632,26 +1632,26 @@ best used in conjunction with the ``unthreadable`` decorator. For example:
|
||||||
Note that ``@()`` is required to pass the python list ``args`` to a subprocess
|
Note that ``@()`` is required to pass the python list ``args`` to a subprocess
|
||||||
command.
|
command.
|
||||||
|
|
||||||
Specification Modifier Aliases
|
Decorator Aliases
|
||||||
------------------------------
|
-----------------
|
||||||
|
|
||||||
Using ``SpecAttrModifierAlias`` and callable ``output_format`` you can
|
Using ``DecoratorAlias`` and ``SpecAttrDecoratorAlias`` and callable ``output_format`` you can
|
||||||
convert subprocess command output into Python object:
|
convert subprocess command output into Python object:
|
||||||
|
|
||||||
.. code-block:: xonshcon
|
.. code-block:: xonshcon
|
||||||
|
|
||||||
import json, pathlib, yaml
|
import json, pathlib, yaml
|
||||||
from xonsh.procs.specs import SpecAttrModifierAlias
|
from xonsh.procs.specs import SpecAttrDecoratorAlias
|
||||||
|
|
||||||
aliases['@lines'] = SpecAttrModifierAlias({"output_format": 'list_lines'},
|
aliases['@lines'] = SpecAttrDecoratorAlias({"output_format": 'list_lines'},
|
||||||
"Set `list_lines` output format.")
|
"Set `list_lines` output format.")
|
||||||
aliases['@json'] = SpecAttrModifierAlias({"output_format": lambda lines: json.loads('\n'.join(lines))},
|
aliases['@json'] = SpecAttrDecoratorAlias({"output_format": lambda lines: json.loads('\n'.join(lines))},
|
||||||
"Set `json` output format.")
|
"Set `json` output format.")
|
||||||
aliases['@path'] = SpecAttrModifierAlias({"output_format": lambda lines: pathlib.Path(':'.join(lines))},
|
aliases['@path'] = SpecAttrDecoratorAlias({"output_format": lambda lines: pathlib.Path(':'.join(lines))},
|
||||||
"Set `path` output format.")
|
"Set `path` output format.")
|
||||||
aliases['@yaml'] = SpecAttrModifierAlias({"output_format": lambda lines: yaml.safe_load('\n'.join(lines))},
|
aliases['@yaml'] = SpecAttrDecoratorAlias({"output_format": lambda lines: yaml.safe_load('\n'.join(lines))},
|
||||||
"Set `yaml` output format.")
|
"Set `yaml` output format.")
|
||||||
aliases['@noerr'] = SpecAttrModifierAlias({"raise_subproc_error": False},
|
aliases['@noerr'] = SpecAttrDecoratorAlias({"raise_subproc_error": False},
|
||||||
"Set `raise_subproc_error` to False.")
|
"Set `raise_subproc_error` to False.")
|
||||||
|
|
||||||
|
|
||||||
|
|
24
news/rename_xthread.rst
Normal file
24
news/rename_xthread.rst
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
**Added:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Changed:**
|
||||||
|
|
||||||
|
* Rename: ``SpecModifier``, ``xthread``, ``xunthread`` renamed to ``DecoratorAlias``, ``@thread``, ``@unthread`` to support idea that
|
||||||
|
spec modifier is like a Python decorator.
|
||||||
|
|
||||||
|
**Deprecated:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Removed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Fixed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Security:**
|
||||||
|
|
||||||
|
* <news item>
|
|
@ -10,8 +10,8 @@ import pytest
|
||||||
from xonsh.procs.posix import PopenThread
|
from xonsh.procs.posix import PopenThread
|
||||||
from xonsh.procs.proxies import STDOUT_DISPATCHER, ProcProxy, ProcProxyThread
|
from xonsh.procs.proxies import STDOUT_DISPATCHER, ProcProxy, ProcProxyThread
|
||||||
from xonsh.procs.specs import (
|
from xonsh.procs.specs import (
|
||||||
SpecAttrModifierAlias,
|
DecoratorAlias,
|
||||||
SpecModifierAlias,
|
SpecAttrDecoratorAlias,
|
||||||
SubprocSpec,
|
SubprocSpec,
|
||||||
_run_command_pipeline,
|
_run_command_pipeline,
|
||||||
cmds_to_specs,
|
cmds_to_specs,
|
||||||
|
@ -288,8 +288,8 @@ def test_run_subproc_background(captured, exp_is_none):
|
||||||
assert (return_val is None) == exp_is_none
|
assert (return_val is None) == exp_is_none
|
||||||
|
|
||||||
|
|
||||||
def test_spec_modifier_alias_alone(xession):
|
def test_spec_decorator_alias_alone(xession):
|
||||||
xession.aliases["xunthread"] = SpecAttrModifierAlias(
|
xession.aliases["xunthread"] = SpecAttrDecoratorAlias(
|
||||||
{"threadable": False, "force_threadable": False}
|
{"threadable": False, "force_threadable": False}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -300,8 +300,8 @@ def test_spec_modifier_alias_alone(xession):
|
||||||
assert spec.alias_name == "xunthread"
|
assert spec.alias_name == "xunthread"
|
||||||
|
|
||||||
|
|
||||||
def test_spec_modifier_alias(xession):
|
def test_spec_decorator_alias(xession):
|
||||||
xession.aliases["xunthread"] = SpecAttrModifierAlias(
|
xession.aliases["xunthread"] = SpecAttrDecoratorAlias(
|
||||||
{"threadable": False, "force_threadable": False}
|
{"threadable": False, "force_threadable": False}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -313,11 +313,11 @@ def test_spec_modifier_alias(xession):
|
||||||
assert spec.force_threadable is False
|
assert spec.force_threadable is False
|
||||||
|
|
||||||
|
|
||||||
def test_spec_modifier_alias_tree(xession):
|
def test_spec_decorator_alias_tree(xession):
|
||||||
xession.aliases["xthread"] = SpecAttrModifierAlias(
|
xession.aliases["xthread"] = SpecAttrDecoratorAlias(
|
||||||
{"threadable": True, "force_threadable": True}
|
{"threadable": True, "force_threadable": True}
|
||||||
)
|
)
|
||||||
xession.aliases["xunthread"] = SpecAttrModifierAlias(
|
xession.aliases["xunthread"] = SpecAttrDecoratorAlias(
|
||||||
{"threadable": False, "force_threadable": False}
|
{"threadable": False, "force_threadable": False}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -337,11 +337,11 @@ def test_spec_modifier_alias_tree(xession):
|
||||||
assert spec.force_threadable is False
|
assert spec.force_threadable is False
|
||||||
|
|
||||||
|
|
||||||
def test_spec_modifier_alias_multiple(xession):
|
def test_spec_decorator_alias_multiple(xession):
|
||||||
xession.aliases["@unthread"] = SpecAttrModifierAlias(
|
xession.aliases["@unthread"] = SpecAttrDecoratorAlias(
|
||||||
{"threadable": False, "force_threadable": False}
|
{"threadable": False, "force_threadable": False}
|
||||||
)
|
)
|
||||||
xession.aliases["@dict"] = SpecAttrModifierAlias({"output_format": "list_lines"})
|
xession.aliases["@dict"] = SpecAttrDecoratorAlias({"output_format": "list_lines"})
|
||||||
|
|
||||||
cmds = [
|
cmds = [
|
||||||
["@unthread", "@dict", "echo", "1"],
|
["@unthread", "@dict", "echo", "1"],
|
||||||
|
@ -356,12 +356,12 @@ def test_spec_modifier_alias_multiple(xession):
|
||||||
|
|
||||||
|
|
||||||
@skip_if_on_windows
|
@skip_if_on_windows
|
||||||
def test_spec_modifier_alias_output_format(xession):
|
def test_spec_decorator_alias_output_format(xession):
|
||||||
class SpecModifierOutputLinesAlias(SpecModifierAlias):
|
class OutputLinesDecoratorAlias(DecoratorAlias):
|
||||||
def on_modifer_added(self, spec):
|
def decorate_spec(self, spec):
|
||||||
spec.output_format = "list_lines"
|
spec.output_format = "list_lines"
|
||||||
|
|
||||||
xession.aliases["xlines"] = SpecModifierOutputLinesAlias()
|
xession.aliases["xlines"] = OutputLinesDecoratorAlias()
|
||||||
|
|
||||||
cmds = [["xlines", "echo", "1\n2\n3"]]
|
cmds = [["xlines", "echo", "1\n2\n3"]]
|
||||||
specs = cmds_to_specs(cmds, captured="stdout")
|
specs = cmds_to_specs(cmds, captured="stdout")
|
||||||
|
@ -531,10 +531,10 @@ def test_alias_return_command_chain(xession):
|
||||||
assert spec.alias_name == "foreground"
|
assert spec.alias_name == "foreground"
|
||||||
|
|
||||||
|
|
||||||
def test_alias_return_command_chain_spec_modifiers(xession):
|
def test_alias_return_command_chain_decorators(xession):
|
||||||
xession.aliases["foreground"] = "midground f0 f1"
|
xession.aliases["foreground"] = "midground f0 f1"
|
||||||
|
|
||||||
xession.aliases["xunthread"] = SpecAttrModifierAlias(
|
xession.aliases["xunthread"] = SpecAttrDecoratorAlias(
|
||||||
{"threadable": False, "force_threadable": False}
|
{"threadable": False, "force_threadable": False}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -556,16 +556,16 @@ def test_alias_return_command_chain_spec_modifiers(xession):
|
||||||
|
|
||||||
|
|
||||||
def test_alias_return_command_eval_inside(xession):
|
def test_alias_return_command_eval_inside(xession):
|
||||||
xession.aliases["xthread"] = SpecAttrModifierAlias(
|
xession.aliases["xthread"] = SpecAttrDecoratorAlias(
|
||||||
{"threadable": True, "force_threadable": True}
|
{"threadable": True, "force_threadable": True}
|
||||||
)
|
)
|
||||||
|
|
||||||
@xession.aliases.register("xsudo")
|
@xession.aliases.register("xsudo")
|
||||||
@xession.aliases.return_command
|
@xession.aliases.return_command
|
||||||
def _midground(args, spec_modifiers=None):
|
def _midground(args, decorators=None):
|
||||||
return [
|
return [
|
||||||
"sudo",
|
"sudo",
|
||||||
*xession.aliases.eval_alias(args, spec_modifiers=spec_modifiers),
|
*xession.aliases.eval_alias(args, decorators=decorators),
|
||||||
]
|
]
|
||||||
|
|
||||||
xession.aliases["cmd"] = "xthread echo 1"
|
xession.aliases["cmd"] = "xthread echo 1"
|
||||||
|
|
|
@ -1365,10 +1365,10 @@ def test_alias_stability():
|
||||||
|
|
||||||
@skip_if_on_windows
|
@skip_if_on_windows
|
||||||
@pytest.mark.flaky(reruns=3, reruns_delay=1)
|
@pytest.mark.flaky(reruns=3, reruns_delay=1)
|
||||||
def test_spec_modifier_alias():
|
def test_spec_decorator_alias():
|
||||||
"""Testing spec modifier alias with `@` in the alias name."""
|
"""Testing spec modifier alias with `@` in the alias name."""
|
||||||
stdin_cmd = (
|
stdin_cmd = (
|
||||||
"from xonsh.procs.specs import SpecAttrModifierAlias as mod\n"
|
"from xonsh.procs.specs import SpecAttrDecoratorAlias as mod\n"
|
||||||
'aliases["@dict"] = mod({"output_format": lambda lines: eval("\\n".join(lines))})\n'
|
'aliases["@dict"] = mod({"output_format": lambda lines: eval("\\n".join(lines))})\n'
|
||||||
"d = $(@dict echo '{\"a\":42}')\n"
|
"d = $(@dict echo '{\"a\":42}')\n"
|
||||||
"print('Answer =', d['a'])\n"
|
"print('Answer =', d['a'])\n"
|
||||||
|
|
|
@ -35,7 +35,7 @@ from xonsh.platform import (
|
||||||
)
|
)
|
||||||
from xonsh.procs.executables import locate_file
|
from xonsh.procs.executables import locate_file
|
||||||
from xonsh.procs.jobs import bg, clean_jobs, disown, fg, jobs
|
from xonsh.procs.jobs import bg, clean_jobs, disown, fg, jobs
|
||||||
from xonsh.procs.specs import SpecAttrModifierAlias, SpecModifierAlias
|
from xonsh.procs.specs import DecoratorAlias, SpecAttrDecoratorAlias
|
||||||
from xonsh.timings import timeit_alias
|
from xonsh.timings import timeit_alias
|
||||||
from xonsh.tools import (
|
from xonsh.tools import (
|
||||||
ALIAS_KWARG_NAMES,
|
ALIAS_KWARG_NAMES,
|
||||||
|
@ -90,7 +90,7 @@ class FuncAlias:
|
||||||
stderr=None,
|
stderr=None,
|
||||||
spec=None,
|
spec=None,
|
||||||
stack=None,
|
stack=None,
|
||||||
spec_modifiers=None,
|
decorators=None,
|
||||||
):
|
):
|
||||||
return run_alias_by_params(
|
return run_alias_by_params(
|
||||||
self.func,
|
self.func,
|
||||||
|
@ -101,7 +101,7 @@ class FuncAlias:
|
||||||
"stderr": stderr,
|
"stderr": stderr,
|
||||||
"spec": spec,
|
"spec": spec,
|
||||||
"stack": stack,
|
"stack": stack,
|
||||||
"spec_modifiers": spec_modifiers,
|
"decorators": decorators,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ class Aliases(cabc.MutableMapping):
|
||||||
value,
|
value,
|
||||||
seen_tokens=frozenset(),
|
seen_tokens=frozenset(),
|
||||||
acc_args=(),
|
acc_args=(),
|
||||||
spec_modifiers=None,
|
decorators=None,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
"Evaluates" the alias ``value``, by recursively looking up the leftmost
|
"Evaluates" the alias ``value``, by recursively looking up the leftmost
|
||||||
|
@ -173,7 +173,7 @@ class Aliases(cabc.MutableMapping):
|
||||||
callable. The resulting callable will be "partially applied" with
|
callable. The resulting callable will be "partially applied" with
|
||||||
``["-al", "arg"]``.
|
``["-al", "arg"]``.
|
||||||
"""
|
"""
|
||||||
spec_modifiers = spec_modifiers if spec_modifiers is not None else []
|
decorators = decorators if decorators is not None else []
|
||||||
# Beware of mutability: default values for keyword args are evaluated
|
# Beware of mutability: default values for keyword args are evaluated
|
||||||
# only once.
|
# only once.
|
||||||
if (
|
if (
|
||||||
|
@ -183,8 +183,8 @@ class Aliases(cabc.MutableMapping):
|
||||||
):
|
):
|
||||||
i = 0
|
i = 0
|
||||||
for v in value:
|
for v in value:
|
||||||
if isinstance(mod := self._raw.get(str(v)), SpecModifierAlias):
|
if isinstance(mod := self._raw.get(str(v)), DecoratorAlias):
|
||||||
spec_modifiers.append(mod)
|
decorators.append(mod)
|
||||||
i += 1
|
i += 1
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
@ -192,7 +192,7 @@ class Aliases(cabc.MutableMapping):
|
||||||
|
|
||||||
if callable(value) and getattr(value, "return_what", "result") == "command":
|
if callable(value) and getattr(value, "return_what", "result") == "command":
|
||||||
try:
|
try:
|
||||||
value = value(acc_args, spec_modifiers=spec_modifiers)
|
value = value(acc_args, decorators=decorators)
|
||||||
acc_args = []
|
acc_args = []
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print_exception(f"Exception inside alias {value}: {e}")
|
print_exception(f"Exception inside alias {value}: {e}")
|
||||||
|
@ -220,14 +220,14 @@ class Aliases(cabc.MutableMapping):
|
||||||
self._raw[token],
|
self._raw[token],
|
||||||
seen_tokens,
|
seen_tokens,
|
||||||
acc_args,
|
acc_args,
|
||||||
spec_modifiers=spec_modifiers,
|
decorators=decorators,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get(
|
def get(
|
||||||
self,
|
self,
|
||||||
key,
|
key,
|
||||||
default=None,
|
default=None,
|
||||||
spec_modifiers=None,
|
decorators=None,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Returns list that represent command with resolved aliases.
|
Returns list that represent command with resolved aliases.
|
||||||
|
@ -235,14 +235,14 @@ class Aliases(cabc.MutableMapping):
|
||||||
In the first position will be the resolved command name or callable alias.
|
In the first position will be the resolved command name or callable alias.
|
||||||
If the key is not present, then `default` is returned.
|
If the key is not present, then `default` is returned.
|
||||||
|
|
||||||
``spec_modifiers`` is the list of SpecModifier objects that found during
|
``decorators`` is the list of `DecoratorAlias` objects that found during
|
||||||
resolving aliases (#5443).
|
resolving aliases (#5443).
|
||||||
|
|
||||||
Note! The return value is always list because during resolving
|
Note! The return value is always list because during resolving
|
||||||
we can find return_command alias that can completely replace
|
we can find return_command alias that can completely replace
|
||||||
command and add new arguments.
|
command and add new arguments.
|
||||||
"""
|
"""
|
||||||
spec_modifiers = spec_modifiers if spec_modifiers is not None else []
|
decorators = decorators if decorators is not None else []
|
||||||
args = []
|
args = []
|
||||||
if isinstance(key, list):
|
if isinstance(key, list):
|
||||||
args = key[1:]
|
args = key[1:]
|
||||||
|
@ -250,7 +250,7 @@ class Aliases(cabc.MutableMapping):
|
||||||
val = self._raw.get(key)
|
val = self._raw.get(key)
|
||||||
if callable(val) and getattr(val, "return_what", "result") == "command":
|
if callable(val) and getattr(val, "return_what", "result") == "command":
|
||||||
try:
|
try:
|
||||||
val = val(args, spec_modifiers=spec_modifiers)
|
val = val(args, decorators=decorators)
|
||||||
args = []
|
args = []
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print_exception(f"Exception inside alias {key!r}: {e}")
|
print_exception(f"Exception inside alias {key!r}: {e}")
|
||||||
|
@ -264,7 +264,7 @@ class Aliases(cabc.MutableMapping):
|
||||||
return self.eval_alias(
|
return self.eval_alias(
|
||||||
val,
|
val,
|
||||||
seen_tokens={key},
|
seen_tokens={key},
|
||||||
spec_modifiers=spec_modifiers,
|
decorators=decorators,
|
||||||
acc_args=args,
|
acc_args=args,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -483,10 +483,10 @@ class PartialEvalAlias7(PartialEvalAliasBase):
|
||||||
stderr=None,
|
stderr=None,
|
||||||
spec=None,
|
spec=None,
|
||||||
stack=None,
|
stack=None,
|
||||||
spec_modifiers=None,
|
decorators=None,
|
||||||
):
|
):
|
||||||
args = list(self.acc_args) + args
|
args = list(self.acc_args) + args
|
||||||
return self.f(args, stdin, stdout, stderr, spec, stack, spec_modifiers)
|
return self.f(args, stdin, stdout, stderr, spec, stack, decorators)
|
||||||
|
|
||||||
|
|
||||||
PARTIAL_EVAL_ALIASES = (
|
PARTIAL_EVAL_ALIASES = (
|
||||||
|
@ -538,7 +538,7 @@ def run_alias_by_params(func: tp.Callable, params: dict[str, tp.Any]):
|
||||||
"stderr": None,
|
"stderr": None,
|
||||||
"spec": None,
|
"spec": None,
|
||||||
"stack": None,
|
"stack": None,
|
||||||
"spec_modifiers": None,
|
"decorators": None,
|
||||||
}
|
}
|
||||||
alias_params |= params
|
alias_params |= params
|
||||||
sign = inspect.signature(func)
|
sign = inspect.signature(func)
|
||||||
|
@ -1064,11 +1064,11 @@ def make_default_aliases():
|
||||||
"completer": xca.completer_alias,
|
"completer": xca.completer_alias,
|
||||||
"xpip": detect_xpip_alias(),
|
"xpip": detect_xpip_alias(),
|
||||||
"xonsh-reset": xonsh_reset,
|
"xonsh-reset": xonsh_reset,
|
||||||
"xthread": SpecAttrModifierAlias(
|
"@thread": SpecAttrDecoratorAlias(
|
||||||
{"threadable": True, "force_threadable": True},
|
{"threadable": True, "force_threadable": True},
|
||||||
"Mark current command as threadable.",
|
"Mark current command as threadable.",
|
||||||
),
|
),
|
||||||
"xunthread": SpecAttrModifierAlias(
|
"@unthread": SpecAttrDecoratorAlias(
|
||||||
{"threadable": False, "force_threadable": False},
|
{"threadable": False, "force_threadable": False},
|
||||||
"Mark current command as unthreadable.",
|
"Mark current command as unthreadable.",
|
||||||
),
|
),
|
||||||
|
|
|
@ -167,8 +167,8 @@ class CommandPipeline:
|
||||||
# to stop.
|
# to stop.
|
||||||
pipeline_group = os.getpgid(0)
|
pipeline_group = os.getpgid(0)
|
||||||
for i, spec in enumerate(specs):
|
for i, spec in enumerate(specs):
|
||||||
for mod in spec.spec_modifiers:
|
for mod in spec.decorators:
|
||||||
mod.on_pre_run(self, spec, i)
|
mod.decorate_spec_pre_run(self, spec, i)
|
||||||
if self.starttime is None:
|
if self.starttime is None:
|
||||||
self.starttime = time.time()
|
self.starttime = time.time()
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -277,10 +277,10 @@ def no_pg_xonsh_preexec_fn():
|
||||||
signal.signal(signal.SIGTSTP, default_signal_pauser)
|
signal.signal(signal.SIGTSTP, default_signal_pauser)
|
||||||
|
|
||||||
|
|
||||||
class SpecModifierAlias:
|
class DecoratorAlias:
|
||||||
"""Spec modifier base class."""
|
"""Decorator alias base class."""
|
||||||
|
|
||||||
descr = "Spec modifier base class."
|
descr = "DecoratorAlias base."
|
||||||
|
|
||||||
def __call__(
|
def __call__(
|
||||||
self,
|
self,
|
||||||
|
@ -294,24 +294,24 @@ class SpecModifierAlias:
|
||||||
):
|
):
|
||||||
print(self.descr, file=stdout)
|
print(self.descr, file=stdout)
|
||||||
|
|
||||||
def on_modifer_added(self, spec):
|
def decorate_spec(self, spec):
|
||||||
"""Modify spec immediately after modifier added."""
|
"""Modify spec immediately after modifier added."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_pre_run(self, pipeline, spec, spec_num):
|
def decorate_spec_pre_run(self, pipeline, spec, spec_num):
|
||||||
"""Modify spec before run."""
|
"""Modify spec before run."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SpecAttrModifierAlias(SpecModifierAlias):
|
class SpecAttrDecoratorAlias(DecoratorAlias):
|
||||||
"""Modifier for spec attributes."""
|
"""Decorator Alias for spec attributes."""
|
||||||
|
|
||||||
def __init__(self, set_attributes: dict, descr=""):
|
def __init__(self, set_attributes: dict, descr=""):
|
||||||
self.set_attributes = set_attributes
|
self.set_attributes = set_attributes
|
||||||
self.descr = descr
|
self.descr = descr
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
def on_modifer_added(self, spec):
|
def decorate_spec(self, spec):
|
||||||
for a, v in self.set_attributes.items():
|
for a, v in self.set_attributes.items():
|
||||||
setattr(spec, a, v)
|
setattr(spec, a, v)
|
||||||
|
|
||||||
|
@ -419,7 +419,7 @@ class SubprocSpec:
|
||||||
self.captured_stdout = None
|
self.captured_stdout = None
|
||||||
self.captured_stderr = None
|
self.captured_stderr = None
|
||||||
self.stack = None
|
self.stack = None
|
||||||
self.spec_modifiers = [] # List of SpecModifierAlias objects that applied to spec.
|
self.decorators = [] # List of DecoratorAlias objects that applied to spec.
|
||||||
self.output_format = XSH.env.get("XONSH_SUBPROC_OUTPUT_FORMAT", "stream_lines")
|
self.output_format = XSH.env.get("XONSH_SUBPROC_OUTPUT_FORMAT", "stream_lines")
|
||||||
self.raise_subproc_error = None # Spec-based $RAISE_SUBPROC_ERROR.
|
self.raise_subproc_error = None # Spec-based $RAISE_SUBPROC_ERROR.
|
||||||
|
|
||||||
|
@ -642,7 +642,7 @@ class SubprocSpec:
|
||||||
# modifications that do not alter cmds may come before creating instance
|
# modifications that do not alter cmds may come before creating instance
|
||||||
spec = kls(cmd, cls=cls, **kwargs)
|
spec = kls(cmd, cls=cls, **kwargs)
|
||||||
# modifications that alter cmds must come after creating instance
|
# modifications that alter cmds must come after creating instance
|
||||||
spec.resolve_spec_modifiers() # keep this first
|
spec.resolve_decorators() # keep this first
|
||||||
spec.resolve_args_list()
|
spec.resolve_args_list()
|
||||||
spec.resolve_redirects()
|
spec.resolve_redirects()
|
||||||
spec.resolve_alias()
|
spec.resolve_alias()
|
||||||
|
@ -653,21 +653,19 @@ class SubprocSpec:
|
||||||
spec.resolve_stack()
|
spec.resolve_stack()
|
||||||
return spec
|
return spec
|
||||||
|
|
||||||
def add_spec_modifier(self, mod: SpecModifierAlias):
|
def add_decorator(self, mod: DecoratorAlias):
|
||||||
"""Add spec modifier to the specification."""
|
"""Add spec modifier to the specification."""
|
||||||
mod.on_modifer_added(self)
|
mod.decorate_spec(self)
|
||||||
self.spec_modifiers.append(mod)
|
self.decorators.append(mod)
|
||||||
|
|
||||||
def resolve_spec_modifiers(self):
|
def resolve_decorators(self):
|
||||||
"""Apply spec modifier."""
|
"""Apply decorators."""
|
||||||
if (ln := len(self.cmd)) == 1:
|
if (ln := len(self.cmd)) == 1:
|
||||||
return
|
return
|
||||||
for i in range(ln):
|
for i in range(ln):
|
||||||
c = self.cmd[i]
|
c = self.cmd[i]
|
||||||
if c in XSH.aliases and isinstance(
|
if c in XSH.aliases and isinstance(mod := XSH.aliases[c], DecoratorAlias):
|
||||||
mod := XSH.aliases[c], SpecModifierAlias
|
self.add_decorator(mod)
|
||||||
):
|
|
||||||
self.add_spec_modifier(mod)
|
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
self.cmd = self.cmd[i:]
|
self.cmd = self.cmd[i:]
|
||||||
|
@ -716,7 +714,7 @@ class SubprocSpec:
|
||||||
if callable(cmd0):
|
if callable(cmd0):
|
||||||
self.alias = cmd0
|
self.alias = cmd0
|
||||||
else:
|
else:
|
||||||
found_spec_modifiers = []
|
decorators = []
|
||||||
if isinstance(XSH.aliases, dict):
|
if isinstance(XSH.aliases, dict):
|
||||||
# Windows tests
|
# Windows tests
|
||||||
alias = XSH.aliases.get(cmd0, None)
|
alias = XSH.aliases.get(cmd0, None)
|
||||||
|
@ -726,7 +724,7 @@ class SubprocSpec:
|
||||||
alias = XSH.aliases.get(
|
alias = XSH.aliases.get(
|
||||||
self.cmd,
|
self.cmd,
|
||||||
None,
|
None,
|
||||||
spec_modifiers=found_spec_modifiers,
|
decorators=decorators,
|
||||||
)
|
)
|
||||||
if alias is not None:
|
if alias is not None:
|
||||||
self.alias_name = cmd0
|
self.alias_name = cmd0
|
||||||
|
@ -738,9 +736,8 @@ class SubprocSpec:
|
||||||
# E.g. `alias == ['ls', '-la']`
|
# E.g. `alias == ['ls', '-la']`
|
||||||
self.alias = alias
|
self.alias = alias
|
||||||
|
|
||||||
if found_spec_modifiers:
|
for mod in decorators:
|
||||||
for mod in found_spec_modifiers:
|
self.add_decorator(mod)
|
||||||
self.add_spec_modifier(mod)
|
|
||||||
|
|
||||||
def resolve_binary_loc(self):
|
def resolve_binary_loc(self):
|
||||||
"""Sets the binary location"""
|
"""Sets the binary location"""
|
||||||
|
|
Loading…
Add table
Reference in a new issue