news 2026/9/24 16:46:09

pip 需求文件格式(requirements.txt)完整指南:语法、选项与源码解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
pip 需求文件格式(requirements.txt)完整指南:语法、选项与源码解析

pip 需求文件格式(requirements.txt)完整指南:语法、选项与源码解析

【免费下载链接】pipThe Python package installer项目地址: https://gitcode.com/gh_mirrors/pi/pip

导读:需求文件(requirements file)是 pip 安装依赖的核心载体,pip install通过它批量读取要安装的项目清单。本文基于 pip 官方文档 requirements-file-format.md 展开,结合 req_file.py 解析器源码与对应测试,系统讲解需求文件的六种行形式、编码与注释规则、支持的全局/单需求选项、-r/-c文件引用以及环境变量展开,帮助读者写出可维护、可复现、可安全校验的 requirements 文件。

一、什么是需求文件

需求文件是 pip 在执行pip install时使用的一份"待安装项目清单"。使用该格式的文件通常命名为requirements.txt——但命名不是强制要求,任何采用该格式的文件都可以传给 pip。

在 pip_install.rst 中,-r--requirement)参数即用于从文件中读取需求;需求文件格式与 pip 内部细节(例如命令行选项)紧密相关:

  • 基础语法相对稳定且可移植;
  • 完整语法仅面向 pip 消费,其他工具在复用时应谨慎评估兼容性。

这一点在官方文档中以 note 形式特别声明,也是编写需求文件时需要记住的前提:以本格式为准、以 pip 的实际解析行为为准。

二、完整示例与逐行解读

官方文档给出了一个覆盖全部核心语法的最小示例,逐行拆解如下:

# 以 # 开头的行是注释,会被忽略 pytest pytest-cov beautifulsoup4 # 这里支持的语法与 requirement specifier 相同 docopt == 0.6.1 requests [security] >= 2.8.1, == 2.8.* ; python_version < "2.7" urllib3 @ https://github.com/urllib3/urllib3/archive/refs/tags/1.26.8.zip # 可以引用其他需求文件或约束文件 -r other-requirements.txt -c constraints.txt # 可以引用本地发行版文件路径 ./downloads/numpy-1.9.2-cp34-none-win32.whl # 可以引用 URL http://wxpython.org/Phoenix/snapshot-builds/wxPython_Phoenix-3.0.3.dev1820+49a8884-cp34-none-win_amd64.whl

各部分的含义:

行内容含义
pytest纯项目名,安装最新可用版本
docopt == 0.6.1版本约束(精确指定版本)
requests [security] >= 2.8.1, == 2.8.* ; python_version < "2.7"extras + 版本约束 + 环境标记(environment marker)
urllib3 @ https://...zip直接 URL 引用形式(name @ url
-r other-requirements.txt嵌套引用另一个需求文件
-c constraints.txt引用一个约束文件
./downloads/...whl本地 wheel 包路径
http://...whl远程 wheel 包 URL

注意示例中有两处细节值得强调:

  1. -c-r的区别-r引入的文件中每个项目都会被安装;-c引入的约束文件只限制版本、不触发安装(详见下文第五节)。
  2. shell 引用的差异:在需求文件里不要给 specifier 加引号(与命令行不同)。唯一的例外是 2015 年 5 月的 pip 7.0/7.0.1,那两个版本要求含环境标记的 specifier 必须加引号,此后的版本均已取消该要求。

关于 requirement specifier 的完整语法(name-based 与 URL-based 两种形式、extras、版本说明符、环境标记等),可参考同目录下的 requirement-specifiers.md。

三、文件结构:六种受支持的行形式

