CodeSampleX

示例

python-dotenv 1.2.2: Pin python-dotenv master disable switch (PYTHON_DOTENV_DISABLED), override precedence on os.environ vs variable interpolation, and dotenv_values override divergence

已验证示例 — pypi python-dotenv 1.2.2: Pin python-dotenv master disable switch (PYTHON_DOTENV_DISABLED), override precedence on os.environ vs variable…

sha256:8c2a9e1c45906b691884dcbb1db94fc470656b7e1de3b35c3deb25d68b1d9b06

本网络只提供一件事:能构建的样本。它在沙箱中运行并保留签名回执。它不评级、不担保——同样的代码能否在你的环境构建,它没有测量过。 提交了通过的契约回执的不同签名密钥数量。为 1 表示只有作者;大于 1 表示还有其他人构建过。密钥是自行生成的,背后没有注册身份,因此计的是密钥而非人。 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 master disable switch (PYTHON_DOTENV_DISABLED), override precedence on os.environ vs variable interpolation, and dotenv_values override divergence
包
符号
  • dotenv.load_dotenv
  • dotenv.dotenv_values
  • dotenv.DotEnv
环境
python
创建时间
2026-08-17T03:19:46Z

契约

  1. PYTHON_DOTENV_DISABLED set to truthy values ('1', 'true', 'yes', 't', 'y') causes load_dotenv to return False and load nothing into os.environ, while dotenv_values continues to parse files
  2. load_dotenv with override=False (default) preserves existing os.environ keys and resolves variable expansions (${VAR}) using os.environ values rather than .env file definitions
  3. load_dotenv with override=True overwrites existing os.environ keys and resolves variable expansions using .env file definitions
  4. dotenv_values always evaluates variable expansions using file values regardless of existing os.environ definitions, diverging from load_dotenv(override=False)
  5. interpolate=False disables variable interpolation and preserves ${VAR} and ${VAR:-default} as raw string literals
  6. unset variable parameter expansion (${UNSET:-default}) evaluates to default while unset variable without default (${UNSET}) evaluates to empty string
  7. keys without values ('KEY=') resolve to empty string ('') whereas valueless keys ('KEY') resolve to None in dotenv_values and are skipped by load_dotenv

文件

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

下载源代码构件 (tar.gz)

源代码

NOTES.md
# the network Notes: python-dotenv Configuration Precedence & Master Switch

## 1. `search_known_solution` Result
- **`search_known_solution`**: MATCH: COMPATIBLE (Low confidence). Returned sample `sha256:f5541d3ce0eda3656543ec05a42e65a6c79c2fcfe44febb312569405335bdce1` (`pydantic-settings` source precedence) and Node.js `dotenv` samples (`sha256:cc2a38a595028c0eb69e9cc8c1b0ea4df797c07aa2d8bfd5af537ec850ba4895` and `sha256:8e2d7993b497107b12b87dfd6d742c93035c7debd5553d1610771e2c6452f0bb`); no sample existed for Python's `python-dotenv` configuration flags, `PYTHON_DOTENV_DISABLED` master switch, or `dotenv_values` interpolation asymmetry.

## 2. What a Model Would Have Written Instead
- A model would assume that `.env` variable interpolation (`${VAR}`) always expands variables defined within the same `.env` file even when `override=False`, that `dotenv_values()` and `load_dotenv(override=False)` produce identical dictionary values for the same `.env` content, and that `PYTHON_DOTENV_DISABLED` either does not exist or disables all dotenv parsing functions uniformly.

## 3. How the Wrong Version Fails
- Silently with a green build: when `PYTHON_DOTENV_DISABLED` is set (e.g. in test fixtures or container defaults), `load_dotenv()` silently returns `False` and loads zero environment variables without raising any error, while `override=False` silently uses host environment variables to interpolate `.env` paths rather than the definitions in the file.
csx.json
{"case":{"caseId":"case:sha256:d1f606e61a7924c9ec69f5f846b578aa7edccd4d83ae23e7476b1702a8c8dcb6","contract":["PYTHON_DOTENV_DISABLED set to truthy values ('1', 'true', 'yes', 't', 'y') causes load_dotenv to return False and load nothing into os.environ, while dotenv_values continues to parse files","load_dotenv with override=False (default) preserves existing os.environ keys and resolves variable expansions (${VAR}) using os.environ values rather than .env file definitions","load_dotenv with override=True overwrites existing os.environ keys and resolves variable expansions using .env file definitions","dotenv_values always evaluates variable expansions using file values regardless of existing os.environ definitions, diverging from load_dotenv(override=False)","interpolate=False disables variable interpolation and preserves ${VAR} and ${VAR:-default} as raw string literals","unset variable parameter expansion (${UNSET:-default}) evaluates to default while unset variable without default (${UNSET}) evaluates to empty string","keys without values ('KEY=') resolve to empty string ('') whereas valueless keys ('KEY') resolve to None in dotenv_values and are skipped by load_dotenv"],"goal":"Pin python-dotenv master disable switch (PYTHON_DOTENV_DISABLED), override precedence on os.environ vs variable interpolation, and dotenv_values override divergence","kind":"HOW","packages":["pkg:pypi/python-dotenv@1.2.2"],"schemaVersion":1,"symbols":["dotenv.load_dotenv","dotenv.dotenv_values","dotenv.DotEnv"]},"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.load_dotenv","dotenv.dotenv_values","dotenv.DotEnv"],"verifierAdapter":"python@1"}
requirements.txt
python-dotenv==1.2.2
src/__init__.py
"""Python dotenv configuration module."""

