首先了解一些背景信息...
我正在尝试建立一个 JupyterLab 环境,在其中我可以(相当无缝地)在 Python 内核之间进行更改以评估代码性能。目标内核将是标准 CPython(Python 3 - 主要是最新版本)和 PyPy。我正在使用 conda 来管理我的环境。
我已经设置了一个 JupyterLab 环境(在基础 conda 环境中安装 JupyterLab),并通过基于不同的 CPython 版本创建各种 conda 环境(其中我也安装了 ipykernel),我可以轻松更改 JupyterLab 中的运行时内核。到目前为止一切顺利。
因此,要完成这项工作,我只需要在 conda 中创建一个 PyPy 环境(按照 PyPy 说明)并在其中安装
ipykernel
。这似乎是不可能做到的。
我的期望是,按照 PyPy 说明 创建一个 PyPy 环境,向其中添加 ipykernel,然后我将能够在 JupyterLab 中切换到基于 PyPy 的内核(正如我在 CPython 环境中成功完成的那样)。我的期望没有达到!
我首先在 conda 中创建一个 PyPy 环境:
conda config --set channel_priority strict
conda create -c conda-forge -n pypy-env pypy python=3.8
这需要一段时间,但似乎有效:
(base) PS C:\Windows\system32> conda env list
# conda environments:
#
base * C:\tools\miniconda3
py-311 C:\tools\miniconda3\envs\py-311
pypy-env C:\tools\miniconda3\envs\pypy-env
(base) PS C:\Windows\system32> conda activate pypy-env
(pypy-env) PS C:\Windows\system32> python --version
Python 3.8.16 | packaged by conda-forge | (a9dbdca6, May 11 2023, 16:56:34)
[PyPy 7.3.11 with MSC v.1929 64 bit (AMD64)]
尝试添加 ipykernel(在 JupyterLab 中启用内核切换所必需的)在经过一番激烈的尝试后失败了,并突出显示了许多冲突(为方便起见缩写):
(pypy-env) PS C:\Windows\system32> conda install ipykernel
Collecting package metadata (current_repodata.json): done
Solving environment: failed with initial frozen solve. Retrying with flexible solve.
Solving environment: failed with repodata from current_repodata.json, will retry with next repodata source.
Collecting package metadata (repodata.json): done
Solving environment: failed with initial frozen solve. Retrying with flexible solve.
Solving environment: -
Found conflicts! Looking for incompatible packages.
This can take several minutes. Press CTRL-C to abort.
failed
UnsatisfiableError: The following specifications were found to be incompatible with each other:
Output in format: Requested package -> Available versions
Package ca-certificates conflicts for:
pip -> python[version='>=2.7,<2.8.0a0'] -> ca-certificates
python=3.8 -> openssl[version='>=3.0.8,<4.0a0'] -> ca-certificates
...
...
Package six conflicts for:
ipykernel -> packaging -> six
pip -> html5lib -> six[version='>=1.9']
Note that strict channel priority may have removed packages required for satisfiability.
尽管 PyPy 建议,但
strict
通道优先级似乎会导致问题。将其从 strict
设置回默认值 flexible
(pypy-env) PS C:\Windows\system32> conda config --set channel_priority flexible
(pypy-env) PS C:\Windows\system32>
实现看似令人满意的安装:
(pypy-env) PS C:\Windows\system32> conda install ipykernel
Collecting package metadata (current_repodata.json): done
Solving environment: done
...
...
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
Retrieving notices: ...working... done
但是,启动 JupyterLab (JL) 并选择新的 pypy-env 内核失败,JL 日志证实:
CONDA_PREFIX=C:\tools\miniconda3
C:\tools\miniconda3\envs\pypy-env\lib\site-packages\jupyter_client\__init__.py:23: UserWarning: Could not import submodules
warnings.warn("Could not import submodules")
Traceback (most recent call last):
File "C:\tools\miniconda3\envs\pypy-env\Lib\runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\tools\miniconda3\envs\pypy-env\Lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "C:\tools\miniconda3\envs\pypy-env\lib\site-packages\ipykernel_launcher.py", line 15, in <module>
from ipykernel import kernelapp as app
File "C:\tools\miniconda3\envs\pypy-env\lib\site-packages\ipykernel\__init__.py", line 5, in <module>
from .connect import * # noqa
File "C:\tools\miniconda3\envs\pypy-env\lib\site-packages\ipykernel\connect.py", line 12, in <module>
from jupyter_client import write_connection_file
ImportError: cannot import name 'write_connection_file' from 'jupyter_client' (C:\tools\miniconda3\envs\pypy-env\lib\site-packages\jupyter_client\__init__.py)
将 JL 内核更改为 CPython conda 环境(除了 JL 日志中的一些警告)似乎工作正常(并在笔记本中正确执行代码):
CONDA_PREFIX=C:\tools\miniconda3
This version of python seems to be incorrectly compiled
(internal generated filenames are not absolute).
This may make the debugger miss breakpoints.
Related bug: http://bugs.python.org/issue1666807
[I 2023-06-30 18:35:24.069 ServerApp] Connecting to kernel 834d68cd-6153-4f99-9beb-ded2e414bc14.
[I 2023-06-30 18:35:24.088 ServerApp] Connecting to kernel 834d68cd-6153-4f99-9beb-ded2e414bc14.
[I 2023-06-30 18:35:24.111 ServerApp] Connecting to kernel 834d68cd-6153-4f99-9beb-ded2e414bc14.
因此,总而言之,遵循 PyPy 的
strict
conda 通道优先级建议将导致无法安装 ipykernel
。忽略 PyPy 关于 conda 通道优先级的建议并坚持使用 flexible
默认值可以实现看似成功的安装,但实际上无法操作(至少在 ipykernel
和 JupyterLab 的上下文中)。
有人对如何纠正这种情况并启用与
ipykernel
和 JupyterLab 一起使用的 PyPy 功能安装有任何建议吗?
好的,根据 mattip 的建议,我检查了 pypy 环境中已安装的软件包列表,发现并非所有软件包都来自
conda-forge
。因此我删除了环境并重新开始。在构建新环境之前,我检查了我的 .condarc 文件内容:
channel_priority: flexible
并且 conda 通过
conda info
: 使用频道 URL
channel URLs :
https://repo.anaconda.com/pkgs/main/win-64
https://repo.anaconda.com/pkgs/main/noarch
https://repo.anaconda.com/pkgs/r/win-64
https://repo.anaconda.com/pkgs/r/noarch
https://repo.anaconda.com/pkgs/msys2/win-64
https://repo.anaconda.com/pkgs/msys2/noarch
和
default channels
通过 conda config --show
:
default_channels:
- https://repo.anaconda.com/pkgs/main
- https://repo.anaconda.com/pkgs/r
- https://repo.anaconda.com/pkgs/msys2
这一次,我确保在环境创建的每个阶段都强制使用 conda-forge 通道:
(base) PS C:\Windows\system32> conda create -c conda-forge --name pypy-env pypy python=3.8
(base) PS C:\Windows\system32> conda activate pypy-env
(pypy-env) PS C:\Windows\system32> conda install -c conda-forge ipykernel
初始环境创建命令专门安装了
conda-forge
源包。然而,当我安装 ipykernel
时,jupyter_core有一个例外:
jupyter_client conda-forge/noarch::jupyter_client-8.3.0-pyhd8ed1ab_0
jupyter_core pkgs/main/win-64::jupyter_core-5.3.0-py38haa95532_0
libsodium conda-forge/win-64::libsodium-1.0.18-h8d14728_1
尽管如此,这种方法还是有效的。我随后运行了 jupyterlab,并且可以成功选择我的 pypy-env 环境并在其中运行代码。
成功!
此练习产生了一些进一步的问题,但这些问题可以针对单独的帖子
就个人而言,我的
.condarc
文件仅指向 conda-forge 通道,并设置为 strict
,以便它不会从其他通道拉取。但是,另一种方法是创建本地 .condarc
文件。
conda create -c conda-forge -n PyPyEnv pypy python=3.8
miniforge3/envs/PyPyEnv/.condarc
channels:
- conda-forge
channel_priority: strict
从现在开始,您在此环境中安装的任何内容都将从 conda-forge 中提取,除非您特别引用另一个频道。但是,其他环境不会受到影响。