使用Setuptools构建Python包时导入bs4遇ModuleNotFoundError求助
解决setuptools构建包时出现的ModuleNotFoundError: 'bs4'问题
问题场景
执行python3 -m build构建wheel/sdist包时触发错误,错误信息如下:
- Creating venv isolated environment...
- Installing packages in isolated environment... (setuptools >= 40.8.0)
- Getting build dependencies for sdist...
ModuleNotFoundError: No module named 'bs4'
ERROR Backend subprocess exited when trying to invoke get_requires_for_build_sdist
报错定位到代码行:
from bs4 import BeautifulSoup
当前使用的setup.py代码:
import setuptools import mypackage def readme(): with open("README.md", 'r') as f: return f.read() setuptools.setup( name="mypackage", version=mypackage.__version__, author=mypackage.__author__, maintainer=mypackage.__author__, description=mypackage.__description__, long_description=readme(), long_description_content_type="text/markdown", license=mypackage.__license__, python_requires=">=3.10", install_requires=[ "beautifulsoup4", ], )
相关版本信息:
- setuptools:69.0.3
- Python:3.11.8
问题原因
python -m build会创建隔离的虚拟环境执行构建流程,这个环境仅预装setuptools等基础构建工具,不会自动安装install_requires里的依赖。而你的setup.py直接导入了mypackage,但mypackage内部依赖bs4,导致构建环境找不到该包触发报错。
解决方案
方案1:避免在setup.py中直接导入整个包(推荐)
将版本、作者等元数据单独放在一个文件中,在setup.py里读取该文件而非导入整个包,从根源避免构建时的依赖问题。
- 创建
mypackage/_version.py文件:
__version__ = "0.1.0" __author__ = "你的名字" __description__ = "你的包描述" __license__ = "MIT"
- 修改
setup.py:
import setuptools def readme(): with open("README.md", 'r') as f: return f.read() # 读取元数据,不导入整个包 version_info = {} with open("mypackage/_version.py") as f: exec(f.read(), version_info) setuptools.setup( name="mypackage", version=version_info["__version__"], author=version_info["__author__"], maintainer=version_info["__author__"], description=version_info["__description__"], long_description=readme(), long_description_content_type="text/markdown", license=version_info["__license__"], python_requires=">=3.10", install_requires=[ "beautifulsoup4", ], )
方案2:声明构建依赖(兼容旧版setuptools)
在setup.py中添加setup_requires参数,让构建环境提前安装所需依赖:
setuptools.setup( # 保留原有参数 install_requires=[ "beautifulsoup4", ], setup_requires=[ "beautifulsoup4", ], )
注意:setup_requires在新版setuptools中已被标记为废弃,更推荐使用方案3。
方案3:用pyproject.toml声明构建依赖(现代标准)
创建pyproject.toml文件,指定构建阶段需要的依赖:
[build-system] requires = ["setuptools>=40.8.0", "wheel", "beautifulsoup4"] build-backend = "setuptools.build_meta"
这样python -m build会在构建环境中先安装beautifulsoup4,解决导入问题。
内容的提问来源于stack exchange,提问作者xyz
相关产品推荐
相关产品推荐

