Skip to content

Commit

Permalink
Strip prefixes, and fixed TOML tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tr11 committed Jul 23, 2024
1 parent e4c5c4f commit 2545048
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 10 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.

## [Unreleased]


## [0.12.0] - 2024-07-23

### Added

- Granular `strip_prefix` parameters across different config types

### Fixed

- Unit tests for .toml files

### Changed

- Enviroment files are now loaded from filenames with a suffix of `.env` or starting with `.env`


## [0.11.0] - 2024-04-23

### Changed
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Source = "https://github.com/tr11/python-configuration"
[project.optional-dependencies]
# cloud
aws = ["boto3>=1.28.20"]
azure = ["azure-keyvault>=5.0.0"]
azure = ["azure-keyvault>=4.2.0", "azure-identity"]
gcp = ["google-cloud-secret-manager>=2.16.3"]
vault = ["hvac>=1.1.1"]
# file formats
Expand Down Expand Up @@ -148,6 +148,7 @@ module = [
'hvac.exceptions',
'jsonschema',
'jsonschema.exceptions',
'azure.identity',
]
ignore_missing_imports = true

Expand Down
2 changes: 1 addition & 1 deletion src/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def config(
config_ = ("toml", config_, True)
elif config_.endswith(".ini"):
config_ = ("ini", config_, True)
elif config_.endswith(".env"):
elif config_.endswith(".env") or config_.startswith(".env"):
config_ = ("dotenv", config_, True, *default_args)
elif os.path.isdir(config_):
config_ = ("path", config_, remove_level)
Expand Down
2 changes: 1 addition & 1 deletion src/config/contrib/gcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class GCPSecretManagerConfiguration(Configuration):
def __init__(
self,
project_id: str,
credentials: Credentials = None,
credentials: Optional[Credentials] = None,
client_options: Optional[ClientOptions] = None,
cache_expiration: int = 5 * 60,
interpolate: InterpolateType = False,
Expand Down
4 changes: 2 additions & 2 deletions tests/contrib/test_azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
from config import config_from_dict

try:
import azure
from config.contrib.azure import AzureKeyVaultConfiguration
from azure.core.exceptions import ResourceNotFoundError
azure = True
except ImportError: # pragma: no cover
azure = None # type: ignore

raise

DICT = {
"foo": "foo_val",
Expand Down
16 changes: 16 additions & 0 deletions tests/test_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,19 @@ def test_reload(): # type: ignore
d = DICT.copy()
d["a2.b2.c3"] = "updated"
assert cfg == config_from_dict(dict((k, str(v)) for k, v in d.items()))


def test_reload_2(): # type: ignore
os.environ.update(
(PREFIX + "__" + k.replace(".", "__").upper(), str(v)) for k, v in DICT.items()
)

cfg = config_from_env(PREFIX, lowercase_keys=True, strip_prefix=False)
assert cfg == config_from_dict(dict((PREFIX.lower() + "." + k, str(v)) for k, v in DICT.items()))

os.environ[PREFIX + "__" + "A2__B2__C3"] = "updated"
assert cfg == config_from_dict(dict((PREFIX.lower() + "." + k, str(v)) for k, v in DICT.items()))
cfg.reload()
d = DICT.copy()
d["a2.b2.c3"] = "updated"
assert cfg == config_from_dict(dict((PREFIX.lower() + "." + k, str(v)) for k, v in d.items()))
30 changes: 30 additions & 0 deletions tests/test_nested.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from config import config_from_dict, config


DICT = {
"a1.B1.c1": 1,
"a1.b1.C2": 2,
"A1.b1.c3": 3,
"a1.b2.c1": "a",
"a1.b2.c2": True,
"a1.b2.c3": 1.1,
"a2.b1.c1": "f",
"a2.b1.c2": False,
"a2.b1.c3": None,
"a2.b2.c1": 10,
"a2.b2.c2": "YWJjZGVmZ2g=",
"a2.b2.c3": "abcdefgh",
}

NESTED = {
"a1": {"b1": {"c1": 1, "C2": 2, "c3": 3}, "b2": {"c1": "a", "c2": True, "c3": 1.1}}
}


def test_load_from_config(): # type: ignore
cfg1 = config_from_dict(DICT, lowercase_keys=True)
cfg2 = config_from_dict(NESTED, lowercase_keys=True)

assert config(DICT, NESTED, lowercase_keys=True ) == config(cfg1, NESTED, lowercase_keys=True )
assert config(DICT, NESTED, lowercase_keys=True ) == config(DICT, cfg2, lowercase_keys=True )
assert config(DICT, NESTED, lowercase_keys=True ) == config(cfg1, cfg2, lowercase_keys=True )
39 changes: 34 additions & 5 deletions tests/test_toml.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
from pathlib import Path
import sys
import tempfile

import pytest

from config import config_from_dict
from config import config_from_dict, config

try:
import toml

if sys.version_info < (3, 11): # pragma: no cover
import tomli as toml
else: # pragma: no cover
import tomllib as toml

from config import config_from_toml
except ImportError:
toml = None
toml = None # type: ignore
config_from_toml = None # type: ignore


Expand All @@ -30,7 +34,20 @@
}

if toml:
TOML = toml.dumps(DICT)
TOML = """
"a1.b1.c1" = 1
"a1.b1.c2" = 2
"a1.b1.c3" = 3
"a1.b2.c1" = "a"
"a1.b2.c2" = true
"a1.b2.c3" = 1.1
"a2.b1.c1" = "f"
"a2.b1.c2" = false
"a2.b1.c3" = ""
"a2.b2.c1" = 10
"a2.b2.c2" = "YWJjZGVmZ2g="
"a2.b2.c3" = "abcdefgh"
"""

TOML2 = """
[owner]
Expand Down Expand Up @@ -110,6 +127,18 @@ def test_load_toml_filename_2(): # type: ignore
assert cfg == config_from_dict(DICT)


@pytest.mark.skipif("toml is None")
def test_load_toml_filename_3(): # type: ignore
with tempfile.NamedTemporaryFile(suffix='.toml') as f:
f.file.write(TOML.encode())
f.file.flush()
cfg = config(f.name)
assert cfg["a1.b1.c1"] == 1
assert cfg["a1.b1"].as_dict() == {"c1": 1, "c2": 2, "c3": 3}
assert cfg["a1.b2"].as_dict() == {"c1": "a", "c2": True, "c3": 1.1}
assert cfg == config_from_dict(DICT)


@pytest.mark.skipif("toml is None")
def test_equality(): # type: ignore
cfg = config_from_toml(TOML)
Expand Down

0 comments on commit 2545048

Please sign in to comment.