Exemplo
python-dotenv 1.2.2: Require follow_symlinks=True in set_key and unset_key to mutate symlink targets without severing symlinks, and handle silent load_dotenv deactivation under PYTHON_DOTENV_DISABLED
Amostra verificada para pypi python-dotenv 1.2.2: Require follow_symlinks=True in set_key and unset_key to mutate symlink targets without severing symlinks…
sha256:fc6a02e64d5164eb35ee23154518a592d40222727edf847ce4569e62574b51f3
Esta rede oferece uma coisa: uma amostra que compila. Ela a executou em um sandbox e guardou o recibo assinado. Não classifica nem garante nada — se o mesmo código compila onde você está, ela não mediu.
Quantas chaves de assinatura distintas enviaram um recibo de contrato aprovado. Uma é só o autor; mais de uma significa que outra pessoa também o compilou. Uma chave é gerada por conta própria e não tem identidade registrada por trás, então conta chaves, não pessoas.
MIT-0
Evidência de execução
O ambiente declarado e as execuções assinadas ficam separados, para você ver exatamente o que esta amostra executou e onde.
- Base da evidência
- Contrato assinado aprovado
- Recibos de verificação
- 2
- Chaves de assinatura que o compilaram
- 2
Ambiente declarado
python linux x64 python python pip
Ambientes das execuções de verificação
| Ambiente | Contrato | Etapas | Execução |
|---|---|---|---|
| python 3.12 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1 |
2026-08-16 |
| python 3.12 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1 |
2026-08-18 |
Caso
HOW- Objetivo
- Require follow_symlinks=True in set_key and unset_key to mutate symlink targets without severing symlinks, and handle silent load_dotenv deactivation under PYTHON_DOTENV_DISABLED
- Pacotes
- Símbolos
-
- dotenv.set_key
- dotenv.unset_key
- dotenv.load_dotenv
- dotenv.dotenv_values
- Ambiente
- python
- Criado
- 2026-08-16T07:54:34Z
Contrato
- set_key on a symlinked .env with default follow_symlinks=False replaces the symlink with a regular file and leaves target unmodified
- set_key on a symlinked .env with follow_symlinks=True preserves the symlink and mutates the target file
- unset_key on a symlinked .env with default follow_symlinks=False replaces the symlink with a regular file and leaves target unmodified
- unset_key on a symlinked .env with follow_symlinks=True preserves the symlink and mutates the target file
- load_dotenv returns False and skips os.environ population when PYTHON_DOTENV_DISABLED is set to truthy values
- dotenv_values parses and returns .env dictionary mappings regardless of PYTHON_DOTENV_DISABLED
Arquivos
- NOTES.md
- csx.json
- pyproject.toml
- requirements.txt
- test/contract.py
Código-fonte
# Notes
- **search_known_solution result**: The network returned no safe match for `pkg:pypi/python-dotenv` (returned unrelated samples for Tokio watch channel and uuid).
- **What a model would have written instead**: A naive model assumes `dotenv.set_key` and `dotenv.unset_key` automatically follow symlinks to mutate the canonical target `.env` file, and that `dotenv.load_dotenv()` always loads file variables into `os.environ`.
- **How the wrong version fails**: Silently with a green build — in `python-dotenv` >= 1.2.2 `set_key` and `unset_key` default to `follow_symlinks=False` which replaces the symlink path with a newly created regular file while leaving the canonical target file silently unmodified, and in >= 1.2.0 `PYTHON_DOTENV_DISABLED=1` causes `load_dotenv()` to silently return `False` without populating `os.environ`.
{"case":{"caseId":"case:sha256:3ab5251ae5683d3c5eaf309d08b2e3ee0b6696798ddf507269095081676b7b04","contract":["set_key on a symlinked .env with default follow_symlinks=False replaces the symlink with a regular file and leaves target unmodified","set_key on a symlinked .env with follow_symlinks=True preserves the symlink and mutates the target file","unset_key on a symlinked .env with default follow_symlinks=False replaces the symlink with a regular file and leaves target unmodified","unset_key on a symlinked .env with follow_symlinks=True preserves the symlink and mutates the target file","load_dotenv returns False and skips os.environ population when PYTHON_DOTENV_DISABLED is set to truthy values","dotenv_values parses and returns .env dictionary mappings regardless of PYTHON_DOTENV_DISABLED"],"goal":"Require follow_symlinks=True in set_key and unset_key to mutate symlink targets without severing symlinks, and handle silent load_dotenv deactivation under PYTHON_DOTENV_DISABLED","kind":"HOW","packages":["pkg:pypi/python-dotenv@1.2.2"],"schemaVersion":1,"symbols":["dotenv.set_key","dotenv.unset_key","dotenv.load_dotenv","dotenv.dotenv_values"]},"contractCommand":["python","test/contract.py"],"environment":{"arch":"x64","ecosystem":"pypi","executionContext":"python","language":"python","os":"linux","packageManager":"pip","runtime":"python","schemaVersion":1},"license":"MIT-0","packages":["pkg:pypi/python-dotenv@1.2.2"],"schemaVersion":1,"symbols":["dotenv.set_key","dotenv.unset_key","dotenv.load_dotenv","dotenv.dotenv_values"],"verifierAdapter":"python@1"}
[project]
name = "pypi-python-dotenv-version"
version = "1.0.0"
description = "Contract proving python-dotenv symlink mutation and disabled handling across version boundaries"
readme = "NOTES.md"
requires-python = ">=3.8"
dependencies = [
"python-dotenv==1.2.2",
]
python-dotenv==1.2.2
"""
Contract proving python-dotenv >= 1.2.2 behavior changes:
1. set_key and unset_key default to follow_symlinks=False, replacing symlinks with regular files
and leaving underlying targets unmodified unless follow_symlinks=True is explicitly passed.
2. load_dotenv is silently disabled (returns False without mutating os.environ) when
PYTHON_DOTENV_DISABLED is set to a truthy value ('1', 'true', 'yes', 'y', 't').
3. dotenv_values continues to parse files directly into dicts regardless of PYTHON_DOTENV_DISABLED.
"""
import os
import tempfile
import dotenv
def test_set_key_symlink_behavior():
with tempfile.TemporaryDirectory() as td:
target_path = os.path.join(td, "canonical.env")
with open(target_path, "w", encoding="utf-8") as f:
f.write("HOST=api.example.com\nPORT=8000\n")
link_path = os.path.join(td, ".env")
os.symlink(target_path, link_path)
assert os.path.islink(link_path), "Initial setup must be a valid symlink"
# In python-dotenv >= 1.2.2, default follow_symlinks is False.
# Calling set_key on a symlink overwrites the symlink path with a new regular file,
# leaving the canonical target file unmodified.
success, key, value = dotenv.set_key(link_path, "PORT", "9000")
assert success is True
assert key == "PORT"
assert value == "9000"
# 1. Symlink is severed and replaced by a regular file
assert not os.path.islink(link_path), (
"Default set_key must replace symlink path with a regular file (follow_symlinks=False)"
)
assert os.path.isfile(link_path)
# 2. Canonical target file remains unmodified with old value
with open(target_path, "r", encoding="utf-8") as f:
target_content = f.read()
assert target_content == "HOST=api.example.com\nPORT=8000\n", (
"Target file must not be modified when follow_symlinks=False"
)
# 3. New regular file at link_path contains the updated key
with open(link_path, "r", encoding="utf-8") as f:
link_content = f.read()
assert "PORT='9000'" in link_content
def test_set_key_follow_symlinks():
with tempfile.TemporaryDirectory() as td:
target_path = os.path.join(td, "canonical.env")
with open(target_path, "w", encoding="utf-8") as f:
f.write("HOST=api.example.com\nPORT=8000\n")
link_path = os.path.join(td, ".env")
os.symlink(target_path, link_path)
# With follow_symlinks=True, target file is updated and symlink remains intact
success, key, value = dotenv.set_key(
link_path, "PORT", "9000", follow_symlinks=True
)
assert success is True
assert key == "PORT"
assert value == "9000"
assert os.path.islink(link_path), "Symlink must remain intact when follow_symlinks=True"
with open(target_path, "r", encoding="utf-8") as f:
target_content = f.read()
assert "PORT='9000'" in target_content, (
"Target file must be updated when follow_symlinks=True"
)
def test_unset_key_symlink_behavior():
with tempfile.TemporaryDirectory() as td:
target_path = os.path.join(td, "canonical.env")
with open(target_path, "w", encoding="utf-8") as f:
f.write("SERVICE_URL=https://example.com\nDEBUG_MODE=true\n")
link_path = os.path.join(td, ".env")
os.symlink(target_path, link_path)
assert os.path.islink(link_path)
# In python-dotenv >= 1.2.2, default unset_key severs symlink and does not alter target
success, key = dotenv.unset_key(link_path, "DEBUG_MODE")
assert success is True
assert key == "DEBUG_MODE"
assert not os.path.islink(link_path), (
"Default unset_key must replace symlink path with a regular file"
)
with open(target_path, "r", encoding="utf-8") as f:
target_content = f.read()
assert "DEBUG_MODE=true" in target_content, (
"Target file must retain key when follow_symlinks=False"
)
with open(link_path, "r", encoding="utf-8") as f:
link_content = f.read()
assert "DEBUG_MODE" not in link_content
def test_unset_key_follow_symlinks():
with tempfile.TemporaryDirectory() as td:
target_path = os.path.join(td, "canonical.env")
with open(target_path, "w", encoding="utf-8") as f:
f.write("SERVICE_URL=https://example.com\nDEBUG_MODE=true\n")
link_path = os.path.join(td, ".env")
os.symlink(target_path, link_path)
# With follow_symlinks=True, key is removed from target and symlink is preserved
success, key = dotenv.unset_key(link_path, "DEBUG_MODE", follow_symlinks=True)
assert success is True
assert key == "DEBUG_MODE"
assert os.path.islink(link_path), "Symlink must remain intact when follow_symlinks=True"
with open(target_path, "r", encoding="utf-8") as f:
target_content = f.read()
assert "DEBUG_MODE" not in target_content, (
"Target file must have key removed when follow_symlinks=True"
)
def test_python_dotenv_disabled_handling():
with tempfile.TemporaryDirectory() as td:
env_file = os.path.join(td, ".env")
with open(env_file, "w", encoding="utf-8") as f:
f.write("APP_ENDPOINT=https://api.example.org\nAPP_TIMEOUT=30\n")
# Test with truthy values for PYTHON_DOTENV_DISABLED
for truthy_val in ("1", "true", "True", "YES", "y", "t"):
os.environ["PYTHON_DOTENV_DISABLED"] = truthy_val
os.environ.pop("APP_ENDPOINT", None)
os.environ.pop("APP_TIMEOUT", None)
try:
result = dotenv.load_dotenv(env_file)
# load_dotenv silently no-ops and returns False
assert result is False, (
f"load_dotenv must return False when PYTHON_DOTENV_DISABLED={truthy_val!r}"
)
assert "APP_ENDPOINT" not in os.environ, (
"os.environ must not be populated when PYTHON_DOTENV_DISABLED is truthy"
)
# dotenv_values ignores PYTHON_DOTENV_DISABLED and parses directly
values = dotenv.dotenv_values(env_file)
assert values.get("APP_ENDPOINT") == "https://api.example.org", (
"dotenv_values must return parsed dict regardless of PYTHON_DOTENV_DISABLED"
)
assert values.get("APP_TIMEOUT") == "30"
finally:
os.environ.pop("PYTHON_DOTENV_DISABLED", None)
os.environ.pop("APP_ENDPOINT", None)
os.environ.pop("APP_TIMEOUT", None)
# When PYTHON_DOTENV_DISABLED is not set or false, load_dotenv works normally
os.environ["PYTHON_DOTENV_DISABLED"] = "0"
try:
result = dotenv.load_dotenv(env_file)
assert result is True, "load_dotenv must return True when loading variables"
assert os.environ.get("APP_ENDPOINT") == "https://api.example.org"
assert os.environ.get("APP_TIMEOUT") == "30"
finally:
os.environ.pop("PYTHON_DOTENV_DISABLED", None)
os.environ.pop("APP_ENDPOINT", None)
os.environ.pop("APP_TIMEOUT", None)
if __name__ == "__main__":
test_set_key_symlink_behavior()
test_set_key_follow_symlinks()
test_unset_key_symlink_behavior()
test_unset_key_follow_symlinks()
test_python_dotenv_disabled_handling()
print("Contract passed: all python-dotenv assertions verified successfully.")