关于Pip安装包和Python版本的问题(在Unix上)

93 阅读2分钟

假设,不是假设,你想安装pyls,一个Python的LSP服务器,这样你就可以和(例如)GNU Emacs的lsp-mode一起使用它。Pyls 可能没有为你的 Unix 打包(它不在 Fedora 或 Ubuntu 上),但你可以用 Pip 安装它(因为它在 PyPi 上),可以用 'sudo pip install' 来安装它的系统范围(这可能与你的软件包管理器冲突),或者用 'pip install --user' 来安装它,只为你。

(如果这是一台共享的Unix机器,你可能需要做后者)。

然后你升级你的Unix版本(或者它被升级),例如从Fedora 31升级到Fedora 32。突然间,pyls 程序不再工作了,更令人费解的是,'pip list --user' 甚至没有列出任何东西。这就好像你个人安装的pyls被升级后抹去了一样。

现在的情况是pip 在一个特定于 Python 小版本的路径下安装东西,当小版本在升级中改变时,新版本的 Python 找不到你的旧包,因为它在一个不同的地方寻找。Fedora 31有Python 3.7,它希望在~/.local/lib/python3.7/Site-packages中找到你的个人软件包,pip把它们放在那里。 Fedora 32有Python 3.8,它希望在~/.local/lib/python3**.8/Site-packages**中找到同样的软件包,而忽略了python3.7/Site-packages中的版本。

(同样的事情发生在Ubuntu上,18.04 LTS有3.6.9,20.04 LTS有3.8.5)。

就我所知,没有好的办法解决这个问题。如果你用 "sudo pip install"在全系统范围内安装东西,也会发生同样的情况(我希望你记下你通过pip安装的东西和系统已经放在那里的东西)。我认为如果你把 pyls 放到 venv 中也会发生这种情况,因为venvs 通常使用系统的 Python并继承这个特定版本的站点包目录。

(有一个 'python3 -m venv --upgrade <dir>' venv 命令可以升级 venv 中的 Python 版本,但是看一下代码,它并没有做任何事情来把已经安装的软件包迁移到新版本上。不过我不能测试这个,所以也许我错过了什么)。

我个人的解决方案是将~/.local/lib/python3.7目录重命名为 "python3.8"。Pip似乎对这个结果很满意,pyls也是如此。更正确的方法可能是从头开始,重新安装所有软件包和程序,比如pyls。

(这是对我的一条推文的阐述。在发推文的时候,我还没有意识到这基本上适用于所有使用pip来安装东西的情况,而不仅仅是 "pip --user")。