需求文件的每一行都表示一个要安装的项,或一条传给pip install的参数。官方文档列出的受支持形式包括:

  • [[--option]...]—— 仅由命令行选项构成的行(例如--pre--no-index
  • <requirement specifier>—— 需求说明符(项目名 + 可选版本约束等)
  • <archive url/path>—— 归档包(wheel / sdist)的 URL 或本地路径
  • [-e] <local project path>—— 本地项目路径,可加-e以可编辑模式安装
  • [-e] <vcs project url>—— 版本控制仓库(Git、Mercurial、Subversion、Bazaar)的 URL,可加-e

这些形式对应源码解析器src/pip/_internal/req/req_file.py中的行处理逻辑:每一行先被拆分为"参数部分(args)"与"选项部分(options)"。break_args_options(req_file.py)按第一个以---开头的 token 为界拆分——它只对选项部分做 shlex 分词,参数部分原样保留,因为参数中可能包含会被 shlex 破坏的环境标记。

四、编码规则

需求文件的默认编码是UTF-8,除非通过 PEP 263 风格的注释指定其他编码:

# -*- coding: <encoding name> -*-

从源码看,编码识别做了三层处理(req_file.py):

  1. BOM 探测:按优先级依次匹配 UTF-8、UTF-32、UTF-32-BE/LE、UTF-16、UTF-16-BE/LE 的 BOM(req_file.py)。源码注释特别提示:BOM_UTF16_LEBOM_UTF32_LE的前缀,因此 UTF-32 必须排在 UTF-16 之前判断。
  2. PEP 263 声明:检查文件前两行中以#开头的行里是否存在coding[:=]\s*([-\w.]+)形式的编码声明。
  3. 兜底 UTF-8:以上均未命中时按 UTF-8 解码;若解码失败,会回退到区域设置(locale)编码,并打印一条警告日志,提示使用者应显式添加 PEP 263 编码注释。

五、行延续(Line Continuation)

以未转义的\结尾的行会被视为行延续,其后的换行符被忽略,前后两行拼接为一行:

--config-settings build_option=--with-x \ --config-settings other=value pkgname

从实现看,join_lines(req_file.py)在拼接时以第一行的行号作为拼接结果的行号,并且只处理不以\结尾的普通行;注释行(以#开头)不会触发延续拼接。

六、注释规则

  • #开头的行整体视为注释并被忽略;
  • 行内空白符后出现的#,会将#及其后的内容视为注释;
  • 注释的剔除发生在行延续处理之后(源码preprocess顺序为join_linesignore_commentsexpand_env_variables,见 req_file.py)。

这带来一个值得注意的行为:如果#出现在行首之后、但前面没有空白符(例如拼接后的行中间),COMMENT_RE = r"(^|\s+)#.*$"(req_file.py)要求#前必须是行首或空白符才被当作注释起点。单元测试 tests/unit/test_req_file.py 中的test_strip_comment"req # comment")即验证了这一"空白符 + #"的剥离行为。

七、支持的选项

需求文件只支持一部分pip install选项,并非所有命令行选项都可写入。选项分为两类。

7.1 全局选项(Global Options)

以下选项作用于整个pip install运行过程,且必须单独占一行。官方文档通过pip-requirements-file-options-ref-list指令动态列出,结合源码 req_file.py 中SUPPORTED_OPTIONS的定义,实际支持集合为:

选项作用
--index-url指定包索引源
--extra-index-url附加包索引源(可多次)
--no-index忽略索引源,仅用本地/链接源
--constraints/-c引用约束文件
--requirements/-r引用其他需求文件
--editable/-e可编辑安装本地/VCS 项目
--find-links额外查找链接位置(可多次)
--no-binary禁止使用二进制发行版
--only-binary只允许二进制发行版
--prefer-binary优先选用旧版 wheel
--require-hashes启用哈希校验模式
--no-require-hashes关闭哈希校验
--pre允许安装预发布版本
--all-releases允许所有发行版(含预发布)
--only-final仅允许正式版本
--trusted-host标记受信任主机
--use-new-feature启用新特性(预览)

官方示例——同时指定--pre--no-index和两个--find-links

--pre --no-index --find-links /my/local/archives --find-links http://some.archives.com/archives

从源码handle_option_line(req_file.py)可见这些选项的底层影响路径:

  • --no-index/--index-url/--extra-index-url/--find-links会被合并重建SearchScope,直接改写PackageFinder的搜索范围;
  • --find-links若给定的是相对路径且相对于需求文件目录存在,会先转换为相对需求文件目录的绝对路径;
  • --pre会被转换为--all-releases :all:语义写入ReleaseControl
  • --prefer-binary调用finder.set_prefer_binary()
  • --trusted-host会把主机加入 session 的受信任列表,并记录来源为"某文件第几行"。

7.2 每需求选项(Per-requirement Options)

自 pip 7.0 起支持。

作用于单个需求行的选项只有两个(req_file.py):

  • --config-settings(即 PEP 517 构建配置设置):可附加在单个需求行上,为该需求的构建指定配置;
  • --hash:配合哈希校验模式使用,为该需求指定期望的哈希值。

两者都可针对普通需求行使用;--config-settings还可用于-e可编辑行(SUPPORTED_OPTIONS_EDITABLE_REQ仅含config_settings)。

源码层面,SUPPORTED_OPTIONS_REQ对应的 dest 值(hashconfig_settings)会被提取到该行的ParsedRequirement.options中(req_file.py),随单个需求生效;而全局选项作用于整次安装。handle_line(req_file.py)明确指出:含需求的行上,只有SUPPORTED_OPTIONS_REQ生效,其他选项被忽略;不含需求的行上反之

哈希校验模式(Hash-Checking Mode)的完整说明见 user_guide.rst 对应章节,典型用法是让 pip 根据文件中的哈希值逐一校验下载包,校验失败即报错,保障供应链安全。

八、引用其他需求文件与约束文件

需求文件可以嵌套引用其他文件:

-r more_requirements.txt

也可以引用约束文件(constraints file)

-c some_constraints.txt

约束文件是需求文件的一个子集:语法与需求文件相同,但只控制某个包被安装时的版本,不决定它是否被安装——把某个包写进约束文件不会触发它的安装。同时约束文件有几类语法不允许:必须包含项目名、不能是可编辑安装、不能指定 extras。命令行用法为python -m pip install -c constraints.txt(详见 user_guide.rst 的 "Constraints Files" 小节)。

源码对嵌套引用的处理(req_file.py)值得注意:

  • 相对路径解析:当外层文件是普通路径时,嵌套文件路径会基于外层文件所在目录做os.path.join后再abspath规范化;当外层文件本身是http(s)://URL 时,则用urllib.parse.urljoin拼接,使相对 URL 也能正确解析。
  • 递归引用检测:解析器维护一个已解析文件栈,若发现某个文件被递归引用(文件引用自身或形成引用环),会抛出RequirementsFileParseError,提示"<path> recursively references itself in <file>"。
  • 文件来源追踪:每个需求行的comes_from都会记录为"-r 文件名 (行号)"或"-c 文件名 (行号)",这在pip freeze、卸载和安装报告中追溯依赖来源时非常有用。

九、使用环境变量

自 pip 10.0 起支持。

需求文件支持环境变量展开,但只认 POSIX 格式的${大写变量名}

${API_TOKEN}

pip 在运行时会去宿主机环境中查找同名变量并替换。约束条件:

  • 变量名必须为大写字母、数字和下划线[A-Z0-9_]+),遵循 POSIX 标准(IEEE Std 1003.1, 2013 Edition);
  • 不支持$VARIABLE%VARIABLE%等其他展开语法;
  • 若变量未定义(os.getenv返回空),则保持原样不展开(req_file.py)。

源码中对应的正则ENV_VAR_RE = r"(?P<var>\$\{(?P<name>[A-Z0-9_]+)\})"(req_file.py),展开发生在注释剔除之后。

这样做的两个设计动机(源码注释中明确说明):

  1. 避免字符串中出现的$被误展开;
  2. 保证不同平台(Windows / Unix)间需求文件行为一致。

实际用途:将 Token、密钥等敏感信息放在环境变量中,需求文件里只写变量名,运行时由 pip 查值。这与常见的 12-factor 配置模式(把配置注入环境)保持一致,例如:

# 私有索引需要认证的场景 --index-url https://${PRIVATE_INDEX_USER}:${PRIVATE_INDEX_TOKEN}@pypi.example.com/simple

注意:环境变量展开同样适用于 URL 片段,因此可以安全地把凭证从文件里剥离出去,避免把密钥提交进版本库。

十、从源码看解析全流程

将文档中的语法规则对应到源码执行顺序,一个需求文件的完整处理链路是:

  1. 读取文件get_file_content(req_file.py)支持普通路径、file://URL 与http(s)://URL(后者通过PipSession拉取);随后按第五节所述进行 BOM / PEP 263 / UTF-8 解码。
  2. 预处理preprocess,req_file.py):join_lines(行延续拼接)→ignore_comments(剔除注释、过滤空行)→expand_env_variables(环境变量展开)。
  3. 逐行解析:每行先经break_args_options拆分为参数与选项,再用build_parser构建的、仅含SUPPORTED_OPTIONS + SUPPORTED_OPTIONS_REQ的 optparse 解析器解析选项(req_file.py);解析失败会包装为OptionParsingError再转成RequirementsFileParseError,并附上出错的原始行文本。
  4. 递归处理:遇到-r/-c行则递归解析嵌套文件并做循环检测。
  5. 生成需求handle_line区分需求行(产出ParsedRequirement)与纯选项行(更新PackageFinder/ session 状态)。

