CodeSampleX

Beispiel

python-dotenv 1.2.2: Pin python-dotenv load_dotenv return semantics, dotenv_values isolation, valueless key handling, and interpolation precedence

Verifiziertes Beispiel für pypi python-dotenv 1.2.2: Pin python-dotenv load_dotenv return semantics, dotenv_values isolation, valueless key handling, and…

sha256:6032931e56a20b51b652c9f7c77e9a8fb979e1513bcd63e107668998f1f1f80f

Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen. Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen. MIT-0

Ausführungsbelege

Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.

Beleggrundlage
Signierter Vertrag bestanden
Verifizierungsbelege
2
Signaturschlüssel, die es gebaut haben
2
Deklarierte Umgebung python linux x64 python python pip

Umgebungen der Verifizierungsläufe

Umgebung Contract Stufen Lauf
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

Fall

HOW
Ziel
Pin python-dotenv load_dotenv return semantics, dotenv_values isolation, valueless key handling, and interpolation precedence
Pakete
Symbole
  • load_dotenv
  • dotenv_values
  • find_dotenv
  • set_key
Umgebung
python
Erstellt
2026-08-17T03:19:39Z

Contract

  1. assert load_dotenv returns False on missing, empty, or comments-only files
  2. assert load_dotenv returns True when valid keys exist even under override=False with pre-existing os.environ
  3. assert valueless keys parse as None in dotenv_values and are omitted from os.environ by load_dotenv
  4. assert dotenv_values does not mutate os.environ and prioritizes file definitions during interpolation
  5. assert load_dotenv with override=False resolves interpolated variables from os.environ over file values
  6. assert load_dotenv with override=True updates os.environ and uses overridden values during interpolation
  7. assert find_dotenv returns an empty string when the file is not found
  8. assert set_key returns a 3-tuple of success bool, key name, and set value

Dateien

  • NOTES.md
  • csx.json
  • requirements.txt
  • src/__init__.py
  • src/loader.py
  • test/contract.py

Quellartefakt herunterladen (tar.gz)

Quelltext

NOTES.md
# the network Notes: python-dotenv Core API Traps & Return Semantics

## 1. Search Result
- **`search_known_solution`**: HIT on `sha256:f5541d3ce0eda3656543ec05a42e65a6c79c2fcfe44febb312569405335bdce1` (Goal: *Pin pydantic-settings source precedence and nested delimiter resolution*), which focused on Pydantic's settings layer rather than direct `python-dotenv` API contracts (`load_dotenv`, `dotenv_values`, `find_dotenv`, and `set_key`).

## 2. What a Model Would Have Written Instead
- A model would assume `load_dotenv()` returns `True` only when `os.environ` is actively modified (returning `False` if `override=False` keeps existing values), that `find_dotenv()` returns `None` on missing files, that `dotenv_values()` and `load_dotenv(override=False)` interpolate variables using the same precedence, and that valueless keys (`KEY` without `=`) are either set to `""` or raise errors.

