news 2026/9/25 7:55:30

python-dotenv 完整变更历史解析:从版本演进看 .env 配置管理库的核心能力

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
python-dotenv 完整变更历史解析:从版本演进看 .env 配置管理库的核心能力
  • 后端

【免费下载链接】python-dotenv

Reads key-value pairs from a .env file and can set them as environment variables. It helps in developing applications following the 12-factor principles.

项目地址:https://gitcode.com/gh_mirrors/py/python-dotenv
点击查看免费下载

本文以 python-dotenv 官方 变更日志 为骨架,结合仓库源码与测试逐版本解读关键演进:从 .env 文件解析、变量插值、load_dotenv/dotenv_values加载语义,到set_key/unset_key写入机制与 CLI 命令的完整能力边界。读完本文,你将掌握该库每个版本引入/修复的核心行为、各 API 参数的准确语义,以及如何用当前仓库源码验证这些行为。

项目与文档概览

python-dotenv 是一个读取.env文件中的 key-value 对并将其设置为环境变量的工具,遵循十二要素(12-factor)应用开发原则,将配置与代码分离。当前仓库版本为1.2.2(见 src/dotenv/version.py),支持 Python 3.10 及以上(见 pyproject.toml)。

变更日志 遵循 Keep a Changelog 格式,并遵循语义化版本控制(Semantic Versioning)。本文将逐版本解读其中的 Added(新增)、Changed(变更)、Fixed(修复)、Breaking Changes(破坏性变更)条目,并用仓库中的源码与测试印证其真实行为。

最新版本 1.2.2(2026-03-01):BOM、符号链接与 CLI 行为

新增:Python 3.14 与自由线程构建支持

  • 支持 Python 3.14,包括 free-threaded(3.14t)构建。对应 pyproject.toml 中新增的Programming Language :: Python :: 3.14classifier 以及requires-python = ">=3.10"。
  • 同步将 PyPy 支持更新到 3.11,并移除了 Python 3.9 支持(Dropped Support for Python 3.9)。

修复:UTF-8 BOM 处理

变更日志 [Unreleased] 与 1.2.2 之前的提交都提及一个关键修复:剥离.env文件内容开头的 UTF-8 BOM,避免当文件以 BOM 保存(例如部分 JetBrains IDE 在 Windows 上保存文件时)导致第一个变量被静默丢弃。

该行为在源码中可直接验证:在 src/dotenv/parser.py 的Reader.__init__中,读取流内容后立即执行self.string = stream.read().removeprefix("\ufeff"),即在解析开始前就移除 BOM 字符。

修复:set_key与unset_key的符号链接行为

1.2.2 修复了set_key/unset_key与符号链接(symlink)交互时的行为(由 src/dotenv/main.py 中的rewrite()上下文管理器实现):

  • 默认不再跟随符号链接:修改时若路径是符号链接,默认会替换链接本身(用普通文件覆盖),而不是修改链接指向的目标文件,避免意外修改到不可信路径下的文件。测试 tests/test_main.py 中test_set_key_symlink_to_existing_file验证:对指向target.env的符号链接调用set_key后,目标文件内容保持不变,而符号链接被替换为普通文件。
  • 恢复旧行为需显式传follow_symlinks=True:此时会先os.path.realpath(path)解析到真实路径再修改。test_set_key_follow_symlinks验证此时目标文件内容被修改且符号链接保持不变。

破坏性变更:文件权限位不再被重置

1.2.2 引入三项 Breaking Changes:

  1. dotenv.set_key和dotenv.unset_key不再在部分场景下跟随符号链接(需follow_symlinks=True恢复)。
  2. CLI 的set和unset命令同样不再跟随符号链接。
  3. set_key、unset_key及 CLIset/unset不再将修改后的.env文件权限重置为0o600:原文件的权限位现在被保留;仅当文件需要被新建或原本不是普通文件时,才使用0o600。

源码验证:rewrite()中通过os.lstat(path)读取原文件模式,若stat.S_ISREG为真则保存stat.S_IMODE(...);写入临时文件后若存在original_mode则os.chmod(dest_path, original_mode),再os.replace原子替换。测试test_set_key_preserves_file_mode验证将文件 chmod 为0o640后执行set_key,权限保持不变。

其他变更

  • dotenv run命令现在将额外 flags 直接透传给指定的命令。
  • 改进了 override 行为与 reference 页面的文档说明。
  • 增加了 FIFO 文件支持的文档(对应下文 1.2.1 的 FIFO 支持)。
  • 修正了包元数据中的 license 说明并补齐了 Python 3.14 classifier。

