Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Env Vars: Add Support for |-syntax Optional Types #106

Merged
merged 13 commits into from
Sep 13, 2024
36 changes: 16 additions & 20 deletions dependencies-dev.log
Original file line number Diff line number Diff line change
Expand Up @@ -7,60 +7,56 @@
# pip freeze
########################################################################
attrs==24.2.0
certifi==2024.7.4
certifi==2024.8.30
charset-normalizer==3.3.2
filelock==3.15.4
filelock==3.16.0
flake8==5.0.4
idna==3.7
idna==3.8
iniconfig==2.0.0
mccabe==0.7.0
mypy==1.11.1
mypy==1.11.2
mypy-extensions==1.0.0
packaging==24.1
pluggy==1.5.0
pycodestyle==2.9.1
pyflakes==2.5.0
pytest==8.3.2
pytest==8.3.3
pytest-flake8==1.2.2
pytest-mypy==0.10.3
requests==2.32.3
semantic-version==2.10.0
setuptools==72.1.0
typing_extensions==4.12.2
urllib3==2.2.2
wheel==0.44.0
urllib3==2.2.3
########################################################################
# pipdeptree
########################################################################
pipdeptree==2.23.1
├── packaging [required: >=23.1, installed: 24.1]
└── pip [required: >=23.1.2, installed: 24.2]
pipdeptree==2.23.3
├── packaging [required: >=24.1, installed: 24.1]
└── pip [required: >=24.2, installed: 24.2]
pytest-flake8==1.2.2
├── flake8 [required: >=5,<6, installed: 5.0.4]
│ ├── mccabe [required: >=0.7.0,<0.8.0, installed: 0.7.0]
│ ├── pycodestyle [required: >=2.9.0,<2.10.0, installed: 2.9.1]
│ └── pyflakes [required: >=2.5.0,<2.6.0, installed: 2.5.0]
└── pytest [required: >=7.0, installed: 8.3.2]
└── pytest [required: >=7.0, installed: 8.3.3]
├── iniconfig [required: Any, installed: 2.0.0]
├── packaging [required: Any, installed: 24.1]
└── pluggy [required: >=1.5,<2, installed: 1.5.0]
pytest-mypy==0.10.3
├── attrs [required: >=19.0, installed: 24.2.0]
├── filelock [required: >=3.0, installed: 3.15.4]
├── mypy [required: >=0.900, installed: 1.11.1]
├── filelock [required: >=3.0, installed: 3.16.0]
├── mypy [required: >=0.900, installed: 1.11.2]
│ ├── mypy-extensions [required: >=1.0.0, installed: 1.0.0]
│ └── typing_extensions [required: >=4.6.0, installed: 4.12.2]
└── pytest [required: >=6.2, installed: 8.3.2]
└── pytest [required: >=6.2, installed: 8.3.3]
├── iniconfig [required: Any, installed: 2.0.0]
├── packaging [required: Any, installed: 24.1]
└── pluggy [required: >=1.5,<2, installed: 1.5.0]
semantic-version==2.10.0
setuptools==72.1.0
wheel==0.44.0
wipac-dev-tools
├── requests [required: Any, installed: 2.32.3]
│ ├── certifi [required: >=2017.4.17, installed: 2024.7.4]
│ ├── certifi [required: >=2017.4.17, installed: 2024.8.30]
│ ├── charset-normalizer [required: >=2,<4, installed: 3.3.2]
│ ├── idna [required: >=2.5,<4, installed: 3.7]
│ └── urllib3 [required: >=1.21.1,<3, installed: 2.2.2]
│ ├── idna [required: >=2.5,<4, installed: 3.8]
│ └── urllib3 [required: >=1.21.1,<3, installed: 2.2.3]
└── typing_extensions [required: Any, installed: 4.12.2]
36 changes: 16 additions & 20 deletions dependencies-mypy.log
Original file line number Diff line number Diff line change
Expand Up @@ -7,60 +7,56 @@
# pip freeze
########################################################################
attrs==24.2.0
certifi==2024.7.4
certifi==2024.8.30
charset-normalizer==3.3.2
filelock==3.15.4
filelock==3.16.0
flake8==5.0.4
idna==3.7
idna==3.8
iniconfig==2.0.0
mccabe==0.7.0
mypy==1.11.1
mypy==1.11.2
mypy-extensions==1.0.0
packaging==24.1
pluggy==1.5.0
pycodestyle==2.9.1
pyflakes==2.5.0
pytest==8.3.2
pytest==8.3.3
pytest-flake8==1.2.2
pytest-mypy==0.10.3
requests==2.32.3
semantic-version==2.10.0
setuptools==72.1.0
typing_extensions==4.12.2
urllib3==2.2.2
wheel==0.44.0
urllib3==2.2.3
########################################################################
# pipdeptree
########################################################################
pipdeptree==2.23.1
├── packaging [required: >=23.1, installed: 24.1]
└── pip [required: >=23.1.2, installed: 24.2]
pipdeptree==2.23.3
├── packaging [required: >=24.1, installed: 24.1]
└── pip [required: >=24.2, installed: 24.2]
pytest-flake8==1.2.2
├── flake8 [required: >=5,<6, installed: 5.0.4]
│ ├── mccabe [required: >=0.7.0,<0.8.0, installed: 0.7.0]
│ ├── pycodestyle [required: >=2.9.0,<2.10.0, installed: 2.9.1]
│ └── pyflakes [required: >=2.5.0,<2.6.0, installed: 2.5.0]
└── pytest [required: >=7.0, installed: 8.3.2]
└── pytest [required: >=7.0, installed: 8.3.3]
├── iniconfig [required: Any, installed: 2.0.0]
├── packaging [required: Any, installed: 24.1]
└── pluggy [required: >=1.5,<2, installed: 1.5.0]
pytest-mypy==0.10.3
├── attrs [required: >=19.0, installed: 24.2.0]
├── filelock [required: >=3.0, installed: 3.15.4]
├── mypy [required: >=0.900, installed: 1.11.1]
├── filelock [required: >=3.0, installed: 3.16.0]
├── mypy [required: >=0.900, installed: 1.11.2]
│ ├── mypy-extensions [required: >=1.0.0, installed: 1.0.0]
│ └── typing_extensions [required: >=4.6.0, installed: 4.12.2]
└── pytest [required: >=6.2, installed: 8.3.2]
└── pytest [required: >=6.2, installed: 8.3.3]
├── iniconfig [required: Any, installed: 2.0.0]
├── packaging [required: Any, installed: 24.1]
└── pluggy [required: >=1.5,<2, installed: 1.5.0]
semantic-version==2.10.0
setuptools==72.1.0
wheel==0.44.0
wipac-dev-tools
├── requests [required: Any, installed: 2.32.3]
│ ├── certifi [required: >=2017.4.17, installed: 2024.7.4]
│ ├── certifi [required: >=2017.4.17, installed: 2024.8.30]
│ ├── charset-normalizer [required: >=2,<4, installed: 3.3.2]
│ ├── idna [required: >=2.5,<4, installed: 3.7]
│ └── urllib3 [required: >=1.21.1,<3, installed: 2.2.2]
│ ├── idna [required: >=2.5,<4, installed: 3.8]
│ └── urllib3 [required: >=1.21.1,<3, installed: 2.2.3]
└── typing_extensions [required: Any, installed: 4.12.2]
22 changes: 9 additions & 13 deletions dependencies-semver.log
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,24 @@
########################################################################
# pip freeze
########################################################################
certifi==2024.7.4
certifi==2024.8.30
charset-normalizer==3.3.2
idna==3.7
idna==3.8
requests==2.32.3
semantic-version==2.10.0
setuptools==72.1.0
typing_extensions==4.12.2
urllib3==2.2.2
wheel==0.44.0
urllib3==2.2.3
########################################################################
# pipdeptree
########################################################################
pipdeptree==2.23.1
├── packaging [required: >=23.1, installed: 24.1]
└── pip [required: >=23.1.2, installed: 24.2]
pipdeptree==2.23.3
├── packaging [required: >=24.1, installed: 24.1]
└── pip [required: >=24.2, installed: 24.2]
semantic-version==2.10.0
setuptools==72.1.0
wheel==0.44.0
wipac-dev-tools
├── requests [required: Any, installed: 2.32.3]
│ ├── certifi [required: >=2017.4.17, installed: 2024.7.4]
│ ├── certifi [required: >=2017.4.17, installed: 2024.8.30]
│ ├── charset-normalizer [required: >=2,<4, installed: 3.3.2]
│ ├── idna [required: >=2.5,<4, installed: 3.7]
│ └── urllib3 [required: >=1.21.1,<3, installed: 2.2.2]
│ ├── idna [required: >=2.5,<4, installed: 3.8]
│ └── urllib3 [required: >=1.21.1,<3, installed: 2.2.3]
└── typing_extensions [required: Any, installed: 4.12.2]
22 changes: 9 additions & 13 deletions dependencies.log
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,22 @@
########################################################################
# pip freeze
########################################################################
certifi==2024.7.4
certifi==2024.8.30
charset-normalizer==3.3.2
idna==3.7
idna==3.8
requests==2.32.3
setuptools==72.1.0
typing_extensions==4.12.2
urllib3==2.2.2
wheel==0.44.0
urllib3==2.2.3
########################################################################
# pipdeptree
########################################################################
pipdeptree==2.23.1
├── packaging [required: >=23.1, installed: 24.1]
└── pip [required: >=23.1.2, installed: 24.2]
setuptools==72.1.0
wheel==0.44.0
pipdeptree==2.23.3
├── packaging [required: >=24.1, installed: 24.1]
└── pip [required: >=24.2, installed: 24.2]
wipac-dev-tools
├── requests [required: Any, installed: 2.32.3]
│ ├── certifi [required: >=2017.4.17, installed: 2024.7.4]
│ ├── certifi [required: >=2017.4.17, installed: 2024.8.30]
│ ├── charset-normalizer [required: >=2,<4, installed: 3.3.2]
│ ├── idna [required: >=2.5,<4, installed: 3.7]
│ └── urllib3 [required: >=1.21.1,<3, installed: 2.2.2]
│ ├── idna [required: >=2.5,<4, installed: 3.8]
│ └── urllib3 [required: >=1.21.1,<3, installed: 2.2.3]
└── typing_extensions [required: Any, installed: 4.12.2]
78 changes: 68 additions & 10 deletions tests/enviro_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import os
import pathlib
import shutil
import sys
import tempfile
import unittest
from typing import Any, Dict, FrozenSet, List, Optional, Set
from typing import Any, Dict, FrozenSet, List, Optional, Set, Union

