Skip to content

Commit 09cf4ab

Browse files
authored
Fix type hint for dotenv_path var, add StrPath alias (#432)
* Fix type hint for load_dotenv Fixes #431 * Quote type hints to avoid runtime errors in earlier Python versions * Revise type of dotenv_path parameter Based on PR feedback and typeshed's type hint for the built-in open() function: https://github.com/python/typeshed/blob/e2d67bf7034f68c07bd35150247e58e0817725d9/stdlib/builtins.pyi#L1421 * Allow only string paths, not byte paths These paths can flow into `shutil.move`, which does not accept byte paths or (int) file descriptors. See python/typeshed#6832 * Create a type alias for the paths this library accepts And use it consistently in main.py.
1 parent f75103c commit 09cf4ab

File tree

1 file changed

+14
-8
lines changed

1 file changed

+14
-8
lines changed

src/dotenv/main.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
from .parser import Binding, parse_stream
1313
from .variables import parse_variables
1414

15+
# A type alias for a string path to be used for the paths in this file.
16+
# These paths may flow to `open()` and `shutil.move()`; `shutil.move()`
17+
# only accepts string paths, not byte paths or file descriptors. See
18+
# https://github.com/python/typeshed/pull/6832.
19+
StrPath = Union[str, 'os.PathLike[str]']
20+
1521
logger = logging.getLogger(__name__)
1622

1723

@@ -28,14 +34,14 @@ def with_warn_for_invalid_lines(mappings: Iterator[Binding]) -> Iterator[Binding
2834
class DotEnv:
2935
def __init__(
3036
self,
31-
dotenv_path: Optional[Union[str, os.PathLike]],
37+
dotenv_path: Optional[StrPath],
3238
stream: Optional[IO[str]] = None,
3339
verbose: bool = False,
3440
encoding: Optional[str] = None,
3541
interpolate: bool = True,
3642
override: bool = True,
3743
) -> None:
38-
self.dotenv_path: Optional[Union[str, os.PathLike]] = dotenv_path
44+
self.dotenv_path: Optional[StrPath] = dotenv_path
3945
self.stream: Optional[IO[str]] = stream
4046
self._dict: Optional[Dict[str, Optional[str]]] = None
4147
self.verbose: bool = verbose
@@ -108,7 +114,7 @@ def get(self, key: str) -> Optional[str]:
108114

109115

110116
def get_key(
111-
dotenv_path: Union[str, os.PathLike],
117+
dotenv_path: StrPath,
112118
key_to_get: str,
113119
encoding: Optional[str] = "utf-8",
114120
) -> Optional[str]:
@@ -122,7 +128,7 @@ def get_key(
122128

123129
@contextmanager
124130
def rewrite(
125-
path: Union[str, os.PathLike],
131+
path: StrPath,
126132
encoding: Optional[str],
127133
) -> Iterator[Tuple[IO[str], IO[str]]]:
128134
if not os.path.isfile(path):
@@ -139,7 +145,7 @@ def rewrite(
139145

140146

141147
def set_key(
142-
dotenv_path: Union[str, os.PathLike],
148+
dotenv_path: StrPath,
143149
key_to_set: str,
144150
value_to_set: str,
145151
quote_mode: str = "always",
@@ -188,7 +194,7 @@ def set_key(
188194

189195

190196
def unset_key(
191-
dotenv_path: Union[str, os.PathLike],
197+
dotenv_path: StrPath,
192198
key_to_unset: str,
193199
quote_mode: str = "always",
194200
encoding: Optional[str] = "utf-8",
@@ -303,7 +309,7 @@ def _is_interactive():
303309

304310

305311
def load_dotenv(
306-
dotenv_path: Union[str, os.PathLike, None] = None,
312+
dotenv_path: Optional[StrPath] = None,
307313
stream: Optional[IO[str]] = None,
308314
verbose: bool = False,
309315
override: bool = False,
@@ -341,7 +347,7 @@ def load_dotenv(
341347

342348

343349
def dotenv_values(
344-
dotenv_path: Union[str, os.PathLike, None] = None,
350+
dotenv_path: Optional[StrPath] = None,
345351
stream: Optional[IO[str]] = None,
346352
verbose: bool = False,
347353
interpolate: bool = True,

0 commit comments

Comments
 (0)