mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 00:14:41 +01:00
update test xsh usage (#4581)
* todo * test: remove usage of DummyEnv and setting .env attribute on xession fixture one step closer to making too much of tweaking to xession during tests * test: fix tests vox and gitstatus-prompt * docs: update test-fixture usage * fix: import flake8 error * test: remove direct access to XSH in tests * test: remove usage of XSH in test files * todo * test: use tmp-dir to create stubs * refactor: use fixture factory to mock out XonshSession * refactor: remove direct access of XSH from functions * refactor: remove direct access of XSH from functions * fix: qa checks * refactor: rename variables to match their values * test: update failing tests because it had no PATH set previously * fix: remove builtins usage from pyghooks.py * style: * refactor: update tests to use fixtures * fix: env varialbe is setup per function some tests accidentally update the env variables and that is leaking into next tests * fix: failing vox tests * test: set commands_cache per test * test: fix failing tests * fix: failing tests on linux ptk-highlight * fix: failing tests on Windows cwd-prompt * test: copy env as to not affect original object * fix: lazily evaluate cmds-cache in pyghooks * test: fix failing tests * fix: qa errors import * test: set commands-cache per test while caching path results * test: speedup test_thread_local_swap * fix: failing tests on windows * refactor: Execer doesn't control session * refactor: XSH.unload will take care of reversing builtins attrs set * test: use env.update over monkeypatch * Revert "test: use env.update over monkeypatch" This reverts commit 010a5022247a098f1741966b8af1bf758663480e.
This commit is contained in:
parent
b6c61e3343
commit
7c4e207abd
42 changed files with 1444 additions and 1402 deletions
|
@ -5,7 +5,7 @@ repos:
|
|||
name: black
|
||||
# this gets run within development environment.
|
||||
# Otherwise will raise command not found or use system level binary
|
||||
entry: black --check xonsh/ xontrib/ tests/
|
||||
entry: black xonsh/ xontrib/ tests/
|
||||
language: system
|
||||
stages: [ commit ]
|
||||
types:
|
||||
|
|
|
@ -246,8 +246,11 @@ parts of xonsh for more test isolation. For a list of the various fixtures::
|
|||
when writing tests it's best to use pytest features i.e. parametrization::
|
||||
|
||||
@pytest.mark.parametrize('env', [test_env1, test_env2])
|
||||
def test_one(env, xonsh_builtins):
|
||||
xonsh_builtins.__xonsh__.env = env
|
||||
def test_one(env, xession):
|
||||
# update the environment variables instead of setting the attribute
|
||||
# which could result in leaks to other tests.
|
||||
# each run will have the same set of default env variables set.
|
||||
xession.env.update(env)
|
||||
...
|
||||
|
||||
this will run the test two times each time with the respective `test_env`.
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import pytest
|
||||
|
||||
from xonsh.built_ins import XSH
|
||||
from xonsh.completers._aliases import add_one_completer
|
||||
from xonsh.completers.tools import non_exclusive_completer
|
||||
|
||||
|
@ -29,7 +28,8 @@ NON_EXCLUSIVE = non_exclusive_completer(lambda: None)
|
|||
),
|
||||
),
|
||||
)
|
||||
def test_add_completer_start(monkeypatch, initial, exp):
|
||||
monkeypatch.setattr(XSH, "completers", initial)
|
||||
def test_add_completer_start(monkeypatch, initial, exp, xession):
|
||||
xession.completers.clear()
|
||||
xession.completers.update(initial)
|
||||
add_one_completer("new", SIMPLE, "start")
|
||||
assert list(XSH.completers.keys()) == exp
|
||||
assert list(xession.completers.keys()) == exp
|
||||
|
|
|
@ -8,7 +8,7 @@ from xonsh.aliases import source_alias, make_default_aliases
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def mockopen(xonsh_builtins, monkeypatch):
|
||||
def mockopen(xession, monkeypatch):
|
||||
@contextmanager
|
||||
def mocked_open(fpath, *args, **kwargs):
|
||||
yield MagicMock(read=lambda: fpath)
|
||||
|
@ -33,7 +33,9 @@ def test_source_current_dir(mockopen, monkeypatch, mocked_execx_checker):
|
|||
assert mocked_execx_checker == ["foo", "bar"]
|
||||
|
||||
|
||||
def test_source_path(mockopen, mocked_execx_checker):
|
||||
def test_source_path(mockopen, mocked_execx_checker, patch_locate_binary, xession):
|
||||
patch_locate_binary(xession.commands_cache)
|
||||
|
||||
source_alias(["foo", "bar"])
|
||||
path_foo = os.path.join("tests", "bin", "foo")
|
||||
path_bar = os.path.join("tests", "bin", "bar")
|
||||
|
|
|
@ -15,9 +15,8 @@ from xonsh.completers.commands import complete_command, complete_skipper
|
|||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def xs_orig_commands_cache(xession, monkeypatch, xonsh_execer):
|
||||
xession.unload()
|
||||
xession.load(execer=xonsh_execer)
|
||||
def xs_orig_commands_cache(xession):
|
||||
pass
|
||||
|
||||
|
||||
def test_complete_command(completion_context_parse):
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import pytest
|
||||
|
||||
from xonsh.environ import Env
|
||||
from xonsh.parsers.completion_context import CompletionContextParser
|
||||
from xonsh.completers.environment import complete_environment_vars
|
||||
|
||||
|
@ -19,7 +18,7 @@ def parser():
|
|||
),
|
||||
)
|
||||
def test_simple(cmd, xession, monkeypatch, parser):
|
||||
monkeypatch.setattr(xession, "env", Env({"WOW": 1}))
|
||||
xession.env.update({"WOW": 1})
|
||||
|
||||
context = parser.parse(cmd, len(cmd))
|
||||
comps, lprefix = complete_environment_vars(context)
|
||||
|
@ -28,7 +27,7 @@ def test_simple(cmd, xession, monkeypatch, parser):
|
|||
|
||||
|
||||
def test_rich_completions(xession, monkeypatch, parser):
|
||||
monkeypatch.setattr(xession, "env", Env({"WOW": 1}))
|
||||
xession.env.update({"WOW": 1})
|
||||
xession.env.register("WOW", type=int, doc="Nice Docs!")
|
||||
|
||||
context = parser.parse("$WO", 3)
|
||||
|
|
|
@ -45,13 +45,12 @@ def test_pip_list_re1(line):
|
|||
["pip show", "", {"setuptools", "wheel", "pip"}],
|
||||
],
|
||||
)
|
||||
def test_completions(
|
||||
line, prefix, exp, check_completer, xession, monkeypatch, session_vars
|
||||
):
|
||||
def test_completions(line, prefix, exp, check_completer, xession, os_env, monkeypatch):
|
||||
# use the actual PATH from os. Otherwise subproc will fail on windows. `unintialized python...`
|
||||
monkeypatch.setattr(xession, "env", os_env)
|
||||
|
||||
if ON_WINDOWS:
|
||||
line = line.replace("pip", "pip.exe")
|
||||
# needs original env for subproc all on all platforms
|
||||
monkeypatch.setattr(xession, "env", session_vars["env"])
|
||||
comps = check_completer(line, prefix=prefix)
|
||||
|
||||
assert comps.intersection(exp)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import builtins
|
||||
import os
|
||||
import sys
|
||||
import types
|
||||
|
@ -13,11 +12,10 @@ from xonsh.completer import Completer
|
|||
from xonsh.execer import Execer
|
||||
from xonsh.jobs import tasks
|
||||
from xonsh.events import events
|
||||
from xonsh.platform import ON_WINDOWS
|
||||
from xonsh.parsers.completion_context import CompletionContextParser
|
||||
|
||||
from xonsh import commands_cache
|
||||
from tools import DummyShell, sp, DummyEnv, DummyHistory
|
||||
from tools import DummyShell, sp, DummyHistory, copy_env
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -28,29 +26,52 @@ def source_path():
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def xonsh_execer(monkeypatch):
|
||||
def xonsh_execer(monkeypatch, xonsh_session):
|
||||
"""Initiate the Execer with a mocked nop `load_builtins`"""
|
||||
execer = Execer()
|
||||
XSH.load(execer=execer)
|
||||
# TODO this monkeypatch *shouldn't* be useful now.
|
||||
monkeypatch.setattr(XSH, "execer", execer)
|
||||
yield execer
|
||||
yield xonsh_session.execer
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def xonsh_execer_exec(xonsh_execer):
|
||||
def factory(input, **kwargs):
|
||||
xonsh_execer.exec(input, **kwargs)
|
||||
return True
|
||||
|
||||
return factory
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def xonsh_execer_parse(xonsh_execer):
|
||||
def factory(input):
|
||||
tree = XSH.execer.parse(input, ctx=None)
|
||||
return tree
|
||||
|
||||
return factory
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def patch_commands_cache_bins(xession, tmp_path, monkeypatch):
|
||||
def _factory(binaries: tp.List[str]):
|
||||
if not xession.env.get("PATH"):
|
||||
xession.env["PATH"] = [tmp_path]
|
||||
xession.env["PATH"] = [tmp_path]
|
||||
exec_mock = MagicMock(return_value=binaries)
|
||||
monkeypatch.setattr(commands_cache, "executables_in", exec_mock)
|
||||
cc = commands_cache.CommandsCache()
|
||||
xession.commands_cache = cc
|
||||
return cc
|
||||
return xession.commands_cache
|
||||
|
||||
return _factory
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def patch_locate_binary(monkeypatch):
|
||||
def locate_binary(self, name):
|
||||
return os.path.join(os.path.dirname(__file__), "bin", name)
|
||||
|
||||
def factory(cc: commands_cache.CommandsCache):
|
||||
monkeypatch.setattr(cc, "locate_binary", types.MethodType(locate_binary, cc))
|
||||
return cc
|
||||
|
||||
return factory
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def monkeypatch_stderr(monkeypatch):
|
||||
"""Monkeypath sys.stderr with no ResourceWarning."""
|
||||
|
@ -70,88 +91,140 @@ def xonsh_events():
|
|||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def session_vars():
|
||||
"""keep costly vars per session"""
|
||||
def session_os_env():
|
||||
"""Env with values from os.environ like real session"""
|
||||
from xonsh.environ import Env, default_env
|
||||
from xonsh.commands_cache import CommandsCache
|
||||
|
||||
execer = Execer()
|
||||
XSH.load(execer=execer)
|
||||
return {
|
||||
"execer": execer,
|
||||
"env": Env(default_env()),
|
||||
"commands_cache": CommandsCache(),
|
||||
return Env(default_env())
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def session_env():
|
||||
"""Env with some initial values that doesn't load from os.environ"""
|
||||
from xonsh.environ import Env
|
||||
|
||||
initial_vars = {
|
||||
"UPDATE_OS_ENVIRON": False,
|
||||
"XONSH_DEBUG": 1,
|
||||
"XONSH_COLOR_STYLE": "default",
|
||||
"VC_BRANCH_TIMEOUT": 1,
|
||||
"XONSH_ENCODING": "utf-8",
|
||||
"XONSH_ENCODING_ERRORS": "strict",
|
||||
"COMMANDS_CACHE_SAVE_INTERMEDIATE": False,
|
||||
}
|
||||
env = Env(initial_vars)
|
||||
return env
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def session_execer():
|
||||
return Execer()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def xonsh_builtins(monkeypatch, xonsh_events, session_vars):
|
||||
"""Mock out most of the builtins xonsh attributes."""
|
||||
old_builtins = dict(vars(builtins).items()) # type: ignore
|
||||
def os_env(session_os_env):
|
||||
"""A mutable copy of Original session_os_env"""
|
||||
|
||||
XSH.load(ctx={}, **session_vars)
|
||||
return copy_env(session_os_env)
|
||||
|
||||
def locate_binary(self, name):
|
||||
return os.path.join(os.path.dirname(__file__), "bin", name)
|
||||
|
||||
for attr, val in [
|
||||
("env", DummyEnv()),
|
||||
("shell", DummyShell()),
|
||||
("help", lambda x: x),
|
||||
("aliases", Aliases()),
|
||||
("exit", False),
|
||||
("history", DummyHistory()),
|
||||
# ("subproc_captured", sp),
|
||||
("subproc_uncaptured", sp),
|
||||
("subproc_captured_stdout", sp),
|
||||
("subproc_captured_inject", sp),
|
||||
("subproc_captured_object", sp),
|
||||
("subproc_captured_hiddenobject", sp),
|
||||
]:
|
||||
monkeypatch.setattr(XSH, attr, val)
|
||||
@pytest.fixture
|
||||
def env(tmpdir, session_env):
|
||||
"""a mutable copy of session_env"""
|
||||
env_copy = copy_env(session_env)
|
||||
initial_vars = {"XONSH_DATA_DIR": str(tmpdir)}
|
||||
|
||||
if ON_WINDOWS:
|
||||
XSH.env["PATHEXT"] = [".EXE", ".BAT", ".CMD"]
|
||||
env_copy.update(initial_vars)
|
||||
return env_copy
|
||||
|
||||
cc = XSH.commands_cache
|
||||
monkeypatch.setattr(cc, "locate_binary", types.MethodType(locate_binary, cc))
|
||||
monkeypatch.setattr(cc, "_cmds_cache", {})
|
||||
|
||||
for attr, val in [
|
||||
("evalx", eval),
|
||||
("execx", None),
|
||||
("compilex", None),
|
||||
# Unlike all the other stuff, this has to refer to the "real" one because all modules that would
|
||||
# be firing events on the global instance.
|
||||
("events", xonsh_events),
|
||||
]:
|
||||
# attributes to builtins are dynamicProxy and should pickup the following
|
||||
monkeypatch.setattr(XSH.builtins, attr, val)
|
||||
@pytest.fixture
|
||||
def xonsh_session(xonsh_events, session_execer, os_env, monkeypatch) -> XonshSession:
|
||||
"""a fixture to use where XonshSession is fully loaded without any mocks"""
|
||||
|
||||
# todo: remove using builtins for tests at all
|
||||
yield builtins
|
||||
XSH.load(
|
||||
ctx={},
|
||||
execer=session_execer,
|
||||
commands_cache=commands_cache.CommandsCache(),
|
||||
env=os_env,
|
||||
)
|
||||
yield XSH
|
||||
XSH.unload()
|
||||
for attr in set(dir(builtins)) - set(old_builtins):
|
||||
if hasattr(builtins, attr):
|
||||
delattr(builtins, attr)
|
||||
for attr, old_value in old_builtins.items():
|
||||
setattr(builtins, attr, old_value)
|
||||
|
||||
tasks.clear() # must to this to enable resetting all_jobs
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def xession(xonsh_builtins) -> XonshSession:
|
||||
return XSH
|
||||
def mock_xonsh_session(monkeypatch, xonsh_events, xonsh_session, env):
|
||||
"""Mock out most of the builtins xonsh attributes."""
|
||||
|
||||
# make sure that all other fixtures call this mock only one time
|
||||
session = []
|
||||
|
||||
def factory(*attrs: str):
|
||||
"""
|
||||
|
||||
Parameters
|
||||
----------
|
||||
attrs
|
||||
do not mock the given attributes
|
||||
|
||||
Returns
|
||||
-------
|
||||
XonshSession
|
||||
with most of the attributes mocked out
|
||||
"""
|
||||
if session:
|
||||
raise RuntimeError("The factory should be called only once per test")
|
||||
|
||||
for attr, val in [
|
||||
("env", env),
|
||||
("shell", DummyShell()),
|
||||
("help", lambda x: x),
|
||||
("aliases", Aliases()),
|
||||
("exit", False),
|
||||
("history", DummyHistory()),
|
||||
(
|
||||
"commands_cache",
|
||||
commands_cache.CommandsCache(),
|
||||
), # since env,aliases change , patch cmds-cache
|
||||
# ("subproc_captured", sp),
|
||||
("subproc_uncaptured", sp),
|
||||
("subproc_captured_stdout", sp),
|
||||
("subproc_captured_inject", sp),
|
||||
("subproc_captured_object", sp),
|
||||
("subproc_captured_hiddenobject", sp),
|
||||
]:
|
||||
if attr in attrs:
|
||||
continue
|
||||
monkeypatch.setattr(xonsh_session, attr, val)
|
||||
|
||||
for attr, val in [
|
||||
("evalx", eval),
|
||||
("execx", None),
|
||||
("compilex", None),
|
||||
# Unlike all the other stuff, this has to refer to the "real" one because all modules that would
|
||||
# be firing events on the global instance.
|
||||
("events", xonsh_events),
|
||||
]:
|
||||
# attributes to builtins are dynamicProxy and should pickup the following
|
||||
monkeypatch.setattr(xonsh_session.builtins, attr, val)
|
||||
|
||||
session.append(xonsh_session)
|
||||
return xonsh_session
|
||||
|
||||
yield factory
|
||||
session.clear()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def xsh_with_aliases(xession, monkeypatch):
|
||||
from xonsh.aliases import Aliases, make_default_aliases
|
||||
def xession(mock_xonsh_session) -> XonshSession:
|
||||
"""Mock out most of the builtins xonsh attributes."""
|
||||
return mock_xonsh_session()
|
||||
|
||||
xsh = xession
|
||||
monkeypatch.setattr(xsh, "aliases", Aliases(make_default_aliases()))
|
||||
return xsh
|
||||
|
||||
@pytest.fixture
|
||||
def xsh_with_aliases(mock_xonsh_session) -> XonshSession:
|
||||
return mock_xonsh_session("aliases")
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
|
@ -160,7 +233,7 @@ def completion_context_parse():
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def check_completer(xession):
|
||||
def check_completer():
|
||||
"""Helper function to run completer and parse the results as set of strings"""
|
||||
completer = Completer()
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ from subprocess import Popen
|
|||
import pytest
|
||||
|
||||
from xonsh.procs.specs import cmds_to_specs, run_subproc
|
||||
from xonsh.built_ins import XSH
|
||||
from xonsh.procs.posix import PopenThread
|
||||
from xonsh.procs.proxies import ProcProxy, ProcProxyThread, STDOUT_DISPATCHER
|
||||
|
||||
|
@ -49,8 +48,8 @@ def test_cmds_to_specs_thread_subproc(xession):
|
|||
|
||||
|
||||
@pytest.mark.parametrize("thread_subprocs", [True, False])
|
||||
def test_cmds_to_specs_capture_stdout_not_stderr(thread_subprocs):
|
||||
env = XSH.env
|
||||
def test_cmds_to_specs_capture_stdout_not_stderr(thread_subprocs, xonsh_session):
|
||||
env = xonsh_session.env
|
||||
cmds = (["ls", "/root"],)
|
||||
|
||||
env["THREAD_SUBPROCS"] = thread_subprocs
|
||||
|
@ -68,7 +67,7 @@ def test_cmds_to_specs_capture_stdout_not_stderr(thread_subprocs):
|
|||
)
|
||||
@pytest.mark.flaky(reruns=5, reruns_delay=2)
|
||||
def test_capture_always(
|
||||
capfd, thread_subprocs, capture_always, alias_type, pipe, monkeypatch
|
||||
capfd, thread_subprocs, capture_always, alias_type, pipe, monkeypatch, xonsh_session
|
||||
):
|
||||
if not thread_subprocs and alias_type in ["func", "exec"]:
|
||||
if pipe:
|
||||
|
@ -76,7 +75,7 @@ def test_capture_always(
|
|||
else:
|
||||
return pytest.skip("https://github.com/xonsh/xonsh/issues/4444")
|
||||
|
||||
env = XSH.env
|
||||
env = xonsh_session.env
|
||||
exp = "HELLO\nBYE\n"
|
||||
cmds = [["echo", "-n", exp]]
|
||||
if pipe:
|
||||
|
@ -88,15 +87,15 @@ def test_capture_always(
|
|||
# Enable capfd for function aliases:
|
||||
monkeypatch.setattr(STDOUT_DISPATCHER, "default", sys.stdout)
|
||||
if alias_type == "func":
|
||||
XSH.aliases["tst"] = (
|
||||
xonsh_session.aliases["tst"] = (
|
||||
lambda: run_subproc([first_cmd], "hiddenobject") and None
|
||||
) # Don't return a value
|
||||
elif alias_type == "exec":
|
||||
first_cmd = " ".join(repr(arg) for arg in first_cmd)
|
||||
XSH.aliases["tst"] = f"![{first_cmd}]"
|
||||
xonsh_session.aliases["tst"] = f"![{first_cmd}]"
|
||||
else:
|
||||
# alias_type == "simple"
|
||||
XSH.aliases["tst"] = first_cmd
|
||||
xonsh_session.aliases["tst"] = first_cmd
|
||||
|
||||
cmds[0] = ["tst"]
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ from unittest.mock import Mock
|
|||
|
||||
import pytest
|
||||
|
||||
from xonsh.environ import Env
|
||||
from xonsh.prompt.base import PromptFormatter, PROMPT_FIELDS
|
||||
|
||||
|
||||
|
@ -76,8 +75,6 @@ def test_format_prompt_with_broken_template_in_func(inp, formatter):
|
|||
|
||||
|
||||
def test_format_prompt_with_invalid_func(formatter, xession):
|
||||
xession.env = Env()
|
||||
|
||||
def p():
|
||||
foo = bar # raises exception # noqa
|
||||
return "{user}"
|
||||
|
@ -86,7 +83,6 @@ def test_format_prompt_with_invalid_func(formatter, xession):
|
|||
|
||||
|
||||
def test_format_prompt_with_func_that_raises(formatter, capsys, xession):
|
||||
xession.env = Env()
|
||||
template = "tt {zerodiv} tt"
|
||||
exp = "tt {BACKGROUND_RED}{ERROR:zerodiv}{RESET} tt"
|
||||
fields = {"zerodiv": lambda: 1 / 0}
|
||||
|
@ -96,13 +92,11 @@ def test_format_prompt_with_func_that_raises(formatter, capsys, xession):
|
|||
assert "prompt: error" in err
|
||||
|
||||
|
||||
def test_format_prompt_with_no_env(formatter, xession, live_fields):
|
||||
def test_format_prompt_with_no_env(formatter, xession, live_fields, env):
|
||||
xession.shell.prompt_formatter = formatter
|
||||
|
||||
env = Env()
|
||||
env.pop("VIRTUAL_ENV", None) # For virtualenv
|
||||
env.pop("CONDA_DEFAULT_ENV", None) # For conda/CircleCI
|
||||
xession.env = env
|
||||
|
||||
assert formatter("{env_name}", fields=live_fields) == ""
|
||||
|
||||
|
@ -111,8 +105,7 @@ def test_format_prompt_with_no_env(formatter, xession, live_fields):
|
|||
def test_format_prompt_with_various_envs(formatter, xession, live_fields, envname):
|
||||
xession.shell.prompt_formatter = formatter
|
||||
|
||||
env = Env(VIRTUAL_ENV=envname)
|
||||
xession.env = env
|
||||
xession.env["VIRTUAL_ENV"] = envname
|
||||
|
||||
exp = live_fields["env_prefix"] + envname + live_fields["env_postfix"]
|
||||
assert formatter("{env_name}", fields=live_fields) == exp
|
||||
|
@ -123,8 +116,7 @@ def test_format_prompt_with_various_envs(formatter, xession, live_fields, envnam
|
|||
def test_format_prompt_with_various_prepost(formatter, xession, live_fields, pre, post):
|
||||
xession.shell.prompt_formatter = formatter
|
||||
|
||||
env = Env(VIRTUAL_ENV="env")
|
||||
xession.env = env
|
||||
xession.env["VIRTUAL_ENV"] = "env"
|
||||
|
||||
live_fields.update({"env_prefix": pre, "env_postfix": post})
|
||||
|
||||
|
@ -134,9 +126,7 @@ def test_format_prompt_with_various_prepost(formatter, xession, live_fields, pre
|
|||
|
||||
def test_noenv_with_disable_set(formatter, xession, live_fields):
|
||||
xession.shell.prompt_formatter = formatter
|
||||
|
||||
env = Env(VIRTUAL_ENV="env", VIRTUAL_ENV_DISABLE_PROMPT=1)
|
||||
xession.env = env
|
||||
xession.env.update(dict(VIRTUAL_ENV="env", VIRTUAL_ENV_DISABLE_PROMPT=1))
|
||||
|
||||
exp = ""
|
||||
assert formatter("{env_name}", fields=live_fields) == exp
|
||||
|
@ -148,10 +138,13 @@ def test_custom_env_overrides_default(formatter, xession, live_fields, disable):
|
|||
|
||||
prompt = "!venv active! "
|
||||
|
||||
env = Env(
|
||||
VIRTUAL_ENV="env", VIRTUAL_ENV_PROMPT=prompt, VIRTUAL_ENV_DISABLE_PROMPT=disable
|
||||
xession.env.update(
|
||||
dict(
|
||||
VIRTUAL_ENV="env",
|
||||
VIRTUAL_ENV_PROMPT=prompt,
|
||||
VIRTUAL_ENV_DISABLE_PROMPT=disable,
|
||||
)
|
||||
)
|
||||
xession.env = env
|
||||
|
||||
exp = "" if disable else prompt
|
||||
assert formatter("{env_name}", fields=live_fields) == exp
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
from xonsh.prompt.cwd import _replace_home_cwd
|
||||
from xonsh.built_ins import XSH
|
||||
|
||||
|
||||
def test_cwd_escapes_curly_brackets_with_more_curly_brackets():
|
||||
XSH.env["PWD"] = "{foo}"
|
||||
def test_cwd_escapes_curly_brackets_with_more_curly_brackets(xession, tmpdir):
|
||||
xession.env["HOME"] = str(tmpdir)
|
||||
xession.env["PWD"] = "{foo}"
|
||||
assert _replace_home_cwd() == "{{foo}}"
|
||||
|
||||
XSH.env["PWD"] = "{{foo}}"
|
||||
xession.env["PWD"] = "{{foo}}"
|
||||
assert _replace_home_cwd() == "{{{{foo}}}}"
|
||||
|
||||
XSH.env["PWD"] = "{"
|
||||
xession.env["PWD"] = "{"
|
||||
assert _replace_home_cwd() == "{{"
|
||||
|
||||
XSH.env["PWD"] = "}}"
|
||||
xession.env["PWD"] = "}}"
|
||||
assert _replace_home_cwd() == "}}}}"
|
||||
|
|
|
@ -3,6 +3,11 @@ import pytest
|
|||
from xonsh.prompt import gitstatus
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def git_no_stash(mocker):
|
||||
return mocker.patch.object(gitstatus, "_get_stash", return_value=0)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hidden, exp",
|
||||
[
|
||||
|
|
|
@ -5,7 +5,6 @@ from unittest.mock import Mock
|
|||
|
||||
import pytest
|
||||
|
||||
from xonsh.environ import Env
|
||||
from xonsh.prompt import vc
|
||||
|
||||
# Xonsh interaction with version control systems.
|
||||
|
@ -46,7 +45,7 @@ defaultBranch = main
|
|||
@pytest.fixture
|
||||
def set_xenv(xession, monkeypatch):
|
||||
def _wrapper(path):
|
||||
monkeypatch.setattr(xession, "env", Env(VC_BRANCH_TIMEOUT=2, PWD=path))
|
||||
xession.env.update(dict(VC_BRANCH_TIMEOUT=2, PWD=path))
|
||||
return xession
|
||||
|
||||
return _wrapper
|
||||
|
|
|
@ -6,7 +6,6 @@ import pytest
|
|||
import inspect
|
||||
|
||||
from xonsh.aliases import Aliases, ExecAlias
|
||||
from xonsh.environ import Env
|
||||
|
||||
from tools import skip_if_on_windows
|
||||
|
||||
|
@ -26,7 +25,7 @@ def make_aliases():
|
|||
return ales
|
||||
|
||||
|
||||
def test_imports(xonsh_builtins):
|
||||
def test_imports(xession):
|
||||
ales = make_aliases()
|
||||
expected = {
|
||||
"o": ["omg", "lala"],
|
||||
|
@ -39,17 +38,17 @@ def test_imports(xonsh_builtins):
|
|||
assert raw == expected
|
||||
|
||||
|
||||
def test_eval_normal(xonsh_builtins):
|
||||
def test_eval_normal(xession):
|
||||
ales = make_aliases()
|
||||
assert ales.get("o") == ["omg", "lala"]
|
||||
|
||||
|
||||
def test_eval_self_reference(xonsh_builtins):
|
||||
def test_eval_self_reference(xession):
|
||||
ales = make_aliases()
|
||||
assert ales.get("ls") == ["ls", "- -"]
|
||||
|
||||
|
||||
def test_eval_recursive(xonsh_builtins):
|
||||
def test_eval_recursive(xession):
|
||||
ales = make_aliases()
|
||||
assert ales.get("color_ls") == ["ls", "- -", "--color=true"]
|
||||
|
||||
|
@ -57,7 +56,7 @@ def test_eval_recursive(xonsh_builtins):
|
|||
@skip_if_on_windows
|
||||
def test_eval_recursive_callable_partial(xonsh_execer, xession):
|
||||
ales = make_aliases()
|
||||
xession.env = Env(HOME=os.path.expanduser("~"))
|
||||
xession.env["HOME"] = os.path.expanduser("~")
|
||||
assert ales.get("indirect_cd")(["arg2", "arg3"]) == ["..", "arg2", "arg3"]
|
||||
|
||||
|
||||
|
@ -74,7 +73,7 @@ def _return_to_sender_all(args, stdin, stdout, stderr, spec, stack):
|
|||
)
|
||||
|
||||
|
||||
def test_recursive_callable_partial_all(xonsh_builtins):
|
||||
def test_recursive_callable_partial_all(xession):
|
||||
ales = Aliases({"rtn": _return_to_sender_all, "rtn-recurse": ["rtn", "arg1"]})
|
||||
alias = ales.get("rtn-recurse")
|
||||
assert callable(alias)
|
||||
|
@ -89,7 +88,7 @@ def _return_to_sender_handles(args, stdin, stdout, stderr):
|
|||
return args, {"stdin": stdin, "stdout": stdout, "stderr": stderr}
|
||||
|
||||
|
||||
def test_recursive_callable_partial_handles(xonsh_builtins):
|
||||
def test_recursive_callable_partial_handles(xession):
|
||||
ales = Aliases({"rtn": _return_to_sender_handles, "rtn-recurse": ["rtn", "arg1"]})
|
||||
alias = ales.get("rtn-recurse")
|
||||
assert callable(alias)
|
||||
|
@ -104,7 +103,7 @@ def _return_to_sender_none():
|
|||
return "wakka", {}
|
||||
|
||||
|
||||
def test_recursive_callable_partial_none(xonsh_builtins):
|
||||
def test_recursive_callable_partial_none(xession):
|
||||
ales = Aliases({"rtn": _return_to_sender_none, "rtn-recurse": ["rtn"]})
|
||||
alias = ales.get("rtn-recurse")
|
||||
assert callable(alias)
|
||||
|
@ -123,7 +122,7 @@ def test_recursive_callable_partial_none(xonsh_builtins):
|
|||
"echo 'hi'; echo 'there'",
|
||||
],
|
||||
)
|
||||
def test_subprocess_logical_operators(xonsh_builtins, alias):
|
||||
def test_subprocess_logical_operators(xession, alias):
|
||||
ales = make_aliases()
|
||||
ales["echocat"] = alias
|
||||
assert isinstance(ales["echocat"], ExecAlias)
|
||||
|
@ -140,7 +139,7 @@ def test_subprocess_logical_operators(xonsh_builtins, alias):
|
|||
"echo 'h|i << x > 3' | grep x",
|
||||
],
|
||||
)
|
||||
def test_subprocess_io_operators(xonsh_builtins, alias):
|
||||
def test_subprocess_io_operators(xession, alias):
|
||||
ales = make_aliases()
|
||||
ales["echocat"] = alias
|
||||
assert isinstance(ales["echocat"], ExecAlias)
|
||||
|
@ -152,7 +151,7 @@ def test_subprocess_io_operators(xonsh_builtins, alias):
|
|||
{"echocat": "ls"},
|
||||
],
|
||||
)
|
||||
def test_dict_merging(xonsh_builtins, alias):
|
||||
def test_dict_merging(xession, alias):
|
||||
ales = make_aliases()
|
||||
assert (ales | alias)["echocat"] == ["ls"]
|
||||
assert (alias | ales)["echocat"] == ["ls"]
|
||||
|
@ -166,7 +165,7 @@ def test_dict_merging(xonsh_builtins, alias):
|
|||
{"echocat": "echo Why?"},
|
||||
],
|
||||
)
|
||||
def test_dict_merging_assignment(xonsh_builtins, alias):
|
||||
def test_dict_merging_assignment(xession, alias):
|
||||
ales = make_aliases()
|
||||
ales |= alias
|
||||
|
||||
|
@ -180,7 +179,7 @@ def test_dict_merging_assignment(xonsh_builtins, alias):
|
|||
assert alias["o"] == ales["o"]
|
||||
|
||||
|
||||
def test_exec_alias_args(xonsh_builtins):
|
||||
def test_exec_alias_args(xession):
|
||||
stack = inspect.stack()
|
||||
try:
|
||||
ExecAlias("myargs = $args")(["arg0"], stack=stack)
|
||||
|
|
|
@ -6,7 +6,7 @@ from xonsh.ast import Tuple, Name, Store, min_line, Call, BinOp, isexpression
|
|||
|
||||
import pytest
|
||||
|
||||
from tools import check_parse, nodes_equal
|
||||
from tools import nodes_equal
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
|
@ -45,20 +45,20 @@ def test_gather_load_store_names_tuple():
|
|||
"l = 1", # ls remains undefined.
|
||||
],
|
||||
)
|
||||
def test_multilline_num(xonsh_execer, line1):
|
||||
def test_multilline_num(xonsh_execer_parse, line1):
|
||||
# Subprocess transformation happens on the second line,
|
||||
# because not all variables are known.
|
||||
code = line1 + "\nls -l\n"
|
||||
tree = check_parse(code)
|
||||
tree = xonsh_execer_parse(code)
|
||||
lsnode = tree.body[1]
|
||||
assert 2 == min_line(lsnode)
|
||||
assert isinstance(lsnode.value, Call)
|
||||
|
||||
|
||||
def test_multilline_no_transform():
|
||||
def test_multilline_no_transform(xonsh_execer_parse):
|
||||
# No subprocess transformations happen here, since all variables are known.
|
||||
code = "ls = 1\nl = 1\nls -l\n"
|
||||
tree = check_parse(code)
|
||||
tree = xonsh_execer_parse(code)
|
||||
lsnode = tree.body[2]
|
||||
assert 3 == min_line(lsnode)
|
||||
assert isinstance(lsnode.value, BinOp)
|
||||
|
@ -109,10 +109,10 @@ for root, dirs, files in os.walk(path):
|
|||
""",
|
||||
],
|
||||
)
|
||||
def test_unmodified(inp):
|
||||
def test_unmodified(inp, xonsh_execer_parse):
|
||||
# Context sensitive parsing should not modify AST
|
||||
exp = pyast.parse(inp)
|
||||
obs = check_parse(inp)
|
||||
obs = xonsh_execer_parse(inp)
|
||||
|
||||
assert nodes_equal(exp, obs)
|
||||
|
||||
|
@ -121,8 +121,8 @@ def test_unmodified(inp):
|
|||
"test_input",
|
||||
["echo; echo && echo\n", "echo; echo && echo a\n", "true && false && true\n"],
|
||||
)
|
||||
def test_whitespace_subproc(test_input):
|
||||
assert check_parse(test_input)
|
||||
def test_whitespace_subproc(test_input, xonsh_execer_parse):
|
||||
assert xonsh_execer_parse(test_input)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"""(A down payment on) Testing for ``xonsh.base_shell.BaseShell`` and associated classes"""
|
||||
import os
|
||||
|
||||
from xonsh.environ import Env
|
||||
from xonsh.base_shell import BaseShell
|
||||
from xonsh.shell import transform_command
|
||||
|
||||
|
@ -9,8 +8,8 @@ from xonsh.shell import transform_command
|
|||
def test_pwd_tracks_cwd(xession, xonsh_execer, tmpdir_factory, monkeypatch):
|
||||
asubdir = str(tmpdir_factory.mktemp("asubdir"))
|
||||
cur_wd = os.getcwd()
|
||||
xession.env = Env(
|
||||
PWD=cur_wd, XONSH_CACHE_SCRIPTS=False, XONSH_CACHE_EVERYTHING=False
|
||||
xession.env.update(
|
||||
dict(PWD=cur_wd, XONSH_CACHE_SCRIPTS=False, XONSH_CACHE_EVERYTHING=False)
|
||||
)
|
||||
|
||||
monkeypatch.setattr(xonsh_execer, "cacheall", False, raising=False)
|
||||
|
|
|
@ -42,7 +42,7 @@ def test_reglob_tests(testfile):
|
|||
@pytest.fixture
|
||||
def home_env(xession):
|
||||
"""Set `__xonsh__.env ` to a new Env instance on `xonsh_builtins`"""
|
||||
xession.env = Env(HOME=HOME_PATH)
|
||||
xession.env["HOME"] = HOME_PATH
|
||||
return xession
|
||||
|
||||
|
||||
|
@ -146,7 +146,7 @@ def test_list_of_strs_or_callables(exp, inp):
|
|||
([["y", "z"], ["a", "b"]], ["ya", "yb", "za", "zb"]),
|
||||
],
|
||||
)
|
||||
def test_list_of_list_of_strs_outer_product(xonsh_builtins, inp, exp):
|
||||
def test_list_of_list_of_strs_outer_product(xession, inp, exp):
|
||||
obs = list_of_list_of_strs_outer_product(inp)
|
||||
assert exp == obs
|
||||
|
||||
|
|
|
@ -15,27 +15,25 @@ from xonsh.commands_cache import (
|
|||
from tools import skip_if_on_windows
|
||||
|
||||
|
||||
def test_commands_cache_lazy(xonsh_builtins):
|
||||
cc = CommandsCache()
|
||||
def test_commands_cache_lazy(xession):
|
||||
cc = xession.commands_cache
|
||||
assert not cc.lazyin("xonsh")
|
||||
assert 0 == len(list(cc.lazyiter()))
|
||||
assert 0 == cc.lazylen()
|
||||
|
||||
|
||||
def test_predict_threadable_unknown_command(xonsh_builtins):
|
||||
cc = CommandsCache()
|
||||
result = cc.predict_threadable(["command_should_not_found"])
|
||||
def test_predict_threadable_unknown_command(xession):
|
||||
result = xession.commands_cache.predict_threadable(["command_should_not_found"])
|
||||
assert isinstance(result, bool)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def commands_cache_tmp(xession, tmp_path, monkeypatch, patch_commands_cache_bins):
|
||||
xession.env["XONSH_DATA_DIR"] = tmp_path
|
||||
xession.env["COMMANDS_CACHE_SAVE_INTERMEDIATE"] = True
|
||||
return patch_commands_cache_bins(["bin1", "bin2"])
|
||||
|
||||
|
||||
def test_commands_cached_between_runs(commands_cache_tmp, tmp_path):
|
||||
def test_commands_cached_between_runs(commands_cache_tmp, tmp_path, tmpdir):
|
||||
# 1. no pickle file
|
||||
# 2. return empty result first and create a thread to populate result
|
||||
# 3. once the result is available then next call to cc.all_commands returns
|
||||
|
@ -76,6 +74,7 @@ def test_commands_cache_uses_pickle_file(commands_cache_tmp, tmp_path, monkeypat
|
|||
}
|
||||
|
||||
file.write_bytes(pickle.dumps(bins))
|
||||
assert str(cc.cache_file) == str(file)
|
||||
assert cc.all_commands == bins
|
||||
assert cc._loaded_pickled
|
||||
|
||||
|
@ -112,14 +111,38 @@ def test_predict_shell_false(args):
|
|||
|
||||
|
||||
PATTERN_BIN_USING_TTY_OR_NOT = [
|
||||
(False, {10: b"isnotatty"}),
|
||||
(False, {12: b"isatty"}),
|
||||
(False, {151: b"gpm"}),
|
||||
(False, {10: b"isatty", 100: b"tcgetattr"}),
|
||||
(False, {10: b"isatty", 100: b"tcsetattr"}),
|
||||
(True, {10: b"isatty", 100: b"tcsetattr", 1000: b"tcgetattr"}),
|
||||
(True, {1000: b"libncurses"}),
|
||||
(True, {4094: b"libgpm"}),
|
||||
(
|
||||
False,
|
||||
{10: b"isnotatty"},
|
||||
),
|
||||
(
|
||||
False,
|
||||
{12: b"isatty"},
|
||||
),
|
||||
(
|
||||
False,
|
||||
{151: b"gpm"},
|
||||
),
|
||||
(
|
||||
False,
|
||||
{10: b"isatty", 100: b"tcgetattr"},
|
||||
),
|
||||
(
|
||||
False,
|
||||
{10: b"isatty", 100: b"tcsetattr"},
|
||||
),
|
||||
(
|
||||
True,
|
||||
{10: b"isatty", 100: b"tcsetattr", 1000: b"tcgetattr"},
|
||||
),
|
||||
(
|
||||
True,
|
||||
{1000: b"libncurses"},
|
||||
),
|
||||
(
|
||||
True,
|
||||
{4094: b"libgpm"},
|
||||
),
|
||||
(
|
||||
True,
|
||||
{2045: b"tcgetattr", 4095: b"tcgetattr", 6140: b"tcsetattr", 8190: b"isatty"},
|
||||
|
@ -129,24 +152,23 @@ PATTERN_BIN_USING_TTY_OR_NOT = [
|
|||
|
||||
@pytest.mark.parametrize("args", PATTERN_BIN_USING_TTY_OR_NOT)
|
||||
@skip_if_on_windows
|
||||
def test_commands_cache_predictor_default(args, xonsh_builtins):
|
||||
cc = CommandsCache()
|
||||
def test_commands_cache_predictor_default(args, xession, tmp_path):
|
||||
use_tty, patterns = args
|
||||
f = open("testfile", "wb")
|
||||
file = tmp_path / "testfile"
|
||||
where = list(patterns.keys())
|
||||
where.sort()
|
||||
|
||||
pos = 0
|
||||
for w in where:
|
||||
f.write(b"\x20" * (w - pos))
|
||||
f.write(patterns[w])
|
||||
pos = w + len(patterns[w])
|
||||
with file.open("wb") as f:
|
||||
pos = 0
|
||||
for w in where:
|
||||
f.write(b"\x20" * (w - pos))
|
||||
f.write(patterns[w])
|
||||
pos = w + len(patterns[w])
|
||||
|
||||
f.write(b"\x20" * (pos // 2))
|
||||
f.close()
|
||||
f.write(b"\x20" * (pos // 2))
|
||||
|
||||
result = cc.default_predictor_readbin(
|
||||
"", os.getcwd() + os.sep + "testfile", timeout=1, failure=None
|
||||
result = xession.commands_cache.default_predictor_readbin(
|
||||
"", str(file), timeout=1, failure=None
|
||||
)
|
||||
expected = predict_false if use_tty else predict_true
|
||||
assert result == expected
|
||||
|
@ -154,26 +176,23 @@ def test_commands_cache_predictor_default(args, xonsh_builtins):
|
|||
|
||||
@skip_if_on_windows
|
||||
def test_cd_is_only_functional_alias(xession):
|
||||
cc = CommandsCache()
|
||||
xession.aliases["cd"] = lambda args: os.chdir(args[0])
|
||||
assert cc.is_only_functional_alias("cd")
|
||||
xession.env["PATH"] = []
|
||||
assert xession.commands_cache.is_only_functional_alias("cd")
|
||||
|
||||
|
||||
def test_non_exist_is_only_functional_alias(xonsh_builtins):
|
||||
cc = CommandsCache()
|
||||
assert not cc.is_only_functional_alias("<not really a command name>")
|
||||
def test_non_exist_is_only_functional_alias(xession):
|
||||
assert not xession.commands_cache.is_only_functional_alias(
|
||||
"<not really a command name>"
|
||||
)
|
||||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_bash_is_only_functional_alias(xession):
|
||||
xession.env["PATH"] = os.environ["PATH"].split(os.pathsep)
|
||||
cc = CommandsCache()
|
||||
assert not cc.is_only_functional_alias("bash")
|
||||
assert not xession.commands_cache.is_only_functional_alias("bash")
|
||||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_bash_and_is_alias_is_only_functional_alias(xession):
|
||||
xession.env["PATH"] = os.environ["PATH"].split(os.pathsep)
|
||||
cc = CommandsCache()
|
||||
xession.aliases["bash"] = lambda args: os.chdir(args[0])
|
||||
assert not cc.is_only_functional_alias("bash")
|
||||
assert not xession.commands_cache.is_only_functional_alias("bash")
|
||||
|
|
|
@ -2,7 +2,7 @@ import itertools
|
|||
import typing as tp
|
||||
|
||||
import pytest
|
||||
|
||||
from unittest import mock
|
||||
from xonsh.parsers.completion_context import (
|
||||
CommandArg,
|
||||
CommandContext,
|
||||
|
@ -10,6 +10,9 @@ from xonsh.parsers.completion_context import (
|
|||
PythonContext,
|
||||
)
|
||||
|
||||
import xonsh.parsers.completion_context as ctx
|
||||
from tests.tools import ON_WINDOWS
|
||||
|
||||
|
||||
DEBUG = False
|
||||
MISSING = object()
|
||||
|
@ -21,8 +24,19 @@ PARSER: tp.Optional[CompletionContextParser] = None
|
|||
def parser():
|
||||
global PARSER
|
||||
PARSER = CompletionContextParser(debug=DEBUG)
|
||||
patcher = None
|
||||
if ON_WINDOWS:
|
||||
# on-windows has an option for interactive sessions. Overriding the lazyObject
|
||||
patcher = mock.patch.object(
|
||||
ctx,
|
||||
"LINE_CONT_REPLACEMENT_DIFF",
|
||||
("\\\n", "", -2),
|
||||
)
|
||||
patcher.start()
|
||||
yield
|
||||
PARSER = None
|
||||
if ON_WINDOWS and patcher:
|
||||
patcher.stop()
|
||||
|
||||
|
||||
def parse(command, inner_index):
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
"""Tests xonsh contexts."""
|
||||
from textwrap import dedent
|
||||
|
||||
from tools import check_exec
|
||||
from xonsh.contexts import Block, Functor
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def xonsh_execer_autouse(xonsh_builtins, xonsh_execer):
|
||||
return xonsh_execer
|
||||
|
||||
|
||||
#
|
||||
# helpers
|
||||
|
@ -75,64 +67,64 @@ def block_checks_func(name, glbs, body, obsg=None, obsl=None):
|
|||
#
|
||||
|
||||
|
||||
def test_block_noexec():
|
||||
def test_block_noexec(xonsh_execer_exec):
|
||||
s = "x = 1\n" "with! Block():\n" " x += 42\n"
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
assert 1 == glbs["x"]
|
||||
|
||||
|
||||
def test_block_oneline():
|
||||
def test_block_oneline(xonsh_execer_exec):
|
||||
body = " x += 42\n"
|
||||
s = X1_WITH + body
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("b", glbs, body, {"x": 1})
|
||||
|
||||
|
||||
def test_block_manylines():
|
||||
def test_block_manylines(xonsh_execer_exec):
|
||||
body = " ![echo wow mom]\n" "# bad place for a comment\n" " x += 42"
|
||||
s = X1_WITH + body
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("b", glbs, body, {"x": 1})
|
||||
|
||||
|
||||
def test_block_leading_comment():
|
||||
def test_block_leading_comment(xonsh_execer_exec):
|
||||
# leading comments do not show up in block lines
|
||||
body = " # I am a leading comment\n" " x += 42\n"
|
||||
s = X1_WITH + body
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("b", glbs, [" x += 42"], {"x": 1})
|
||||
|
||||
|
||||
def test_block_trailing_comment():
|
||||
def test_block_trailing_comment(xonsh_execer_exec):
|
||||
# trailing comments show up in block lines
|
||||
body = " x += 42\n" " # I am a trailing comment\n"
|
||||
s = X1_WITH + body
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("b", glbs, body, {"x": 1})
|
||||
|
||||
|
||||
def test_block_trailing_line_continuation():
|
||||
def test_block_trailing_line_continuation(xonsh_execer_exec):
|
||||
body = " x += \\\n" " 42\n"
|
||||
s = X1_WITH + body
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("b", glbs, body, {"x": 1})
|
||||
|
||||
|
||||
def test_block_trailing_close_paren():
|
||||
def test_block_trailing_close_paren(xonsh_execer_exec):
|
||||
body = ' x += int("42"\n' " )\n"
|
||||
s = X1_WITH + body
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("b", glbs, body, {"x": 1})
|
||||
|
||||
|
||||
def test_block_trailing_close_many():
|
||||
def test_block_trailing_close_many(xonsh_execer_exec):
|
||||
body = (
|
||||
' x = {None: [int("42"\n'
|
||||
" )\n"
|
||||
|
@ -141,69 +133,69 @@ def test_block_trailing_close_many():
|
|||
)
|
||||
s = SIMPLE_WITH + body
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("b", glbs, body)
|
||||
|
||||
|
||||
def test_block_trailing_triple_string():
|
||||
def test_block_trailing_triple_string(xonsh_execer_exec):
|
||||
body = ' x = """This\n' "is\n" '"probably"\n' "'not' what I meant.\n" '"""\n'
|
||||
s = SIMPLE_WITH + body
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("b", glbs, body)
|
||||
|
||||
|
||||
def test_block_func_oneline():
|
||||
def test_block_func_oneline(xonsh_execer_exec):
|
||||
body = " x += 42\n"
|
||||
s = FUNC_WITH.format(body=body)
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
|
||||
|
||||
|
||||
def test_block_func_manylines():
|
||||
def test_block_func_manylines(xonsh_execer_exec):
|
||||
body = " ![echo wow mom]\n" "# bad place for a comment\n" " x += 42\n"
|
||||
s = FUNC_WITH.format(body=body)
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
|
||||
|
||||
|
||||
def test_block_func_leading_comment():
|
||||
def test_block_func_leading_comment(xonsh_execer_exec):
|
||||
# leading comments do not show up in block lines
|
||||
body = " # I am a leading comment\n" " x += 42\n"
|
||||
s = FUNC_WITH.format(body=body)
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_func("rtn", glbs, " x += 42\n", FUNC_OBSG, FUNC_OBSL)
|
||||
|
||||
|
||||
def test_block_func_trailing_comment():
|
||||
def test_block_func_trailing_comment(xonsh_execer_exec):
|
||||
# trailing comments show up in block lines
|
||||
body = " x += 42\n" " # I am a trailing comment\n"
|
||||
s = FUNC_WITH.format(body=body)
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
|
||||
|
||||
|
||||
def test_blockfunc__trailing_line_continuation():
|
||||
def test_blockfunc__trailing_line_continuation(xonsh_execer_exec):
|
||||
body = " x += \\\n" " 42\n"
|
||||
s = FUNC_WITH.format(body=body)
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
|
||||
|
||||
|
||||
def test_block_func_trailing_close_paren():
|
||||
def test_block_func_trailing_close_paren(xonsh_execer_exec):
|
||||
body = ' x += int("42"\n' " )\n"
|
||||
s = FUNC_WITH.format(body=body)
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
|
||||
|
||||
|
||||
def test_block_func_trailing_close_many():
|
||||
def test_block_func_trailing_close_many(xonsh_execer_exec):
|
||||
body = (
|
||||
' x = {None: [int("42"\n'
|
||||
" )\n"
|
||||
|
@ -212,15 +204,15 @@ def test_block_func_trailing_close_many():
|
|||
)
|
||||
s = FUNC_WITH.format(body=body)
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
|
||||
|
||||
|
||||
def test_block_func_trailing_triple_string():
|
||||
def test_block_func_trailing_triple_string(xonsh_execer_exec):
|
||||
body = ' x = """This\n' "is\n" '"probably"\n' "'not' what I meant.\n" '"""\n'
|
||||
s = FUNC_WITH.format(body=body)
|
||||
glbs = {"Block": Block}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
|
||||
|
||||
|
||||
|
@ -231,55 +223,55 @@ def test_block_func_trailing_triple_string():
|
|||
X2_WITH = "{var} = 1\n" "with! Functor() as f:\n" "{body}" "{var} += 1\n" "{calls}\n"
|
||||
|
||||
|
||||
def test_functor_oneline_onecall_class():
|
||||
def test_functor_oneline_onecall_class(xonsh_execer_exec):
|
||||
body = " global y\n" " y += 42\n"
|
||||
calls = "f()"
|
||||
s = X2_WITH.format(body=body, calls=calls, var="y")
|
||||
glbs = {"Functor": Functor}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("f", glbs, body, {"y": 44})
|
||||
|
||||
|
||||
def test_functor_oneline_onecall_func():
|
||||
def test_functor_oneline_onecall_func(xonsh_execer_exec):
|
||||
body = " global z\n" " z += 42\n"
|
||||
calls = "f.func()"
|
||||
s = X2_WITH.format(body=body, calls=calls, var="z")
|
||||
glbs = {"Functor": Functor}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("f", glbs, body, {"z": 44})
|
||||
|
||||
|
||||
def test_functor_oneline_onecall_both():
|
||||
def test_functor_oneline_onecall_both(xonsh_execer_exec):
|
||||
body = " global x\n" " x += 42\n"
|
||||
calls = "f()\nf.func()"
|
||||
s = X2_WITH.format(body=body, calls=calls, var="x")
|
||||
glbs = {"Functor": Functor}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("f", glbs, body, {"x": 86})
|
||||
|
||||
|
||||
XA_WITH = "x = [1]\n" "with! Functor() as f:\n" "{body}" "x.append(2)\n" "{calls}\n"
|
||||
|
||||
|
||||
def test_functor_oneline_append():
|
||||
def test_functor_oneline_append(xonsh_execer_exec):
|
||||
body = " x.append(3)\n"
|
||||
calls = "f()\n"
|
||||
s = XA_WITH.format(body=body, calls=calls)
|
||||
glbs = {"Functor": Functor}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("f", glbs, body, {"x": [1, 2, 3]})
|
||||
|
||||
|
||||
def test_functor_return():
|
||||
def test_functor_return(xonsh_execer_exec):
|
||||
body = " x = 42"
|
||||
t = "res = 0\n" 'with! Functor(rtn="x") as f:\n' "{body}\n" "res = f()\n"
|
||||
s = t.format(body=body)
|
||||
glbs = {"Functor": Functor}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("f", glbs, body, {"res": 42})
|
||||
|
||||
|
||||
def test_functor_args():
|
||||
def test_functor_args(xonsh_execer_exec):
|
||||
body = " x = 42 + a"
|
||||
t = (
|
||||
"res = 0\n"
|
||||
|
@ -289,11 +281,11 @@ def test_functor_args():
|
|||
)
|
||||
s = t.format(body=body)
|
||||
glbs = {"Functor": Functor}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("f", glbs, body, {"res": 44})
|
||||
|
||||
|
||||
def test_functor_kwargs():
|
||||
def test_functor_kwargs(xonsh_execer_exec):
|
||||
body = " x = 42 + a + b"
|
||||
t = (
|
||||
"res = 0\n"
|
||||
|
@ -303,11 +295,11 @@ def test_functor_kwargs():
|
|||
)
|
||||
s = t.format(body=body)
|
||||
glbs = {"Functor": Functor}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("f", glbs, body, {"res": 49})
|
||||
|
||||
|
||||
def test_functor_fullsig():
|
||||
def test_functor_fullsig(xonsh_execer_exec):
|
||||
body = " x = 42 + a + b + c"
|
||||
t = (
|
||||
"res = 0\n"
|
||||
|
@ -317,5 +309,5 @@ def test_functor_fullsig():
|
|||
)
|
||||
s = t.format(body=body)
|
||||
glbs = {"Functor": Functor}
|
||||
check_exec(s, glbs=glbs, locs=None)
|
||||
xonsh_execer_exec(s, glbs=glbs, locs=None)
|
||||
block_checks_glb("f", glbs, body, {"res": 110})
|
||||
|
|
|
@ -6,7 +6,6 @@ import os
|
|||
import pytest # noqa F401
|
||||
|
||||
from xonsh import dirstack
|
||||
from xonsh.environ import Env
|
||||
|
||||
|
||||
HERE = os.path.abspath(os.path.dirname(__file__))
|
||||
|
@ -22,7 +21,7 @@ def chdir(adir):
|
|||
|
||||
|
||||
def test_simple(xession):
|
||||
xession.env = Env(CDPATH=PARENT, PWD=PARENT)
|
||||
xession.env.update(dict(CDPATH=PARENT, PWD=PARENT))
|
||||
with chdir(PARENT):
|
||||
assert os.getcwd() != HERE
|
||||
dirstack.cd(["tests"])
|
||||
|
@ -30,7 +29,7 @@ def test_simple(xession):
|
|||
|
||||
|
||||
def test_cdpath_simple(xession):
|
||||
xession.env = Env(CDPATH=PARENT, PWD=HERE)
|
||||
xession.env.update(dict(CDPATH=PARENT, PWD=HERE))
|
||||
with chdir(os.path.normpath("/")):
|
||||
assert os.getcwd() != HERE
|
||||
dirstack.cd(["tests"])
|
||||
|
@ -38,7 +37,7 @@ def test_cdpath_simple(xession):
|
|||
|
||||
|
||||
def test_cdpath_collision(xession):
|
||||
xession.env = Env(CDPATH=PARENT, PWD=HERE)
|
||||
xession.env.update(dict(CDPATH=PARENT, PWD=HERE))
|
||||
sub_tests = os.path.join(HERE, "tests")
|
||||
if not os.path.exists(sub_tests):
|
||||
os.mkdir(sub_tests)
|
||||
|
@ -49,7 +48,7 @@ def test_cdpath_collision(xession):
|
|||
|
||||
|
||||
def test_cdpath_expansion(xession):
|
||||
xession.env = Env(HERE=HERE, CDPATH=("~", "$HERE"))
|
||||
xession.env.update(dict(HERE=HERE, CDPATH=("~", "$HERE")))
|
||||
test_dirs = (
|
||||
os.path.join(HERE, "xonsh-test-cdpath-here"),
|
||||
os.path.expanduser("~/xonsh-test-cdpath-home"),
|
||||
|
@ -68,7 +67,7 @@ def test_cdpath_expansion(xession):
|
|||
|
||||
|
||||
def test_cdpath_events(xession, tmpdir):
|
||||
xession.env = Env(CDPATH=PARENT, PWD=os.getcwd())
|
||||
xession.env.update(dict(CDPATH=PARENT, PWD=os.getcwd()))
|
||||
target = str(tmpdir)
|
||||
|
||||
ev = None
|
||||
|
@ -91,7 +90,7 @@ def test_cdpath_events(xession, tmpdir):
|
|||
|
||||
|
||||
def test_cd_autopush(xession, tmpdir):
|
||||
xession.env = Env(CDPATH=PARENT, PWD=os.getcwd(), AUTO_PUSHD=True)
|
||||
xession.env.update(dict(CDPATH=PARENT, PWD=os.getcwd(), AUTO_PUSHD=True))
|
||||
target = str(tmpdir)
|
||||
|
||||
old_dir = os.getcwd()
|
||||
|
|
|
@ -8,7 +8,6 @@ import sys
|
|||
|
||||
import pytest
|
||||
from xonsh import dirstack
|
||||
from xonsh.environ import Env
|
||||
from xonsh.dirstack import DIRSTACK
|
||||
from xonsh.platform import ON_WINDOWS
|
||||
from xonsh.dirstack import _unc_tempDrives
|
||||
|
@ -93,7 +92,7 @@ def shares_setup(tmpdir_factory):
|
|||
|
||||
def test_pushdpopd(xession):
|
||||
"""Simple non-UNC push/pop to verify we didn't break nonUNC case."""
|
||||
xession.env = Env(CDPATH=PARENT, PWD=HERE)
|
||||
xession.env.update(dict(CDPATH=PARENT, PWD=HERE))
|
||||
|
||||
dirstack.cd([PARENT])
|
||||
owd = os.getcwd()
|
||||
|
@ -106,7 +105,7 @@ def test_pushdpopd(xession):
|
|||
|
||||
|
||||
def test_cd_dot(xession):
|
||||
xession.env = Env(PWD=os.getcwd())
|
||||
xession.env.update(dict(PWD=os.getcwd()))
|
||||
|
||||
owd = os.getcwd().casefold()
|
||||
dirstack.cd(["."])
|
||||
|
@ -117,7 +116,7 @@ def test_cd_dot(xession):
|
|||
def test_uncpushd_simple_push_pop(xession, shares_setup):
|
||||
if shares_setup is None:
|
||||
return
|
||||
xession.env = Env(CDPATH=PARENT, PWD=HERE)
|
||||
xession.env.update(dict(CDPATH=PARENT, PWD=HERE))
|
||||
dirstack.cd([PARENT])
|
||||
owd = os.getcwd()
|
||||
assert owd.casefold() == xession.env["PWD"].casefold()
|
||||
|
@ -134,7 +133,7 @@ def test_uncpushd_simple_push_pop(xession, shares_setup):
|
|||
def test_uncpushd_push_to_same_share(xession, shares_setup):
|
||||
if shares_setup is None:
|
||||
return
|
||||
xession.env = Env(CDPATH=PARENT, PWD=HERE)
|
||||
xession.env.update(dict(CDPATH=PARENT, PWD=HERE))
|
||||
|
||||
dirstack.cd([PARENT])
|
||||
owd = os.getcwd()
|
||||
|
@ -168,7 +167,7 @@ def test_uncpushd_push_other_push_same(xession, shares_setup):
|
|||
Then push to a again. Pop (check b unmapped and a still mapped), pop, pop (check a is unmapped)"""
|
||||
if shares_setup is None:
|
||||
return
|
||||
xession.env = Env(CDPATH=PARENT, PWD=HERE)
|
||||
xession.env.update(dict(CDPATH=PARENT, PWD=HERE))
|
||||
|
||||
dirstack.cd([PARENT])
|
||||
owd = os.getcwd()
|
||||
|
|
|
@ -11,7 +11,6 @@ from time import sleep
|
|||
import pytest
|
||||
|
||||
from xonsh.tools import always_true, DefaultNotGiven
|
||||
from xonsh.commands_cache import CommandsCache
|
||||
from xonsh.environ import (
|
||||
Env,
|
||||
locate_binary,
|
||||
|
@ -168,13 +167,13 @@ def test_thread_local_swap():
|
|||
success_variables[index] = False
|
||||
break
|
||||
with env.swap(a=index):
|
||||
sleep(0.1)
|
||||
sleep(0.01)
|
||||
if env["a"] == index:
|
||||
success_variables[index] = True
|
||||
else:
|
||||
success_variables[index] = False
|
||||
break
|
||||
sleep(0.1)
|
||||
sleep(0.01)
|
||||
|
||||
with env.swap(a="swapped"):
|
||||
threads = [
|
||||
|
@ -200,7 +199,6 @@ def test_locate_binary_on_windows(xession):
|
|||
with open(fpath, "w") as f:
|
||||
f.write(fpath)
|
||||
xession.env.update({"PATH": [tmpdir], "PATHEXT": [".COM", ".EXE", ".BAT"]})
|
||||
xession.commands_cache = CommandsCache()
|
||||
assert locate_binary("file1") == os.path.join(tmpdir, "file1.exe")
|
||||
assert locate_binary("file1.exe") == os.path.join(tmpdir, "file1.exe")
|
||||
assert locate_binary("file2") == os.path.join(tmpdir, "FILE2.BAT")
|
||||
|
@ -208,9 +206,8 @@ def test_locate_binary_on_windows(xession):
|
|||
assert locate_binary("file3") is None
|
||||
|
||||
|
||||
def test_event_on_envvar_change(xession):
|
||||
env = Env(TEST=0)
|
||||
xession.env = env
|
||||
def test_event_on_envvar_change(xession, env):
|
||||
env["TEST"] = 0
|
||||
share = []
|
||||
# register
|
||||
|
||||
|
@ -224,9 +221,7 @@ def test_event_on_envvar_change(xession):
|
|||
assert share == ["TEST", 0, 1]
|
||||
|
||||
|
||||
def test_event_on_envvar_new(xession):
|
||||
env = Env()
|
||||
xession.env = env
|
||||
def test_event_on_envvar_new(xession, env):
|
||||
share = []
|
||||
# register
|
||||
|
||||
|
@ -240,9 +235,8 @@ def test_event_on_envvar_new(xession):
|
|||
assert share == ["TEST", 1]
|
||||
|
||||
|
||||
def test_event_on_envvar_change_from_none_value(xession):
|
||||
env = Env(TEST=None)
|
||||
xession.env = env
|
||||
def test_event_on_envvar_change_from_none_value(xession, env):
|
||||
env["TEST"] = None
|
||||
share = []
|
||||
# register
|
||||
|
||||
|
@ -257,9 +251,8 @@ def test_event_on_envvar_change_from_none_value(xession):
|
|||
|
||||
|
||||
@pytest.mark.parametrize("val", [1, None, True, "ok"])
|
||||
def test_event_on_envvar_change_no_fire_when_value_is_same(val, xession):
|
||||
env = Env(TEST=val)
|
||||
xession.env = env
|
||||
def test_event_on_envvar_change_no_fire_when_value_is_same(val, xession, env):
|
||||
env["TEST"] = val
|
||||
share = []
|
||||
# register
|
||||
|
||||
|
@ -273,9 +266,7 @@ def test_event_on_envvar_change_no_fire_when_value_is_same(val, xession):
|
|||
assert share == []
|
||||
|
||||
|
||||
def test_events_on_envvar_called_in_right_order(xession):
|
||||
env = Env()
|
||||
xession.env = env
|
||||
def test_events_on_envvar_called_in_right_order(xession, env):
|
||||
share = []
|
||||
# register
|
||||
|
||||
|
@ -341,7 +332,7 @@ def test_delitem_default():
|
|||
assert env[a_key] == a_value
|
||||
|
||||
|
||||
def test_lscolors_target(xonsh_builtins):
|
||||
def test_lscolors_target(xession):
|
||||
lsc = LsColors.fromstring("ln=target")
|
||||
assert lsc["ln"] == ("RESET",)
|
||||
assert lsc.is_target("ln")
|
||||
|
|
|
@ -1,82 +1,93 @@
|
|||
"""Tests the xonsh lexer."""
|
||||
import os
|
||||
|
||||
from tools import (
|
||||
check_eval,
|
||||
check_exec,
|
||||
check_parse,
|
||||
skip_if_on_unix,
|
||||
skip_if_on_windows,
|
||||
)
|
||||
from tools import skip_if_on_unix, skip_if_on_windows, ON_WINDOWS
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def xonsh_execer_autouse(xonsh_builtins, xonsh_execer):
|
||||
return xonsh_execer
|
||||
@pytest.fixture
|
||||
def check_eval(xonsh_execer, xonsh_session, monkeypatch):
|
||||
def factory(input):
|
||||
|
||||
env = {
|
||||
"AUTO_CD": False,
|
||||
"XONSH_ENCODING": "utf-8",
|
||||
"XONSH_ENCODING_ERRORS": "strict",
|
||||
"PATH": [],
|
||||
}
|
||||
for key, val in env.items():
|
||||
monkeypatch.setitem(xonsh_session.env, key, val)
|
||||
if ON_WINDOWS:
|
||||
monkeypatch.setitem(
|
||||
xonsh_session.env, "PATHEXT", [".COM", ".EXE", ".BAT", ".CMD"]
|
||||
)
|
||||
xonsh_execer.eval(input)
|
||||
return True
|
||||
|
||||
return factory
|
||||
|
||||
|
||||
@skip_if_on_unix
|
||||
def test_win_ipconfig():
|
||||
def test_win_ipconfig(check_eval):
|
||||
assert check_eval(os.environ["SYSTEMROOT"] + "\\System32\\ipconfig.exe /all")
|
||||
|
||||
|
||||
@skip_if_on_unix
|
||||
def test_ipconfig():
|
||||
def test_ipconfig(check_eval):
|
||||
assert check_eval("ipconfig /all")
|
||||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_bin_ls():
|
||||
def test_bin_ls(check_eval):
|
||||
assert check_eval("/bin/ls -l")
|
||||
|
||||
|
||||
def test_ls_dashl():
|
||||
assert check_parse("ls -l")
|
||||
def test_ls_dashl(xonsh_execer_parse):
|
||||
assert xonsh_execer_parse("ls -l")
|
||||
|
||||
|
||||
def test_which_ls():
|
||||
assert check_parse("which ls")
|
||||
def test_which_ls(xonsh_execer_parse):
|
||||
assert xonsh_execer_parse("which ls")
|
||||
|
||||
|
||||
def test_echo_hello():
|
||||
assert check_parse("echo hello")
|
||||
def test_echo_hello(xonsh_execer_parse):
|
||||
assert xonsh_execer_parse("echo hello")
|
||||
|
||||
|
||||
def test_echo_star_with_semi():
|
||||
assert check_parse("echo * spam ; ![echo eggs]\n")
|
||||
def test_echo_star_with_semi(xonsh_execer_parse):
|
||||
assert xonsh_execer_parse("echo * spam ; ![echo eggs]\n")
|
||||
|
||||
|
||||
def test_simple_func():
|
||||
def test_simple_func(xonsh_execer_parse):
|
||||
code = "def prompt():\n" " return '{user}'.format(user='me')\n"
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_lookup_alias():
|
||||
def test_lookup_alias(xonsh_execer_parse):
|
||||
code = "def foo(a, s=None):\n" ' return "bar"\n' "@(foo)\n"
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_lookup_anon_alias():
|
||||
def test_lookup_anon_alias(xonsh_execer_parse):
|
||||
code = 'echo "hi" | @(lambda a, s=None: a[0]) foo bar baz\n'
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_simple_func_broken():
|
||||
def test_simple_func_broken(xonsh_execer_parse):
|
||||
code = "def prompt():\n" " return '{user}'.format(\n" " user='me')\n"
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_bad_indent():
|
||||
def test_bad_indent(xonsh_execer_parse):
|
||||
code = "if True:\n" "x = 1\n"
|
||||
with pytest.raises(SyntaxError):
|
||||
check_parse(code)
|
||||
xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_comment_colon_ending():
|
||||
def test_comment_colon_ending(xonsh_execer_parse):
|
||||
code = "# this is a comment:\necho hello"
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_good_rhs_subproc():
|
||||
|
@ -85,56 +96,56 @@ def test_good_rhs_subproc():
|
|||
assert code
|
||||
|
||||
|
||||
def test_bad_rhs_subproc():
|
||||
def test_bad_rhs_subproc(xonsh_execer_parse):
|
||||
# nonsense but unparsable
|
||||
code = "str().split() | grep exit\n"
|
||||
with pytest.raises(SyntaxError):
|
||||
check_parse(code)
|
||||
xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_indent_with_empty_line():
|
||||
def test_indent_with_empty_line(xonsh_execer_parse):
|
||||
code = "if True:\n" "\n" " some_command for_sub_process_mode\n"
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_command_in_func():
|
||||
def test_command_in_func(xonsh_execer_parse):
|
||||
code = "def f():\n" " echo hello\n"
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_command_in_func_with_comment():
|
||||
def test_command_in_func_with_comment(xonsh_execer_parse):
|
||||
code = "def f():\n" " echo hello # comment\n"
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_pyeval_redirect():
|
||||
def test_pyeval_redirect(xonsh_execer_parse):
|
||||
code = 'echo @("foo") > bar\n'
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_pyeval_multiline_str():
|
||||
def test_pyeval_multiline_str(xonsh_execer_parse):
|
||||
code = 'echo @("""hello\nmom""")\n'
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_echo_comma():
|
||||
def test_echo_comma(xonsh_execer_parse):
|
||||
code = "echo ,\n"
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_echo_comma_val():
|
||||
def test_echo_comma_val(xonsh_execer_parse):
|
||||
code = "echo ,1\n"
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_echo_comma_2val():
|
||||
def test_echo_comma_2val(xonsh_execer_parse):
|
||||
code = "echo 1,2\n"
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_echo_line_cont():
|
||||
def test_echo_line_cont(xonsh_execer_parse):
|
||||
code = 'echo "1 \\\n2"\n'
|
||||
assert check_parse(code)
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -146,40 +157,40 @@ def test_echo_line_cont():
|
|||
"if True:\\\n echo a \\\n b\n",
|
||||
],
|
||||
)
|
||||
def test_two_echo_line_cont(code):
|
||||
assert check_parse(code)
|
||||
def test_two_echo_line_cont(code, xonsh_execer_parse):
|
||||
assert xonsh_execer_parse(code)
|
||||
|
||||
|
||||
def test_eval_eol():
|
||||
def test_eval_eol(check_eval):
|
||||
assert check_eval("0") and check_eval("0\n")
|
||||
|
||||
|
||||
def test_annotated_assign():
|
||||
def test_annotated_assign(xonsh_execer_exec):
|
||||
# issue #3959 - didn't work because of `CtxAwareTransformer`
|
||||
assert check_exec("x : int = 42")
|
||||
assert xonsh_execer_exec("x : int = 42")
|
||||
|
||||
|
||||
def test_exec_eol():
|
||||
def test_exec_eol(xonsh_execer_exec):
|
||||
locs = dict()
|
||||
assert check_exec("a=0", locs=locs) and check_exec("a=0\n", locs=locs)
|
||||
assert xonsh_execer_exec("a=0", locs=locs) and xonsh_execer_exec("a=0\n", locs=locs)
|
||||
|
||||
|
||||
def test_exec_print(capsys):
|
||||
def test_exec_print(capsys, xonsh_execer_exec):
|
||||
ls = {"nested": "some long list"}
|
||||
check_exec("print(ls)", locs=dict(ls=ls))
|
||||
xonsh_execer_exec("print(ls)", locs=dict(ls=ls))
|
||||
out, err = capsys.readouterr()
|
||||
assert out.strip() == repr(ls)
|
||||
|
||||
|
||||
def test_exec_function_scope():
|
||||
def test_exec_function_scope(xonsh_execer_exec):
|
||||
# issue 4363
|
||||
assert check_exec("x = 0; (lambda: x)()")
|
||||
assert check_exec("x = 0; [x for _ in [0]]")
|
||||
assert xonsh_execer_exec("x = 0; (lambda: x)()")
|
||||
assert xonsh_execer_exec("x = 0; [x for _ in [0]]")
|
||||
|
||||
|
||||
def test_exec_scope_reuse():
|
||||
def test_exec_scope_reuse(xonsh_execer_exec):
|
||||
# Scopes should not be reused between execs.
|
||||
# A first-pass incorrect solution to issue 4363 made this mistake.
|
||||
assert check_exec("x = 0")
|
||||
assert xonsh_execer_exec("x = 0")
|
||||
with pytest.raises(NameError):
|
||||
check_exec("print(x)")
|
||||
xonsh_execer_exec("print(x)")
|
||||
|
|
|
@ -5,16 +5,13 @@ from importlib import import_module
|
|||
import pytest
|
||||
|
||||
from xonsh import imphooks
|
||||
from xonsh.environ import Env
|
||||
from xonsh.built_ins import XSH
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def imp_env(xession):
|
||||
xession.env = Env({"PATH": [], "PATHEXT": []})
|
||||
xession.env.update({"PATH": [], "PATHEXT": []})
|
||||
imphooks.install_import_hooks(xession.execer)
|
||||
yield
|
||||
XSH.unload()
|
||||
|
||||
|
||||
def test_import():
|
||||
|
|
|
@ -423,7 +423,7 @@ def test_xonsh_failback(
|
|||
rc_shells,
|
||||
exp_shell,
|
||||
shell,
|
||||
xonsh_builtins,
|
||||
xession,
|
||||
monkeypatch,
|
||||
monkeypatch_stderr,
|
||||
):
|
||||
|
|
1470
tests/test_parser.py
1470
tests/test_parser.py
File diff suppressed because it is too large
Load diff
|
@ -8,22 +8,23 @@ import pytest
|
|||
from xonsh.platform import ON_WINDOWS
|
||||
from xonsh.procs.pipelines import CommandPipeline
|
||||
from tests.tools import skip_if_on_windows, skip_if_on_unix
|
||||
from xonsh.built_ins import XSH
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def patched_events(monkeypatch, xonsh_events, xonsh_execer):
|
||||
def patched_events(monkeypatch, xonsh_events, xonsh_session):
|
||||
from xonsh.jobs import tasks
|
||||
|
||||
tasks.clear()
|
||||
# needed for ci tests
|
||||
monkeypatch.setitem(
|
||||
XSH.env, "RAISE_SUBPROC_ERROR", False
|
||||
xonsh_session.env, "RAISE_SUBPROC_ERROR", False
|
||||
) # for the failing `grep` commands
|
||||
monkeypatch.setitem(XSH.env, "XONSH_CAPTURE_ALWAYS", True) # capture output of ![]
|
||||
monkeypatch.setitem(
|
||||
xonsh_session.env, "XONSH_CAPTURE_ALWAYS", True
|
||||
) # capture output of ![]
|
||||
if ON_WINDOWS:
|
||||
monkeypatch.setattr(
|
||||
XSH,
|
||||
xonsh_session,
|
||||
"aliases",
|
||||
{
|
||||
"echo": "cmd /c echo".split(),
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
"""Test XonshLexer for pygments"""
|
||||
|
||||
import gc
|
||||
|
||||
import pytest
|
||||
from pygments.token import (
|
||||
|
@ -16,55 +15,51 @@ from pygments.token import (
|
|||
)
|
||||
from tools import skip_if_on_windows
|
||||
|
||||
from xonsh.platform import ON_WINDOWS
|
||||
from xonsh.built_ins import XSH
|
||||
from xonsh.pyghooks import XonshLexer, Color, XonshStyle, on_lscolors_change
|
||||
from xonsh.environ import LsColors
|
||||
from xonsh.events import events, EventManager
|
||||
from tools import DummyShell
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def load_command_cache(xession):
|
||||
gc.collect()
|
||||
XSH.unload()
|
||||
XSH.load()
|
||||
if ON_WINDOWS:
|
||||
for key in ("cd", "bash"):
|
||||
xession.aliases[key] = lambda *args, **kwargs: None
|
||||
@pytest.fixture
|
||||
def xsh(xession, monkeypatch):
|
||||
for key in ("cd", "bash"):
|
||||
monkeypatch.setitem(xession.aliases, key, lambda *args, **kwargs: None)
|
||||
|
||||
|
||||
def check_token(code, tokens):
|
||||
"""Make sure that all tokens appears in code in order"""
|
||||
lx = XonshLexer()
|
||||
tks = list(lx.get_tokens(code))
|
||||
@pytest.fixture()
|
||||
def check_token(xsh):
|
||||
def factory(code, tokens):
|
||||
"""Make sure that all tokens appears in code in order"""
|
||||
lx = XonshLexer()
|
||||
tks = list(lx.get_tokens(code))
|
||||
|
||||
for tk in tokens:
|
||||
while tks:
|
||||
if tk == tks[0]:
|
||||
for tk in tokens:
|
||||
while tks:
|
||||
if tk == tks[0]:
|
||||
break
|
||||
tks = tks[1:]
|
||||
else:
|
||||
msg = f"Token {tk!r} missing: {list(lx.get_tokens(code))!r}"
|
||||
pytest.fail(msg)
|
||||
break
|
||||
tks = tks[1:]
|
||||
else:
|
||||
msg = f"Token {tk!r} missing: {list(lx.get_tokens(code))!r}"
|
||||
pytest.fail(msg)
|
||||
break
|
||||
|
||||
return factory
|
||||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_ls():
|
||||
check_token("ls -al", [(Name.Builtin, "ls")])
|
||||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_bin_ls():
|
||||
check_token("/bin/ls -al", [(Name.Builtin, "/bin/ls")])
|
||||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_py_print():
|
||||
check_token(
|
||||
'print("hello")',
|
||||
[
|
||||
_cases = {
|
||||
"ls": {
|
||||
"ls -al": [
|
||||
(Name.Builtin, "ls"),
|
||||
],
|
||||
},
|
||||
"ls-bin": {
|
||||
"/bin/ls -al": [
|
||||
(Name.Builtin, "/bin/ls"),
|
||||
],
|
||||
},
|
||||
"print": {
|
||||
'print("hello")': [
|
||||
(Name.Builtin, "print"),
|
||||
(Punctuation, "("),
|
||||
(Literal.String.Double, '"'),
|
||||
|
@ -72,46 +67,44 @@ def test_py_print():
|
|||
(Literal.String.Double, '"'),
|
||||
(Punctuation, ")"),
|
||||
(Text, "\n"),
|
||||
]
|
||||
},
|
||||
"invalid-cmd": {
|
||||
"non-existance-cmd -al": [
|
||||
(Name, "non"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_invalid_cmd():
|
||||
check_token("non-existance-cmd -al", [(Name, "non")]) # parse as python
|
||||
check_token(
|
||||
"![non-existance-cmd -al]", [(Error, "non-existance-cmd")]
|
||||
) # parse as error
|
||||
check_token("for i in range(10):", [(Keyword, "for")]) # as py keyword
|
||||
check_token("(1, )", [(Punctuation, "("), (Number.Integer, "1")])
|
||||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_multi_cmd():
|
||||
check_token(
|
||||
"cd && cd", [(Name.Builtin, "cd"), (Operator, "&&"), (Name.Builtin, "cd")]
|
||||
)
|
||||
check_token(
|
||||
"cd || non-existance-cmd",
|
||||
[(Name.Builtin, "cd"), (Operator, "||"), (Error, "non-existance-cmd")],
|
||||
)
|
||||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_nested():
|
||||
check_token(
|
||||
'echo @("hello")',
|
||||
[
|
||||
"![non-existance-cmd -al]": [
|
||||
(Error, "non-existance-cmd"),
|
||||
],
|
||||
"for i in range(10):": [
|
||||
(Keyword, "for"),
|
||||
],
|
||||
"(1, )": [
|
||||
(Punctuation, "("),
|
||||
(Number.Integer, "1"),
|
||||
],
|
||||
},
|
||||
"multi-cmd": {
|
||||
"cd && cd": [
|
||||
(Name.Builtin, "cd"),
|
||||
(Operator, "&&"),
|
||||
(Name.Builtin, "cd"),
|
||||
],
|
||||
"cd || non-existance-cmd": [
|
||||
(Name.Builtin, "cd"),
|
||||
(Operator, "||"),
|
||||
(Error, "non-existance-cmd"),
|
||||
],
|
||||
},
|
||||
"nested": {
|
||||
'echo @("hello")': [
|
||||
(Name.Builtin, "echo"),
|
||||
(Keyword, "@"),
|
||||
(Punctuation, "("),
|
||||
(String.Double, "hello"),
|
||||
(Punctuation, ")"),
|
||||
],
|
||||
)
|
||||
check_token(
|
||||
"print($(cd))",
|
||||
[
|
||||
"print($(cd))": [
|
||||
(Name.Builtin, "print"),
|
||||
(Punctuation, "("),
|
||||
(Keyword, "$"),
|
||||
|
@ -121,10 +114,7 @@ def test_nested():
|
|||
(Punctuation, ")"),
|
||||
(Text, "\n"),
|
||||
],
|
||||
)
|
||||
check_token(
|
||||
r'print(![echo "])\""])',
|
||||
[
|
||||
r'print(![echo "])\""])': [
|
||||
(Name.Builtin, "print"),
|
||||
(Punctuation, "("),
|
||||
(Keyword, "!"),
|
||||
|
@ -136,7 +126,53 @@ def test_nested():
|
|||
(Punctuation, ")"),
|
||||
(Text, "\n"),
|
||||
],
|
||||
)
|
||||
},
|
||||
"subproc-args": {
|
||||
"cd 192.168.0.1": [
|
||||
(Text, "192.168.0.1"),
|
||||
],
|
||||
},
|
||||
"backtick": {
|
||||
r"echo g`.*\w+`": [
|
||||
(String.Affix, "g"),
|
||||
(String.Backtick, "`"),
|
||||
(String.Regex, "."),
|
||||
(String.Regex, "*"),
|
||||
(String.Escape, r"\w"),
|
||||
],
|
||||
},
|
||||
"macro": {
|
||||
r"g!(42, *, 65)": [
|
||||
(Name, "g"),
|
||||
(Keyword, "!"),
|
||||
(Punctuation, "("),
|
||||
(Number.Integer, "42"),
|
||||
],
|
||||
r"echo! hello world": [
|
||||
(Name.Builtin, "echo"),
|
||||
(Keyword, "!"),
|
||||
(String, "hello world"),
|
||||
],
|
||||
r"bash -c ! export var=42; echo $var": [
|
||||
(Name.Builtin, "bash"),
|
||||
(Text, "-c"),
|
||||
(Keyword, "!"),
|
||||
(String, "export var=42; echo $var"),
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _convert_cases():
|
||||
for title, input_dict in _cases.items():
|
||||
for idx, item in enumerate(input_dict.items()):
|
||||
yield pytest.param(*item, id=f"{title}-{idx}")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("inp, expected", list(_convert_cases()))
|
||||
@skip_if_on_windows
|
||||
def test_xonsh_lexer(inp, expected, check_token):
|
||||
check_token(inp, expected)
|
||||
|
||||
|
||||
# can't seem to get thie test to import pyghooks and define on_lscolors_change handler like live code does.
|
||||
|
@ -160,8 +196,7 @@ def xonsh_builtins_ls_colors(xession, events_fxt):
|
|||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_path(tmpdir, xonsh_builtins_ls_colors):
|
||||
|
||||
def test_path(tmpdir, xonsh_builtins_ls_colors, check_token):
|
||||
test_dir = str(tmpdir.mkdir("xonsh-test-highlight-path"))
|
||||
check_token(f"cd {test_dir}", [(Name.Builtin, "cd"), (Color.BOLD_BLUE, test_dir)])
|
||||
check_token(
|
||||
|
@ -175,7 +210,7 @@ def test_path(tmpdir, xonsh_builtins_ls_colors):
|
|||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_color_on_lscolors_change(tmpdir, xonsh_builtins_ls_colors):
|
||||
def test_color_on_lscolors_change(tmpdir, xonsh_builtins_ls_colors, check_token):
|
||||
"""Verify colorizer returns Token.Text if file type not defined in LS_COLORS"""
|
||||
|
||||
lsc = xonsh_builtins_ls_colors.env["LS_COLORS"]
|
||||
|
@ -188,43 +223,3 @@ def test_color_on_lscolors_change(tmpdir, xonsh_builtins_ls_colors):
|
|||
del lsc["di"]
|
||||
|
||||
check_token(f"cd {test_dir}", [(Name.Builtin, "cd"), (Text, test_dir)])
|
||||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_subproc_args():
|
||||
check_token("cd 192.168.0.1", [(Text, "192.168.0.1")])
|
||||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_backtick():
|
||||
check_token(
|
||||
r"echo g`.*\w+`",
|
||||
[
|
||||
(String.Affix, "g"),
|
||||
(String.Backtick, "`"),
|
||||
(String.Regex, "."),
|
||||
(String.Regex, "*"),
|
||||
(String.Escape, r"\w"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@skip_if_on_windows
|
||||
def test_macro():
|
||||
check_token(
|
||||
r"g!(42, *, 65)",
|
||||
[(Name, "g"), (Keyword, "!"), (Punctuation, "("), (Number.Integer, "42")],
|
||||
)
|
||||
check_token(
|
||||
r"echo! hello world",
|
||||
[(Name.Builtin, "echo"), (Keyword, "!"), (String, "hello world")],
|
||||
)
|
||||
check_token(
|
||||
r"bash -c ! export var=42; echo $var",
|
||||
[
|
||||
(Name.Builtin, "bash"),
|
||||
(Text, "-c"),
|
||||
(Keyword, "!"),
|
||||
(String, "export var=42; echo $var"),
|
||||
],
|
||||
)
|
||||
|
|
|
@ -32,7 +32,7 @@ def test_prompt_toolkit_version_checks(
|
|||
exp_shell_type,
|
||||
warn_snip,
|
||||
monkeypatch,
|
||||
xonsh_builtins,
|
||||
xession,
|
||||
):
|
||||
|
||||
mocked_warn = ""
|
||||
|
|
|
@ -23,18 +23,24 @@ from xonsh.environ import LsColors
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def xs_LS_COLORS(xession):
|
||||
def xs_LS_COLORS(xession, os_env, monkeypatch):
|
||||
"""Xonsh environment including LS_COLORS"""
|
||||
e = xession.env
|
||||
|
||||
# original env is needed on windows. since it will skip enhanced coloring
|
||||
# for some emulators
|
||||
monkeypatch.setattr(xession, "env", os_env)
|
||||
|
||||
lsc = LsColors(LsColors.default_settings)
|
||||
xession.env["LS_COLORS"] = lsc
|
||||
|
||||
# todo: a separate test for this as True
|
||||
xession.env["INTENSIFY_COLORS_ON_WIN"] = False
|
||||
|
||||
xession.shell.shell_type = "prompt_toolkit"
|
||||
xession.shell.shell.styler = XonshStyle() # default style
|
||||
|
||||
yield xession
|
||||
|
||||
xession.env = e
|
||||
|
||||
|
||||
DEFAULT_STYLES = {
|
||||
# Reset
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"""Testing for ``xonsh.shell.Shell``"""
|
||||
import os
|
||||
|
||||
from xonsh.environ import Env
|
||||
from xonsh.shell import Shell
|
||||
from xonsh.history.json import JsonHistory
|
||||
from xonsh.history.sqlite import SqliteHistory
|
||||
|
@ -32,12 +31,14 @@ def test_shell_with_json_history(xession, xonsh_execer, tmpdir_factory):
|
|||
)
|
||||
h.flush()
|
||||
|
||||
xession.env = Env(
|
||||
XONSH_DATA_DIR=tempdir,
|
||||
XONSH_INTERACTIVE=True,
|
||||
XONSH_HISTORY_BACKEND="json",
|
||||
XONSH_HISTORY_FILE=history_file,
|
||||
# XONSH_DEBUG=1 # to show errors
|
||||
xession.env.update(
|
||||
dict(
|
||||
XONSH_DATA_DIR=tempdir,
|
||||
XONSH_INTERACTIVE=True,
|
||||
XONSH_HISTORY_BACKEND="json",
|
||||
XONSH_HISTORY_FILE=history_file,
|
||||
# XONSH_DEBUG=1 # to show errors
|
||||
)
|
||||
)
|
||||
|
||||
Shell(xonsh_execer, shell_type="none")
|
||||
|
@ -69,12 +70,14 @@ def test_shell_with_sqlite_history(xession, xonsh_execer, tmpdir_factory):
|
|||
)
|
||||
h.flush()
|
||||
|
||||
xession.env = Env(
|
||||
XONSH_DATA_DIR=tempdir,
|
||||
XONSH_INTERACTIVE=True,
|
||||
XONSH_HISTORY_BACKEND="sqlite",
|
||||
XONSH_HISTORY_FILE=history_file,
|
||||
# XONSH_DEBUG=1 # to show errors
|
||||
xession.env.update(
|
||||
dict(
|
||||
XONSH_DATA_DIR=tempdir,
|
||||
XONSH_INTERACTIVE=True,
|
||||
XONSH_HISTORY_BACKEND="sqlite",
|
||||
XONSH_HISTORY_FILE=history_file,
|
||||
# XONSH_DEBUG=1 # to show errors
|
||||
)
|
||||
)
|
||||
|
||||
Shell(xonsh_execer, shell_type="none")
|
||||
|
@ -86,7 +89,7 @@ def test_shell_with_dummy_history_in_not_interactive(xession, xonsh_execer):
|
|||
"""
|
||||
Check that shell use Dummy history in not interactive mode.
|
||||
"""
|
||||
xession.env = Env(XONSH_INTERACTIVE=False)
|
||||
xession.env["XONSH_INTERACTIVE"] = False
|
||||
xession.history = None
|
||||
Shell(xonsh_execer, shell_type="none")
|
||||
assert isinstance(xession.history, DummyHistory)
|
||||
|
|
|
@ -90,7 +90,6 @@ from xonsh.tools import (
|
|||
expand_case_matching,
|
||||
expandvars,
|
||||
)
|
||||
from xonsh.environ import Env
|
||||
|
||||
from tools import skip_if_on_windows
|
||||
|
||||
|
@ -536,7 +535,7 @@ mom"""
|
|||
|
||||
|
||||
@pytest.mark.parametrize("src, idx, exp_line, exp_n", LOGICAL_LINE_CASES)
|
||||
def test_get_logical_line(src, idx, exp_line, exp_n, xonsh_builtins):
|
||||
def test_get_logical_line(src, idx, exp_line, exp_n, xession):
|
||||
lines = src.splitlines()
|
||||
line, n, start = get_logical_line(lines, idx)
|
||||
assert exp_line == line
|
||||
|
@ -544,7 +543,7 @@ def test_get_logical_line(src, idx, exp_line, exp_n, xonsh_builtins):
|
|||
|
||||
|
||||
@pytest.mark.parametrize("src, idx, exp_line, exp_n", LOGICAL_LINE_CASES)
|
||||
def test_replace_logical_line(src, idx, exp_line, exp_n, xonsh_builtins):
|
||||
def test_replace_logical_line(src, idx, exp_line, exp_n, xession):
|
||||
lines = src.splitlines()
|
||||
logical = exp_line
|
||||
while idx > 0 and lines[idx - 1].endswith("\\"):
|
||||
|
@ -1651,10 +1650,9 @@ def test_expand_case_matching(inp, exp):
|
|||
)
|
||||
def test_expandvars(inp, exp, xession):
|
||||
"""Tweaked for xonsh cases from CPython `test_genericpath.py`"""
|
||||
env = Env(
|
||||
{"foo": "bar", "spam": "eggs", "a_bool": True, "an_int": 42, "none": None}
|
||||
xession.env.update(
|
||||
dict({"foo": "bar", "spam": "eggs", "a_bool": True, "an_int": 42, "none": None})
|
||||
)
|
||||
xession.env = env
|
||||
assert expandvars(inp) == exp
|
||||
|
||||
|
||||
|
@ -1699,9 +1697,8 @@ def test_expand_path(expand_user, inp, expand_env_vars, exp_end, xession):
|
|||
inp = inp.replace("/", os.sep)
|
||||
exp_end = exp_end.replace("/", os.sep)
|
||||
|
||||
env = Env({"foo": "bar", "a_bool": True, "an_int": 42, "none": None})
|
||||
env["EXPAND_ENV_VARS"] = expand_env_vars
|
||||
xession.env = env
|
||||
xession.env.update({"foo": "bar", "a_bool": True, "an_int": 42, "none": None})
|
||||
xession.env["EXPAND_ENV_VARS"] = expand_env_vars
|
||||
|
||||
path = expand_path(inp, expand_user=expand_user)
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ def test_activate_non_vox_venv(xession, vox, record_events, tmpdir):
|
|||
Create a virtual environment using Python's built-in venv module
|
||||
(not in VIRTUALENV_HOME) and verify that vox can activate it correctly.
|
||||
"""
|
||||
xession.env.setdefault("PATH", [])
|
||||
xession.env["PATH"] = []
|
||||
|
||||
record_events("vox_on_activate", "vox_on_deactivate")
|
||||
|
||||
|
@ -286,9 +286,8 @@ def patched_cmd_cache(xession, vox, venvs, monkeypatch):
|
|||
def no_change(self, *_):
|
||||
return False, False, False
|
||||
|
||||
monkeypatch.setattr(cc, "_update_if_changed", types.MethodType(no_change, cc))
|
||||
monkeypatch.setattr(cc, "_check_changes", types.MethodType(no_change, cc))
|
||||
monkeypatch.setattr(cc, "_update_cmds_cache", types.MethodType(no_change, cc))
|
||||
monkeypatch.setattr(cc, "cache_file", None)
|
||||
bins = {path: (path, False) for path in _PY_BINS}
|
||||
cc._cmds_cache.update(bins)
|
||||
yield cc
|
||||
|
|
|
@ -15,7 +15,7 @@ from xonsh.tools import ON_WINDOWS
|
|||
from xonsh.xonfig import xonfig_main
|
||||
|
||||
|
||||
def test_xonfg_help(capsys, xonsh_builtins):
|
||||
def test_xonfg_help(capsys, xession):
|
||||
"""verify can invoke it, and usage knows about all the options"""
|
||||
with pytest.raises(SystemExit):
|
||||
xonfig_main(["-h"])
|
||||
|
@ -46,7 +46,7 @@ def test_xonfg_help(capsys, xonsh_builtins):
|
|||
),
|
||||
], # NOQA E231
|
||||
)
|
||||
def test_xonfig_info(args, xonsh_builtins):
|
||||
def test_xonfig_info(args, xession):
|
||||
"""info works, and reports no jupyter if none in environment"""
|
||||
capout = xonfig_main(args)
|
||||
assert capout.startswith("+---")
|
||||
|
@ -89,7 +89,7 @@ def fake_lib(monkeypatch):
|
|||
del sys.modules[m]
|
||||
|
||||
|
||||
def test_xonfig_kernel_with_jupyter(monkeypatch, capsys, fake_lib, xonsh_builtins):
|
||||
def test_xonfig_kernel_with_jupyter(monkeypatch, capsys, fake_lib, xession):
|
||||
cap_args = None
|
||||
cap_spec = None
|
||||
|
||||
|
@ -129,6 +129,6 @@ def test_xonfig_kernel_with_jupyter(monkeypatch, capsys, fake_lib, xonsh_builtin
|
|||
assert cap_spec["argv"][2] == "xonsh.jupyter_kernel"
|
||||
|
||||
|
||||
def test_xonfig_kernel_no_jupyter(capsys, xonsh_builtins):
|
||||
def test_xonfig_kernel_no_jupyter(capsys, xession):
|
||||
with pytest.raises(ImportError):
|
||||
rc = xonfig_main(["jupyter-kernel"]) # noqa F841
|
||||
|
|
124
tests/tools.py
124
tests/tools.py
|
@ -1,17 +1,15 @@
|
|||
"""Tests the xonsh lexer."""
|
||||
import copy
|
||||
import os
|
||||
import sys
|
||||
import ast
|
||||
import platform
|
||||
import subprocess
|
||||
import contextlib
|
||||
import threading
|
||||
from collections import defaultdict
|
||||
from collections.abc import MutableMapping
|
||||
|
||||
import pytest
|
||||
|
||||
from xonsh.built_ins import XSH
|
||||
from xonsh.environ import Env
|
||||
from xonsh.base_shell import BaseShell
|
||||
|
||||
|
||||
|
@ -24,9 +22,6 @@ ON_CONDA = True in [
|
|||
conda in pytest.__file__.lower() for conda in ["conda", "anaconda", "miniconda"]
|
||||
]
|
||||
ON_TRAVIS = "TRAVIS" in os.environ and "CI" in os.environ
|
||||
ON_AZURE_PIPELINES = os.environ.get("TF_BUILD", "") == "True"
|
||||
print("ON_AZURE_PIPELINES", repr(ON_AZURE_PIPELINES))
|
||||
print("os.environ['TF_BUILD']", repr(os.environ.get("TF_BUILD", "")))
|
||||
TEST_DIR = os.path.dirname(__file__)
|
||||
|
||||
# pytest skip decorators
|
||||
|
@ -40,10 +35,6 @@ skip_if_on_msys = pytest.mark.skipif(
|
|||
|
||||
skip_if_on_windows = pytest.mark.skipif(ON_WINDOWS, reason="Unix stuff")
|
||||
|
||||
skip_if_on_azure_pipelines = pytest.mark.skipif(
|
||||
ON_AZURE_PIPELINES, reason="not suitable for azure"
|
||||
)
|
||||
|
||||
skip_if_on_unix = pytest.mark.skipif(not ON_WINDOWS, reason="Windows stuff")
|
||||
|
||||
skip_if_on_darwin = pytest.mark.skipif(ON_DARWIN, reason="not Mac friendly")
|
||||
|
@ -94,103 +85,6 @@ class DummyHistory:
|
|||
pass
|
||||
|
||||
|
||||
class DummyEnv(MutableMapping):
|
||||
|
||||
DEFAULTS = {
|
||||
"XONSH_DEBUG": 1,
|
||||
"XONSH_COLOR_STYLE": "default",
|
||||
"VC_BRANCH_TIMEOUT": 1,
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._d = self.DEFAULTS.copy()
|
||||
self._d.update(dict(*args, **kwargs))
|
||||
|
||||
def detype(self):
|
||||
return {k: str(v) for k, v in self._d.items()}
|
||||
|
||||
def __getitem__(self, k):
|
||||
if k is ...:
|
||||
return self
|
||||
else:
|
||||
return self._d[k]
|
||||
|
||||
def __setitem__(self, k, v):
|
||||
assert k is not ...
|
||||
self._d[k] = v
|
||||
|
||||
def __delitem__(self, k):
|
||||
assert k is not ...
|
||||
del self._d[k]
|
||||
|
||||
def __len__(self):
|
||||
return len(self._d)
|
||||
|
||||
def __iter__(self):
|
||||
yield from self._d
|
||||
|
||||
@contextlib.contextmanager
|
||||
def swap(self, other=None, **kwargs):
|
||||
old = {}
|
||||
# single positional argument should be a dict-like object
|
||||
if other is not None:
|
||||
for k, v in other.items():
|
||||
old[k] = self.get(k, NotImplemented)
|
||||
self[k] = v
|
||||
# kwargs could also have been sent in
|
||||
for k, v in kwargs.items():
|
||||
old[k] = self.get(k, NotImplemented)
|
||||
self[k] = v
|
||||
yield self
|
||||
# restore the values
|
||||
for k, v in old.items():
|
||||
if v is NotImplemented:
|
||||
del self[k]
|
||||
else:
|
||||
self[k] = v
|
||||
|
||||
@staticmethod
|
||||
def get_swapped_values():
|
||||
return {}
|
||||
|
||||
@staticmethod
|
||||
def set_swapped_values(_):
|
||||
pass
|
||||
|
||||
def is_manually_set(self, key):
|
||||
return False
|
||||
|
||||
|
||||
#
|
||||
# Execer tools
|
||||
#
|
||||
|
||||
|
||||
def check_exec(input, **kwargs):
|
||||
XSH.execer.exec(input, **kwargs)
|
||||
return True
|
||||
|
||||
|
||||
def check_eval(input):
|
||||
XSH.env = Env(
|
||||
{
|
||||
"AUTO_CD": False,
|
||||
"XONSH_ENCODING": "utf-8",
|
||||
"XONSH_ENCODING_ERRORS": "strict",
|
||||
"PATH": [],
|
||||
}
|
||||
)
|
||||
if ON_WINDOWS:
|
||||
XSH.env["PATHEXT"] = [".COM", ".EXE", ".BAT", ".CMD"]
|
||||
XSH.execer.eval(input)
|
||||
return True
|
||||
|
||||
|
||||
def check_parse(input):
|
||||
tree = XSH.execer.parse(input, ctx=None)
|
||||
return tree
|
||||
|
||||
|
||||
#
|
||||
# Parser tools
|
||||
#
|
||||
|
@ -245,3 +139,17 @@ def completions_from_result(results):
|
|||
if results is None:
|
||||
return set()
|
||||
return results
|
||||
|
||||
|
||||
def copy_env(old):
|
||||
from xonsh.environ import Env, InternalEnvironDict
|
||||
|
||||
env: Env = copy.copy(old)
|
||||
internal = InternalEnvironDict()
|
||||
internal._global = env._d._global.copy()
|
||||
internal._thread_local = threading.local()
|
||||
|
||||
env._d = internal
|
||||
env._vars = env._vars.copy()
|
||||
env._detyped = None
|
||||
return env
|
||||
|
|
|
@ -5,6 +5,7 @@ A background predictor is a function that accepts a single argument list
|
|||
and returns whether or not the process can be run in the background (returns
|
||||
True) or must be run the foreground (returns False).
|
||||
"""
|
||||
import functools
|
||||
import os
|
||||
import pickle
|
||||
import sys
|
||||
|
@ -39,15 +40,24 @@ class CommandsCache(cabc.Mapping):
|
|||
self.threadable_predictors = default_threadable_predictors()
|
||||
self._loaded_pickled = False
|
||||
|
||||
# Path to the cache-file where all commands/aliases are cached for pre-loading"""
|
||||
env = XSH.env
|
||||
self.cache_file = (
|
||||
(Path(env["XONSH_DATA_DIR"]).joinpath(self.CACHE_FILE).resolve())
|
||||
if env is not None
|
||||
and "XONSH_DATA_DIR" in env
|
||||
and env.get("COMMANDS_CACHE_SAVE_INTERMEDIATE")
|
||||
else None
|
||||
)
|
||||
# force it to load from env by setting it to None
|
||||
self._cache_file = None
|
||||
|
||||
@property
|
||||
def cache_file(self):
|
||||
"""Keeping a property that lies on instance-attribute"""
|
||||
env = XSH.env or {}
|
||||
# Path to the cache-file where all commands/aliases are cached for pre-loading
|
||||
if self._cache_file is None:
|
||||
if "XONSH_DATA_DIR" in env and env.get("COMMANDS_CACHE_SAVE_INTERMEDIATE"):
|
||||
self._cache_file = (
|
||||
Path(env["XONSH_DATA_DIR"]).joinpath(self.CACHE_FILE).resolve()
|
||||
)
|
||||
else:
|
||||
# set a falsy value other than None
|
||||
self._cache_file = ""
|
||||
|
||||
return self._cache_file
|
||||
|
||||
def __contains__(self, key):
|
||||
self.update_cache()
|
||||
|
@ -98,7 +108,7 @@ class CommandsCache(cabc.Mapping):
|
|||
if os.path.isdir(p):
|
||||
yield p
|
||||
|
||||
def _update_if_changed(self, paths: tp.Tuple[str, ...], aliases):
|
||||
def _check_changes(self, paths: tp.Tuple[str, ...], aliases):
|
||||
# did PATH change?
|
||||
path_hash = hash(paths)
|
||||
yield path_hash == self._path_checksum
|
||||
|
@ -120,20 +130,20 @@ class CommandsCache(cabc.Mapping):
|
|||
return self._cmds_cache
|
||||
|
||||
def update_cache(self):
|
||||
env = XSH.env
|
||||
path = [] if env is None else XSH.env.get("PATH", [])
|
||||
path_immut = tuple(CommandsCache.remove_dups(path))
|
||||
env = XSH.env or {}
|
||||
paths = tuple(CommandsCache.remove_dups(env.get("PATH") or []))
|
||||
|
||||
# in case it is empty or unset
|
||||
alss = {} if XSH.aliases is None else XSH.aliases
|
||||
|
||||
(
|
||||
has_path_changed,
|
||||
has_alias_changed,
|
||||
has_any_path_updated,
|
||||
) = tuple(self._update_if_changed(path_immut, alss))
|
||||
if has_path_changed and has_any_path_updated:
|
||||
if not has_alias_changed:
|
||||
no_new_paths,
|
||||
no_new_alias,
|
||||
no_new_bins,
|
||||
) = tuple(self._check_changes(paths, alss))
|
||||
|
||||
if no_new_paths and no_new_bins:
|
||||
if not no_new_alias: # only aliases have changed
|
||||
for cmd, alias in alss.items():
|
||||
key = cmd.upper() if ON_WINDOWS else cmd
|
||||
if key in self._cmds_cache:
|
||||
|
@ -153,26 +163,41 @@ class CommandsCache(cabc.Mapping):
|
|||
# also start a thread that updates the cache in the bg
|
||||
worker = threading.Thread(
|
||||
target=self._update_cmds_cache,
|
||||
args=[path_immut, alss],
|
||||
args=[paths, alss],
|
||||
daemon=True,
|
||||
)
|
||||
worker.start()
|
||||
else:
|
||||
self._update_cmds_cache(path_immut, alss)
|
||||
self._update_cmds_cache(paths, alss)
|
||||
return self._cmds_cache
|
||||
|
||||
@staticmethod
|
||||
@functools.lru_cache(maxsize=10)
|
||||
def _get_all_cmds(paths: tp.Sequence[str]):
|
||||
"""Cache results when possible
|
||||
|
||||
This will be helpful especially during tests where the PATH will be the same mostly.
|
||||
"""
|
||||
|
||||
def _getter():
|
||||
for path in reversed(paths):
|
||||
# iterate backwards so that entries at the front of PATH overwrite
|
||||
# entries at the back.
|
||||
for cmd in executables_in(path):
|
||||
yield cmd, os.path.join(path, cmd)
|
||||
|
||||
return dict(_getter())
|
||||
|
||||
def _update_cmds_cache(
|
||||
self, paths: tp.Sequence[str], aliases: tp.Dict[str, str]
|
||||
) -> tp.Dict[str, tp.Any]:
|
||||
"""Update the cmds_cache variable in background without slowing down parseLexer"""
|
||||
env = XSH.env or {} # type: ignore
|
||||
|
||||
allcmds = {}
|
||||
for path in reversed(paths):
|
||||
# iterate backwards so that entries at the front of PATH overwrite
|
||||
# entries at the back.
|
||||
for cmd in executables_in(path):
|
||||
key = cmd.upper() if ON_WINDOWS else cmd
|
||||
allcmds[key] = (os.path.join(path, cmd), aliases.get(key, None))
|
||||
|
||||
for cmd, path in self._get_all_cmds(paths).items():
|
||||
key = cmd.upper() if ON_WINDOWS else cmd
|
||||
allcmds[key] = (path, aliases.get(key, None))
|
||||
|
||||
warn_cnt = env.get("COMMANDS_CACHE_SIZE_WARNING")
|
||||
if warn_cnt and len(allcmds) > warn_cnt:
|
||||
|
@ -185,6 +210,7 @@ class CommandsCache(cabc.Mapping):
|
|||
if cmd not in allcmds:
|
||||
key = cmd.upper() if ON_WINDOWS else cmd
|
||||
allcmds[key] = (cmd, True) # type: ignore
|
||||
|
||||
return self.set_cmds_cache(allcmds)
|
||||
|
||||
def get_cached_commands(self) -> tp.Dict[str, str]:
|
||||
|
|
|
@ -26,7 +26,6 @@ class Execer:
|
|||
filename="<xonsh-code>",
|
||||
debug_level=0,
|
||||
parser_args=None,
|
||||
unload=True,
|
||||
scriptcache=True,
|
||||
cacheall=False,
|
||||
):
|
||||
|
@ -50,7 +49,6 @@ class Execer:
|
|||
self.filename = filename
|
||||
self._default_filename = filename
|
||||
self.debug_level = debug_level
|
||||
self.unload = unload
|
||||
self.scriptcache = scriptcache
|
||||
self.cacheall = cacheall
|
||||
self.ctxtransformer = CtxAwareTransformer(self.parser)
|
||||
|
|
|
@ -8,21 +8,16 @@ import xonsh.platform as xp
|
|||
from xonsh.built_ins import XSH
|
||||
|
||||
|
||||
def _replace_home(x):
|
||||
if xp.ON_WINDOWS:
|
||||
home = XSH.env["HOMEDRIVE"] + XSH.env["HOMEPATH"][0]
|
||||
if x.startswith(home):
|
||||
x = x.replace(home, "~", 1)
|
||||
def _replace_home(x: str):
|
||||
home = os.path.expanduser("~")
|
||||
if x.startswith(home):
|
||||
x = x.replace(home, "~", 1)
|
||||
|
||||
if XSH.env.get("FORCE_POSIX_PATHS"):
|
||||
if xp.ON_WINDOWS:
|
||||
if XSH.env.get("FORCE_POSIX_PATHS") and os.altsep:
|
||||
x = x.replace(os.sep, os.altsep)
|
||||
|
||||
return x
|
||||
else:
|
||||
home = XSH.env["HOME"]
|
||||
if x.startswith(home):
|
||||
x = x.replace(home, "~", 1)
|
||||
return x
|
||||
return x
|
||||
|
||||
|
||||
def _replace_home_cwd():
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
import builtins
|
||||
import stat
|
||||
from collections import ChainMap
|
||||
from collections.abc import MutableMapping
|
||||
|
@ -268,7 +267,7 @@ def partial_color_tokenize(template):
|
|||
These sub-strings maybe templates themselves.
|
||||
"""
|
||||
if XSH.shell is not None:
|
||||
styles = __xonsh__.shell.shell.styler.styles
|
||||
styles = XSH.shell.shell.styler.styles
|
||||
else:
|
||||
styles = None
|
||||
color = Color.DEFAULT
|
||||
|
@ -1651,16 +1650,12 @@ class XonshLexer(Python3Lexer):
|
|||
def __init__(self, *args, **kwargs):
|
||||
# If the lexer is loaded as a pygment plugin, we have to mock
|
||||
# __xonsh__.env and __xonsh__.commands_cache
|
||||
if not hasattr(builtins, "__xonsh__"):
|
||||
from argparse import Namespace
|
||||
|
||||
builtins.__xonsh__ = Namespace()
|
||||
if not hasattr(XSH, "env"):
|
||||
XSH.env = {}
|
||||
if ON_WINDOWS:
|
||||
pathext = os_environ.get("PATHEXT", [".EXE", ".BAT", ".CMD"])
|
||||
XSH.env["PATHEXT"] = pathext.split(os.pathsep)
|
||||
if not getattr(XSH, "commands_cache", None):
|
||||
if getattr(XSH, "commands_cache", None) is None:
|
||||
XSH.commands_cache = CommandsCache()
|
||||
_ = XSH.commands_cache.all_commands # NOQA
|
||||
super().__init__(*args, **kwargs)
|
||||
|
|
|
@ -541,10 +541,12 @@ def get_line_continuation():
|
|||
mode on Windows the backslash must be preceded by a space. This is because
|
||||
paths on Windows may end in a backslash.
|
||||
"""
|
||||
if ON_WINDOWS and hasattr(xsh, "env") and xsh.env.get("XONSH_INTERACTIVE", False):
|
||||
return " \\"
|
||||
else:
|
||||
return "\\"
|
||||
if ON_WINDOWS:
|
||||
env = getattr(xsh, "env", None) or {}
|
||||
if env.get("XONSH_INTERACTIVE", False):
|
||||
return " \\"
|
||||
|
||||
return "\\"
|
||||
|
||||
|
||||
def get_logical_line(lines, idx):
|
||||
|
|
|
@ -434,7 +434,7 @@ class Vox(collections.abc.Mapping):
|
|||
|
||||
def _get_vox_default_interpreter():
|
||||
"""Return the interpreter set by the $VOX_DEFAULT_INTERPRETER if set else sys.executable"""
|
||||
default = "python"
|
||||
default = "python3"
|
||||
if default in XSH.commands_cache:
|
||||
default = XSH.commands_cache.locate_binary(default)
|
||||
else:
|
||||
|
|
Loading…
Add table
Reference in a new issue