API refactor
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-10-07 16:25:52 +09:00
parent 76d0d86211
commit 91c7e04474
1171 changed files with 81940 additions and 44117 deletions

View File

@@ -1,13 +1,13 @@
import io
import logging
import os
import pathlib
import shutil
import sys
import tempfile
from collections import OrderedDict
from contextlib import contextmanager
from typing import (IO, Dict, Iterable, Iterator, Mapping, Optional, Tuple,
Union)
from typing import IO, Dict, Iterable, Iterator, Mapping, Optional, Tuple, Union
from .parser import Binding, parse_stream
from .variables import parse_variables
@@ -16,7 +16,7 @@ from .variables import parse_variables
# These paths may flow to `open()` and `shutil.move()`; `shutil.move()`
# only accepts string paths, not byte paths or file descriptors. See
# https://github.com/python/typeshed/pull/6832.
StrPath = Union[str, 'os.PathLike[str]']
StrPath = Union[str, "os.PathLike[str]"]
logger = logging.getLogger(__name__)
@@ -25,7 +25,7 @@ def with_warn_for_invalid_lines(mappings: Iterator[Binding]) -> Iterator[Binding
for mapping in mappings:
if mapping.error:
logger.warning(
"Python-dotenv could not parse statement starting at line %s",
"python-dotenv could not parse statement starting at line %s",
mapping.original.line,
)
yield mapping
@@ -59,10 +59,10 @@ class DotEnv:
else:
if self.verbose:
logger.info(
"Python-dotenv could not find configuration file %s.",
self.dotenv_path or '.env',
"python-dotenv could not find configuration file %s.",
self.dotenv_path or ".env",
)
yield io.StringIO('')
yield io.StringIO("")
def dict(self) -> Dict[str, Optional[str]]:
"""Return dotenv as dict"""
@@ -72,7 +72,9 @@ class DotEnv:
raw_values = self.parse()
if self.interpolate:
self._dict = OrderedDict(resolve_variables(raw_values, override=self.override))
self._dict = OrderedDict(
resolve_variables(raw_values, override=self.override)
)
else:
self._dict = OrderedDict(raw_values)
@@ -100,8 +102,7 @@ class DotEnv:
return True
def get(self, key: str) -> Optional[str]:
"""
"""
""" """
data = self.dict()
if key in data:
@@ -131,17 +132,21 @@ def rewrite(
path: StrPath,
encoding: Optional[str],
) -> Iterator[Tuple[IO[str], IO[str]]]:
if not os.path.isfile(path):
with open(path, mode="w", encoding=encoding) as source:
source.write("")
pathlib.Path(path).touch()
with tempfile.NamedTemporaryFile(mode="w", encoding=encoding, delete=False) as dest:
error = None
try:
with open(path, encoding=encoding) as source:
yield (source, dest)
except BaseException:
os.unlink(dest.name)
raise
shutil.move(dest.name, path)
except BaseException as err:
error = err
if error is None:
shutil.move(dest.name, path)
else:
os.unlink(dest.name)
raise error from None
def set_key(
@@ -161,9 +166,8 @@ def set_key(
if quote_mode not in ("always", "auto", "never"):
raise ValueError(f"Unknown quote_mode: {quote_mode}")
quote = (
quote_mode == "always"
or (quote_mode == "auto" and not value_to_set.isalnum())
quote = quote_mode == "always" or (
quote_mode == "auto" and not value_to_set.isalnum()
)
if quote:
@@ -171,7 +175,7 @@ def set_key(
else:
value_out = value_to_set
if export:
line_out = f'export {key_to_set}={value_out}\n'
line_out = f"export {key_to_set}={value_out}\n"
else:
line_out = f"{key_to_set}={value_out}\n"
@@ -218,7 +222,9 @@ def unset_key(
dest.write(mapping.original.string)
if not removed:
logger.warning("Key %s not removed from %s - key doesn't exist.", key_to_unset, dotenv_path)
logger.warning(
"Key %s not removed from %s - key doesn't exist.", key_to_unset, dotenv_path
)
return None, key_to_unset
return removed, key_to_unset
@@ -230,7 +236,7 @@ def resolve_variables(
) -> Mapping[str, Optional[str]]:
new_values: Dict[str, Optional[str]] = {}
for (name, value) in values:
for name, value in values:
if value is None:
result = None
else:
@@ -254,7 +260,7 @@ def _walk_to_root(path: str) -> Iterator[str]:
Yield directories starting from the given directory up to the root
"""
if not os.path.exists(path):
raise IOError('Starting path not found')
raise IOError("Starting path not found")
if os.path.isfile(path):
path = os.path.dirname(path)
@@ -268,7 +274,7 @@ def _walk_to_root(path: str) -> Iterator[str]:
def find_dotenv(
filename: str = '.env',
filename: str = ".env",
raise_error_if_not_found: bool = False,
usecwd: bool = False,
) -> str:
@@ -279,11 +285,19 @@ def find_dotenv(
"""
def _is_interactive():
""" Decide whether this is running in a REPL or IPython notebook """
main = __import__('__main__', None, None, fromlist=['__file__'])
return not hasattr(main, '__file__')
"""Decide whether this is running in a REPL or IPython notebook"""
if hasattr(sys, "ps1") or hasattr(sys, "ps2"):
return True
try:
main = __import__("__main__", None, None, fromlist=["__file__"])
except ModuleNotFoundError:
return False
return not hasattr(main, "__file__")
if usecwd or _is_interactive() or getattr(sys, 'frozen', False):
def _is_debugger():
return sys.gettrace() is not None
if usecwd or _is_interactive() or _is_debugger() or getattr(sys, "frozen", False):
# Should work without __file__, e.g. in REPL or IPython notebook.
path = os.getcwd()
else:
@@ -291,7 +305,9 @@ def find_dotenv(
frame = sys._getframe()
current_file = __file__
while frame.f_code.co_filename == current_file:
while frame.f_code.co_filename == current_file or not os.path.exists(
frame.f_code.co_filename
):
assert frame.f_back is not None
frame = frame.f_back
frame_filename = frame.f_code.co_filename
@@ -303,9 +319,9 @@ def find_dotenv(
return check_path
if raise_error_if_not_found:
raise IOError('File not found')
raise IOError("File not found")
return ''
return ""
def load_dotenv(
@@ -330,7 +346,9 @@ def load_dotenv(
Bool: True if at least one environment variable is set else False
If both `dotenv_path` and `stream` are `None`, `find_dotenv()` is used to find the
.env file.
.env file with it's default parameters. If you need to change the default parameters
of `find_dotenv()`, you can explicitly call `find_dotenv()` and pass the result
to this function as `dotenv_path`.
"""
if dotenv_path is None and stream is None:
dotenv_path = find_dotenv()