返回

VS Code安装gym-retro报错?搞定metadata-generation-failed

Ai

搞定 VS Code 安装 gym-retro 报错:metadata-generation-failed 与 setuptools_scm 那点事

写代码搞强化学习,想用 gym-retro 玩玩经典游戏?结果 pip install gym-retro 一敲,直接懵逼了。特别是在 VS Code 的终端里,遇到一堆红字,类似下面这样:

pip install --use-pep517 gym-retro
>>
Collecting gym-retro
  Downloading gym-retro-0.7.1.tar.gz (168.7 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 168.7/168.7 MB 582.0 kB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... error
  error: subprocess-exited-with-error

  × Preparing metadata (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [33 lines of output]
      Traceback (most recent call last):
        File "C:\Users\OMEN\Desktop\Street_Fighter\SF-env\Lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 353, in <module>
          main()
        File "C:\Users\OMEN\Desktop\Street_Fighter\SF-env\Lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 335, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "C:\Users\OMEN\Desktop\Street_Fighter\SF-env\Lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 149, in prepare_metadata_for_build_wheel
          return hook(metadata_directory, config_settings)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "C:\Users\OMEN\AppData\Local\Temp\pip-build-env-f5zhred0\overlay\Lib\site-packages\setuptools\build_meta.py", line 373, in prepare_metadata_for_build_wheel
          self.run_setup()
        File "C:\Users\OMEN\AppData\Local\Temp\pip-build-env-f5zhred0\overlay\Lib\site-packages\setuptools\build_meta.py", line 503, in run_setup
          super().run_setup(setup_script=setup_script)
        File "C:\Users\OMEN\AppData\Local\Temp\pip-build-env-f5zhred0\overlay\Lib\site-packages\setuptools\build_meta.py", line 318, in run_setup
          exec(code, locals())
        File "<string>", line 71, in <module>
        File "C:\Users\OMEN\AppData\Local\Temp\pip-build-env-f5zhred0\overlay\Lib\site-packages\setuptools\__init__.py", line 117, in setup
          return distutils.core.setup(**attrs)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "C:\Users\OMEN\AppData\Local\Temp\pip-build-env-f5zhred0\overlay\Lib\site-packages\setuptools\_distutils\core.py", line 146, in setup
          _setup_distribution = dist = klass(attrs)
                                       ^^^^^^^^^^^^
        File "C:\Users\OMEN\AppData\Local\Temp\pip-build-env-f5zhred0\overlay\Lib\site-packages\setuptools\dist.py", line 283, in __init__
          _Distribution.__init__(self, dist_attrs)
        File "C:\Users\OMEN\AppData\Local\Temp\pip-build-env-f5zhred0\overlay\Lib\site-packages\setuptools\_distutils\dist.py", line 278, in __init__
          self.finalize_options()
        File "C:\Users\OMEN\AppData\Local\Temp\pip-build-env-f5zhred0\overlay\Lib\site-packages\setuptools\dist.py", line 635, in finalize_options
          ep(self)
        File "C:\Users\OMEN\AppData\Local\Temp\pip-build-env-f5zhred0\overlay\Lib\site-packages\setuptools\dist.py", line 655, in _finalize_setup_keywords
          ep.load()(self, ep.name, value)
        File "C:\Users\OMEN\AppData\Local\Temp\pip-build-env-f5zhred0\normal\Lib\site-packages\setuptools_scm\_integration\setuptools.py", line 82, in version_keyword
          assert isinstance(value, dict), "version_keyword expects a dict or True"
      AssertionError: version_keyword expects a dict or True
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

看这错误信息挺吓人,一长串。核心问题在 Preparing metadata (pyproject.toml) ... error 和最后那个 AssertionError: version_keyword expects a dict or True

这表示在准备 gym-retro 的安装包元数据(可以理解为包的"说明书"和构建指令)时出了岔子,而且错误直接指向了 setuptools_scm 这个工具。setuptools_scm 通常用来根据 Git 标签自动生成 Python 包的版本号。错误信息说 version_keyword 期望收到一个字典 (dict) 或者布尔值 True,但实际收到的类型不对。

你可能已经试过更新 setuptools_scmsetuptoolswheel,甚至装了最新的 Visual Studio 构建工具(像 VS 2019/2022),但问题依旧。这是怎么回事呢?

问题原因分析:为啥装不上?

这个问题的根源通常在于 setuptools_scmsetuptools 这些构建工具链的版本,跟 gym-retro (特定版本,比如这里的 0.7.1) 的 setup.pypyproject.toml 文件里的配置方式不兼容。

简单说,gym-retro 包定义了如何构建自己,这个过程可能依赖 setuptools_scm 来确定版本。但新版本的 setuptools_scmsetuptools 可能修改了某些内部工作方式或参数要求,导致 gym-retro 原来的配置代码在新的构建环境下跑不通,触发了那个 AssertionError

这个错误发生在 pip 尝试理解包的元数据阶段,还没到真正需要 C++ 编译器编译代码那一步。所以,即使你装好了 VS 构建工具,也可能卡在这里。

解决方案:试试这几招

下面列出几种常见的解决办法,你可以按顺序试试。

方案一:降级 setuptools_scm 版本 (推荐先试)

既然错误信息明确指向了 setuptools_scm,而且新版本可能引入了不兼容的改动,那最直接的方法就是把它降级到一个已知的、可能与 gym-retro 兼容的旧版本。版本 6.0.0 之前似乎是个比较稳妥的选择点,不少包在这个版本前后遇到了构建问题。

原理与作用:

使用一个较旧版本的 setuptools_scm,其 API 和行为可能更符合 gym-retro 在其 setup.pypyproject.toml 中预期的那样。避免新版本中可能引入的不兼容变更。

操作步骤:

  1. 确保你在你的虚拟环境里操作。 (看路径 SF-env,你似乎已经用了虚拟环境,这是个好习惯!)
  2. 卸载当前可能存在的 setuptools_scm 版本:
    pip uninstall setuptools_scm
    
    如果提示没装,直接跳到下一步。
  3. 安装一个较旧的版本,比如 5.x 系列的最后一个版本或者直接 <6.0.0
    pip install "setuptools_scm<6.0.0"
    
    或者,如果你想尝试更具体的版本,可以查阅资料或尝试类似:
    pip install setuptools_scm==5.0.2
    
  4. 再次尝试安装 gym-retro
    pip install gym-retro
    
    注意,这次可以先不用 --use-pep517,让 pip 自行决定构建方式。如果还不行,再带上试试。

额外建议:

  • 有时候也需要同时控制 setuptools 的版本。如果降级 setuptools_scm 还不行,可以试试把 setuptools 也降级到某个稳定版本,例如:
    pip install "setuptools<58.0.0" "setuptools_scm<6.0.0"
    pip install gym-retro
    
  • 操作完成后,可以用 pip list 检查一下 setuptoolssetuptools_scm 的版本确实是你指定的旧版本。

方案二:清理构建缓存和环境

pip 和构建系统会产生一些缓存文件。有时这些缓存,或者虚拟环境本身的状态出了问题,也可能导致奇怪的构建错误。彻底清理一下没坏处。

原理与作用:

删除 pip 的下载缓存和构建时产生的临时文件,避免脏数据干扰。重新创建虚拟环境可以保证一个干净的、无历史遗留问题的依赖环境。

操作步骤:

  1. 清理 pip 缓存:
    pip cache purge
    
  2. (可选,但推荐) 重新创建虚拟环境:
    • 首先退出当前虚拟环境:
      deactivate
      
    • 然后删除整个虚拟环境目录 (假设它叫 SF-env 且在当前目录下):
      # Windows
      rmdir /s /q SF-env
      # macOS / Linux
      # rm -rf SF-env
      
      注意: 这会删除环境里所有已安装的包,需要重新安装。
    • 重新创建虚拟环境:
      python -m venv SF-env
      
    • 激活新环境:
      # Windows (CMD)
      .\SF-env\Scripts\activate
      # Windows (PowerShell)
      # .\SF-env\Scripts\Activate.ps1
      # macOS / Linux
      # source SF-env/bin/activate
      
  3. 在新环境里,再次尝试安装 gym-retro (可能先装一下必要的旧版 setuptools_scm):
    pip install "setuptools_scm<6.0.0" # 或者其他你认为合适的版本
    pip install gym-retro
    

安全建议:

  • 删除虚拟环境前,确认里面没有你需要保留的未提交代码或数据。用 pip freeze > requirements.txt 备份依赖列表是个好习惯,这样在新环境可以 pip install -r requirements.txt 快速恢复大部分依赖(但要注意 gym-retrosetuptools_scm 这种需要特定处理的)。

方案三:调整安装命令

pip 的安装行为可以通过参数调整。

原理与作用:

  • --use-pep517 强制使用 pyproject.toml 定义的现代构建系统。有时,包的旧式 setup.py 可能与强制 PEP 517 不兼容。反之,有些包则必须用 PEP 517。
  • --no-build-isolation 禁止 pip 创建隔离的构建环境。默认情况下,pip 会在一个临时环境里安装构建依赖(如 setuptools, wheel)。使用 --no-build-isolation 会让 pip 直接使用你当前环境(或系统)里安装的构建工具。这有时能绕过隔离环境中的版本冲突,但也可能引入新的问题(比如你本地的 setuptools 版本也不对)。

操作步骤:

  1. 尝试不加 --use-pep517 (让 pip 自动选择):
    pip install gym-retro
    
  2. 尝试禁用构建隔离 (通常不推荐,但可作为最后手段):
    • 首先,确保你的主环境(或虚拟环境)中安装了合适的 setuptoolswheel,以及你认为正确的 setuptools_scm 版本。
      pip install wheel "setuptools<58.0.0" "setuptools_scm<6.0.0" # 示例版本
      
    • 然后带上 --no-build-isolation 标志安装:
      pip install --no-build-isolation gym-retro
      

额外建议:

  • 使用 --no-build-isolation 是一种“权宜之计”,它破坏了构建过程的可复现性。如果这种方法有效,它强烈暗示了问题出在构建依赖的版本冲突上。长期来看,最好还是找到能让隔离构建成功的依赖版本组合。

方案四:检查 C++ 构建工具和系统依赖

虽然当前的错误发生在元数据阶段,但 gym-retro 最终是需要 C++ 编译器和 CMake 来构建其 C++ 部分的。确保这些基础工具就绪,有时能间接解决一些看似无关的问题,或者至少保证下一步的编译能顺利进行。

原理与作用:

gym-retro 包含 C++ 代码,需要编译才能在 Python 中使用。Windows 上通常需要 Visual Studio C++ Build Tools。构建过程还依赖 CMake 来管理编译配置。缺少这些或配置不当,即使元数据生成成功,后续编译也会失败。确保基础环境完备总是没错的。

操作步骤:

  1. 检查 Visual Studio Build Tools:
    • 打开 "Visual Studio Installer"。
    • 找到你安装的 VS 版本(比如 VS 2019 或 VS 2022),点击“修改”。
    • 在“工作负载”选项卡下,确保勾选了 “使用 C++ 的桌面开发 ”。
    • 在右侧的“安装详细信息”里,确保至少勾选了最新的 “MSVC v142 - VS 2019 C++ x64/x86 build tools ”(或对应 VS 2022 的 v143)和 “Windows 10 SDK ”(或更新的 Windows SDK)。
    • 点击“修改”按钮完成安装或更新。
  2. 安装 CMake:
    • gym-retro 需要 CMake。如果你还没装,去 CMake 官网 (https://cmake.org/download/) 下载适合你 Windows 版本的安装包。
    • 安装时,确保选择“Add CMake to the system PATH for all users ”或“... for current user ”。这会让命令行能直接找到 cmake 命令。
    • 安装后,可以打开新的命令行窗口,输入 cmake --version 检查是否安装成功并添加到了 PATH。
  3. 重启 VS Code 或你的终端: 有时更改了系统 PATH 或安装了新工具后,需要重启终端才能让它识别到新的环境。

进阶使用技巧:

  • 如果你有多个 VS 版本,或想指定特定的工具集,可以通过设置环境变量 (如 VCTargetsPath) 来控制,但这通常比较复杂,默认情况下 setuptools 会自动查找已安装的最新可用版本。

方案五:尝试安装旧版本的 gym-retro

如果特定版本的 gym-retro(比如 0.7.1)就是跟最新的构建工具有兼容性问题,而维护者还没更新,试试安装一个稍微旧一点的版本或许能行。

原理与作用:

软件开发中,新版本有时会引入未预料到的问题。回退到一个之前的稳定版本是常见的解决策略。

操作步骤:

# 先确保 setuptools_scm 版本是你认为合适的 (比如 <6.0.0)
pip install "setuptools_scm<6.0.0"

# 尝试安装 gym-retro 的 0.7.0 版本
pip install gym-retro==0.7.0

# 如果 0.7.0 还是不行,可以试试更早的,比如 0.6.0 (版本号可能需要查证)
# pip install gym-retro==0.6.0

额外建议:

总结一下(但不用“综上所述”)

遇到 gym-retro 安装时报 metadata-generation-failedAssertionError: version_keyword expects a dict or True 这类错,别慌。问题多半出在构建工具链(特别是 setuptools_scm)和包本身的配置不太搭。

优先试试降级 setuptools_scm 到 6.0.0 以下 。如果不行,清理缓存、重建虚拟环境 也是个好思路。再不行,调整一下 pip安装参数 ,或者检查确认 C++ 构建工具和 CMake 都装好了。作为备选,也可以尝试安装一个旧版本的 gym-retro

通常组合拳下来,总有一款适合你。耐心点,多试几次,应该就能搞定这个拦路虎,愉快地开始你的复古游戏强化学习之旅了。