Skip to content

Commit b3b09a1

Browse files
committed
Add option not to override existing env variables
The reason the default behavior of this plugin is what it is, is because it has origins during the time when there were a lot of users migrating away from [Pipenv](https://github.com/pypa/pipenv), many switching to Poetry. [Pipenv had built-in `.env` loading](https://pipenv.pypa.io/en/latest/shell/#automatic-loading-of-env) which [did override by default (and still does)](https://github.com/pypa/pipenv/blob/98bdb5f8b2f08a435a825915d7d7d215a7aaec19/pipenv/utils/environment.py#L37). In order to support the many people coming from `pipenv` the goal was to make the fewest changes from that toolset possible in regards to `.env` loading. That is also why there are other some [analogous environment variables between this project and `pipenv` with a section about them in the README](https://github.com/mpeteuil/poetry-dotenv-plugin#coming-from-pipenv). If you're coming from vanilla `python-dotenv` then this is unexpected. That needs to be reconciled with the expectations of anyone coming from `pipenv`. Here we add a system environment variable—`POETRY_DOTENV_DONT_OVERRIDE`. I think it should solve most cases. This is because most users who want it to [behave like `python-dotenv`'s defaults](https://github.com/theskumar/python-dotenv#getting-started) probably want that everywhere and the same for anyone who wants it to behave like `pipenv`.
1 parent b0c573a commit b3b09a1

3 files changed

Lines changed: 54 additions & 1 deletion

File tree

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,9 @@ Pipenv env var | Poetry env var
3434
-------------- | ----------------------
3535
PIPENV_DOTENV_LOCATION | POETRY_DOTENV_LOCATION
3636
PIPENV_DONT_LOAD_ENV | POETRY_DONT_LOAD_ENV
37+
38+
### Overriding existing environment variables
39+
40+
By default, this plugin will override existing environment variables. This is because this plugin was built to make onboarding for users coming from `pipenv` as seamless as possible. If you want to prevent existing environment variables from being overridden, you can set the `POETRY_DOTENV_DONT_OVERRIDE` environment variable to `true`.[^1]
41+
42+
[^1]: See [#16](https://github.com/mpeteuil/poetry-dotenv-plugin/pull/16) for background.

poetry_dotenv_plugin/dotenv_plugin.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,9 @@ def load_dotenv(
2929
io.write_line("<debug>Loading environment variables.</debug>")
3030

3131
path = POETRY_DOTENV_LOCATION or dotenv.find_dotenv(usecwd=True)
32-
dotenv.load_dotenv(dotenv_path=path, override=True)
32+
POETRY_DOTENV_DONT_OVERRIDE = os.environ.get("POETRY_DOTENV_DONT_OVERRIDE", "")
33+
DOTENV_OVERRIDE = not POETRY_DOTENV_DONT_OVERRIDE.lower() in (
34+
"true",
35+
"1",
36+
)
37+
dotenv.load_dotenv(dotenv_path=path, override=DOTENV_OVERRIDE)

tests/test_system.sh

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,46 @@ function test_end_to_end_system_with_dotenv_location_override() {
5656
fi
5757
}
5858

59+
function test_end_to_end_system_with_default_env_overrides() {
60+
# Setup
61+
local expected
62+
expected='foo'
63+
create_dotenv_file
64+
65+
local output
66+
output=$(export MY_ENV_VAR='bar' && poetry run python -c "import os; print(os.environ['MY_ENV_VAR'])")
67+
68+
# Cleanup
69+
delete_dotenv_file
70+
71+
if [ "$expected" = "$output" ]; then
72+
printf "test_end_to_end_system_with_default_env_overrides: PASSED\n"
73+
else
74+
printf "Expected '$expected', but got '%s'.\n" "$output"
75+
exit 1
76+
fi
77+
}
78+
79+
function test_end_to_end_system_without_env_overrides() {
80+
# Setup
81+
local expected
82+
expected='bar'
83+
create_dotenv_file
84+
85+
local output
86+
output=$(export MY_ENV_VAR='bar' POETRY_DOTENV_DONT_OVERRIDE=true && poetry run python -c "import os; print(os.environ['MY_ENV_VAR'])")
87+
88+
# Cleanup
89+
delete_dotenv_file
90+
91+
if [ "$expected" = "$output" ]; then
92+
printf "test_end_to_end_system_without_env_overrides: PASSED\n"
93+
else
94+
printf "Expected '$expected', but got '%s'.\n" "$output"
95+
exit 1
96+
fi
97+
}
98+
5999
function test_end_to_end_system_without_loading_dotenv_file() {
60100
# Setup
61101
local expected
@@ -78,4 +118,6 @@ function test_end_to_end_system_without_loading_dotenv_file() {
78118

79119
test_end_to_end_system_with_default_dotenv_file
80120
test_end_to_end_system_with_dotenv_location_override
121+
test_end_to_end_system_with_default_env_overrides
122+
test_end_to_end_system_without_env_overrides
81123
test_end_to_end_system_without_loading_dotenv_file

0 commit comments

Comments
 (0)