import pytest
from typing_extensions import Final
Expand Down Expand Up @@ -529,39 +530,96 @@ class Config:
assert config.FOO == {"bar": 2, "baz": 3, "foo": 1}


if sys.version_info >= (3, 10):
# this trips up the py <3.9 interpreter
extra_params = [
bool | None,
None | bool,
]
else:
extra_params = [] # type: ignore[var-annotated]


@pytest.mark.parametrize(
"typo",
[
Optional[bool],
Union[bool, None],
Union[None, bool],
]
+ extra_params, # type: ignore
)
@pytest.mark.usefixtures("isolated_env")
def test_052__optional_bool() -> None:
def test_060__optional_bool(typo) -> None:
"""Test normal use case."""

@dc.dataclass(frozen=True)
class Config:
FOO: Optional[bool]
FOO: typo # type: ignore

os.environ["FOO"] = "T"
config = from_environment_as_dataclass(Config)
assert config.FOO is True


if sys.version_info >= (3, 10):
# this trips up the py <3.9 interpreter
extra_params = [
Dict[str, int] | None,
None | Dict[str, int],
]
else:
extra_params = []


@pytest.mark.parametrize(
"typo",
[
Optional[Dict[str, int]],
Union[Dict[str, int], None],
Union[None, Dict[str, int]],
]
+ extra_params, # type: ignore
)
@pytest.mark.usefixtures("isolated_env")
def test_053__optional_dict_str_int() -> None:
def test_061__optional_dict_str_int(typo) -> None:
"""Test normal use case."""

@dc.dataclass(frozen=True)
class Config:
FOO: Optional[Dict[str, int]]
FOO: typo # type: ignore

os.environ["FOO"] = "foo=1 bar=2 baz=3"
config = from_environment_as_dataclass(Config)
assert config.FOO == {"bar": 2, "baz": 3, "foo": 1}


if sys.version_info >= (3, 10):
# this trips up the py <3.9 interpreter
extra_params = [
dict | None,
None | dict,
]
else:
extra_params = []


@pytest.mark.parametrize(
"typo",
[
Optional[dict],
Union[dict, None],
Union[None, dict],
]
+ extra_params, # type: ignore
)
@pytest.mark.usefixtures("isolated_env")
def test_054__optional_dict() -> None:
def test_062__optional_dict(typo) -> None:
"""Test normal use case."""

@dc.dataclass(frozen=True)
class Config:
FOO: Optional[dict]
FOO: typo # type: ignore

os.environ["FOO"] = "foo=1 bar=2 baz=3"
config = from_environment_as_dataclass(Config)
Expand Down Expand Up @@ -655,9 +713,9 @@ class Config:
from_environment_as_dataclass(Config)
assert str(cm.value) == (
"'typing.List[typing.Dict[str, int]]' is not a "
"supported type: field='FOO' (the typing-module's alias types "
"must resolve to 'type' within 1 nesting, or 2 if using "
"'Final' or 'Optional')"
"supported type: field='FOO' (typehints "
"must resolve to 'type' within 1 nesting, or "
"2 if using 'Final', 'Optional', or a None-'Union' pairing)"
)


Expand Down
Loading
Loading