版本 1.2.1(2025-10-26):FIFO 与构建配置精简

  • 新增从 FIFO(Unix 命名管道)读取.env的能力:load_dotenv可以接收一个 FIFO 路径作为dotenv_path。源码中_is_file_or_fifo()(见 src/dotenv/main.py)在os.path.isfile不成立时进一步通过os.stat判断stat.S_ISFIFO;find_dotenv查找文件时也使用该判定。
    • 测试 tests/test_fifo_dotenv.py 演示了完整用法:os.mkfifo(fifo)创建命名管道,在一个线程中向管道写入MY_PASSWORD=pipe-secret,主线程调用load_dotenv(dotenv_path=str(fifo), override=True)即可把值读入环境变量——适合从外部进程"注入"机密而避免落盘。
  • 构建配置进一步迁入pyproject.toml,移除了setup.cfg。

版本 1.2.0(2025-10-26):PYTHON_DOTENV_DISABLED与 PEP 517 构建

新增:全局禁用开关

本版本新增通过环境变量PYTHON_DOTENV_DISABLED禁用load_dotenv()的能力。其语义为:

  • 若该变量被设置为真值(1、true、t、yes、y,大小写不敏感),load_dotenv()直接返回False且不加载任何内容。
  • 该判定在 src/dotenv/main.py 的_load_dotenv_disabled()中实现:先检查变量是否存在于os.environ,再用.casefold()归一化后与真值集合比对。
  • 测试 tests/test_main.py 的test_load_dotenv_disabled用"true"、"yes"、"1"、"t"、"y"及其大写形式验证返回False;test_load_dotenv_enabled用""、"false"、"no"、"0"、"f"、"n"等验证仍正常加载。

典型使用场景:在 CI、容器或测试环境中需要临时关闭.env加载时,无需修改代码,只需注入该环境变量。

其他

  • 构建系统升级为 PEP 517 & PEP 518,使用build与 pyproject.toml([build-system]声明setuptools >= 77.0)。
  • 增加 Python 3.14 支持。

版本 1.1.x(2025):dotenv run的 execvpe 化与 Python 3.13

1.1.0(2025-03-25)

  • 新增 Python 3.13 支持。
  • dotenv run切换到execvpe:在非 Windows 平台,run_command()(src/dotenv/cli.py)用os.execvpe(command[0], args=command, env=cmd_env)替换当前进程,从而获得更好的资源管理与信号处理——子进程信号直接作用于运行中的命令本身;在 Windows 平台则回退为subprocess.Popen+communicate()+sys.exit(returncode)。
  • 修复find_dotenv与load_dotenv在调试器/pdb 中运行时的查找目录:现在会正确地在当前目录查找。源码中find_dotenv通过_is_debugger()(sys.gettrace() is not None)判断是否处于调试器环境,若是则从os.getcwd()开始向上查找。

1.1.1(2025-06-24)

  • 修复 CLI 中find_dotenv在 Python 3.13 上的可靠性。
  • 在 Windows 上回退了execvpe的使用(即采用上述 Popen 方案)。

Misc

  • 移除了 Python 3.8 支持。

版本 1.0.x(2023-2024):稳定版收尾

1.0.0(2023-02-24)

  • 移除 Python 3.7 支持,新增 Python 3.12-dev 支持。
  • 处理当前工作目录(cwd)不存在的情况:enumerate_env()(src/dotenv/cli.py)捕获os.getcwd()抛出的FileNotFoundError并返回None,避免 CLI 在异常目录下崩溃。

1.0.1(2024-01-23)

  • 优雅处理从 zipfile 导入的代码(test_zip_imports.py有对应测试):当模块位于 zip 归档中时__file__指向 zip 内部路径,find_dotenv的帧遍历逻辑会跳过不存在路径的帧。
  • 允许在独立线程中启动时重载使用load_dotenv的模块。
  • 修复删除后文件句柄未关闭、rewrite 函数中的错误处理:对应 src/dotenv/main.pyrewrite()中try/finally式的关闭逻辑;测试test_rewrite_closes_file_handle_on_lstat_failure验证 lstat 失败时所有打开的句柄都被关闭。

