PyInstaller无法找到myproj包元数据问题求助
解决PyInstaller打包PDM+SCM版本包时的importlib.metadata错误
问题根源
你用PDM+SCM动态生成版本,本地开发时包是可编辑安装(editable install),importlib.metadata能通过开发环境的特殊配置找到元数据,但PyInstaller打包时:
- 直接用开发环境打包,
--copy-metadata找不到完整的dist-info目录(可编辑安装的元数据不完整) - 省略参数打包后,可执行文件里没有包含包的元数据,运行时自然报错
解决方案
方案1:生成静态版本文件(最稳妥)
让包直接读取本地静态版本文件,彻底不依赖importlib.metadata的元数据:
- 在
pyproject.toml中添加配置,让PDM/setuptools-scm自动生成_version.py:# 如果用PDM自带的SCM [tool.pdm] version-file = "src/myproj/_version.py" # 如果用setuptools-scm(PDM默认也依赖它) [tool.setuptools_scm] write_to = "src/myproj/_version.py" - 修改代码,直接导入静态版本:
# 在myproj/__init__.py或__main__.py中 try: from ._version import __version__ except ImportError: # 兼容开发环境未生成文件的情况 from importlib.metadata import version __version__ = version("myproj") - 重新执行
pdm install生成_version.py,之后打包时不管用不用--copy-metadata,都能正常读取版本。
方案2:先构建正式包再打包
让PyInstaller基于完整安装的包获取元数据:
- 构建wheel包:
pdm build - 创建新虚拟环境,安装刚构建的wheel:
python -m venv venv-pack # Windows venv-pack\Scripts\activate # Linux/macOS source venv-pack/bin/activate pip install dist/myproj-*.whl - 在这个虚拟环境中执行PyInstaller打包命令:
pyinstaller -F --name MyProj --copy-metadata myproj src/myproj/__main__.py
方案3:自定义PyInstaller Spec文件手动添加元数据
- 先生成基础spec文件:
pyinstaller -F --name MyProj --copy-metadata myproj src/myproj/__main__.py --specpath . - 打开生成的
MyProj.spec,在Analysis的datas参数中添加包的元数据目录:
可以手动填写路径,或者用代码动态获取:from importlib.metadata import distribution dist = distribution("myproj") a = Analysis( ['src/myproj/__main__.py'], pathex=[], binaries=[], # 这里添加元数据目录 datas=[(dist.locate_file(''), f"{dist.name}-{dist.version}.dist-info")], hiddenimports=[], hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=[], noarchive=False, ) - 用spec文件重新打包:
pyinstaller MyProj.spec
内容的提问来源于stack exchange,提问作者Mike van Dyke
相关产品推荐
相关产品推荐

