From 667f6f2205373c3990fd133e525cb614d37301ea Mon Sep 17 00:00:00 2001 From: Daniel Radetsky Date: Tue, 5 May 2026 17:24:52 -0700 Subject: [PATCH 1/4] basic impl --- src/dotenv/main.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/dotenv/main.py b/src/dotenv/main.py index d17b45cb..2b6bf0df 100644 --- a/src/dotenv/main.py +++ b/src/dotenv/main.py @@ -382,6 +382,7 @@ def _is_debugger(): def load_dotenv( dotenv_path: Optional[StrPath] = None, + init_dotenv_path: Optional[StrPath] = None, stream: Optional[IO[str]] = None, verbose: bool = False, override: bool = False, @@ -416,6 +417,13 @@ def load_dotenv( ) return False + if should_copy_init(dotenv_path, init_dotenv_path, stream): + copy_dotenv_path = dotenv_path or ".env" + logger.warning("Copying %s to %s", init_dotenv_path, copy_dotenv_path) + import shutil + + shutil.copyfile(init_dotenv_path, copy_dotenv_path) + if dotenv_path is None and stream is None: dotenv_path = find_dotenv() @@ -430,6 +438,20 @@ def load_dotenv( return dotenv.set_as_environment_variables() +def should_copy_init( + arg_dotenv_path: Optional[StrPath], + init_dotenv_path: Optional[StrPath], + stream: Optional[IO[str]], +) -> Bool: + dotenv_path = arg_dotenv_path or ".env" + return ( + (stream is None) + and init_dotenv_path + and os.path.exists(init_dotenv_path) + and (not os.path.exists(dotenv_path)) + ) + + def dotenv_values( dotenv_path: Optional[StrPath] = None, stream: Optional[IO[str]] = None, From f9db99c5b9f648c5abb6240df979cb29fe8d454e Mon Sep 17 00:00:00 2001 From: Daniel Radetsky Date: Tue, 5 May 2026 17:25:05 -0700 Subject: [PATCH 2/4] reminder to update dox --- src/dotenv/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dotenv/main.py b/src/dotenv/main.py index 2b6bf0df..bf9a3b27 100644 --- a/src/dotenv/main.py +++ b/src/dotenv/main.py @@ -393,6 +393,7 @@ def load_dotenv( Parameters: dotenv_path: Absolute or relative path to .env file. + init_dotenv_path: TODO stream: Text stream (such as `io.StringIO`) with .env content, used if `dotenv_path` is `None`. verbose: Whether to output a warning the .env file is missing. From d05e0c065a220e7260c58956802f9ecf13af1d5e Mon Sep 17 00:00:00 2001 From: Daniel Radetsky Date: Tue, 5 May 2026 17:31:48 -0700 Subject: [PATCH 3/4] oops --- src/dotenv/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dotenv/main.py b/src/dotenv/main.py index bf9a3b27..b678879c 100644 --- a/src/dotenv/main.py +++ b/src/dotenv/main.py @@ -443,7 +443,7 @@ def should_copy_init( arg_dotenv_path: Optional[StrPath], init_dotenv_path: Optional[StrPath], stream: Optional[IO[str]], -) -> Bool: +) -> bool: dotenv_path = arg_dotenv_path or ".env" return ( (stream is None) From cb4d5ec6b8ebd0cb76a6740638468e3cda1e3757 Mon Sep 17 00:00:00 2001 From: Daniel Radetsky Date: Tue, 5 May 2026 17:44:01 -0700 Subject: [PATCH 4/4] fix types --- src/dotenv/main.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dotenv/main.py b/src/dotenv/main.py index b678879c..878db002 100644 --- a/src/dotenv/main.py +++ b/src/dotenv/main.py @@ -423,6 +423,7 @@ def load_dotenv( logger.warning("Copying %s to %s", init_dotenv_path, copy_dotenv_path) import shutil + assert init_dotenv_path is not None shutil.copyfile(init_dotenv_path, copy_dotenv_path) if dotenv_path is None and stream is None: @@ -445,9 +446,9 @@ def should_copy_init( stream: Optional[IO[str]], ) -> bool: dotenv_path = arg_dotenv_path or ".env" - return ( + return bool( (stream is None) - and init_dotenv_path + and (init_dotenv_path is not None) and os.path.exists(init_dotenv_path) and (not os.path.exists(dotenv_path)) )