Skip to content
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ Optional flags:
- `-o` to override existing variables.
- `-v` for increased verbosity.

### Disable load_dotenv

You can disable automatic loading of dotenv values by setting the `DOTENV_AUTOLOAD_DISABLED` environmental variable to `true`. This can be useful if you are using a library that uses `load_dotenv` and you want to manage the environment in a different way.

## Command-line Interface

A CLI interface `dotenv` is also included, which helps you manipulate the `.env` file
Expand Down
12 changes: 12 additions & 0 deletions src/dotenv/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@ def load_dotenv(
of `find_dotenv()`, you can explicitly call `find_dotenv()` and pass the result
to this function as `dotenv_path`.
"""
if _dotenv_autoload_disabled():
Comment thread
theskumar marked this conversation as resolved.
Outdated
return False

if dotenv_path is None and stream is None:
dotenv_path = find_dotenv()

Expand Down Expand Up @@ -398,3 +401,12 @@ def dotenv_values(
override=True,
encoding=encoding,
).dict()

def _dotenv_autoload_disabled() -> bool:
"""
Determine if dotenv autoloading has been disabled.
"""
if "DOTENV_AUTOLOAD_DISABLED" not in os.environ:
return False
value = os.environ["DOTENV_AUTOLOAD_DISABLED"].casefold()
return value in {"1", "true", "t", "yes", "y"}
65 changes: 65 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,71 @@ def test_load_dotenv_existing_file(dotenv_path):
assert os.environ == {"a": "b"}


@pytest.mark.parametrize(
"flag_value",
[
"true",
"yes",
"1",
"t",
"y",
"True",
"Yes",
"TRUE",
"YES",
"T",
"Y",
],
)
def test_load_dotenv_disabled(dotenv_path, flag_value):
Comment thread
theskumar marked this conversation as resolved.
expected_environ = {"DOTENV_AUTOLOAD_DISABLED": flag_value}
with mock.patch.dict(os.environ, {"DOTENV_AUTOLOAD_DISABLED": flag_value}, clear=True):
dotenv_path.write_text("a=b")

result = dotenv.load_dotenv(dotenv_path)

assert result is False
assert os.environ == expected_environ


@pytest.mark.parametrize(
"flag_value",
[
"",
"false",
"no",
"0",
"f",
"n",
"False",
"No",
"FALSE",
"NO",
"F",
"N",
],
)
def test_load_dotenv_enabled(dotenv_path, flag_value):
expected_environ = {"DOTENV_AUTOLOAD_DISABLED": flag_value, "a": "b"}
with mock.patch.dict(os.environ, {"DOTENV_AUTOLOAD_DISABLED": flag_value}, clear=True):
dotenv_path.write_text("a=b")

result = dotenv.load_dotenv(dotenv_path)

assert result is True
assert os.environ == expected_environ


@mock.patch.dict(os.environ, {}, clear=True)
def test_load_dotenv_doesnt_disable_itself(dotenv_path):
dotenv_path.write_text("DOTENV_AUTOLOAD_DISABLED=true")

result = dotenv.load_dotenv(dotenv_path)

assert result is True
assert os.environ == {"DOTENV_AUTOLOAD_DISABLED": "true"}


def test_load_dotenv_no_file_verbose():
logger = logging.getLogger("dotenv.main")

Expand Down