Repository: xonsh/xonsh

Issue:
Build using Nuitka
Just wondering... did anyone ever try to build Xonsh using Nuitka?
I noticed that for some CLI applications, building it with Nuitka gives a statically linked binary with an improved start-up time as well.

I tried it as follows:
```sh
python -O -m nuitka --follow-imports ./scripts/xonsh 
```
This creates a "xonsh.bin" executable of about 28M.
I works mostly here, but doesn't give me the prompt_toolkit shell. I tried it for pyvim, where it works great.

@scopatz ?

You can close this issue. I only wanted to share the idea.


Discussion:
Hey @jonathanslenders -- thanks for the suggestion!  I think there's probably a bunch of users who could benefit from this.  I'll try to see if I can get it to start up the `prompt_toolkit` backend.
This is an awesome idea @jonathanslenders - thanks!  I think we'll keep this open until we figure out if this is feasible.  I am curious how Nuitka compares to Cython.  But it certainly seems to handle the "app" idea better.
Wow, it doesn't seem to like lazyasd at all
After a year I've tried to run this again:

<details>

```python
python3 -O -m nuitka --follow-imports /xonsh/scripts/xonsh
xonsh
#Traceback (most recent call last):
#  File "/usr/local/lib/python3.6/dist-packages/xonsh/main.py", line 404, in main
#    args = premain(argv)
#  File "/usr/local/lib/python3.6/dist-packages/xonsh/main.py", line 357, in premain
#    env = start_services(shell_kwargs, args)
#  File "/usr/local/lib/python3.6/dist-packages/xonsh/main.py", line 283, in start_services
#    execer = Execer(
#  File "/usr/local/lib/python3.6/dist-packages/xonsh/execer.py", line 63, in __init__
#    load_builtins(execer=self, ctx=xonsh_ctx)
#  File "/usr/local/lib/python3.6/dist-packages/xonsh/built_ins.py", line 1300, in load_builtins
#    builtins.__xonsh__.load(execer=execer, ctx=ctx)
#  File "/usr/local/lib/python3.6/dist-packages/xonsh/built_ins.py", line 1372, in load
#    self.env = Env(default_env())
#  File "/usr/local/lib/python3.6/dist-packages/xonsh/environ.py", line 1770, in default_env
#    ctx = dict(BASE_ENV)
#  File "/usr/local/lib/python3.6/dist-packages/xonsh/lazyasd.py", line 54, in __getattribute__
#    obj = self._lazy_obj()
#  File "/usr/local/lib/python3.6/dist-packages/xonsh/lazyasd.py", line 53, in __getattribute__
#    return super().__getattribute__(name)
#AttributeError: 'method-wrapper' object has no attribute '_lazy_obj'
#Xonsh encountered an issue during launch
#Failback to /bin/sh
 
# Prepared by xontrib-hist-format
```

</details>
May be lazyasd is not needed in nuitka bin and it could be switched off?
Yeah, we could try to do that
Is there anyway to know that nukita is running?
I have opened https://github.com/Nuitka/Nuitka/issues/650
_Originally posted by @anki-code in https://github.com/Nuitka/Nuitka/issues/650#issuecomment-605450552_

> I've found a way how to build static linked binary portable python app using Nuitka. Docker example you can find in https://github.com/xxh/xxh-portable . The main feature is avoiding using glibc and use static linked musle libc instead. It works on many linux.
>
>If anybody can suggest workaround for the lazyasd exception I'll be happy to try build xonsh using this technique.



Resolving patch:
diff --git a/xonsh/environ.py b/xonsh/environ.py
--- a/xonsh/environ.py
+++ b/xonsh/environ.py
@@ -16,7 +16,7 @@
 import typing as tp
 
 from xonsh import __version__ as XONSH_VERSION
-from xonsh.lazyasd import LazyObject, lazyobject
+from xonsh.lazyasd import lazyobject
 from xonsh.codecache import run_script_with_cache
 from xonsh.dirstack import _get_cwd
 from xonsh.events import events
@@ -2218,17 +2218,6 @@ def locate_binary(name):
     return builtins.__xonsh__.commands_cache.locate_binary(name)
 
 
-BASE_ENV = LazyObject(
-    lambda: {
-        "BASH_COMPLETIONS": list(DEFAULT_VARS["BASH_COMPLETIONS"].default),
-        "PROMPT_FIELDS": dict(DEFAULT_VARS["PROMPT_FIELDS"].default),
-        "XONSH_VERSION": XONSH_VERSION,
-    },
-    globals(),
-    "BASE_ENV",
-)
-
-
 def xonshrc_context(rcfiles=None, execer=None, ctx=None, env=None, login=True):
     """Attempts to read in all xonshrc files and return the context."""
     loaded = env["LOADED_RC_FILES"] = []
@@ -2296,7 +2285,11 @@ def xonsh_script_run_control(filename, ctx, env, execer=None, login=True):
 def default_env(env=None):
     """Constructs a default xonsh environment."""
     # in order of increasing precedence
-    ctx = dict(BASE_ENV)
+    ctx = {
+        "BASH_COMPLETIONS": list(DEFAULT_VARS["BASH_COMPLETIONS"].default),
+        "PROMPT_FIELDS": dict(DEFAULT_VARS["PROMPT_FIELDS"].default),
+        "XONSH_VERSION": XONSH_VERSION,
+    }
     ctx.update(os_environ)
     ctx["PWD"] = _get_cwd() or ""
     # These can cause problems for programs (#2543)


Test patch: