Skip to content

Commit

Permalink
Use UTF-8 as default encoding
Browse files Browse the repository at this point in the history
The default value for the `encoding` paramter of `load_dotenv` and
`dotenv_values` is now `"utf-8"` instead of `None` (which selected the
encoding based on the user's locale).  It is passed directly to
`io.open`.

The rationale for this change is that the encoding of a project file
like `.env` should not depend on the user's locale by default.  UTF-8
makes sense as the default encoding since it is also used for Python
source files.  The main drawback is that it departs from `open`'s
default value of `None` for the `encoding` parameter.

The default value of `None` was a source of confusion for some users.
The Flask and Docker Compose projects already use `encoding="utf-8"` to
enforce the use of UTF-8 and avoid that sort of confusion.

This is a breaking change but only for users with a non-UTF-8 locale and
non-UTF-8 characters in their .env files.
  • Loading branch information
bbc2 committed Mar 27, 2021
1 parent a7fe93f commit b158aa7
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 11 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Expand Up @@ -7,7 +7,11 @@ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

- Fix resolution order in variable expansion with `override=False` (#? by [@bbc2]).
### Changed

- The default value of the `encoding` parameter for `load_dotenv` and `dotenv_values` is
now `"utf-8"` instead of `None` (#? by [@bbc2]).
- Fix resolution order in variable expansion with `override=False` (#287 by [@bbc2]).

## [0.15.0] - 2020-10-28

Expand Down
61 changes: 51 additions & 10 deletions src/dotenv/main.py
Expand Up @@ -293,22 +293,63 @@ def _is_interactive():
return ''


def load_dotenv(dotenv_path=None, stream=None, verbose=False, override=False, interpolate=True, **kwargs):
# type: (Union[Text, _PathLike, None], Optional[_StringIO], bool, bool, bool, Union[None, Text]) -> bool
def load_dotenv(
dotenv_path=None,
stream=None,
verbose=False,
override=False,
interpolate=True,
encoding="utf-8",
):
# type: (Union[Text, _PathLike, None], Optional[_StringIO], bool, bool, bool, Optional[Text]) -> bool # noqa
"""Parse a .env file and then load all the variables found as environment variables.
- *dotenv_path*: absolute or relative path to .env file.
- *stream*: `StringIO` object with .env content.
- *verbose*: whether to output the warnings related to missing .env file etc. Defaults to `False`.
- *override*: where to override the system environment variables with the variables in `.env` file.
Defaults to `False`.
- *stream*: `StringIO` object with .env content, used if `dotenv_path` is `None`.
- *verbose*: whether to output a warning the .env file is missing. Defaults to
`False`.
- *override*: whether to override the system environment variables with the variables
in `.env` file. Defaults to `False`.
- *encoding*: encoding to be used to read the file.
If both `dotenv_path` and `stream`, `find_dotenv()` is used to find the .env file.
"""
f = dotenv_path or stream or find_dotenv()
dotenv = DotEnv(f, verbose=verbose, interpolate=interpolate, override=override, **kwargs)
dotenv = DotEnv(
f,
verbose=verbose,
interpolate=interpolate,
override=override,
encoding=encoding,
)
return dotenv.set_as_environment_variables()


def dotenv_values(dotenv_path=None, stream=None, verbose=False, interpolate=True, **kwargs):
# type: (Union[Text, _PathLike, None], Optional[_StringIO], bool, bool, Union[None, Text]) -> Dict[Text, Optional[Text]] # noqa: E501
def dotenv_values(
dotenv_path=None,
stream=None,
verbose=False,
interpolate=True,
encoding="utf-8",
):
# type: (Union[Text, _PathLike, None], Optional[_StringIO], bool, bool, Optional[Text]) -> Dict[Text, Optional[Text]] # noqa: E501
"""
Parse a .env file and return its content as a dict.
- *dotenv_path*: absolute or relative path to .env file.
- *stream*: `StringIO` object with .env content, used if `dotenv_path` is `None`.
- *verbose*: whether to output a warning the .env file is missing. Defaults to
`False`.
in `.env` file. Defaults to `False`.
- *encoding*: encoding to be used to read the file.
If both `dotenv_path` and `stream`, `find_dotenv()` is used to find the .env file.
"""
f = dotenv_path or stream or find_dotenv()
return DotEnv(f, verbose=verbose, interpolate=interpolate, override=True, **kwargs).dict()
return DotEnv(
f,
verbose=verbose,
interpolate=interpolate,
override=True,
encoding=encoding,
).dict()

0 comments on commit b158aa7

Please sign in to comment.