Skip to content

Fix xonsh xontrib in .xsh scripts and execx#907

Open
anki-code wants to merge 1 commit into
evhub:developfrom
anki-code:fix-xonsh-exec-mode-5823
Open

Fix xonsh xontrib in .xsh scripts and execx#907
anki-code wants to merge 1 commit into
evhub:developfrom
anki-code:fix-xonsh-exec-mode-5823

Conversation

@anki-code
Copy link
Copy Markdown
Contributor

Summary

Resolves xonsh/xonsh#5823 and refs #883.

The xonsh xontrib only preprocessed code in xonsh's single parse mode (interactive REPL). When a .xsh script or execx(...) runs, xonsh compiles with mode="exec", so Coconut left |> alone and xonsh's parser then split it into | and >, eventually crashing in run_subproc with IndexError: list index out of range (xonsh/procs/specs.py:707).

#!/usr/bin/env xonsh
$(ls) |> .splitlines() |> len |> print   # IndexError before this PR

Changes

  • coconut/constants.py — add "exec" to enabled_xonsh_modes so the xontrib hooks run for scripts and execx. xonsh already caches compiled .xsh bytecode via run_script_with_cache, and Coconut already memoizes parse_xonsh per process, so the original .xonshrc slowness from coconut makes .xonshrc take an unreasonable amount of time to load #724 stays mitigated.
  • coconut/compiler/grammar.pyunsafe_xonsh_parser was built from single_input, which accepts only one statement, so multi-statement scripts failed with CoconutParseError: Expected end of text once exec was enabled. Switch to file_input (superset of single_input); single-statement input still parses correctly.
  • coconut/tests/main_test.pyexecx("10 |> print") previously asserted failure (subprocess mode / IndexError); it now succeeds and prints 10.
  • DOCS.md — note that .xsh scripts and execx now work; only @(<code>) and evalx remain Python-only.
  • coconut/root.py — bump DEVELOP.

Test plan

  • Original issue repro: $(ls) |> .splitlines() |> len |> print from a .xsh script — works.
  • Multi-statement script with 1 |> print, "hello" |> .upper() |> print, [1,2,3] |> sum |> print — all run.
  • execx("10 |> print") — prints 10.
  • Plain Python .xsh scripts and subprocess-mode commands (echo, ls) — no regression.
  • Existing interactive REPL behavior (!(ls -la) |> bool, '1; 2' |> print, len("""1\n3\n5""")) — unchanged.
  • Existing API assertions for parse(..., "xonsh") in extras.coco (lines 326–327) — still pass.

Resolves xonsh/xonsh#5823 and refs evhub#883.

Coconut's xontrib only preprocessed code in xonsh's "single" parse
mode (interactive REPL), so |> in .xsh scripts and inside execx
(both compiled with mode="exec") was left for xonsh to parse and
got split into | and >, causing IndexError in run_subproc.

Two changes are needed:

* enabled_xonsh_modes now includes "exec" so the xontrib hooks
  run for scripts and execx. xonsh already caches compiled .xsh
  bytecode via run_script_with_cache, and Coconut already
  memoizes parse_xonsh per process, so the original .xonshrc
  slowness from evhub#724 stays mitigated.

* unsafe_xonsh_parser was built from single_input, accepting
  only one statement. Scripts contain multiple statements, so
  switch to file_input. Single-statement input still parses
  correctly since file_input is a superset.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant