From 7d11d782054a601027d5de20cae8f581ed992917 Mon Sep 17 00:00:00 2001 From: Steven Loria Date: Mon, 8 Jan 2024 17:51:01 -0500 Subject: [PATCH] Json non str default (#309) * Accept non str values as default json parser value * Add type checking when importing default json. * Add tests to default json validation. * Update changelog --------- Co-authored-by: Tom Co-authored-by: Brunno Vanelli --- CHANGELOG.md | 7 +++++++ environs/__init__.py | 9 +++++++-- tests/test_environs.py | 7 +++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bd4c6e..e191392 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 10.1.0 (unreleased) + +Features: + +- Allow `default` for `env.json` to be a `dict` or `list` ([#240](https://github.com/sloria/environs/pull/240)). + Thanks [tomgrin10](https://github.com/tomgrin10) and [bvanelli](https://github.com/bvanelli) for the PRs. + ## 10.0.0 (2023-12-15) Features: diff --git a/environs/__init__.py b/environs/__init__.py index c892c85..4b00fc8 100644 --- a/environs/__init__.py +++ b/environs/__init__.py @@ -231,9 +231,14 @@ def _preprocess_dict( } -def _preprocess_json(value: str, **kwargs): +def _preprocess_json(value: typing.Union[str, typing.Mapping, typing.List], **kwargs): try: - return pyjson.loads(value) + if isinstance(value, str): + return pyjson.loads(value) + elif isinstance(value, dict) or isinstance(value, list) or value is None: + return value + else: + raise ma.ValidationError("Not valid JSON.") except pyjson.JSONDecodeError as error: raise ma.ValidationError("Not valid JSON.") from error diff --git a/tests/test_environs.py b/tests/test_environs.py index 95efff8..2e77396 100644 --- a/tests/test_environs.py +++ b/tests/test_environs.py @@ -198,6 +198,13 @@ def test_invalid_json_raises_error(self, set_env, env): env.json("JSON") assert "Not valid JSON." in exc.value.args[0] + def test_json_default(self, set_env, env): + assert env.json("JSON", {"foo": "bar"}) == {"foo": "bar"} + assert env.json("JSON", ["foo", "bar"]) == ["foo", "bar"] + with pytest.raises(environs.EnvError) as exc: + env.json("JSON", int) # a builtin is not a valid json + assert "Not valid JSON." in exc.value.args[0] + def test_datetime_cast(self, set_env, env): dtime = dt.datetime.utcnow() set_env({"DTIME": dtime.isoformat()})