如何实现setuptools源码分发含原始数据,Wheel包含转换后文件?
解决方案
1. 让源码分发(sdist)包含原始data文件
在项目根目录创建MANIFEST.in文件,添加以下内容:
include data/*
生成sdist包时,原始data目录下的所有文件会被自动包含,确保后续构建Wheel时临时目录中存在这些文件。
2. 调整构建逻辑,生成pickle并隔离原始文件
更新setup.py中的代码,修改自定义BuildPy类的执行逻辑,直接在构建目标目录生成pickle文件(避免污染源码目录),同时确保原始data文件不被打包进Wheel:
from setuptools.command.build_py import build_py from setuptools import setup from pathlib import Path import pickle ROOT = Path(__file__).resolve().parent class BuildPy(build_py): def run(self): # 先执行父类构建逻辑,确保包结构已复制到临时构建目录 super().run() # 定位构建后的包目录(Wheel最终会打包此目录内容) build_package_path = Path(self.build_lib) / "package" # 定位原始data目录 data_dir = ROOT / "data" # 遍历data文件,转换为pickle并写入构建目录的包中 for data_file in data_dir.glob("*"): if not data_file.is_file(): continue # 读取原始数据(根据你的数据格式调整读取逻辑,比如文本文件用"r"模式) with open(data_file, "rb") as f: raw_data = f.read() # 生成对应pickle文件路径 pickle_filename = f"{data_file.stem}.pickle" pickle_file_path = build_package_path / pickle_filename # 写入pickle文件 with open(pickle_file_path, "wb") as f: pickle.dump(raw_data, f) setup( # 保留你原有的其他配置... cmdclass={"build_py": BuildPy}, package_data={"package": ["*.pickle"]}, include_package_data=False, )
3. 验证效果
- 生成sdist:执行
python setup.py sdist,解压后检查是否包含data/目录下的原始文件 - 生成Wheel:执行
python setup.py bdist_wheel,将Wheel包后缀改为.zip解压,检查package/目录下仅存在.pickle文件 - 安装测试:分别安装sdist和Wheel包,验证功能正常运行
关键细节
- 先调用
super().run()确保包结构已复制到临时构建目录,再在该目录生成pickle,避免修改本地源码 MANIFEST.in仅控制sdist的文件包含范围,不影响Wheel打包内容package_data仅指定.pickle文件,搭配include_package_data=False,彻底避免原始data文件进入Wheel包
内容的提问来源于stack exchange,提问作者Nil Admirari
相关产品推荐
相关产品推荐

