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

deprecate warning for not catch lowercase env var #2344

Merged
9 changes: 9 additions & 0 deletions sanic/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,12 @@ def __init__(self, name) -> None:
`See user guide re: config
<https://sanicframework.org/guide/deployment/configuration.html>`__
"""
lower_case_var_found = False
for key, value in environ.items():
if not key.startswith(prefix):
continue
if not key.isupper():
lower_case_var_found = True

_, config_key = key.split(prefix, 1)

Expand All @@ -233,6 +236,12 @@ def __init__(self, name) -> None:
break
except ValueError:
pass
if lower_case_var_found:
deprecation(
"Lowercase environment variables will not be "
"loaded into Sanic config beginning in v22.9.",
22.9,
)

def update_config(self, config: Union[bytes, str, dict, Any]):
"""
Expand Down
50 changes: 32 additions & 18 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import pytest

from pytest import MonkeyPatch

from sanic import Sanic
from sanic.config import DEFAULT_CONFIG, Config
from sanic.exceptions import PyFileError
Expand Down Expand Up @@ -39,21 +41,21 @@ def __init__(self, answer):
self.answer = int(answer)


def test_load_from_object(app):
def test_load_from_object(app: Sanic):
app.config.load(ConfigTest)
assert "CONFIG_VALUE" in app.config
assert app.config.CONFIG_VALUE == "should be used"
assert "not_for_config" not in app.config


def test_load_from_object_string(app):
def test_load_from_object_string(app: Sanic):
app.config.load("test_config.ConfigTest")
assert "CONFIG_VALUE" in app.config
assert app.config.CONFIG_VALUE == "should be used"
assert "not_for_config" not in app.config


def test_load_from_instance(app):
def test_load_from_instance(app: Sanic):
app.config.load(ConfigTest())
assert "CONFIG_VALUE" in app.config
assert app.config.CONFIG_VALUE == "should be used"
Expand All @@ -62,7 +64,7 @@ def test_load_from_instance(app):
assert "another_not_for_config" not in app.config


def test_load_from_object_string_exception(app):
def test_load_from_object_string_exception(app: Sanic):
with pytest.raises(ImportError):
app.config.load("test_config.Config.test")

Expand Down Expand Up @@ -120,6 +122,18 @@ def test_env_w_custom_converter():
del environ["SANIC_TEST_ANSWER"]


def test_env_lowercase():
with pytest.warns(None) as record:
environ["SANIC_test_answer"] = "42"
app = Sanic(name=__name__)
assert app.config.test_answer == 42
assert str(record[0].message) == (
"[DEPRECATION v22.9] Lowercase environment variables will not be "
"loaded into Sanic config beginning in v22.9."
)
del environ["SANIC_test_answer"]


def test_add_converter_multiple_times(caplog):
def converter():
...
Expand All @@ -136,7 +150,7 @@ def converter():
assert len(config._converters) == 5


def test_load_from_file(app):
def test_load_from_file(app: Sanic):
config = dedent(
"""
VALUE = 'some value'
Expand All @@ -155,12 +169,12 @@ def test_load_from_file(app):
assert "condition" not in app.config


def test_load_from_missing_file(app):
def test_load_from_missing_file(app: Sanic):
with pytest.raises(IOError):
app.config.load("non-existent file")


def test_load_from_envvar(app):
def test_load_from_envvar(app: Sanic):
config = "VALUE = 'some value'"
with temp_path() as config_path:
config_path.write_text(config)
Expand All @@ -170,7 +184,7 @@ def test_load_from_envvar(app):
assert app.config.VALUE == "some value"


def test_load_from_missing_envvar(app):
def test_load_from_missing_envvar(app: Sanic):
with pytest.raises(IOError) as e:
app.config.load("non-existent variable")
assert str(e.value) == (
Expand All @@ -180,7 +194,7 @@ def test_load_from_missing_envvar(app):
)


def test_load_config_from_file_invalid_syntax(app):
def test_load_config_from_file_invalid_syntax(app: Sanic):
config = "VALUE = some value"
with temp_path() as config_path:
config_path.write_text(config)
Expand All @@ -189,7 +203,7 @@ def test_load_config_from_file_invalid_syntax(app):
app.config.load(config_path)


def test_overwrite_exisiting_config(app):
def test_overwrite_exisiting_config(app: Sanic):
app.config.DEFAULT = 1

class Config:
Expand All @@ -199,7 +213,7 @@ class Config:
assert app.config.DEFAULT == 2


def test_overwrite_exisiting_config_ignore_lowercase(app):
def test_overwrite_exisiting_config_ignore_lowercase(app: Sanic):
app.config.default = 1

class Config:
Expand All @@ -209,7 +223,7 @@ class Config:
assert app.config.default == 1


def test_missing_config(app):
def test_missing_config(app: Sanic):
with pytest.raises(AttributeError, match="Config has no 'NON_EXISTENT'"):
_ = app.config.NON_EXISTENT

Expand Down Expand Up @@ -277,7 +291,7 @@ def test_config_custom_defaults_with_env():
del environ[key]


def test_config_access_log_passing_in_run(app):
def test_config_access_log_passing_in_run(app: Sanic):
assert app.config.ACCESS_LOG is True

@app.listener("after_server_start")
Expand All @@ -292,7 +306,7 @@ async def _request(sanic, loop):


@pytest.mark.asyncio
async def test_config_access_log_passing_in_create_server(app):
async def test_config_access_log_passing_in_create_server(app: Sanic):
assert app.config.ACCESS_LOG is True

@app.listener("after_server_start")
Expand Down Expand Up @@ -341,18 +355,18 @@ def test_config_rewrite_keep_alive():
],
ids=["from_dict", "from_class", "from_file"],
)
def test_update(app, conf_object):
def test_update(app: Sanic, conf_object):
app.update_config(conf_object)
assert app.config["TEST_SETTING_VALUE"] == 1


def test_update_from_lowercase_key(app):
def test_update_from_lowercase_key(app: Sanic):
d = {"test_setting_value": 1}
app.update_config(d)
assert "test_setting_value" not in app.config


def test_deprecation_notice_when_setting_logo(app):
def test_deprecation_notice_when_setting_logo(app: Sanic):
message = (
"Setting the config.LOGO is deprecated and will no longer be "
"supported starting in v22.6."
Expand All @@ -361,7 +375,7 @@ def test_deprecation_notice_when_setting_logo(app):
app.config.LOGO = "My Custom Logo"


def test_config_set_methods(app, monkeypatch):
def test_config_set_methods(app: Sanic, monkeypatch: MonkeyPatch):
post_set = Mock()
monkeypatch.setattr(Config, "_post_set", post_set)

Expand Down