-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added type hints for methods Fix #367 * Build docs with py313 * Modernize type hints * Fix typing * Fix type hints * Add mypy test cases * Move types to environs.types * Rename types * Rename mypy test file so it doesn't get run my pytest * DRY common kwargs * Add __future__ import to fix py39 * Update changelog * Add back subcast_keys and subcast_values * Add case for untyped parser --------- Co-authored-by: Steven Loria <[email protected]>
- Loading branch information
Showing
5 changed files
with
192 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
"""Custom types and type aliases. | ||
.. warning:: | ||
This module is provisional. Types may be modified, added, and removed between minor releases. | ||
""" | ||
|
||
from __future__ import annotations | ||
|
||
import enum | ||
import typing | ||
|
||
try: | ||
from typing import Unpack | ||
except ImportError: # Remove when dropping Python 3.10 | ||
from typing_extensions import Unpack | ||
|
||
import marshmallow as ma | ||
|
||
T = typing.TypeVar("T") | ||
EnumT = typing.TypeVar("EnumT", bound=enum.Enum) | ||
|
||
|
||
ErrorMapping = typing.Mapping[str, list[str]] | ||
ErrorList = list[str] | ||
FieldFactory = typing.Callable[..., ma.fields.Field] | ||
Subcast = typing.Union[type, typing.Callable[..., T], ma.fields.Field] | ||
FieldType = type[ma.fields.Field] | ||
FieldOrFactory = typing.Union[FieldType, FieldFactory] | ||
ParserMethod = typing.Callable[..., T] | ||
|
||
|
||
class BaseMethodKwargs(typing.TypedDict, total=False): | ||
# Subset of relevant marshmallow.Field kwargs shared by all parser methods | ||
load_default: typing.Any | ||
validate: ( | ||
typing.Callable[[typing.Any], typing.Any] | ||
| typing.Iterable[typing.Callable[[typing.Any], typing.Any]] | ||
| None | ||
) | ||
required: bool | ||
allow_none: bool | None | ||
error_messages: dict[str, str] | None | ||
metadata: typing.Mapping[str, typing.Any] | None | ||
|
||
|
||
class FieldMethod(typing.Generic[T]): | ||
def __call__( | ||
self, | ||
name: str, | ||
default: typing.Any = ma.missing, | ||
subcast: Subcast[T] | None = None, | ||
**kwargs: Unpack[BaseMethodKwargs], | ||
) -> T | None: ... | ||
|
||
|
||
class ListFieldMethod: | ||
def __call__( | ||
self, | ||
name: str, | ||
default: typing.Any = ma.missing, | ||
subcast: Subcast[T] | None = None, | ||
*, | ||
delimiter: str | None = None, | ||
**kwargs: Unpack[BaseMethodKwargs], | ||
) -> list | None: ... | ||
|
||
|
||
class DictFieldMethod: | ||
def __call__( | ||
self, | ||
name: str, | ||
default: typing.Any = ma.missing, | ||
*, | ||
subcast_keys: Subcast[T] | None = None, | ||
subcast_values: Subcast[T] | None = None, | ||
delimiter: str | None = None, | ||
**kwargs: Unpack[BaseMethodKwargs], | ||
) -> dict | None: ... | ||
|
||
|
||
class EnumFuncMethod: | ||
def __call__( | ||
self, | ||
value, | ||
type: type[EnumT], | ||
default: EnumT | None = None, | ||
ignore_case: bool = False, | ||
) -> EnumT | None: ... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
"""Test cases for type hints of environs.Env. | ||
To run these, use: :: | ||
tox -e mypy-marshmallow3 | ||
Or :: | ||
tox -e mypy-marshmallowdev | ||
""" | ||
|
||
import datetime as dt | ||
import decimal | ||
import pathlib | ||
import uuid | ||
from typing import Any | ||
from urllib.parse import ParseResult | ||
|
||
import environs | ||
|
||
env = environs.Env() | ||
|
||
A: int | None = env.int("FOO", None) | ||
B: bool | None = env.bool("FOO", None) | ||
C: str | None = env.str("FOO", None) | ||
D: float | None = env.float("FOO", None) | ||
E: decimal.Decimal | None = env.decimal("FOO", None) | ||
F: list | None = env.list("FOO", None) | ||
G: list[int] | None = env.list("FOO", None, subcast=int) | ||
H: dict | None = env.dict("FOO", None) | ||
J: dict[str, int] | None = env.dict("FOO", None, subcast_keys=str, subcast_values=int) | ||
K: list | dict | None = env.json("FOO", None) | ||
L: dt.datetime | None = env.datetime("FOO", None) | ||
M: dt.date | None = env.date("FOO", None) | ||
N: dt.time | None = env.time("FOO", None) | ||
P: dt.timedelta | None = env.timedelta("FOO", None) | ||
Q: pathlib.Path | None = env.path("FOO", None) | ||
R: int | None = env.log_level("FOO", None) | ||
S: uuid.UUID | None = env.uuid("FOO", None) | ||
T: ParseResult | None = env.url("FOO", None) | ||
U: Any = env("FOO", None) |