Skip to content

Commit

Permalink
Parse negative numbers from envvar Fix #799 and Fix #585 (#802)
Browse files Browse the repository at this point in the history
  • Loading branch information
rochacbruno committed Sep 5, 2022
1 parent d7824e5 commit a55cdba
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 8 deletions.
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -133,6 +133,7 @@ test_examples:
cd example/issues/741_envvars_ignored;pwd;sh recreate.sh
cd example/issues/705_flask_dynaconf_init;pwd;make test;make clean
cd example/issues/794_includes;pwd;python app.py
cd example/issues/799_negative_numbers;pwd;DYNACONF_NUM="-1" python app.py

test_vault:
# @cd example/vault;pwd;python write.py
Expand Down
8 changes: 0 additions & 8 deletions dynaconf/utils/parse_conf.py
Expand Up @@ -356,7 +356,6 @@ def parse_conf_data(data, tomlfy=False, box_settings=None):
box_settings = box_settings or {}

if isinstance(data, (tuple, list)):

# recursively parse each sequence item
return [
parse_conf_data(item, tomlfy=tomlfy, box_settings=box_settings)
Expand All @@ -372,13 +371,6 @@ def parse_conf_data(data, tomlfy=False, box_settings=None):
)
return _parsed

if (
isinstance(data, str)
and data.startswith(("+", "-"))
and data[1:].isdigit()
):
return data

# return parsed string value
return _parse_conf_data(data, tomlfy=tomlfy, box_settings=box_settings)

Expand Down
17 changes: 17 additions & 0 deletions dynaconf/validator.py
Expand Up @@ -135,6 +135,9 @@ def __init__(
self.envs: Sequence[str] | None = None
self.apply_default_on_none = apply_default_on_none

# See #585
self.is_type_of = operations.get("is_type_of")

if isinstance(env, str):
self.envs = [env]
elif isinstance(env, (list, tuple)):
Expand Down Expand Up @@ -243,6 +246,20 @@ def _validate_items(
else:
default_value = empty

# THIS IS A FIX FOR #585 in contrast with #799
# toml considers signed strings "+-1" as integers
# however existing users are passing strings
# to default on validator (see #585)
# The solution we added on #667 introduced a new problem
# This fix here makes it to work for both cases.
if (
isinstance(default_value, str)
and default_value.startswith(("+", "-"))
and self.is_type_of is str
):
# avoid TOML from parsing "+-1" as integer
default_value = f"'{default_value}'"

value = self.cast(
settings.setdefault(
name,
Expand Down
11 changes: 11 additions & 0 deletions example/issues/799_negative_numbers/app.py
@@ -0,0 +1,11 @@
from __future__ import annotations

from dynaconf import Dynaconf

settings = Dynaconf(settings_files=["settings.toml"])

print(settings.num)
print(type(settings.num))

assert settings.num == -1, settings.num
assert isinstance(settings.num, int)
1 change: 1 addition & 0 deletions example/issues/799_negative_numbers/settings.toml
@@ -0,0 +1 @@
num = -1
14 changes: 14 additions & 0 deletions tests/test_env_loader.py
Expand Up @@ -206,6 +206,20 @@ def test_backwards_compat_using_env_argument():
assert settings.VALUE == "BLARG as prefix"


def test_load_signed_integer():
environ["799_SIGNED_NEG_INT"] = "-1"
environ["799_SIGNED_POS_INT"] = "+1"
load_from_env(
identifier="env_global",
key=None,
prefix="799",
obj=settings,
silent=True,
)
assert settings.SIGNED_NEG_INT == -1
assert settings.SIGNED_POS_INT == 1


def test_env_is_not_str_raises():
with pytest.raises(TypeError):
load_from_env(settings, prefix=int)
Expand Down
11 changes: 11 additions & 0 deletions tests/test_validators.py
Expand Up @@ -739,6 +739,17 @@ def test_toml_should_not_change_validator_type_with_is_type_set():
assert settings.test == "+172800"


def test_toml_should_not_change_validator_type_with_is_type_not_set_int():
settings = Dynaconf(
validators=[Validator("TEST", default="+172800")]
# The ways to force a string is
# passing is_type_of=str
# or default="@str +172800" or default="'+172800'"
)

assert settings.test == +172800


def test_toml_should_not_change_validator_type_using_at_sign():
settings = Dynaconf(
validators=[Validator("TEST", is_type_of=str, default="@str +172800")]
Expand Down

0 comments on commit a55cdba

Please sign in to comment.