"""dotenv_load — parsea un archivo .env y popula os.environ sin sobreescribir.""" import os def dotenv_load(path: str) -> None: """Parsea un archivo .env y setea variables en os.environ. Reglas de parseo: - Lineas que empiezan con # (tras strip) son comentarios y se ignoran. - Lineas vacias se ignoran. - Formato esperado: KEY=VALUE (separador es el primer =). - Valores con comillas simples o dobles externas se stripean. - Variables ya presentes en os.environ NO se sobreescriben. Args: path: ruta al archivo .env. Returns: None Raises: FileNotFoundError: si el archivo no existe. ValueError: si una linea no tiene el separador '='. """ with open(path, encoding="utf-8") as fh: for lineno, raw_line in enumerate(fh, start=1): line = raw_line.strip() # skip blanks and comments if not line or line.startswith("#"): continue if "=" not in line: raise ValueError( f"dotenv_load: {path!r} line {lineno}: missing '=' in {line!r}" ) key, _, val = line.partition("=") key = key.strip() val = _strip_quotes(val) # only set if not already present if key not in os.environ or os.environ[key] == "": os.environ[key] = val def _strip_quotes(s: str) -> str: """Remove surrounding single or double quotes.""" if len(s) >= 2: if (s[0] == '"' and s[-1] == '"') or (s[0] == "'" and s[-1] == "'"): return s[1:-1] return s