Repository: xonsh/xonsh

Issue:
bug: no error message in cd when $THREAD_SUBPROCS is False
<!--- Provide a general summary of the issue in the Title above -->
<!--- If you have a question along the lines of "How do I do this Bash command in xonsh"
please first look over the Bash to Xonsh translation guide: https://xon.sh/bash_to_xsh.html
If you don't find an answer there, please do open an issue! -->

## xonfig

<details>

```
+------------------+----------------------+
| xonsh            | 0.13.0               |
| Python           | 3.10.5               |
| PLY              | 3.11                 |
| have readline    | True                 |
| prompt toolkit   | 3.0.30               |
| shell type       | prompt_toolkit       |
| history backend  | json                 |
| pygments         | 2.12.0               |
| on posix         | True                 |
| on linux         | True                 |
| distro           | arch                 |
| on wsl           | False                |
| on darwin        | False                |
| on windows       | False                |
| on cygwin        | False                |
| on msys2         | False                |
| is superuser     | False                |
| default encoding | utf-8                |
| xonsh encoding   | utf-8                |
| encoding errors  | surrogateescape      |
| xontrib 1        | sh                   |
| xontrib 2        | cd                   |
| xontrib 3        | z                    |
| xontrib 4        | bashisms             |
| xontrib 5        | whole_word_jumping   |
| xontrib 6        | voxapi               |
| xontrib 7        | vox                  |
| RC file 1        | /home/user/.xonshrc |
+------------------+----------------------+
```
</details>

## Expected Behavior
<!--- Tell us what should happen -->
When I use `cd a_nonexistent_directory`, I expect the error message `cd: no such file or directory: a_nonexistent_directory`

## Current Behavior
<!--- Tell us what happens instead of the expected behavior -->
<!--- If part of your bug report is a traceback, please first enter debug mode before triggering the error
To enter debug mode, set the environment variable `XONSH_DEBUG=1` _before_ starting `xonsh`.
On Linux and OSX, an easy way to to do this is to run `env XONSH_DEBUG=1 xonsh` -->

I don't get any error message.  The return code is 1 but there is no message.
```
~ @ > cd a_non_existant_directory
~ [1] @ >
```
When I remove the load bashism in xonshrc and restart, I get back the expected behavior.
### Traceback (if applicable)


<details>

```
> cd a_nonexistent_directory
--- before precommand event
+++ after precommand event
@@ -1 +1 @@
-cd a_nonexistent_directory
+cd! a_nonexistent_directory
<stdin>:1:2:28 - cd! a_nonexistent_directory
<stdin>:1:2:28 + ![cd! a_nonexistent_directory]
```
</details>

## Steps to Reproduce
<!--- Please try to write out a minimal reproducible snippet to trigger the bug, it will help us fix it! -->

## For community
⬇️  **Please click the 👍 reaction instead of leaving a `+1` or 👍  comment**