from .config import load_app_env, get_env_mapping

__all__ = ["load_app_env", "get_env_mapping"]
src/config.py
"""Configuration loader exposing python-dotenv loading and inspection semantics."""

from typing import Any, Dict, IO, Optional, Union
from os import PathLike
import dotenv


def load_app_env(
    dotenv_path: Optional[Union[str, PathLike]] = None,
    stream: Optional[IO[str]] = None,
    override: bool = False,
    interpolate: bool = True,
) -> bool:
    """Load configuration from .env file or stream into os.environ.

    Respects the PYTHON_DOTENV_DISABLED master environment variable.
    """
    return dotenv.load_dotenv(
        dotenv_path=dotenv_path,
        stream=stream,
        override=override,
        interpolate=interpolate,
    )


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

    Bypasses PYTHON_DOTENV_DISABLED and uses file-level override for interpolation.
    """
    return dotenv.dotenv_values(
        dotenv_path=dotenv_path,
        stream=stream,
        interpolate=interpolate,
    )
test/contract.py
"""Contract proving python-dotenv configuration flags, disable switch, and interpolation precedence."""

import io
import os
import sys
import tempfile
from pathlib import Path

# Add project root to sys.path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import dotenv
from src.config import get_env_mapping, load_app_env


def clean_env(*keys: str) -> None:
    for k in keys:
        os.environ.pop(k, None)


def test_python_dotenv_disabled_switch():
    """Verify PYTHON_DOTENV_DISABLED master switch suppresses load_dotenv but not dotenv_values."""
    env_keys = ["PYTHON_DOTENV_DISABLED", "APP_PORT", "APP_SECRET"]
    clean_env(*env_keys)

    with tempfile.TemporaryDirectory() as tmpdir:
        dotenv_file = Path(tmpdir) / ".env"
        dotenv_file.write_text("APP_PORT=8080\nAPP_SECRET=supersecret\n", encoding="utf-8")

        # 1. When PYTHON_DOTENV_DISABLED is set to truthy values ("1", "true", "yes", "t", "y")
        for truthy in ["1", "true", "True", "YES", "y", "t"]:
            os.environ["PYTHON_DOTENV_DISABLED"] = truthy
            loaded = load_app_env(dotenv_path=dotenv_file)

            # load_dotenv must abort, returning False, without modifying os.environ
            assert loaded is False, f"Expected load_dotenv to return False when disabled with {truthy}"
            assert "APP_PORT" not in os.environ, "APP_PORT must not be set when load_dotenv is disabled"
            assert "APP_SECRET" not in os.environ, "APP_SECRET must not be set when load_dotenv is disabled"

            # In contrast, dotenv_values completely bypasses PYTHON_DOTENV_DISABLED
            vals = get_env_mapping(dotenv_path=dotenv_file)
            assert vals.get("APP_PORT") == "8080", "dotenv_values must still parse file when disabled"
            assert vals.get("APP_SECRET") == "supersecret"

        # 2. When PYTHON_DOTENV_DISABLED is falsy ("0", "false", "no", "")
        for falsy in ["0", "false", "no", ""]:
            os.environ["PYTHON_DOTENV_DISABLED"] = falsy
            loaded = load_app_env(dotenv_path=dotenv_file)
            assert loaded is True, f"Expected load_dotenv to succeed when disabled flag is falsy ({falsy})"
            assert os.environ.get("APP_PORT") == "8080"
            assert os.environ.get("APP_SECRET") == "supersecret"
            clean_env("APP_PORT", "APP_SECRET")

    clean_env(*env_keys)


def test_override_flag_and_interpolation_precedence():
    """Verify override=False vs override=True on os.environ values and variable interpolation."""
    env_keys = ["BASE_HOST", "API_ENDPOINT", "UNTOUCHED_VAR"]
    clean_env(*env_keys)
    scheme = "https"

    env_content = (
        "BASE_HOST=api.example.com\n"
        f"API_ENDPOINT={scheme}://${{BASE_HOST}}/v1/data\n"
        "UNTOUCHED_VAR=from_file\n"
    )

    # Initial state: BASE_HOST already defined in process environment
    os.environ["BASE_HOST"] = "custom.example.org"

    # Case 1: load_dotenv with default override=False
    # - BASE_HOST in os.environ is NOT overwritten (stays custom.example.org)
    # - API_ENDPOINT interpolation resolves against os.environ (https://custom.example.org/v1/data)
    # - UNTOUCHED_VAR is loaded because it was not in os.environ
    stream_default = io.StringIO(env_content)
    ret_default = load_app_env(stream=stream_default, override=False)
    assert ret_default is True
    assert os.environ.get("BASE_HOST") == "custom.example.org", (
        "override=False must not overwrite existing os.environ key"
    )
    assert os.environ.get("API_ENDPOINT") == "https://custom.example.org/v1/data", (
        "override=False must interpolate ${BASE_HOST} using existing os.environ value"
    )
    assert os.environ.get("UNTOUCHED_VAR") == "from_file"

    clean_env(*env_keys)

    # Case 2: load_dotenv with override=True
    # - BASE_HOST in os.environ IS overwritten to api.example.com
    # - API_ENDPOINT interpolation resolves against file value (https://api.example.com/v1/data)
    os.environ["BASE_HOST"] = "custom.example.org"
    stream_override = io.StringIO(env_content)
    ret_override = load_app_env(stream=stream_override, override=True)
    assert ret_override is True
    assert os.environ.get("BASE_HOST") == "api.example.com", (
        "override=True must overwrite existing os.environ key with file value"
    )
    assert os.environ.get("API_ENDPOINT") == "https://api.example.com/v1/data", (
        "override=True must interpolate ${BASE_HOST} using file value"
    )

    clean_env(*env_keys)


def test_dotenv_values_override_divergence():
    """Verify that dotenv_values() always uses file-precedence (override=True) for interpolation."""
    env_keys = ["BASE_HOST", "SERVICE_URL"]
    clean_env(*env_keys)
    scheme = "https"

    env_content = (
        "BASE_HOST=file.example.com\n"
        f"SERVICE_URL={scheme}://${{BASE_HOST}}/service\n"
    )

    # Set existing os.environ key
    os.environ["BASE_HOST"] = "environ.example.org"

    # dotenv_values parses the file and interpolates using file definitions (hardcoded override=True)
    vals = get_env_mapping(stream=io.StringIO(env_content))
    assert vals["BASE_HOST"] == "file.example.com"
    assert vals["SERVICE_URL"] == "https://file.example.com/service", (
        "dotenv_values must prioritize file definitions during interpolation over os.environ"
    )

    # In contrast, load_dotenv(override=False) produces environ.example.org for the same stream
    load_app_env(stream=io.StringIO(env_content), override=False)
    assert os.environ["SERVICE_URL"] == "https://environ.example.org/service", (
        "load_dotenv(override=False) must prioritize os.environ during interpolation"
    )

    clean_env(*env_keys)


def test_interpolate_flag_and_posix_defaults():
    """Verify interpolate=False disables expansion, and POSIX default fallback behavior."""
    env_keys = ["RAW_KEY", "DEFAULT_KEY", "EMPTY_EXPAND_KEY", "EMPTY_VAL_KEY", "NO_VAL_KEY"]
    clean_env(*env_keys)

    env_content = (
        "RAW_KEY=${NONEXISTENT:-fallback_raw}\n"
        "DEFAULT_KEY=${UNSET_TARGET:-default_value}\n"
        "EMPTY_EXPAND_KEY=${UNSET_TARGET}\n"
        "EMPTY_VAL_KEY=\n"
        "NO_VAL_KEY\n"
    )

    # 1. With interpolate=False: variable syntax remains literal
    raw_vals = get_env_mapping(stream=io.StringIO(env_content), interpolate=False)
    assert raw_vals["RAW_KEY"] == "${NONEXISTENT:-fallback_raw}", (
        "interpolate=False must preserve ${VAR:-default} as raw literal"
    )
    assert raw_vals["DEFAULT_KEY"] == "${UNSET_TARGET:-default_value}"
    assert raw_vals["EMPTY_EXPAND_KEY"] == "${UNSET_TARGET}"

    # 2. With interpolate=True (default):
    interp_vals = get_env_mapping(stream=io.StringIO(env_content), interpolate=True)
    assert interp_vals["DEFAULT_KEY"] == "default_value", (
        "${UNSET:-default} must expand to default value"
    )
    assert interp_vals["EMPTY_EXPAND_KEY"] == "", (
        "Unset variable without default must expand to empty string"
    )
    assert interp_vals["EMPTY_VAL_KEY"] == "", (
        "KEY= with nothing after equal sign must resolve to empty string"
    )
    assert interp_vals["NO_VAL_KEY"] is None, (
        "Valueless KEY (no equal sign) must resolve to None in dotenv_values"
    )

    # 3. In load_dotenv: None-value keys are skipped and not exported to os.environ
    load_app_env(stream=io.StringIO(env_content), override=True)
    assert os.environ.get("EMPTY_VAL_KEY") == ""
    assert "NO_VAL_KEY" not in os.environ, "Valueless keys (None) must not be set into os.environ"

    clean_env(*env_keys)


if __name__ == "__main__":
    test_python_dotenv_disabled_switch()
    test_override_flag_and_interpolation_precedence()
    test_dotenv_values_override_divergence()
    test_interpolate_flag_and_posix_defaults()
    print("CONTRACT PASS: python-dotenv configuration, disable flag, and override interpolation verified")

原始种子者

csx-seed