版本 0.21.x:CLI 与类型现代化(2022-2023)

  • CLI 支持python -m dotenv调用:入口在 src/dotenv/main.py,if __name__ == "__main__": cli();同时 pyproject.toml 中[project.scripts]声明dotenv = "dotenv.__main__:cli",因此dotenv命令与python -m dotenv等价。
  • load_dotenv现在返回False而非此前可能抛错,语义更明确:True表示至少设置了一个环境变量,False表示没有。
  • CLIlist命令新增--format=选项,取值simple(默认)、json、shell、export(见 tests/test_cli.py 的参数化测试)。
  • 修复get/list命令在 env 文件无法打开时的错误信息(src/dotenv/cli.py 的stream_file()打印Error opening env file: ...并以退出码 2 退出)。
  • 修复 IPython 测试中已弃用的magic警告;为dotenv_path添加StrPath类型别名;License 对齐 BSD OSI 模板。

版本 0.20.0(2022-03-24):encoding参数全面化

  • 为get_key、set_key、unset_key增加encoding(Optional[str])参数。至此库内所有读写入口(load_dotenv、dotenv_values、get_key、set_key、unset_key)都支持自定义编码。
  • 测试 tests/test_main.py 中test_set_key_encoding/test_get_key_encoding/test_unset_encoding用latin-1编码验证了非 UTF-8 场景。
  • 不再构建 universal wheel(py2.py3-none-any),仅构建 py3 wheel。

版本 0.19.x:Python 版本边界与参数类型放宽

  • 0.19.0:要求 Python 3.5+,正式放弃 Python 2 与 3.4。
    • set_key/unset_key的dotenv_path参数类型从os.PathLike放宽为Union[str, os.PathLike]。
    • load_dotenv/dotenv_values的stream参数现在接受文本流IO[str],包括io.StringIO("foo")与open("file.env", "r")这类对象(对应test_load_dotenv_string_io_utf_8、test_load_dotenv_file_stream测试)。
  • 0.19.2:修复set_key在追加新条目时若文件末尾缺少换行符则补上\n的问题(对应 src/dotenv/main.pyset_key中的missing_newline逻辑)。

版本 0.18.0(2021-06-20):引号策略的形式化

本版本重新定义了set_key与dotenv set <key> <value>写值时的引号规则:

  • 非法quote_mode抛ValueError:quote_mode必须是always、auto、never三者之一(src/dotenv/main.pyset_key开头即校验)。
  • 写入时优先使用单引号而非双引号。
  • 不再剥离值两侧的引号(如值本身是'b'会原样写入a='\'b\'',见test_set_key参数化用例)。
  • auto模式下仅当值由纯字母数字组成(str.isalnum())时不加引号:源码quote = quote_mode == "always" or (quote_mode == "auto" and not value_to_set.isalnum())。

注意 CLI 全局选项-q/--quote的三个取值always/never/auto与此一一对应(src/dotenv/cli.py)。

版本 0.17.x-0.16.0:run 覆盖控制与插值解析顺序

  • 0.17.0:dotenv get <key>只输出值本身(b),不再输出key=value;新增dotenv run --override/--no-override选项(run命令默认override=True,见 src/dotenv/cli.py)。
  • 0.16.0:
    • load_dotenv/dotenv_values的encoding默认值从None改为"utf-8"(当前签名即encoding: Optional[str] = "utf-8")。
    • 修复override=False时变量展开(variable expansion)的解析顺序:源码resolve_variables()(src/dotenv/main.py)中,override=True时先合并os.environ再合并.env内新值(文件优先);override=False时先合并新值再合并os.environ(环境优先)。对应测试test_load_dotenv_redefine_var_used_in_file_no_override(a=c已存在、文件写a=b、d="${a}",结果为d=c)。

版本 0.15.0(2020-10-28):export前缀与自动建文件

  • CLIset命令新增--export选项:写入时在绑定前加export前缀(如export KEY=value),使.env文件可直接作为 bash 脚本source执行。源码set_key的export: bool = False参数控制line_out = f"export {key_to_set}={value_out}\n"或普通形式。
  • set命令在未找到.env文件时,会在当前目录创建.env。对应test_set_key_no_file:对不存在的路径调用set_key返回(True, "foo", "bar")且文件被创建。
  • 修复重复 key 时可能出现的空展开值;修复未加引号值中多个相邻空格/制表符的解析(对应_unquoted_value正则([^\r\n]*)与parse_unquoted_value中re.sub(r"\s+#.*", "", part).rstrip())。