Discussion:
After further investigation it seems that it is not due to bashisms at all sorry. 
I removed and readded things in my xonshrc and found out that it was due to the way I started X in xonshrc (linked possibly to https://github.com/xonsh/xonsh/issues/1156).

I don't know why but at some point, removing bashism also solved the issue but this must be due to some weird combination I guess.

**EDIT:** In the end, the problem reappeared even when doing startx by hand so for now I don't know what causes the problem. If anyone have an idea, please tell me. I also don't get error messages with other commands.
For information, here is my xonshrc:

<details>

```   
$COMMANDS_CACHE_SIZE_WARNING = 10000

from xonsh.tools import register_custom_style
import time


mystyle = {
    "CYAN": "#00cccc",
    "Token.PTK.Aborting ": "#ffffff",
    "Token.PTK.AutoSuggestion": "#64baff",
    "Token.PTK.CompletionMenu": "#ffffff",
    "Token.PTK.CompletionMenu.Completion": "#ffffff",
    "Token.PTK.CompletionMenu.Completion.Current": "#ffffff",
    "BOLD_INTENSE_CYAN": "#00cccc"
}


$XONSH_STYLE_OVERRIDES["Token.Literal.String.Single"] = "#00ff00" 
$XONSH_STYLE_OVERRIDES["completion-menu"] = "bg:#000000 #fff" 
$XONSH_STYLE_OVERRIDES["Token.PTK.CompletionMenu.Completion.Current"] = "bg:#555555 #fff"

register_custom_style("mystyle", mystyle, base="rrt")
$XONSH_COLOR_STYLE="mystyle"

def _field_date_time_tz():
    t = time.strftime('%H:%M', time.localtime())
    return t
__xonsh__.env['PROMPT_FIELDS']['date_time'] = _field_date_time_tz
$PROMPT = '{CYAN}{user}@{hostname}{CYAN} {date_time} {cwd}{RESET} {BOLD_CYAN}{last_return_code_if_nonzero:[{BOLD_INTENSE_CYAN}{}{CYAN}] }{RESET}\n@ >'

$XONTRIB_SH_SHELLS = ['bash', 'sh', 'zsh']  # defauls
$COMPLETIONS_DISPLAY = 'readline'

$SHELL_TYPE = 'prompt-toolkit'
$COMPLETIONS_MENU_ROWS = 10
$COMPLETIONS_DISPLAY = 'multi'
$AUTO_SUGGEST_IN_COMPLETIONS=True
$XONSH_HISTORY_MATCH_ANYWHERE = True
$COMPLETIONS_CONFIRM = True

$COMMANDS_CACHE_SAVE_INTERMEDIATE = True
$PROMPT_TOOLKIT_COLOR_DEPTH="DEPTH_8_BIT"
$XONSH_SHOW_TRACEBACK = True


$LS_COLORS='no=00:rs=0:fi=00:di=01;34:ln=36:mh=04;36:pi=04;01;36:so=04;33:do=04;01;36:bd=01;33:cd=33:or=31:mi=01;37;41:ex=01;36:su=01;04;37:sg=01;04;37:ca=01;37:tw=01;37;44:ow=01;04;34:st=04;37;44:*.7z=01;32:*.ace=01;32:*.alz=01;32:*.arc=01;32:*.arj=01;32:*.bz=01;32:*.bz2=01;32:*.cab=01;32:*.cpio=01;32:*.deb=01;32:*.dz=01;32:*.ear=01;32:*.gz=01;32:*.jar=01;32:*.lha=01;32:*.lrz=01;32:*.lz=01;32:*.lz4=01;32:*.lzh=01;32:*.lzma=01;32:*.lzo=01;32:*.rar=01;32:*.rpm=01;32:*.rz=01;32:*.sar=01;32:*.t7z=01;32:*.tar=01;32:*.taz=01;32:*.tbz=01;32:*.tbz2=01;32:*.tgz=01;32:*.tlz=01;32:*.txz=01;32:*.tz=01;32:*.tzo=01;32:*.tzst=01;32:*.war=01;32:*.xz=01;32:*.z=01;32:*.Z=01;32:*.zip=01;32:*.zoo=01;32:*.zst=01;32:*.aac=32:*.au=32:*.flac=32:*.m4a=32:*.mid=32:*.midi=32:*.mka=32:*.mp3=32:*.mpa=32:*.mpeg=32:*.mpg=32:*.ogg=32:*.opus=32:*.ra=32:*.wav=32:*.3des=01;35:*.aes=01;35:*.gpg=01;35:*.pgp=01;35:*.doc=32:*.docx=32:*.dot=32:*.odg=32:*.odp=32:*.ods=32:*.odt=32:*.otg=32:*.otp=32:*.ots=32:*.ott=32:*.pdf=32:*.ppt=32:*.pptx=32:*.xls=32:*.xlsx=32:*.app=01;36:*.bat=01;36:*.btm=01;36:*.cmd=01;36:*.com=01;36:*.exe=01;36:*.reg=01;36:*~=02;37:*.bak=02;37:*.BAK=02;37:*.log=02;37:*.log=02;37:*.old=02;37:*.OLD=02;37:*.orig=02;37:*.ORIG=02;37:*.swo=02;37:*.swp=02;37:*.bmp=32:*.cgm=32:*.dl=32:*.dvi=32:*.emf=32:*.eps=32:*.gif=32:*.jpeg=32:*.jpg=32:*.JPG=32:*.mng=32:*.pbm=32:*.pcx=32:*.pgm=32:*.png=32:*.PNG=32:*.ppm=32:*.pps=32:*.ppsx=32:*.ps=32:*.svg=32:*.svgz=32:*.tga=32:*.tif=32:*.tiff=32:*.xbm=32:*.xcf=32:*.xpm=32:*.xwd=32:*.xwd=32:*.yuv=32:*.anx=32:*.asf=32:*.avi=32:*.axv=32:*.flc=32:*.fli=32:*.flv=32:*.gl=32:*.m2v=32:*.m4v=32:*.mkv=32:*.mov=32:*.MOV=32:*.mp4=32:*.mpeg=32:*.mpg=32:*.nuv=32:*.ogm=32:*.ogv=32:*.ogx=32:*.qt=32:*.rm=32:*.rmvb=32:*.swf=32:*.vob=32:*.webm=32:*.wmv=32:'


$XONSH_HISTORY_SIZE = (100000, 'commands')
$HISTFILE='~/.zhistory'

xontrib load sh
# # Example : ! ls *.{tex,aux}

xontrib load cd
xontrib load core
xontrib load whole_word_jumping

xontrib load bashisms

xontrib load vox
aliases['ls']='/bin/ls --color'
```

<\details>
What is `xontrib load cd` doing?
https://xon.sh/xontribs.html#cd
Does the error persist if you don't load that `xontrib`?
Yes, the error is still there.
What about if you start `xonsh` with the `--no-rc` flag?
Yes, with `--no-rc` it works, I have the error message. 
This issue occurs because `bashisms` sets `$THREAD_SUBPROCS=False`.

Without loading `bashisms`, when I start `xonsh --no-rc` and then set `$THREAD_SUBPROCS=False`, I can reproduce the issue.

Resolving patch:
diff --git a/xonsh/procs/specs.py b/xonsh/procs/specs.py
--- a/xonsh/procs/specs.py
+++ b/xonsh/procs/specs.py
@@ -737,7 +737,9 @@ def _update_last_spec(last):
         return
     callable_alias = callable(last.alias)
     if callable_alias:
-        pass
+        if last.cls is ProcProxy and captured == "hiddenobject":
+            # a ProcProxy run using ![] should not be captured
+            return
     else:
         cmds_cache = XSH.commands_cache
         thable = (


Test patch:
diff --git a/tests/procs/test_specs.py b/tests/procs/test_specs.py
--- a/tests/procs/test_specs.py
+++ b/tests/procs/test_specs.py
@@ -166,3 +166,18 @@ def __call__(self, *args, **kwargs):
     spec = cmds_to_specs(cmds, captured="stdout")[0]
     proc = spec.run()
     assert proc.f == obj
+
+
+@pytest.mark.parametrize("captured", ["hiddenobject", False])
+def test_procproxy_not_captured(xession, captured):
+    xession.aliases["tst"] = lambda: 0
+    cmds = (["tst", "/root"],)
+
+    xession.env["THREAD_SUBPROCS"] = False
+    specs = cmds_to_specs(cmds, captured)
+
+    assert specs[0].cls is ProcProxy
+
+    # neither stdout nor stderr should be captured
+    assert specs[0].stdout is None
+    assert specs[0].stderr is None