From b6f6176af878737c47ed030eb1eecbd0e80578a4 Mon Sep 17 00:00:00 2001 From: Volodymyr Pivoshenko Date: Sun, 1 Sep 2024 18:26:53 +0100 Subject: [PATCH] fix(dotenv.core): partially rollback optimization changes to resolve issue with overriding variables --- src/poetry_plugin_dotenv/dotenv/core.py | 63 ++++++++++++++----------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/src/poetry_plugin_dotenv/dotenv/core.py b/src/poetry_plugin_dotenv/dotenv/core.py index e59db18..98ecdc3 100644 --- a/src/poetry_plugin_dotenv/dotenv/core.py +++ b/src/poetry_plugin_dotenv/dotenv/core.py @@ -43,40 +43,41 @@ def __init__( def dict(self) -> OrderedDict[str, str]: """Return content of a dotenv file.""" - if self._dict is None: - raw_values = self.parse() - self._dict = ( - resolve(raw_values, override=self.override) - if self.interpolate - else OrderedDict(raw_values) # type: ignore[arg-type] - ) + if self._dict: + return self._dict + + raw_values = self.parse() + + if self.interpolate: + self._dict = resolve(raw_values, override=self.override) + + else: + self._dict = OrderedDict(raw_values) return self._dict - def parse(self) -> Iterator[tuple[str, str | None]]: + def parse(self) -> Iterator[tuple[str, str]]: """Parse a dotenv file.""" with self._get_stream() as stream: for mapping in parsers.parse_stream(stream): if mapping.key is not None: - yield mapping.key, mapping.value + yield mapping.key, mapping.value # type: ignore[misc] def set_as_environment_variables(self) -> bool: - """Load current dotenv as system environment variables.""" - - env_dict = self.dict() + """Load current dotenv as a system environment variable.""" - if not env_dict: - return False + if self.dict(): + for key, value in self.dict().items(): + if key in os.environ and not self.override: + continue - for key, value in env_dict.items(): - if key in os.environ and not self.override: - continue + if value: + os.environ[key] = value - if value: - os.environ[key] = value + return True - return True + return False # pragma: nocover @contextlib.contextmanager def _get_stream(self) -> Iterator[IO[str]]: @@ -90,31 +91,37 @@ def _get_stream(self) -> Iterator[IO[str]]: yield self.stream else: - yield io.StringIO("") + yield io.StringIO("") # pragma: nocover def resolve( - values: Iterable[tuple[str, str | None]], + values: Iterable[tuple[str, str]], *, override: bool, ) -> OrderedDict[str, str]: """Resolve dotenv variables.""" new_values: OrderedDict[str, str] = OrderedDict() - env = OrderedDict(os.environ.copy()) if override else OrderedDict() for name, value in values: - if value is not None: + if value is None: + result = None # pragma: nocover + + else: atoms = variables.parse(value) + env: OrderedDict[str, str] = OrderedDict() - if not override: + if override: + env.update(os.environ) env.update(new_values) else: - env = OrderedDict({**env, **new_values}) + env.update(new_values) + env.update(os.environ) + + result = "".join(atom.resolve(env) for atom in atoms) - resolved_value = "".join(atom.resolve(env) for atom in atoms) - new_values[name] = resolved_value + new_values[name] = result return new_values