版本 0.14.0-0.11.0:插值语义的演进

  • 0.14.0:变量展开时文件中的定义优先于环境变量(对应上述resolve_variables的override=True合并顺序)。
  • 0.13.0:新增 Bash 风格的默认值语法${VAR:-default}。源码 src/dotenv/variables.py 的正则_posix_variable支持可选(?::-(?P<default>[^\}]*))?分组;Variable.resolve()中default = self.default if self.default is not None else "",未定义变量时回退到默认值。
  • 0.12.0:使用 PyInstaller 打包时改用当前工作目录查找.env(对应find_dotenv中getattr(sys, "frozen", False)判定)。
  • 0.11.0:
    • load_dotenv/dotenv_values新增interpolate参数:设为False可禁用 POSIX 变量插值(见 src/dotenv/main.pyDotEnv.dict()中if self.interpolate: resolve_variables(...)的分支)。
    • 从warnings切换为logging输出(当前为logger.warning(...)/logger.info(...),见with_warn_for_invalid_lines)。

插值行为一览(可用dotenv_values验证,测试见 tests/test_main.py):

输入是否插值结果
a=$b(环境b=c)任意a=$b($b不展开)
a=${b}(环境b=c)是a=c
a=${b}(未定义)是a=(空串)
a=${b:-d}(未定义)是a=d
a=${b:-d}(环境b=c)是a=c
文件内b=d后a=${b}是a=d(文件定义优先)
a=${b}${b}(环境b=c)是a=cc

