Pip安装自定义包时无法将非Python文件复制到指定Temp目录如何解决?
问题原因
- 核心问题1:wheel包安装不会执行自定义install命令。你构建的是bdist_wheel格式的包,wheel是预构建的分发格式,安装过程只会将包内的文件解压到对应site-packages目录,完全不会运行setup.py里的自定义install逻辑,只有源码包(sdist)安装时才会执行setup.py的install阶段。你本地测试时是直接运行setup.py install,所以会触发自定义逻辑,但是上传到pip源后用户pip安装默认优先拉取wheel包,自然不会运行你的复制逻辑。
- 问题2:文件查找路径错误。你写的路径是基于本地源码根目录的相对路径,只有在你本地构建源码的环境下存在,用户安装后包文件是放在site-packages下的包目录里,不存在你本地的源码目录结构,就算命令被触发也找不到目标文件。
- 问题3:MANIFEST.in配置错误。你要包含的
file_I_want_to_cppy.tar.gz在folder-with-extra-stuff目录下,你直接写include file_I_want_to_cppy.tar.gz匹配不到对应文件,且include_package_data=True需要配合package_data配置才能将非py文件打包进安装后的包目录。
解决方法
- 更推荐的方案:放弃自定义install命令,改用首次运行包时复制文件的逻辑,在你的
__main__.py或者包的初始化逻辑里加判断,如果temp目录下不存在目标文件,就从安装后的包目录里读取文件复制过去,不管是wheel还是源码包安装都能生效。
读取安装后包内文件可以用importlib.resources(Python3.7+自带,低版本可以用importlib_resources兼容库),示例代码:
from importlib.resources import read_binary import sys, os # 注意Python包名不允许横杠,需要先把folder-with-extra-stuff改名为folder_with_extra_stuff import folder_with_extra_stuff # 读取包内的压缩包内容 file_content = read_binary(folder_with_extra_stuff, "file_I_want_to_cppy.tar.gz") # 写入到temp目录 temp_dir = r'c:\temp' if sys.platform == "win32" else r'/tmp' temp_col_dir = os.path.join(temp_dir, 'dump') os.makedirs(temp_col_dir, exist_ok=True) target_path = os.path.join(temp_col_dir, 'file_I_want_to_cppy.tar.gz') with open(target_path, 'wb') as f: f.write(file_content)
- 修正包配置,确保非py文件被打包进安装包:
- setup.py里增加package_data配置:
setup( # 其他原有配置保持不变 package_data={ "folder_with_extra_stuff": ["*.tar.gz"], } )
- 修正MANIFEST.in里的文件路径:
include folder_with_extra_stuff/file_I_want_to_cppy.tar.gz
- 如果一定要坚持安装时执行逻辑的方案,就不要上传wheel包,只上传sdist源码包,并且要求用户安装时加参数
--no-binary :all:强制从源码安装,该方案对用户不友好,不推荐使用。
内容的提问来源于stack exchange,提问作者Dibyendu Dey
相关产品推荐
相关产品推荐

