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 --no-rc`` to prevent using control files.
* Use ``xonsh --rc snail.xsh`` to run only a certain control file. * 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 -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. 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" 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( def run_xonsh(
cmd, cmd,
@ -52,35 +62,31 @@ def run_xonsh(
path=None, path=None,
args=None, args=None,
timeout=20, timeout=20,
add_env=None, env=None,
): ):
env = dict(os.environ) # Env
if path is None: popen_env = dict(os.environ)
env["PATH"] = PATH popen_env |= base_env
else: if path:
env["PATH"] = path popen_env["PATH"] = path
env["XONSH_DEBUG"] = "0" # was "1" if env:
env["XONSH_SHOW_TRACEBACK"] = "1" popen_env |= env
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
# Args
xonsh = shutil.which("xonsh", path=PATH) xonsh = shutil.which("xonsh", path=PATH)
popen_args = [xonsh] popen_args = [xonsh]
if not args: if not args:
popen_args += ["--no-rc"] popen_args += ["--no-rc"]
else: else:
popen_args += args popen_args += args
if interactive: if interactive:
popen_args.append("-i") popen_args.append("-i")
if cmd and isinstance(cmd, str) and not cmd.endswith("\n"): if cmd and isinstance(cmd, str) and not cmd.endswith("\n"):
# In interactive mode we need to emulate "Press Enter". # In interactive mode we need to emulate "Press Enter".
cmd += "\n" cmd += "\n"
if single_command: if single_command:
popen_args += ["-c", cmd] popen_args += ["-c", cmd]
input = None input = None
@ -89,7 +95,7 @@ def run_xonsh(
proc = sp.Popen( proc = sp.Popen(
popen_args, popen_args,
env=env, env=popen_env,
stdin=stdin, stdin=stdin,
stdout=stdout, stdout=stdout,
stderr=stderr, stderr=stderr,
@ -1349,102 +1355,77 @@ def test_alias_stability_exception():
assert "Bad file descriptor" not in out assert "Bad file descriptor" not in out
@pytest.mark.flaky(reruns=3, reruns_delay=2) @pytest.mark.parametrize(
def test_rc_no_xonshrc_for_non_interactive(tmpdir): "cmd,exp",
"""Testing no ``~/.xonshrc`` execution in non-interactive commands (#5491).""" [
rc_dir = tmpdir.mkdir("rc_dir") ["-i", ".*CONFIG_XONSH_RC_XSH.*HOME_XONSHRC.*CONFIG_XONSH_RCD.*"],
user_home_dir = tmpdir.mkdir("user_home") ["--rc rc.xsh", ".*RCXSH.*"],
user_not_home_dir = tmpdir.mkdir("user_not_home") ["-i --rc rc.xsh", ".*RCXSH.*"],
["-c print('CMD')", ".*CONFIG_XONSH_RC_XSH.*CONFIG_XONSH_RCD.*CMD.*"],
(rc_dir / "rc_dir.xsh").write_text("echo RC_DIR", encoding="utf8") [
(user_home_dir / ".xonshrc").write_text("echo RC_HOME", encoding="utf8") "-i -c print('CMD')",
(script := user_home_dir / "script.xsh").write_text("echo SCRIPT", encoding="utf8") ".*CONFIG_XONSH_RC_XSH.*HOME_XONSHRC.*CONFIG_XONSH_RCD.*CMD.*",
user_home_rc_path_crossplatform = str( ],
(Path(user_home_dir) / ".xonshrc").expanduser() ["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 = [ args = [
f'-DHOME="{str(user_home_dir)}"', f'-DHOME="{str(home)}"',
f'-DXONSHRC="{os.pathsep.join(xonshrc_files)}"', f'-DXONSHRC="{os.pathsep.join(xonshrc_files)}"',
f'-DXONSHRC_DIR="{os.pathsep.join(xonshrc_dir)}"', f'-DXONSHRC_DIR="{os.pathsep.join(xonshrc_dir)}"',
] ]
cmd = "print(42+42)" env = {"HOME": str(home)}
add_env = {"HOME": str(user_home_dir)}
cmd = cmd.replace("rc.xsh", str(rc_xsh)).replace("script.xsh", str(script_xsh))
args = args + cmd.split()
# xonsh # xonsh
out, err, ret = run_xonsh( out, err, ret = run_xonsh(
cmd=None, cmd=None,
stdin=None,
single_command=False,
interactive=True,
args=args, args=args,
add_env=add_env, env=env,
) )
exp = ".*RC_NOT_HOME.*RC_HOME.*RC_DIR.*" exp = exp
assert re.match( assert re.match(
exp, exp,
out, out,
re.MULTILINE | re.DOTALL, 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}"
# 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}"

View file

@ -309,7 +309,7 @@ def _get_rc_files(shell_kwargs: dict, args, env):
rc = env.get("XONSHRC") rc = env.get("XONSHRC")
rcd = env.get("XONSHRC_DIR") 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 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 as the place where interactive tools can add configs. To avoid unintended and unexpected affection