ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

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

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.dev182049a8884-cp34-none-win_amd64.whl各部分的含义行内容含义pytest纯项目名安装最新可用版本docopt 0.6.1版本约束精确指定版本requests [security] 2.8.1, 2.8.* ; python_version 2.7extras 版本约束 环境标记environment markerurllib3 https://...zip直接 URL 引用形式name url-r other-requirements.txt嵌套引用另一个需求文件-c constraints.txt引用一个约束文件./downloads/...whl本地 wheel 包路径http://...whl远程 wheel 包 URL注意示例中有两处细节值得强调-c与-r的区别-r引入的文件中每个项目都会被安装-c引入的约束文件只限制版本、不触发安装详见下文第五节。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-indexrequirement 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_optionsreq_file.py按第一个以-或--开头的 token 为界拆分——它只对选项部分做 shlex 分词参数部分原样保留因为参数中可能包含会被 shlex 破坏的环境标记。四、编码规则需求文件的默认编码是UTF-8除非通过 PEP 263 风格的注释指定其他编码# -*- coding: encoding name -*-从源码看编码识别做了三层处理req_file.pyBOM 探测按优先级依次匹配 UTF-8、UTF-32、UTF-32-BE/LE、UTF-16、UTF-16-BE/LE 的 BOMreq_file.py。源码注释特别提示BOM_UTF16_LE是BOM_UTF32_LE的前缀因此 UTF-32 必须排在 UTF-16 之前判断。PEP 263 声明检查文件前两行中以#开头的行里是否存在coding[:]\s*([-\w.])形式的编码声明。兜底 UTF-8以上均未命中时按 UTF-8 解码若解码失败会回退到区域设置locale编码并打印一条警告日志提示使用者应显式添加 PEP 263 编码注释。五、行延续Line Continuation以未转义的\结尾的行会被视为行延续其后的换行符被忽略前后两行拼接为一行--config-settings build_option--with-x \ --config-settings othervalue pkgname从实现看join_linesreq_file.py在拼接时以第一行的行号作为拼接结果的行号并且只处理不以\结尾的普通行注释行以#开头不会触发延续拼接。六、注释规则以#开头的行整体视为注释并被忽略行内空白符后出现的#会将#及其后的内容视为注释注释的剔除发生在行延续处理之后源码preprocess顺序为join_lines→ignore_comments→expand_env_variables见 req_file.py。这带来一个值得注意的行为如果#出现在行首之后、但前面没有空白符例如拼接后的行中间COMMENT_RE r(^|\s)#.*$req_file.py要求#前必须是行首或空白符才被当作注释起点。单元测试 tests/unit/test_req_file.py 中的test_strip_commentreq # 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_linereq_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 值hash、config_settings会被提取到该行的ParsedRequirement.options中req_file.py随单个需求生效而全局选项作用于整次安装。handle_linereq_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(?Pvar\$\{(?Pname[A-Z0-9_])\})req_file.py展开发生在注释剔除之后。这样做的两个设计动机源码注释中明确说明避免字符串中出现的$被误展开保证不同平台Windows / Unix间需求文件行为一致。实际用途将 Token、密钥等敏感信息放在环境变量中需求文件里只写变量名运行时由 pip 查值。这与常见的 12-factor 配置模式把配置注入环境保持一致例如# 私有索引需要认证的场景 --index-url https://${PRIVATE_INDEX_USER}:${PRIVATE_INDEX_TOKEN}pypi.example.com/simple注意环境变量展开同样适用于 URL 片段因此可以安全地把凭证从文件里剥离出去避免把密钥提交进版本库。十、从源码看解析全流程将文档中的语法规则对应到源码执行顺序一个需求文件的完整处理链路是读取文件get_file_contentreq_file.py支持普通路径、file://URL 与http(s)://URL后者通过PipSession拉取随后按第五节所述进行 BOM / PEP 263 / UTF-8 解码。预处理preprocessreq_file.pyjoin_lines行延续拼接→ignore_comments剔除注释、过滤空行→expand_env_variables环境变量展开。逐行解析每行先经break_args_options拆分为参数与选项再用build_parser构建的、仅含SUPPORTED_OPTIONS SUPPORTED_OPTIONS_REQ的 optparse 解析器解析选项req_file.py解析失败会包装为OptionParsingError再转成RequirementsFileParseError并附上出错的原始行文本。递归处理遇到-r/-c行则递归解析嵌套文件并做循环检测。生成需求handle_line区分需求行产出ParsedRequirement与纯选项行更新PackageFinder/ session 状态。对应地tests/unit/test_req_file.py 中的test_comments_and_joins_case1/2/3、test_ignore_comment、test_strip_comment等用例直接验证了注释与拼接的交互规则可以作为阅读解析行为的入口。十一、实践建议与常见坑结合上述语法与源码行为编写需求文件时建议留意以下几点区分-r与-c需求文件中的包会被安装约束文件只锁版本。多层引用时保持两者语义清晰避免用-c引入的文件意外漏装依赖。避免引用环-r互相引用会触发RequirementsFileParseError用相对路径引用时注意目录层级善用相对需求文件目录的解析规则。选项行单独成行全局选项必须独占一行且每行只放一个选项源码实现支持多选项但文档约定为单选项便于阅读与调试。哈希校验与敏感信息对不可变版本建议启用--require-hashes 每行--hash提升供应链安全性认证凭证一律走${ENV_VAR}而非明文。编码声明文件含非 UTF-8 内容时务必在首行或次行加 PEP 263 编码注释否则会回退到区域设置编码并产生警告日志。不要加 shell 引号需求文件内的 specifier 不加引号只有命令行中因 shell 解释才需要引号包裹、或环境标记。需求文件格式是 pip 生态中被引用最广泛的接口之一理解其语法边界哪些选项可用、哪些不可用与解析行为能帮助你写出既稳定又可审计的依赖管理配置。【免费下载链接】pipThe Python package installer项目地址: https://gitcode.com/gh_mirrors/pi/pip创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表