## 3. How the Wrong Version Fails
- It fails silently with a green build: checking `if load_dotenv():` produces false positives when environment variables are preserved untouched, expecting valueless `.env` keys in `os.environ` silently omits them without error, and `${VAR}` interpolation in `load_dotenv(override=False)` silently reads host environment variables instead of in-file definitions.
csx.json
{"case":{"caseId":"case:sha256:6227a18f4bd4554b7390e911fbe0d803c97336dc0606698f80d2aafccc2b0e94","contract":["assert load_dotenv returns False on missing, empty, or comments-only files","assert load_dotenv returns True when valid keys exist even under override=False with pre-existing os.environ","assert valueless keys parse as None in dotenv_values and are omitted from os.environ by load_dotenv","assert dotenv_values does not mutate os.environ and prioritizes file definitions during interpolation","assert load_dotenv with override=False resolves interpolated variables from os.environ over file values","assert load_dotenv with override=True updates os.environ and uses overridden values during interpolation","assert find_dotenv returns an empty string when the file is not found","assert set_key returns a 3-tuple of success bool, key name, and set value"],"goal":"Pin python-dotenv load_dotenv return semantics, dotenv_values isolation, valueless key handling, and interpolation precedence","kind":"HOW","packages":["pkg:pypi/python-dotenv@1.2.2"],"schemaVersion":1,"symbols":["load_dotenv","dotenv_values","find_dotenv","set_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":["load_dotenv","dotenv_values","find_dotenv","set_key"],"verifierAdapter":"python@1"}
requirements.txt
python-dotenv==1.2.2
src/__init__.py
"""python-dotenv API contract sample."""
src/loader.py
"""Safe helpers wrapping python-dotenv core functions."""

import io
import os
from typing import IO, Dict, Optional, Tuple, Union
import dotenv


def safe_load_env(
    dotenv_path: Optional[Union[str, os.PathLike]] = None,
    stream: Optional[IO[str]] = None,
    override: bool = False,
) -> bool:
    """
    Load environment variables from a .env file or stream.

    Returns True if valid bindings were parsed, False if the target was missing or empty.
    Note: Valueless keys are parsed by dotenv but skipped when populating os.environ.
    """
    return dotenv.load_dotenv(dotenv_path=dotenv_path, stream=stream, override=override)


def parse_env_isolated(
    dotenv_path: Optional[Union[str, os.PathLike]] = None,
    stream: Optional[IO[str]] = None,
) -> Dict[str, Optional[str]]:
    """
    Parse .env into a dictionary without modifying os.environ.

    Variable expansion internally prioritizes definitions in the stream/file over os.environ.
    """
    return dict(dotenv.dotenv_values(dotenv_path=dotenv_path, stream=stream))


def find_env_path(filename: str = ".env") -> Optional[str]:
    """
    Locate .env file walking up directory hierarchy.

    Returns the path string, or None if not found (wrapping find_dotenv's empty string return).
    """
    found = dotenv.find_dotenv(filename=filename)
    return found if found else None


def update_env_variable(
    dotenv_path: Union[str, os.PathLike],
    key: str,
    value: str,
    quote_mode: str = "always",
) -> Tuple[bool, str, str]:
    """
    Write or update a single key in .env file, returning (success, key, value).
    """
    return dotenv.set_key(dotenv_path=dotenv_path, key_to_set=key, value_to_set=value, quote_mode=quote_mode)
test/contract.py
import io
import os
import sys
import tempfile
from pathlib import Path
import dotenv


def test_load_dotenv_return_values():
    """Prove load_dotenv return bool semantics across missing, empty, and existing keys."""
    with tempfile.TemporaryDirectory() as td:
        # Nonexistent file returns False
        missing_path = Path(td) / ".env.missing"
        assert dotenv.load_dotenv(dotenv_path=missing_path) is False

        # Empty file returns False
        empty_path = Path(td) / ".env.empty"
        empty_path.write_text("   \n\n", encoding="utf-8")
        assert dotenv.load_dotenv(dotenv_path=empty_path) is False

        # Comments-only file returns False
        comment_path = Path(td) / ".env.comment"
        comment_path.write_text("# Just a comment\n# Another comment\n", encoding="utf-8")
        assert dotenv.load_dotenv(dotenv_path=comment_path) is False

        # File with valid keys returns True even when override=False and keys already exist in os.environ
        valid_path = Path(td) / ".env.valid"
        valid_path.write_text("PRESET_VALUE=from_dotenv\n", encoding="utf-8")
        os.environ["PRESET_VALUE"] = "from_environ"
        res = dotenv.load_dotenv(dotenv_path=valid_path, override=False)
        assert res is True, "load_dotenv must return True when file contains bindings"
        assert os.environ["PRESET_VALUE"] == "from_environ", "override=False must not overwrite existing os.environ"


def test_valueless_keys_and_dotenv_values_isolation():
    """Prove that valueless keys parse as None in dotenv_values and are skipped in load_dotenv."""
    env_content = (
        "DEFINED_EMPTY=\n"
        "VALNAME_NO_EQUALS\n"
        "REGULAR_VAR=value_123\n"
    )

    # Clean up test keys
    for k in ["DEFINED_EMPTY", "VALNAME_NO_EQUALS", "REGULAR_VAR"]:
        os.environ.pop(k, None)

    # 1. dotenv_values parse test
    parsed = dotenv.dotenv_values(stream=io.StringIO(env_content))
    assert parsed["DEFINED_EMPTY"] == "", "Key with '=' and empty value must parse as empty string"
    assert parsed["VALNAME_NO_EQUALS"] is None, "Key without '=' must parse as None"
    assert parsed["REGULAR_VAR"] == "value_123"

    # dotenv_values must NOT mutate os.environ
    assert "REGULAR_VAR" not in os.environ, "dotenv_values must not mutate os.environ"

    # 2. load_dotenv behavior with valueless keys
    res = dotenv.load_dotenv(stream=io.StringIO(env_content))
    assert res is True
    assert os.environ["DEFINED_EMPTY"] == "", "DEFINED_EMPTY must be set to empty string"
    assert "VALNAME_NO_EQUALS" not in os.environ, "Valueless key (None) must be skipped in os.environ"
    assert os.environ["REGULAR_VAR"] == "value_123"


def test_interpolation_precedence():
    """Prove interpolation precedence delta between dotenv_values and load_dotenv."""
    env_content = (
        "HOST_DOMAIN=example.org\n"
        "EXPANDED_PATH=${HOST_DOMAIN}/api\n"
    )

    # Case 1: Pre-existing os.environ with dotenv_values
    # dotenv_values hardcodes override=True during resolution: uses stream's HOST_DOMAIN (example.org)
    os.environ["HOST_DOMAIN"] = "example.com"
    os.environ.pop("EXPANDED_PATH", None)

    parsed = dotenv.dotenv_values(stream=io.StringIO(env_content))
    assert parsed["EXPANDED_PATH"] == "example.org/api", (
        "dotenv_values must prioritize file definitions during interpolation"
    )

    # Case 2: load_dotenv with override=False
    # override=False resolves ${HOST_DOMAIN} from os.environ (example.com), NOT the stream value!
    os.environ["HOST_DOMAIN"] = "example.com"
    os.environ.pop("EXPANDED_PATH", None)

    dotenv.load_dotenv(stream=io.StringIO(env_content), override=False)
    assert os.environ["HOST_DOMAIN"] == "example.com"
    assert os.environ["EXPANDED_PATH"] == "example.com/api", (
        "load_dotenv(override=False) must prioritize os.environ for variable interpolation"
    )

    # Case 3: load_dotenv with override=True
    # override=True updates os.environ and uses the stream value (example.org) for interpolation
    os.environ["HOST_DOMAIN"] = "example.com"
    os.environ.pop("EXPANDED_PATH", None)

    dotenv.load_dotenv(stream=io.StringIO(env_content), override=True)
    assert os.environ["HOST_DOMAIN"] == "example.org"
    assert os.environ["EXPANDED_PATH"] == "example.org/api", (
        "load_dotenv(override=True) must overwrite os.environ and interpolate the new value"
    )


def test_find_dotenv_and_set_key_signatures():
    """Prove find_dotenv return type on missing file and set_key return signature."""
    # find_dotenv returns empty string, NOT None
    missing_file = dotenv.find_dotenv(filename="nonexistent_dotenv_file_xyz.env")
    assert missing_file == "", f"find_dotenv must return empty string on missing file, got {missing_file!r}"

    # set_key returns (success_bool, key, value) 3-tuple
    with tempfile.TemporaryDirectory() as td:
        env_file = Path(td) / ".env"
        ret = dotenv.set_key(env_file, "DB_HOST", "localhost", quote_mode="always")
        assert ret == (True, "DB_HOST", "localhost"), f"set_key must return 3-tuple, got {ret!r}"
        assert env_file.read_text(encoding="utf-8") == "DB_HOST='localhost'\n"


if __name__ == "__main__":
    # Clean up environment variables
    clean_keys = [
        "PRESET_VALUE",
        "DEFINED_EMPTY",
        "VALNAME_NO_EQUALS",
        "REGULAR_VAR",
        "HOST_DOMAIN",
        "EXPANDED_PATH",
    ]
    for k in clean_keys:
        os.environ.pop(k, None)

    test_load_dotenv_return_values()
    test_valueless_keys_and_dotenv_values_isolation()
    test_interpolation_precedence()
    test_find_dotenv_and_set_key_signatures()

    for k in clean_keys:
        os.environ.pop(k, None)

    print("CONTRACT PASS: python-dotenv API traps and return semantics verified")

Ursprungs-Seeder

csx-seed