对应地,tests/unit/test_req_file.py 中的test_comments_and_joins_case1/2/3test_ignore_commenttest_strip_comment等用例直接验证了注释与拼接的交互规则,可以作为阅读解析行为的入口。

十一、实践建议与常见坑

结合上述语法与源码行为,编写需求文件时建议留意以下几点:

  1. 区分-r-c:需求文件中的包会被安装;约束文件只锁版本。多层引用时保持两者语义清晰,避免用-c引入的文件意外漏装依赖。
  2. 避免引用环-r互相引用会触发RequirementsFileParseError;用相对路径引用时注意目录层级,善用"相对需求文件目录"的解析规则。
  3. 选项行单独成行:全局选项必须独占一行,且每行只放一个选项(源码实现支持多选项但文档约定为单选项),便于阅读与调试。
  4. 哈希校验与敏感信息:对不可变版本建议启用--require-hashes+ 每行--hash提升供应链安全性;认证凭证一律走${ENV_VAR}而非明文。
  5. 编码声明:文件含非 UTF-8 内容时,务必在首行或次行加 PEP 263 编码注释,否则会回退到区域设置编码并产生警告日志。
  6. 不要加 shell 引号:需求文件内的 specifier 不加引号,只有命令行中因 shell 解释才需要引号包裹><或环境标记。

