mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 00:14:41 +01:00
xonsh script.xsh should not fail over
This commit is contained in:
parent
c3ece749c5
commit
335fc71bc7
5 changed files with 38 additions and 12 deletions
14
news/failover-script.rst
Normal file
14
news/failover-script.rst
Normal file
|
@ -0,0 +1,14 @@
|
|||
**Added:** None
|
||||
|
||||
**Changed:** None
|
||||
|
||||
**Deprecated:** None
|
||||
|
||||
**Removed:** None
|
||||
|
||||
**Fixed:**
|
||||
|
||||
* Fixed an issue that xonsh would fail over to external shells when
|
||||
running .xsh script which raises exceptions.
|
||||
|
||||
**Security:** None
|
1
tests/scripts/raise.xsh
Normal file
1
tests/scripts/raise.xsh
Normal file
|
@ -0,0 +1 @@
|
|||
raise Exception('oh no')
|
|
@ -9,6 +9,7 @@ import sys
|
|||
|
||||
import xonsh.main
|
||||
import pytest
|
||||
from tools import TEST_DIR
|
||||
|
||||
|
||||
def Shell(*args, **kwargs):
|
||||
|
@ -91,7 +92,7 @@ def test_xonsh_failback(shell, monkeypatch):
|
|||
assert failback_checker == ['/bin/xshell', '/bin/xshell']
|
||||
|
||||
|
||||
def test_xonsh_failback_non_interactive(shell, monkeypatch):
|
||||
def test_xonsh_failback_single(shell, monkeypatch):
|
||||
class FakeFailureError(Exception):
|
||||
pass
|
||||
|
||||
|
@ -103,3 +104,17 @@ def test_xonsh_failback_non_interactive(shell, monkeypatch):
|
|||
|
||||
with pytest.raises(FakeFailureError):
|
||||
xonsh.main.main()
|
||||
|
||||
|
||||
def test_xonsh_failback_script_from_file(shell, monkeypatch):
|
||||
checker = []
|
||||
def mocked_execlp(f, *args):
|
||||
checker.append(f)
|
||||
monkeypatch.setattr(os, 'execlp', mocked_execlp)
|
||||
|
||||
script = os.path.join(TEST_DIR, 'scripts', 'raise.xsh')
|
||||
monkeypatch.setattr(sys, 'argv', ['xonsh', script])
|
||||
monkeypatch.setattr(sys, 'stderr', open(os.devnull, 'w'))
|
||||
with pytest.raises(Exception):
|
||||
xonsh.main.main()
|
||||
assert len(checker) == 0
|
||||
|
|
|
@ -24,6 +24,7 @@ ON_DARWIN = (platform.system() == 'Darwin')
|
|||
ON_WINDOWS = (platform.system() == 'Windows')
|
||||
ON_CONDA = True in [conda in pytest.__file__ for conda
|
||||
in ['anaconda', 'miniconda']]
|
||||
TEST_DIR = os.path.dirname(__file__)
|
||||
|
||||
# pytest skip decorators
|
||||
skip_if_py34 = pytest.mark.skipif(VER_MAJOR_MINOR < VER_3_5, reason="Py3.5+ only test")
|
||||
|
|
|
@ -253,17 +253,11 @@ def premain(argv=None):
|
|||
return args
|
||||
|
||||
|
||||
def _failback_to_other_shells(argv, err):
|
||||
args = None
|
||||
try:
|
||||
args = premain(argv)
|
||||
except Exception:
|
||||
pass
|
||||
def _failback_to_other_shells(args, err):
|
||||
# only failback for interactive shell; if we cannot tell, treat it
|
||||
# as an interactive one for safe.
|
||||
if hasattr(args, 'mode') and args.mode != XonshMode.interactive:
|
||||
raise err
|
||||
|
||||
foreign_shell = None
|
||||
shells_file = '/etc/shells'
|
||||
if not os.path.exists(shells_file):
|
||||
|
@ -294,15 +288,16 @@ def _failback_to_other_shells(argv, err):
|
|||
|
||||
|
||||
def main(argv=None):
|
||||
args = None
|
||||
try:
|
||||
return main_xonsh(argv)
|
||||
except Exception as err:
|
||||
_failback_to_other_shells(argv, err)
|
||||
|
||||
|
||||
def main_xonsh(argv=None):
|
||||
"""Main entry point for xonsh cli."""
|
||||
args = premain(argv)
|
||||
return main_xonsh(args)
|
||||
except Exception as err:
|
||||
_failback_to_other_shells(args, err)
|
||||
|
||||
|
||||
def main_xonsh(args):
|
||||
"""Main entry point for xonsh cli."""
|
||||
events.on_post_init.fire()
|
||||
env = builtins.__xonsh_env__
|
||||
shell = builtins.__xonsh_shell__
|
||||
|
|
Loading…
Add table
Reference in a new issue