Fix #5491: more tests (#5498)

Fix #5491: 
* fix condition
* added more well organized tests

## 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-06-14 07:39:16 +02:00 committed by GitHub
parent 5ee386eed9
commit 06aca868a2
Failed to generate hash of commit
3 changed files with 82 additions and 100 deletions

View file

@ -24,6 +24,7 @@ In addition:
* Use ``xonsh --no-rc`` to prevent using control files.
* Use ``xonsh --rc snail.xsh`` to run only a certain control file.
* Use ``xonsh -i script.xsh`` to run xonsh in interactive mode with loading all possible control files.
* Use ``xonsh --rc rc1.xsh rc2.xsh -- script.xsh`` to run scripts with multiple control files.
The options set per user override settings in the system-wide control file.

View file

@ -40,6 +40,16 @@ skip_if_no_sleep = pytest.mark.skipif(
shutil.which("sleep") is None, reason="sleep command not on PATH"
)
base_env = {
"PATH": PATH,
"XONSH_DEBUG": "0",
"XONSH_SHOW_TRACEBACK": "1",
"RAISE_SUBPROC_ERROR": "0",
"FOREIGN_ALIASES_SUPPRESS_SKIP_MESSAGE": "1",
"PROMPT": "",
"TERM": "linux", # disable ansi escape codes
}
def run_xonsh(
cmd,
@ -52,35 +62,31 @@ def run_xonsh(
path=None,
args=None,
timeout=20,
add_env=None,
env=None,
):
env = dict(os.environ)
if path is None:
env["PATH"] = PATH
else:
env["PATH"] = path
env["XONSH_DEBUG"] = "0" # was "1"
env["XONSH_SHOW_TRACEBACK"] = "1"
env["RAISE_SUBPROC_ERROR"] = "0"
env["FOREIGN_ALIASES_SUPPRESS_SKIP_MESSAGE"] = "1"
env["PROMPT"] = ""
# disable ansi escape codes
env["TERM"] = "linux"
if add_env:
env |= add_env
# Env
popen_env = dict(os.environ)
popen_env |= base_env
if path:
popen_env["PATH"] = path
if env:
popen_env |= env
# Args
xonsh = shutil.which("xonsh", path=PATH)
popen_args = [xonsh]
if not args:
popen_args += ["--no-rc"]
else:
popen_args += args
if interactive:
popen_args.append("-i")
if cmd and isinstance(cmd, str) and not cmd.endswith("\n"):
# In interactive mode we need to emulate "Press Enter".
cmd += "\n"
if single_command:
popen_args += ["-c", cmd]
input = None
@ -89,7 +95,7 @@ def run_xonsh(
proc = sp.Popen(
popen_args,
env=env,
env=popen_env,
stdin=stdin,
stdout=stdout,
stderr=stderr,
@ -1349,102 +1355,77 @@ def test_alias_stability_exception():
assert "Bad file descriptor" not in out
@pytest.mark.flaky(reruns=3, reruns_delay=2)
def test_rc_no_xonshrc_for_non_interactive(tmpdir):
"""Testing no ``~/.xonshrc`` execution in non-interactive commands (#5491)."""
rc_dir = tmpdir.mkdir("rc_dir")
user_home_dir = tmpdir.mkdir("user_home")
user_not_home_dir = tmpdir.mkdir("user_not_home")
(rc_dir / "rc_dir.xsh").write_text("echo RC_DIR", encoding="utf8")
(user_home_dir / ".xonshrc").write_text("echo RC_HOME", encoding="utf8")
(script := user_home_dir / "script.xsh").write_text("echo SCRIPT", encoding="utf8")
user_home_rc_path_crossplatform = str(
(Path(user_home_dir) / ".xonshrc").expanduser()
@pytest.mark.parametrize(
"cmd,exp",
[
["-i", ".*CONFIG_XONSH_RC_XSH.*HOME_XONSHRC.*CONFIG_XONSH_RCD.*"],
["--rc rc.xsh", ".*RCXSH.*"],
["-i --rc rc.xsh", ".*RCXSH.*"],
["-c print('CMD')", ".*CONFIG_XONSH_RC_XSH.*CONFIG_XONSH_RCD.*CMD.*"],
[
"-i -c print('CMD')",
".*CONFIG_XONSH_RC_XSH.*HOME_XONSHRC.*CONFIG_XONSH_RCD.*CMD.*",
],
["script.xsh", ".*CONFIG_XONSH_RC_XSH.*CONFIG_XONSH_RCD.*SCRIPT.*"],
[
"-i script.xsh",
".*CONFIG_XONSH_RC_XSH.*HOME_XONSHRC.*CONFIG_XONSH_RCD.*SCRIPT.*",
],
["--rc rc.xsh -- script.xsh", ".*RCXSH.*SCRIPT.*"],
["-i --rc rc.xsh -- script.xsh", ".*RCXSH.*SCRIPT.*"],
["--no-rc --rc rc.xsh -- script.xsh", ".*SCRIPT.*"],
["-i --no-rc --rc rc.xsh -- script.xsh", ".*SCRIPT.*"],
],
)
# @pytest.mark.flaky(reruns=3, reruns_delay=2)
def test_xonshrc(tmpdir, cmd, exp):
# ~/.xonshrc
home = tmpdir.mkdir("home")
(home / ".xonshrc").write_text("echo HOME_XONSHRC", encoding="utf8")
home_xonsh_rc_path = str( # crossplatform path
(Path(home) / ".xonshrc").expanduser()
)
(user_not_home_rc := user_not_home_dir / "rc.xsh").write_text(
"echo RC_NOT_HOME", encoding="utf8"
)
xonshrc_files = [str(user_not_home_rc), str(user_home_rc_path_crossplatform)]
xonshrc_dir = [str(rc_dir)]
# Here `eval()` is needed in Windows case where the path contains `:` symbol (e.g. `C:\\path`) and treated as list delimiter.
# ~/.config/xonsh/rc.xsh
home_config_xonsh = tmpdir.mkdir("home_config_xonsh")
(home_config_xonsh_rc_xsh := home_config_xonsh / "rc.xsh").write_text(
"echo CONFIG_XONSH_RC_XSH", encoding="utf8"
)
# ~/.config/xonsh/rc.d/
home_config_xonsh_rcd = tmpdir.mkdir("home_config_xonsh_rcd")
(home_config_xonsh_rcd / "rcd1.xsh").write_text(
"echo CONFIG_XONSH_RCD", encoding="utf8"
)
# ~/home/rc.xsh
(rc_xsh := home / "rc.xsh").write_text("echo RCXSH", encoding="utf8")
(script_xsh := home / "script.xsh").write_text("echo SCRIPT_XSH", encoding="utf8")
# Construct $XONSHRC and $XONSHRC_DIR
xonshrc_files = [str(home_config_xonsh_rc_xsh), str(home_xonsh_rc_path)]
xonshrc_dir = [str(home_config_xonsh_rcd)]
args = [
f'-DHOME="{str(user_home_dir)}"',
f'-DHOME="{str(home)}"',
f'-DXONSHRC="{os.pathsep.join(xonshrc_files)}"',
f'-DXONSHRC_DIR="{os.pathsep.join(xonshrc_dir)}"',
]
cmd = "print(42+42)"
add_env = {"HOME": str(user_home_dir)}
env = {"HOME": str(home)}
cmd = cmd.replace("rc.xsh", str(rc_xsh)).replace("script.xsh", str(script_xsh))
args = args + cmd.split()
# xonsh
out, err, ret = run_xonsh(
cmd=None,
stdin=None,
single_command=False,
interactive=True,
args=args,
add_env=add_env,
env=env,
)
exp = ".*RC_NOT_HOME.*RC_HOME.*RC_DIR.*"
exp = exp
assert re.match(
exp,
out,
re.MULTILINE | re.DOTALL,
), f"Expected: {exp!r},\nResult: {out!r},\nargs={args!r}"
# xonsh -c "cmd"
out, err, ret = run_xonsh(cmd=cmd, interactive=False, args=args, add_env=add_env)
exp = ".*RC_NOT_HOME.*RC_DIR.*84.*"
assert re.match(
exp,
out,
re.MULTILINE | re.DOTALL,
), f"Expected: {exp!r},\nResult: {out!r},\nargs={args!r}"
# xonsh -i -c "cmd"
out, err, ret = run_xonsh(
cmd=cmd + "\n", interactive=True, args=args, add_env=add_env
)
exp = ".*RC_NOT_HOME.*RC_HOME.*RC_DIR.*"
if not ON_WINDOWS:
# On Windows we well have `NoConsoleScreenBufferError` in interactive mode so avoid checking interactive output of the command.
exp += "84.*"
assert re.match(
exp,
out,
re.MULTILINE | re.DOTALL,
), f"Expected: {exp!r},\nResult: {out!r},\nargs={args!r}"
# xonsh script.xsh
out, err, ret = run_xonsh(
cmd=cmd + "\n",
interactive=False,
single_command=False,
args=args + ["--", script],
add_env=add_env,
)
exp = ".*RC_NOT_HOME.*RC_DIR.*SCRIPT.*"
assert re.match(
exp,
out,
re.MULTILINE | re.DOTALL,
), f"Expected: {exp!r},\nResult: {out!r},\nargs={args!r}"
# xonsh -i script.xsh
out, err, ret = run_xonsh(
cmd=None,
interactive=False,
single_command=False,
args=args + ["-i", "--", script],
add_env=add_env,
)
exp = ".*RC_NOT_HOME.*RC_HOME.*RC_DIR.*SCRIPT.*"
assert re.match(
exp,
out,
re.MULTILINE | re.DOTALL,
), f"Expected: {exp!r},\nResult: {out!r},\nargs={args!r}"
), f"Case: xonsh {cmd},\nExpected: {exp!r},\nResult: {out!r},\nargs={args!r}"

View file

@ -309,7 +309,7 @@ def _get_rc_files(shell_kwargs: dict, args, env):
rc = env.get("XONSHRC")
rcd = env.get("XONSHRC_DIR")
if not env.get("XONSH_INTERACTIVE", False) or not args.force_interactive:
if not env.get("XONSH_INTERACTIVE", False):
"""
Home based ``~/.xonshrc`` file has special meaning and history. The ecosystem around shells treats this kind of files
as the place where interactive tools can add configs. To avoid unintended and unexpected affection