版本 0.10.x:解析器重构与容错

  • 0.10.0:支持 UTF-8 非引号值、行尾注释、值中的反斜杠、值中的换行;Windows 上 Python 2 强制将环境变量转为str;移除 Python 3.3 支持。
  • 0.10.1:修复无值变量的解析。
  • 0.10.2:添加类型提示并对用户公开;load_dotenv/dotenv_values接受encoding参数(当时默认None)。
  • 0.10.3:改进交互式环境检测(_is_interactive()判断sys.ps1/sys.ps2或__main__无__file__);重构解析器统一行为:
    • 转义仅在双引号字符串中被解释为控制字符(_double_quote_escapes匹配\\[\\'\"abfnrtv])。
    • #仅在其前有空白时才被当作注释开始(parse_unquoted_value中re.sub(r"\s+#.*", "", part))。
  • 0.10.4:类型标注变为可选;格式错误的行打印警告;支持无值的 key(解析结果中 value 为None,dotenv_values返回{"foo": None})。
  • 0.10.5:进一步拒绝更多畸形行(如A: B、a='b',c),无值 key 不再告警,纯注释行正确处理。

版本 0.9.0-0.6.0:CLI 成型期

  • 0.9.0:CLI 新增--version参数(由 src/dotenv/cli.py 的@click.version_option(version=__version__)提供);支持从当前目录加载;新增dotenv run命令——用.env中的变量运行任意 shell 命令。
  • 0.8.1:cli支持变为可选,需pip install python-dotenv[cli](pyproject.toml 中[project.optional-dependencies] cli = ["click>=5.0"];src/dotenv/cli.py 在 import click 失败时提示该安装命令)。
  • 0.8.0:set_key/unset_key改为只修改受影响的行而不是解析后重写整个文件,注释与其余内容原样保留(rewrite()中逐行比对mapping.key == key_to_set,其余行dest.write(mapping.original.string));支持行内export前缀;load_dotenv/dotenv_values支持StringIO。
  • 0.7.1:移除对 iPython 的硬依赖。
  • 0.7.0:支持通过.env覆盖系统环境变量(override);".env not found" 警告默认关闭(verbose=False)。
  • 0.6.x:支持特殊字符\;修复单引号问题;CLIlist命令修复;新增 iPython 支持(%dotenvmagic,见 src/dotenv/ipython.py,%load_ext dotenv后可通过%dotenv加载,支持-o/-v选项)。
  • 0.6.0:移除 Python 2.6 支持;处理引号值中的转义字符与换行;去除未加引号 key/value 周围空白;新增 POSIX 变量展开。

早期版本(0.4.0-0.5.1):能力奠基

  • 0.5.0:新增find_dotenv方法——从调用处所在文件目录开始逐级向根目录查找.env(_walk_to_root逐级向上遍历,命中_is_file_or_fifo即返回)。
  • 0.5.1:修复find_dotenv从调用该函数的文件处开始搜索(当前实现通过sys._getframe()回溯栈帧获取调用方文件路径)。
  • 0.4.0:CLI 新增-q/--quote选项控制.env中值的引号行为(即现在的always/never/auto前身)。

从变更日志看当前 API 全貌

综合上述演进,当前版本的公开 API(见 src/dotenv/init.py 的__all__)为:

API核心参数说明
load_dotenv(dotenv_path=None, stream=None, verbose=False, override=False, interpolate=True, encoding="utf-8")路径或流二选一解析并写入os.environ;返回是否至少设置了 1 个变量;受PYTHON_DOTENV_DISABLED控制
dotenv_values(dotenv_path=None, stream=None, verbose=False, interpolate=True, encoding="utf-8")同上只返回 dict,不写环境;无值 key 对应None;内部override=True
find_dotenv(filename=".env", raise_error_if_not_found=False, usecwd=False)查找策略从调用文件目录逐级向上查找,交互式/调试器/PyInstaller 下从 cwd 开始
get_key(dotenv_path, key_to_get, encoding="utf-8")单键读取找不到或无值返回None
set_key(dotenv_path, key_to_set, value_to_set, quote_mode="always", export=False, encoding="utf-8", follow_symlinks=False)写入/更新文件不存在则创建;默认单引号、不跟随符号链接、保留原文件权限
unset_key(dotenv_path, key_to_unset, quote_mode="always", encoding="utf-8", follow_symlinks=False)删除键文件或 key 不存在时返回(None, key)并告警
get_cli_string(path=None, action=None, key=None, value=None, quote=None)CLI 辅助生成适合 shell 执行的dotenv命令字符串
load_ipython_extension(ipython)iPython 集成注册%dotenvmagic

CLI 命令面(python -m dotenv或dotenv,依赖python-dotenv[cli]):

  • 全局选项:-f/--file(默认当前目录.env)、-q/--quote(always/never/auto)、-e/--export、--version。
  • dotenv list [--format simple|json|shell|export]:列出所有键值。
  • dotenv get <key>:只输出值。
  • dotenv set <key> <value>:写入并回显key=value。
  • dotenv unset <key>:删除键。
  • dotenv run [--override/--no-override] <command>...:携带.env变量执行命令(非 Windows 下通过execvpe替换进程)。

结语

从 0.4.0 的-q/--quote选项,到 1.2.2 的 BOM 剥离与符号链接安全策略,python-dotenv 的变更日志完整记录了一个配置加载工具走向生产可用的全过程。透过这些版本条目去阅读 src/dotenv/main.py、src/dotenv/parser.py、src/dotenv/cli.py 与 tests/test_main.py 等源码,可以精确理解每个参数的真实语义——这正是把变更日志从"新闻列表"升华为"技术手册"的正确方式。

  • 后端

【免费下载链接】python-dotenv

Reads key-value pairs from a .env file and can set them as environment variables. It helps in developing applications following the 12-factor principles.

项目地址:https://gitcode.com/gh_mirrors/py/python-dotenv
点击查看免费下载

相关推荐

上一篇:未来已来:IBM Granite-4.1系列模型路线图与131072序列长度的应用前景
下一篇:Smart-Admin技术栈选型:为什么选择Vue3与Spring Boot构建现代化企业后台管理系统

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

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

豆瓣图书知识图谱实战:Neo4j图数据库推荐系统搭建

简介&#xff1a;本资源是一套面向高校计算机及相关专业&#xff08;人工智能、自动化、物联网等&#xff09;学生的毕业设计级实践项目&#xff0c;聚焦豆瓣图书推荐系统与知识图谱构建&#xff0c;深度融合Neo4j图数据库应用开发。项目完整覆盖数据采集、清洗、图模型设计、实…

作者头像 李华
网站建设 2026/9/25 7:52:18

新手避坑指南:AI博士周有贵教你,选GEO软件拒绝套路只讲干货

很多做网站获客、搜索运营的新手&#xff0c;刚接触 GEO 生成式搜索引擎优化的时候&#xff0c;很容易被各种宣传话术绕晕。市面上相关工具、服务商参差不齐&#xff0c;不少运营新人踩坑&#xff1a;工具功能虚标、关键词挖掘不准、收费暗藏套路&#xff0c;做出来的内容不匹配…

作者头像 李华
网站建设 2026/9/25 7:49:54

安徽部分地区用户力荐的净菜加工配送服务商挑选全攻略

很多安徽连锁餐饮品牌拓展长三角市场&#xff0c;或是跨城布局门店的时候&#xff0c;都在找能做食材溯源的配送公司&#xff0c;也会疑问长三角地区有哪些好的食材配送企业&#xff0c;也会咨询能做食材批量加工配送的公司有哪些靠谱选择。伴随着长三角餐饮连锁化发展不断提速…

作者头像 李华