サンプル
python-dotenv 1.2.2: Pin python-dotenv quote escaping, inline comments, export prefix stripping, default variable expansions, and in-place key mutation
検証済みサンプル — pypi python-dotenv 1.2.2: Pin python-dotenv quote escaping, inline comments, export prefix stripping, default variable expansions, and in-place…
sha256:c9e927eed4079b93ffded0f4740090343478b422f37ebb726907d38cd6295463
このネットワークが提供するのは一つだけです。ビルドされるサンプル。サンドボックスで実行し、署名済みの受領証を保管します。等級はつけず、何も保証しません — 同じコードがあなたの環境でビルドされるかは測定していません。
合格した契約受領証を提出した異なる署名鍵の数です。1 なら作者だけ、2 以上なら他の誰かもビルドしています。鍵は自己生成で背後に登録された身元がないため、数えているのは人ではなく鍵です。
MIT-0
実行証拠
宣言された環境と署名済みの実行を分けてあります。このサンプルが何をどこで実行したかをそのまま確認できます。
- 証拠の基準
- 署名済みコントラクト合格
- 検証レシート
- 2
- ビルドした署名鍵
- 2
宣言された環境
python linux x64 python python pip
検証実行環境
| 環境 | コントラクト | ステージ | 実行日 |
|---|---|---|---|
| python 3.12 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1 |
2026-08-17 |
| 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 |
ケース
HOW- ゴール
- Pin python-dotenv quote escaping, inline comments, export prefix stripping, default variable expansions, and in-place key mutation
- パッケージ
- シンボル
-
- dotenv_values
- get_key
- set_key
- unset_key
- 環境
- python
- 作成日
- 2026-08-17T16:03:38Z
コントラクト
- Double-quoted values interpret escape sequences whereas single-quoted values preserve characters literally in python-dotenv parsing
- assert inline comments are stripped from unquoted values but preserved inside quotes
- assert leading export prefixes are stripped from environment variable definitions
- assert variable expansion ${VAR:-default} resolves to default when the variable is unset
- assert circular variable references resolve safely to empty strings without recursion errors
- assert get_key retrieves values and returns None for missing keys
- assert set_key modifies key bindings in place preserving surrounding comments
- assert unset_key removes bindings returning (True, key) for existing keys and (None, key) for missing keys
ファイル
- NOTES.md
- csx.json
- requirements.txt
- src/__init__.py
- src/parser_utils.py
- test/contract.py
ソース
# python-dotenv Parser Quoting, Variable Defaults, and Key Mutation
## 1. Search Result
- **`search_known_solution`**: HIT on `sha256:6032931e56a20b51b652c9f7c77e9a8fb979e1513bcd63e107668998f1f1f80f` (Goal: *Pin python-dotenv load_dotenv return semantics, dotenv_values isolation, valueless key handling, and interpolation precedence*).
- **Targeted Behaviour**: This sample targets complementary parser and file manipulation behaviors not covered in prior samples: double-quote escape decoding versus single-quote literal preservation, inline comment stripping versus quoted `#` preservation, `export ` prefix stripping, `${VAR:-default}` fallback syntax, circular reference handling, and the in-place file mutation lifecycle (`get_key`, `set_key`, `unset_key`).
## 2. Exact Release Pinned
- `python-dotenv==1.2.2` pinned in `requirements.txt`.
## 3. Observed Behaviour
- **Escape Sequences & Quotes**: In double-quoted strings (`"..."`), escape characters such as `\n`, `\t`, `\"`, and `\\` are decoded into their respective control and quote characters. In single-quoted strings (`'...'`), characters and backslashes are preserved literally.
- **Comments**: For unquoted values, `#` starts an inline comment and trailing whitespace is stripped. Inside quoted strings, `#` is preserved as a literal character.
- **Export Prefix**: Definitions beginning with `export KEY=VALUE` have the `export ` prefix stripped, correctly binding `KEY` to `VALUE`.
- **Variable Expansions**: The parser supports bash-style fallback defaults `${VAR:-default}`, which evaluate to `default` when `VAR` is unset. Unset variables without defaults resolve to empty strings `""`, and circular variable references resolve safely to empty strings without raising recursion errors.
- **In-Place File Operations**:
- `dotenv.get_key(path, key)` returns the string value if found, or `None` if missing.
- `dotenv.set_key(path, key, value, ...)` updates the key in place preserving surrounding comments and ordering, returning `(True, key, value)`. When `export=True`, it formats the written line with an `export ` prefix.
- `dotenv.unset_key(path, key)` deletes the key binding from the file and returns `(True, key)` if found, or `(None, key)` if the key was not present.
{"case":{"caseId":"case:sha256:7b15c5a864aae32199af2c0cf357371f773ef77b78248afd527efca40ff7f6c3","contract":["Double-quoted values interpret escape sequences whereas single-quoted values preserve characters literally in python-dotenv parsing","assert inline comments are stripped from unquoted values but preserved inside quotes","assert leading export prefixes are stripped from environment variable definitions","assert variable expansion ${VAR:-default} resolves to default when the variable is unset","assert circular variable references resolve safely to empty strings without recursion errors","assert get_key retrieves values and returns None for missing keys","assert set_key modifies key bindings in place preserving surrounding comments","assert unset_key removes bindings returning (True, key) for existing keys and (None, key) for missing keys"],"goal":"Pin python-dotenv quote escaping, inline comments, export prefix stripping, default variable expansions, and in-place key mutation","kind":"HOW","packages":["pkg:pypi/python-dotenv@1.2.2"],"schemaVersion":1,"symbols":["dotenv_values","get_key","set_key","unset_key"]},"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_values","get_key","set_key","unset_key"],"verifierAdapter":"python@1"}
python-dotenv==1.2.2
"""python-dotenv version depth contract sample."""
"""Helper functions demonstrating python-dotenv parser, quoting, and key manipulation behavior."""
import io
import os
import tempfile
from pathlib import Path
from typing import Dict, Optional, Tuple, Union
import dotenv
def parse_env_stream(content: str) -> Dict[str, Optional[str]]:
"""
Parse .env string content into a dictionary of key-value pairs.
Demonstrates quote handling, escape parsing, export prefix stripping,
and variable fallback expansions.
"""
return dict(dotenv.dotenv_values(stream=io.StringIO(content)))
def read_file_key(
dotenv_path: Union[str, os.PathLike],
key: str,
encoding: str = "utf-8",
) -> Optional[str]:
"""Retrieve the value of a key from a .env file, returning None if absent."""
return dotenv.get_key(dotenv_path=dotenv_path, key_to_get=key, encoding=encoding)
def write_file_key(
dotenv_path: Union[str, os.PathLike],
key: str,
value: str,
quote_mode: str = "auto",
export: bool = False,
encoding: str = "utf-8",
) -> Tuple[Optional[bool], str, str]:
"""
Update or append a key in a .env file in place, preserving existing comments and ordering.
"""
return dotenv.set_key(
dotenv_path=dotenv_path,
key_to_set=key,
value_to_set=value,
quote_mode=quote_mode,
export=export,
encoding=encoding,
)
def remove_file_key(
dotenv_path: Union[str, os.PathLike],
key: str,
quote_mode: str = "always",
encoding: str = "utf-8",
) -> Tuple[Optional[bool], str]:
"""
Remove a key from a .env file in place.
Returns (True, key) if the key was present and removed,
or (None, key) if the key was not found.
"""
return dotenv.unset_key(
dotenv_path=dotenv_path,
key_to_unset=key,
quote_mode=quote_mode,
encoding=encoding,
)
import io
import os
import sys
import tempfile
from pathlib import Path
# Ensure project root is in sys.path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from src.parser_utils import parse_env_stream, read_file_key, write_file_key, remove_file_key
def test_quote_and_escape_semantics():
"""Verify double-quote escape interpretation vs single-quote literal handling."""
content = (
"PLAIN_TEXT=hello world # trailing comment\n"
'DOUBLE_ESCAPED="line1\\nline2\\ttab\\"quote\\"\\\\backslash"\n'
"SINGLE_LITERAL='line1\\nline2\\ttab\\\"quote\\\"\\\\backslash'\n"
'QUOTED_HASH="value # not a comment"\n'
"MULTILINE_STR='first line\nsecond line'\n"
)
parsed = parse_env_stream(content)
# Double quotes expand escape sequences (\n -> newline, \t -> tab, \" -> ", \\ -> \)
assert parsed["DOUBLE_ESCAPED"] == 'line1\nline2\ttab"quote"\\backslash', (
"Double-quoted values must interpret escape sequences like \\n, \\t, \\\", and \\\\"
)
# Single quotes preserve characters literally
assert parsed["SINGLE_LITERAL"] == 'line1\\nline2\\ttab\\"quote\\"\\backslash', (
"Single-quoted values must preserve escape characters as raw literals"
)
# Unquoted inline comments are stripped, quoted '#' characters are preserved
assert parsed["PLAIN_TEXT"] == "hello world"
assert parsed["QUOTED_HASH"] == "value # not a comment"
assert parsed["MULTILINE_STR"] == "first line\nsecond line"
def test_export_prefix_and_variable_expansion_defaults():
"""Verify export prefix stripping, variable fallback defaults, and circular reference safety."""
content = (
"export ACTIVE_EXPORT=enabled\n"
"APP_FALLBACK=${UNSET_CONFIG_VAR:-default_endpoint}\n"
"APP_EMPTY_EXPAND=${NONEXISTENT_VAR}\n"
"NODE_A=${NODE_B}\n"
"NODE_B=${NODE_A}\n"
"LITERAL_DOLLAR_SIGN=\\$NOT_EXPANDED\n"
)
parsed = parse_env_stream(content)
# Export prefix stripped
assert parsed["ACTIVE_EXPORT"] == "enabled", "Leading 'export ' keyword must be stripped from variable names"
# Default fallback syntax ${VAR:-default} expands to fallback if VAR is unset
assert parsed["APP_FALLBACK"] == "default_endpoint", (
"Variable expression ${VAR:-default} must expand to the provided default when unset"
)
# Unset variable without default resolves to empty string
assert parsed["APP_EMPTY_EXPAND"] == ""
# Circular variable references resolve safely to empty string without raising RecursionError
assert parsed["NODE_A"] == ""
assert parsed["NODE_B"] == ""
# Escaped dollar sign remains literal
assert parsed["LITERAL_DOLLAR_SIGN"] == "\\$NOT_EXPANDED"
def test_in_place_key_mutation_lifecycle():
"""Verify get_key, set_key, and unset_key operations on .env files."""
with tempfile.TemporaryDirectory() as td:
env_file = Path(td) / ".env"
env_file.write_text(
"# System Configuration\n"
"SERVICE_PORT=8080\n"
"DB_HOST=localhost\n",
encoding="utf-8",
)
# 1. get_key on existing and absent keys
assert read_file_key(env_file, "SERVICE_PORT") == "8080"
assert read_file_key(env_file, "MISSING_KEY") is None
# 2. set_key updates existing key in place, preserving comments and format
res1 = write_file_key(env_file, "SERVICE_PORT", "9090", quote_mode="never")
assert res1 == (True, "SERVICE_PORT", "9090")
# 3. set_key with export=True appends exported line
res2 = write_file_key(env_file, "APP_ENV", "production", export=True, quote_mode="never")
assert res2 == (True, "APP_ENV", "production")
# Check updated file content structure
lines = env_file.read_text(encoding="utf-8").splitlines()
assert "# System Configuration" in lines
assert "SERVICE_PORT=9090" in lines
assert "DB_HOST=localhost" in lines
assert "export APP_ENV=production" in lines
# 4. unset_key removes key in place
unset_res1 = remove_file_key(env_file, "DB_HOST")
assert unset_res1 == (True, "DB_HOST"), "unset_key must return (True, key) for existing key"
# 5. unset_key on missing key returns (None, key) without error
unset_res2 = remove_file_key(env_file, "NONEXISTENT_KEY")
assert unset_res2 == (None, "NONEXISTENT_KEY"), "unset_key must return (None, key) for missing key"
# Verify key was removed from file
final_content = env_file.read_text(encoding="utf-8")
assert "DB_HOST" not in final_content
assert "SERVICE_PORT=9090" in final_content
assert "export APP_ENV=production" in final_content
if __name__ == "__main__":
test_quote_and_escape_semantics()
test_export_prefix_and_variable_expansion_defaults()
test_in_place_key_mutation_lifecycle()
print("CONTRACT PASS: python-dotenv escape semantics, variable defaults, and key mutation verified")