PyPy运行ensurepip出错

2024-06-21
2分钟阅读时长

提前剧透,这是一个只会在互联网阴暗角落才能找到的问题及其解决方案,想要复现你可能得在Windows下挂载一个RamDisk。

环境相关

  • Windows 11 22H2
  • PyPy 7.3.16(通过Scoop全局安装)
  • RamDisk内存盘(通过ImDisk ToolKit挂载)

复现过程

  1. 设置 TEMP环境变量到 R:\Temp
  2. 运行命令:
pypy -m ensurepip
  1. 成功地报错了,报错信息:
ERROR: Exception:
Traceback (most recent call last):
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_vendor\pkg_resources\__init__.py", line 2347, in _normalize_cached
    return _cache[filename]
KeyError: 'R:\\Temp\\tmpf1fwghql\\setuptools-65.5.0-py3-none-any.whl'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\ProgramData\scoop\apps\pypy3\current\Lib\ntpath.py", line 691, in realpath
    path = _getfinalpathname(path)
OSError: [WinError 0] 鎿嶄綔鎴愬姛瀹屾垚銆? 'R:\\Temp\\tmpf1fwghql\\setuptools-65.5.0-py3-none-any.whl'


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_internal\cli\base_command.py", line 160, in exc_logging_wrapper
    status = run_func(*args)
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_internal\cli\req_command.py", line 247, in wrapper
    return func(self, options, args)
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_internal\commands\install.py", line 345, in run
    session = self.get_default_session(options)
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_internal\cli\req_command.py", line 98, in get_default_session
    self._session = self.enter_context(self._build_session(options))
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_internal\cli\req_command.py", line 125, in _build_session
    session = PipSession(
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_internal\network\session.py", line 343, in __init__
    self.headers["User-Agent"] = user_agent()
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_internal\network\session.py", line 175, in user_agent
    setuptools_dist = get_default_environment().get_distribution("setuptools")
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_internal\metadata\__init__.py", line 75, in get_default_environment
    return select_backend().Environment.default()
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_internal\metadata\__init__.py", line 63, in select_backend
    from . import pkg_resources
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_internal\metadata\pkg_resources.py", line 8, in <module>
    from pip._vendor import pkg_resources
  File "<frozen importlib._bootstrap>", line 1078, in _handle_fromlist
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_vendor\pkg_resources\__init__.py", line 3252, in <module>
    def _initialize_master_working_set():
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_vendor\pkg_resources\__init__.py", line 3235, in _call_aside
    f(*args, **kwargs)
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_vendor\pkg_resources\__init__.py", line 3277, in _initialize_master_working_set
    tuple(
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_vendor\pkg_resources\__init__.py", line 3278, in <genexpr>
    dist.activate(replace=False)
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_vendor\pkg_resources\__init__.py", line 2780, in activate
    self.insert_on(path, replace=replace)
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_vendor\pkg_resources\__init__.py", line 2896, in insert_on
    npath = [(p and _normalize_cached(p) or p) for p in path]
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_vendor\pkg_resources\__init__.py", line 2896, in <listcomp>
    npath = [(p and _normalize_cached(p) or p) for p in path]
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_vendor\pkg_resources\__init__.py", line 2349, in _normalize_cached
    _cache[filename] = result = normalize_path(filename)
  File "R:\Temp\tmpf1fwghql\pip-23.0.1-py3-none-any.whl\pip\_vendor\pkg_resources\__init__.py", line 2331, in normalize_path
    return os.path.normcase(os.path.realpath(os.path.normpath(_cygwin_patch(filename))))
  File "C:\ProgramData\scoop\apps\pypy3\current\Lib\ntpath.py", line 697, in realpath
    path = _getfinalpathname_nonstrict(path)
  File "C:\ProgramData\scoop\apps\pypy3\current\Lib\ntpath.py", line 645, in _getfinalpathname_nonstrict
    path = _getfinalpathname(path)
OSError: [WinError 0] 鎿嶄綔鎴愬姛瀹屾垚銆? 'R:\\Temp\\tmpf1fwghql\\setuptools-65.5.0-py3-none-any.whl'

Traceback (most recent call last):
  File "C:\ProgramData\scoop\apps\pypy3\current\Lib\runpy.py", line 199, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\ProgramData\scoop\apps\pypy3\current\Lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\ProgramData\scoop\apps\pypy3\current\Lib\ensurepip\__main__.py", line 5, in <module>
    sys.exit(ensurepip._main())
             ^^^^^^^^^^^^^^^^^
  File "C:\ProgramData\scoop\apps\pypy3\current\Lib\ensurepip\__init__.py", line 287, in _main
    return _bootstrap(
  File "C:\ProgramData\scoop\apps\pypy3\current\Lib\ensurepip\__init__.py", line 203, in _bootstrap
    return _run_pip([*args, *_PACKAGE_NAMES], additional_paths)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\ProgramData\scoop\apps\pypy3\current\Lib\ensurepip\__init__.py", line 104, in _run_pip
    return subprocess.run(cmd, check=True).returncode
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\ProgramData\scoop\apps\pypy3\current\Lib\subprocess.py", line 526, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['C:\\ProgramData\\scoop\\apps\\pypy3\\current\\pypy.exe', '-W', 'ignore::DeprecationWarning', '-c', '\nimport runpy\nimport sys\nsys.path = [\'R:\\\\Temp\\\\tmpf1fwghql\\\\setuptools-65.5.0-py3-none-any.whl\', \'R:\\\\Temp\\\\tmpf1fwghql\\\\pip-23.0.1-py3-none-any.whl\'] + sys.path\nsys.argv[1:] = [\'install\', \'--no-cache-dir\', \'--no-index\', \'--find-links\', \'R:\\\\Temp\\\\tmpf1fwghql\', \'setuptools\', \'pip\']\nrunpy.run_module("pip", run_name="__main__", alter_sys=True)\n']' returned non-zero exit status 2.

样例分析

异常调用栈中,R:是笔者使用 ImDisk挂载的Ramdisk盘符,R:\Temp是笔者通过 ImDisk自带工具自动设置的 %TEMP%环境变量所指路径。

根据调用栈集中在 R:\Temp来看,笔者初步认为 ensurepip无法运行是因为 %TEMP%环境变量因为某种缘故无法访问的关系(由于笔者的 nushell至今无法访问到 R:盘符下的路径,所以哥们很自然地就认为是 %TEMP%环境变量相关),那么更改 %TEMP%环境变量似乎就可以解决了,至于具体的原因和影响需要后续分析。

解决方案

修改 %TEMP%环境变量

只需要在终端里面临时指定 TEMP环境变量到 R:\以外的路径即可,如在 PowerShell下运行:

$env:TEMP = "$env:LOCALAPPDATA/Temp"; pypy -m ensurepip

则可以正常得到预期输出

Looking in links: c:\Users\username\.cache\tmpj0axfryo
Requirement already satisfied: setuptools in c:\programdata\scoop\apps\pypy3\7.3.16\lib\site-packages (65.5.0)
Requirement already satisfied: pip in c:\programdata\scoop\apps\pypy3\7.3.16\lib\site-packages (23.0.1)

不过,TEMP环境变量使用 ~指代家目录的话,ensurepip似乎也是无法解析的,Windows下改成其它的路径或者用 USERPROFILE变量就好。