You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

构建Python包:如何仅将指定文件/文件夹纳入源码分发包而非wheel?

好问题!这两个场景在Python打包里确实挺常见的,我来一步步给你拆解解决方案:

一、通用方法:将文件/文件夹仅纳入源码分发包(sdist)而非wheel

Python打包中,sdist(源码包)和wheel(二进制包)的文件包含逻辑是分开控制的,我们可以利用这一点实现“仅进sdist”的需求,主要有两种方式:

1. 使用MANIFEST.in配置(传统且兼容广泛)

MANIFEST.in是专门控制sdist包含文件的配置文件,而wheel的文件则由setup.py/setup.cfg/pyproject.toml里的包数据规则控制。

步骤:

  • 项目根目录创建MANIFEST.in文件,添加你要纳入sdist的文件/文件夹规则:
    # 比如要包含vendor/pipenv下所有内容
    recursive-include vendor/pipenv *
    
  • 然后确保这些文件不被wheel包含
    • 如果你用include_package_data = True(自动包含版本控制追踪的文件),需要在setup.cfg里添加排除规则:
      [options]
      include_package_data = True
      
      [options.exclude_package_data]
      * = vendor/pipenv/*
      
    • 如果你手动用package_data指定wheel要包含的文件,只要不把vendor/pipenv加进去,它自然不会出现在wheel里。

2. 使用pyproject.toml配置(现代推荐,适用于setuptools>=61.0.0)

如果你已经在使用pyproject.toml管理构建配置,可以直接在里面分别控制sdist和wheel的文件:

# 先指定构建后端(必须是setuptools)
[build-system]
requires = ["setuptools>=61.0.0", "wheel"]
build-backend = "setuptools.build_meta"

# 控制sdist要包含的文件
[tool.setuptools.sdist]
include = ["vendor/pipenv/**/*"]

# 控制wheel要排除的文件(或只指定要包含的)
[tool.setuptools.exclude-package-data]
* = ["vendor/pipenv/**/*"]
二、针对你的pipenv依赖场景的具体实现

你的需求是vendor/pipenv要在setup.py执行前运行,所以必须随源码包分发,但不能进入wheel(避免冗余安装),结合上面的方法,具体步骤如下:

1. 配置文件设置

用上面两种方式中的任意一种,确保vendor/pipenv被纳入sdist但排除在wheel外。比如用MANIFEST.in + setup.cfg的组合。

2. 修改setup.py加载本地pipenv

setup.py的最开头,把vendor目录加入Python的路径,这样就能直接导入里面的pipenv代码了:

import sys
from pathlib import Path

# 将项目根目录下的vendor文件夹加入Python路径
sys.path.insert(0, str(Path(__file__).parent / "vendor"))

# 现在可以导入pipenv的模块来解析install_requires了
from pipenv.some_module import parse_install_requires

# 解析依赖列表
install_requires = parse_install_requires()

# 正常编写setup逻辑
from setuptools import setup

setup(
    name="your_package_name",
    version="0.1.0",
    install_requires=install_requires,
    # 其他配置项...
)

3. 验证效果

运行以下命令生成包,然后检查内容:

# 生成sdist和wheel
python -m build
  • 解压生成的.tar.gz源码包,确认vendor/pipenv存在;
  • unzip或查看wheel工具(比如wheel unpack)检查生成的.whl文件,确认vendor/pipenv不在其中。

内容的提问来源于stack exchange,提问作者Stephan Fitzpatrick

火山引擎 最新活动