lsp-python-ms补全python2虚拟环境的方案

最近远程办公,办公环境迁移到macOS,配置mspyls+python2+virtualenv时候发现了一些问题.

我本地python虚拟环境一直使用的方案是pyenv+pyenv-virtualenv,由于公司项目还是python2,所以我的虚拟环境相当于是用virtualenv创建的.

我发现用virtualenv创建出来的python2虚拟环境激活mspyls会报错:

Traceback (most recent call last):
  File "/Users/test/Projects/python-language-server/output/bin/Release/osx-x64/publish/get_search_paths.py", line 31, in <module>
    import site
  File "/Users/test/.pyenv/versions/Py2Ansible/lib/python2.7/site.py", line 165, in <module>
    main()
  File "/Users/test/.pyenv/versions/Py2Ansible/lib/python2.7/site.py", line 19, in main
    load_host_site()
  File "/Users/test/.pyenv/versions/Py2Ansible/lib/python2.7/site.py", line 54, in load_host_site
    full_path = os.path.abspath(os.path.join(here, path.encode("utf-8")))
LookupError: no codec search functions registered: can't find encoding

但是创建出来的python3虚拟环境就不会:

/Users/test/.pyenv/versions/3.8.1/lib/python3.8|stdlib|
/Users/test/.pyenv/versions/3.8.1/lib/python3.8/lib-dynload|stdlib|
/Users/test/.pyenv/versions/Ansible/lib/python3.8/site-packages|site|

目前定位到是virtualenv创建python2虚拟环境利用site.py文件去定位系统库,但是mspyls寻找补全库路径会使用python -S -E参数导致虚拟环境中的python2找不到系统库…

期间尝试了解释器直接配置python2然后配置lsp-python-ms-extra-paths增加虚拟环境的site-packages目录没有成功.

目前使用了规避方案,使用minicoda+conda create --name Test python=2.7 pip的方式创建虚拟环境,然后在Emacs中激活conda的虚拟环境可以补全第三方库… 不过目前项目中的导入还不行…应该是项目根目录配置问题,应该就比较好解决了.

现在都推荐用 venv。另外你正确设置 lsp-python-ms-python-executable-cmdlsp-python-ms-extra-paths了吗?

venv不支持python2吧. lsp-python-ms-python-executable-cmd设置为创建虚拟环境的python2时可以补全系统库了,但是虚拟环境的库找不到,我试着把虚拟环境中的site-packages加到lsp-python-ms-extra-paths然后重启lsp,还是找不到.

1赞

pyenv 可以试试我这个包:https://github.com/twlz0ne/shim.el

现在还在用 Python2 啊,该升级啦~~~

如果一定要用 virtualenv,需要改下 lsp-python-ms-locate-python。你看看就明白了。因为我没有用 virtualenv,所以没法测试。你可以提个 PR。

我刚才试了一下,我的elisp不行,硬编码测试了一下.

我把lsp-python-ms-locate-python硬编码返回虚拟环境中的python,用于提取三方包的路径. 然后再硬编码了lsp-python-ms--get-python-ver-and-syspath返回的python为创建虚拟环境的python2解释器.

结果返回是在searchPaths中有了虚拟环境中装的三方包路径,但是lsp还是找不到这些包…

我试试看,不过我这个问题不是解释器指向不对,而是virtualenv创建的python2环境的问题.

我最近遇到了相同的错误。 看起来根本原因是virtualenv 20

我通过重新安装virtualenv来修复它:

rm -rf ~/.virtualenv/python2
sudo python2.7 -m pip install "virtualenv<20"
python2.7 -m virtualenv -p /usr/bin/python2.7 ~/.virtualenv/python2

virtualenv 20改了实现逻辑吗?

我不确定,但也许他们正在放弃python2支持。

看这个

renat@LAPTOP-LCN5ROS8:~$ python2 -m virtualenv --version
virtualenv 20.1.0 from /usr/local/lib/python2.7/dist-packages/virtualenv/__init__.pyc
renat@LAPTOP-LCN5ROS8:~$ python2 -m virtualenv --quiet -p /usr/bin/python2.7 venv20
renat@LAPTOP-LCN5ROS8:~$ source venv20/bin/activate
(venv20) renat@LAPTOP-LCN5ROS8:~$ python -S -c 'import site'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/renat/venv20/lib/python2.7/site.py", line 164, in <module>
    main()
  File "/home/renat/venv20/lib/python2.7/site.py", line 19, in main
    load_host_site()
  File "/home/renat/venv20/lib/python2.7/site.py", line 54, in load_host_site
    full_path = os.path.abspath(os.path.join(here, path.encode("utf-8")))
LookupError: no codec search functions registered: can't find encoding
(venv20) renat@LAPTOP-LCN5ROS8:~$ deactivate
renat@LAPTOP-LCN5ROS8:~$ sudo pip install -q 'virtualenv<20'
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
renat@LAPTOP-LCN5ROS8:~$ python2 -m virtualenv --version
16.7.10
renat@LAPTOP-LCN5ROS8:~$ python2 -m virtualenv --quiet -p /usr/bin/python2.7 venv16
Already using interpreter /usr/bin/python2.7
renat@LAPTOP-LCN5ROS8:~$ source venv16/bin/activate
(venv16) renat@LAPTOP-LCN5ROS8:~$ python -S -c 'import site'
(venv16) renat@LAPTOP-LCN5ROS8:~$

请问你是用虚拟环境做隔离还是就用系统解释器,Centaur emacs用虚拟环境方便吗?

我是直接用的系统环境,用虚拟环境没有多大区别,自行设置就好。

看了lsp-pyright的文档,可以对 lsp-pyright-venv-path变量作定制,应该就是设置虚拟环境的