swyddfa/esbonio

Breaks if `esbonio` is installed globally

neongreen-sc opened this issue · 7 comments

Expected behavior

If global python has esbonio installed, it should either be ignored or I should get an error message.

Actual behavior

Esbonio cannot start the server.

Log output

[esbonio] Unable to import module 'esbonio.server.features.preview_manager'
Traceback (most recent call last):
  File "c:\workspace\python-3.11.2\Lib\site-packages\esbonio\server\setup.py", line 123, in _load_module
    module = importlib.import_module(modname)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "importlib\__init__.py", line 126, in import_module
  File "<frozen importlib._bootstrap>", line 1206, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "c:\workspace\python-3.11.2\Lib\site-packages\esbonio\server\features\preview_manager\__init__.py", line 18, in <module>
    from .webview import WebviewServer
  File "c:\workspace\python-3.11.2\Lib\site-packages\esbonio\server\features\preview_manager\webview.py", line 13, in <module>
    from websockets.server import serve
ModuleNotFoundError: No module named 'websockets'

(Optional) Settings from conf.py

No response

NB: this is for the prerelease version (0.92.1)

I can't think of why this might be happening since the extension does try to ensure that the bundled version of esbonio is used. (By running python -S and using the PYTHONPATH environment variable to make the relevant dependencies available)

Could you add a file called test.py to the root of your workspace that contains

import sys
print(sys.path, file=sys.stderr)

and set esbonio.server.startupModule to test.py before running the Esbonio: Restart Language Server command.

You'll get a bunch of errors, but you should also see the contents of sys.path in the Output window e.g.

[client] Starting Language Server
['/var/home/alex/Projects/swyddfa/esbonio/develop/docs', '/var/home/alex/Projects/swyddfa/esbonio/develop/code/bundled/libs', '/usr/lib64/python312.zip', '/usr/lib64/python3.12', '/usr/lib64/python3.12/lib-dynload']
[Error - 19:52:42] Server process exited with code 0.

We should then at least be able to see where Python is looking for esbonio and work backwards from there.

@alcarney done!

['c:\\workspace\\python-3.11.2\\python311.zip', 'c:\\workspace\\python-3.11.2', 'c:\\workspace\\python-3.11.2\\Lib\\site-packages']

This corresponds to the python interpreter I chose in VSCode.

I also printed os.environ and it does look like PYTHONPATH is set correctly:

'PYTHONPATH': 'c:\\Users\\[username]\\.vscode\\extensions\\swyddfa.esbonio-0.92.1\\bundled\\libs'

Oh wait, right.

I forgot that our org ships a broken version of Python that does not respect $PYTHONPATH.

Yeah that would explain it.

Do you know if there's any way to initialize sys.path manually that wouldn't involve forking the VSCode extension?

Umm... we could probably do it here in test.py and start the server ourselves...

I think something like the following would work

import os
import sys

sys.path.insert(0, os.environ['PYTHONPATH'])

from esbonio.server.cli import main

sys.exit(main())

I will close this issue, because there's nothing esbonio can do with broken python.