需求文件格式是 pip 生态中被引用最广泛的接口之一,理解其语法边界(哪些选项可用、哪些不可用)与解析行为,能帮助你写出既稳定又可审计的依赖管理配置。

【免费下载链接】pipThe Python package installer项目地址: https://gitcode.com/gh_mirrors/pi/pip

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 16:44:57

Linux驱动01-系统移植

一、系统移植1.1 系统移植介绍① 系统移植主要指在开发板上运行Linux操作系统&#xff0c;涉及硬件驱动开发、Linux系统与硬件设备的兼容适配以及内核层面的编程工作。② 将Linux系统移植到开发板的过程中&#xff0c;需要完成四个关键组件的移植&#xff1a;Bootloader&#x…

作者头像 李华
网站建设 2026/9/24 16:43:44

TVA具身智能运行机理(38):如何推动具身智能产业跨越式发展

前沿技术探索&#xff1a;TVA智能体&#xff08;简称TVA&#xff09; TVA智能体&#xff08;亦称“AI智能体视觉”&#xff09;是依托Transformer架构与“因式智能体”理论构建的新型工业视觉系统&#xff0c;也是当前最具代表性的具身视觉技术之一。它有机融合深度强化学习&a…

作者头像 李华
网站建设 2026/9/24 16:43:12

AI旅游赛道独立开发者怎么切入?4条路径不踩坑

AI旅游市场2026年预计2224亿美元&#xff0c;年增速33.7%&#xff0c;40%旅客已在用AI规划行程。海外Wanderlog积累100万用户&#xff0c;Layla年费49.99美元&#xff0c;已跑通订阅加联盟返佣的双收入模型。但照搬国内会立刻撞墙。 虎嗅网近期复盘的一个踩了五个坑的真实案例&…

作者头像 李华