From b10b6d4af1127fdfb0a74221af0c020ced71fece Mon Sep 17 00:00:00 2001 From: AntoineMath Date: Wed, 22 Feb 2023 14:40:49 +0100 Subject: [PATCH] add text parameter to config.from_file --- CHANGES.rst | 2 ++ src/flask/config.py | 11 ++++++++--- tests/static/config.toml | 2 ++ tests/test_config.py | 13 +++++++++++-- 4 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 tests/static/config.toml diff --git a/CHANGES.rst b/CHANGES.rst index 88bfbc68..8159ea45 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -33,6 +33,8 @@ Unreleased - Use modern packaging metadata with ``pyproject.toml`` instead of ``setup.cfg``. :pr:`4947` - Ensure subdomains are applied with nested blueprints. :issue:`4834` +- ``config.from_file`` can use ``text=False`` to indicate that the parser wants a + binary file instead. :issue:`4989` Version 2.2.3 diff --git a/src/flask/config.py b/src/flask/config.py index d4fc310f..5e48be33 100644 --- a/src/flask/config.py +++ b/src/flask/config.py @@ -234,6 +234,7 @@ class Config(dict): filename: str, load: t.Callable[[t.IO[t.Any]], t.Mapping], silent: bool = False, + text: bool = True, ) -> bool: """Update the values in the config from a file that is loaded using the ``load`` parameter. The loaded data is passed to the @@ -244,8 +245,8 @@ class Config(dict): import json app.config.from_file("config.json", load=json.load) - import toml - app.config.from_file("config.toml", load=toml.load) + import tomllib + app.config.from_file("config.toml", load=tomllib.load, text=False) :param filename: The path to the data file. This can be an absolute path or relative to the config root path. @@ -254,14 +255,18 @@ class Config(dict): :type load: ``Callable[[Reader], Mapping]`` where ``Reader`` implements a ``read`` method. :param silent: Ignore the file if it doesn't exist. + :param text: Open the file in text or binary mode. :return: ``True`` if the file was loaded successfully. + .. versionchanged:: 2.3 + The ``text`` parameter was added. + .. versionadded:: 2.0 """ filename = os.path.join(self.root_path, filename) try: - with open(filename) as f: + with open(filename, "r" if text else "rb") as f: obj = load(f) except OSError as e: if silent and e.errno in (errno.ENOENT, errno.EISDIR): diff --git a/tests/static/config.toml b/tests/static/config.toml new file mode 100644 index 00000000..64acdbdd --- /dev/null +++ b/tests/static/config.toml @@ -0,0 +1,2 @@ +TEST_KEY="foo" +SECRET_KEY="config" diff --git a/tests/test_config.py b/tests/test_config.py index 76c5d272..580ae864 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -6,7 +6,6 @@ import pytest import flask - # config keys used for the TestConfig TEST_KEY = "foo" SECRET_KEY = "config" @@ -30,13 +29,23 @@ def test_config_from_object(): common_object_test(app) -def test_config_from_file(): +def test_config_from_file_json(): app = flask.Flask(__name__) current_dir = os.path.dirname(os.path.abspath(__file__)) app.config.from_file(os.path.join(current_dir, "static", "config.json"), json.load) common_object_test(app) +def test_config_from_file_toml(): + tomllib = pytest.importorskip("tomllib", reason="tomllib added in 3.11") + app = flask.Flask(__name__) + current_dir = os.path.dirname(os.path.abspath(__file__)) + app.config.from_file( + os.path.join(current_dir, "static", "config.toml"), tomllib.load, text=False + ) + common_object_test(app) + + def test_from_prefixed_env(monkeypatch): monkeypatch.setenv("FLASK_STRING", "value") monkeypatch.setenv("FLASK_BOOL", "true")