forked from orbit-oss/flask
add encoding parameter to open_resource
co-authored-by: mark <lopkophacked@protonmail.com>
This commit is contained in:
parent
66af0e55ef
commit
28d5a4d718
4 changed files with 79 additions and 51 deletions
|
|
@ -3,7 +3,9 @@ Version 3.1.0
|
||||||
|
|
||||||
- Provide a configuration option to control automatic option
|
- Provide a configuration option to control automatic option
|
||||||
responses. :pr:`5496`
|
responses. :pr:`5496`
|
||||||
|
- ``Flask.open_resource``/``open_instance_resource`` and
|
||||||
|
``Blueprint.open_resource`` take an ``encoding`` parameter to use when
|
||||||
|
opening in text mode. It defaults to ``utf-8``. :issue:`5504`
|
||||||
|
|
||||||
Version 3.0.3
|
Version 3.0.3
|
||||||
-------------
|
-------------
|
||||||
|
|
|
||||||
|
|
@ -320,9 +320,10 @@ class Flask(App):
|
||||||
t.cast(str, self.static_folder), filename, max_age=max_age
|
t.cast(str, self.static_folder), filename, max_age=max_age
|
||||||
)
|
)
|
||||||
|
|
||||||
def open_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]:
|
def open_resource(
|
||||||
"""Open a resource file relative to :attr:`root_path` for
|
self, resource: str, mode: str = "rb", encoding: str | None = None
|
||||||
reading.
|
) -> t.IO[t.AnyStr]:
|
||||||
|
"""Open a resource file relative to :attr:`root_path` for reading.
|
||||||
|
|
||||||
For example, if the file ``schema.sql`` is next to the file
|
For example, if the file ``schema.sql`` is next to the file
|
||||||
``app.py`` where the ``Flask`` app is defined, it can be opened
|
``app.py`` where the ``Flask`` app is defined, it can be opened
|
||||||
|
|
@ -333,31 +334,46 @@ class Flask(App):
|
||||||
with app.open_resource("schema.sql") as f:
|
with app.open_resource("schema.sql") as f:
|
||||||
conn.executescript(f.read())
|
conn.executescript(f.read())
|
||||||
|
|
||||||
:param resource: Path to the resource relative to
|
:param resource: Path to the resource relative to :attr:`root_path`.
|
||||||
:attr:`root_path`.
|
:param mode: Open the file in this mode. Only reading is supported,
|
||||||
:param mode: Open the file in this mode. Only reading is
|
valid values are ``"r"`` (or ``"rt"``) and ``"rb"``.
|
||||||
supported, valid values are "r" (or "rt") and "rb".
|
:param encoding: Open the file with this encoding when opening in text
|
||||||
|
mode. This is ignored when opening in binary mode.
|
||||||
Note this is a duplicate of the same method in the Flask
|
|
||||||
class.
|
|
||||||
|
|
||||||
|
.. versionchanged:: 3.1
|
||||||
|
Added the ``encoding`` parameter.
|
||||||
"""
|
"""
|
||||||
if mode not in {"r", "rt", "rb"}:
|
if mode not in {"r", "rt", "rb"}:
|
||||||
raise ValueError("Resources can only be opened for reading.")
|
raise ValueError("Resources can only be opened for reading.")
|
||||||
|
|
||||||
return open(os.path.join(self.root_path, resource), mode)
|
path = os.path.join(self.root_path, resource)
|
||||||
|
|
||||||
def open_instance_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]:
|
if mode == "rb":
|
||||||
"""Opens a resource from the application's instance folder
|
return open(path, mode)
|
||||||
(:attr:`instance_path`). Otherwise works like
|
|
||||||
:meth:`open_resource`. Instance resources can also be opened for
|
|
||||||
writing.
|
|
||||||
|
|
||||||
:param resource: the name of the resource. To access resources within
|
return open(path, mode, encoding=encoding)
|
||||||
subfolders use forward slashes as separator.
|
|
||||||
:param mode: resource file opening mode, default is 'rb'.
|
def open_instance_resource(
|
||||||
|
self, resource: str, mode: str = "rb", encoding: str | None = "utf-8"
|
||||||
|
) -> t.IO[t.AnyStr]:
|
||||||
|
"""Open a resource file relative to the application's instance folder
|
||||||
|
:attr:`instance_path`. Unlike :meth:`open_resource`, files in the
|
||||||
|
instance folder can be opened for writing.
|
||||||
|
|
||||||
|
:param resource: Path to the resource relative to :attr:`instance_path`.
|
||||||
|
:param mode: Open the file in this mode.
|
||||||
|
:param encoding: Open the file with this encoding when opening in text
|
||||||
|
mode. This is ignored when opening in binary mode.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.1
|
||||||
|
Added the ``encoding`` parameter.
|
||||||
"""
|
"""
|
||||||
return open(os.path.join(self.instance_path, resource), mode)
|
path = os.path.join(self.instance_path, resource)
|
||||||
|
|
||||||
|
if "b" in mode:
|
||||||
|
return open(path, mode)
|
||||||
|
|
||||||
|
return open(path, mode, encoding=encoding)
|
||||||
|
|
||||||
def create_jinja_environment(self) -> Environment:
|
def create_jinja_environment(self) -> Environment:
|
||||||
"""Create the Jinja environment based on :attr:`jinja_options`
|
"""Create the Jinja environment based on :attr:`jinja_options`
|
||||||
|
|
|
||||||
|
|
@ -101,29 +101,28 @@ class Blueprint(SansioBlueprint):
|
||||||
t.cast(str, self.static_folder), filename, max_age=max_age
|
t.cast(str, self.static_folder), filename, max_age=max_age
|
||||||
)
|
)
|
||||||
|
|
||||||
def open_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]:
|
def open_resource(
|
||||||
"""Open a resource file relative to :attr:`root_path` for
|
self, resource: str, mode: str = "rb", encoding: str | None = "utf-8"
|
||||||
reading.
|
) -> t.IO[t.AnyStr]:
|
||||||
|
"""Open a resource file relative to :attr:`root_path` for reading. The
|
||||||
|
blueprint-relative equivalent of the app's :meth:`~.Flask.open_resource`
|
||||||
|
method.
|
||||||
|
|
||||||
For example, if the file ``schema.sql`` is next to the file
|
:param resource: Path to the resource relative to :attr:`root_path`.
|
||||||
``app.py`` where the ``Flask`` app is defined, it can be opened
|
:param mode: Open the file in this mode. Only reading is supported,
|
||||||
with:
|
valid values are ``"r"`` (or ``"rt"``) and ``"rb"``.
|
||||||
|
:param encoding: Open the file with this encoding when opening in text
|
||||||
.. code-block:: python
|
mode. This is ignored when opening in binary mode.
|
||||||
|
|
||||||
with app.open_resource("schema.sql") as f:
|
|
||||||
conn.executescript(f.read())
|
|
||||||
|
|
||||||
:param resource: Path to the resource relative to
|
|
||||||
:attr:`root_path`.
|
|
||||||
:param mode: Open the file in this mode. Only reading is
|
|
||||||
supported, valid values are "r" (or "rt") and "rb".
|
|
||||||
|
|
||||||
Note this is a duplicate of the same method in the Flask
|
|
||||||
class.
|
|
||||||
|
|
||||||
|
.. versionchanged:: 3.1
|
||||||
|
Added the ``encoding`` parameter.
|
||||||
"""
|
"""
|
||||||
if mode not in {"r", "rt", "rb"}:
|
if mode not in {"r", "rt", "rb"}:
|
||||||
raise ValueError("Resources can only be opened for reading.")
|
raise ValueError("Resources can only be opened for reading.")
|
||||||
|
|
||||||
return open(os.path.join(self.root_path, resource), mode)
|
path = os.path.join(self.root_path, resource)
|
||||||
|
|
||||||
|
if mode == "rb":
|
||||||
|
return open(path, mode)
|
||||||
|
|
||||||
|
return open(path, mode, encoding=encoding)
|
||||||
|
|
|
||||||
|
|
@ -334,16 +334,27 @@ class TestHelpers:
|
||||||
assert rv.data == b"Hello"
|
assert rv.data == b"Hello"
|
||||||
assert rv.mimetype == "text/html"
|
assert rv.mimetype == "text/html"
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ("r", "rb", "rt"))
|
|
||||||
def test_open_resource(self, mode):
|
|
||||||
app = flask.Flask(__name__)
|
|
||||||
|
|
||||||
with app.open_resource("static/index.html", mode) as f:
|
@pytest.mark.parametrize("mode", ("r", "rb", "rt"))
|
||||||
assert "<h1>Hello World!</h1>" in str(f.read())
|
def test_open_resource(mode):
|
||||||
|
app = flask.Flask(__name__)
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ("w", "x", "a", "r+"))
|
with app.open_resource("static/index.html", mode) as f:
|
||||||
def test_open_resource_exceptions(self, mode):
|
assert "<h1>Hello World!</h1>" in str(f.read())
|
||||||
app = flask.Flask(__name__)
|
|
||||||
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
app.open_resource("static/index.html", mode)
|
@pytest.mark.parametrize("mode", ("w", "x", "a", "r+"))
|
||||||
|
def test_open_resource_exceptions(mode):
|
||||||
|
app = flask.Flask(__name__)
|
||||||
|
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
app.open_resource("static/index.html", mode)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("encoding", ("utf-8", "utf-16-le"))
|
||||||
|
def test_open_resource_with_encoding(tmp_path, encoding):
|
||||||
|
app = flask.Flask(__name__, root_path=os.fspath(tmp_path))
|
||||||
|
(tmp_path / "test").write_text("test", encoding=encoding)
|
||||||
|
|
||||||
|
with app.open_resource("test", mode="rt", encoding=encoding) as f:
|
||||||
|
assert f.read() == "test"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue