Add support for PathLike objects in static file helpers

See: https://www.python.org/dev/peps/pep-0519/

This is mostly encountered with pathlib in python 3, but this API
suggests any PathLike object can be treated like a filepath with
`__fspath__` function.
This commit is contained in:
Matt Robenolt 2019-01-03 17:17:45 -08:00 committed by David Lord
parent f7d50d4b67
commit 25de45cbb6
No known key found for this signature in database
GPG key ID: 7A1C87E3F5BC42A8
4 changed files with 62 additions and 5 deletions

View file

@ -36,6 +36,19 @@ def has_encoding(name):
return False
class FakePath(object):
"""Fake object to represent a ``PathLike object``.
This represents a ``pathlib.Path`` object in python 3.
See: https://www.python.org/dev/peps/pep-0519/
"""
def __init__(self, path):
self.path = path
def __fspath__(self):
return self.path
class FixedOffset(datetime.tzinfo):
"""Fixed offset in hours east from UTC.
@ -527,6 +540,15 @@ class TestSendfile(object):
assert 'x-sendfile' not in rv.headers
rv.close()
def test_send_file_pathlike(self, app, req_ctx):
rv = flask.send_file(FakePath('static/index.html'))
assert rv.direct_passthrough
assert rv.mimetype == 'text/html'
with app.open_resource('static/index.html') as f:
rv.direct_passthrough = False
assert rv.data == f.read()
rv.close()
@pytest.mark.skipif(
not callable(getattr(Range, 'to_content_range_header', None)),
reason="not implemented within werkzeug"
@ -681,6 +703,12 @@ class TestSendfile(object):
assert cc.max_age == 3600
rv.close()
# Test with static file handler.
rv = app.send_static_file(FakePath('index.html'))
cc = parse_cache_control_header(rv.headers['Cache-Control'])
assert cc.max_age == 3600
rv.close()
class StaticFileApp(flask.Flask):
def get_send_file_max_age(self, filename):
return 10
@ -706,6 +734,14 @@ class TestSendfile(object):
assert rv.data.strip() == b'Hello Subdomain'
rv.close()
def test_send_from_directory_pathlike(self, app, req_ctx):
app.root_path = os.path.join(os.path.dirname(__file__),
'test_apps', 'subdomaintestmodule')
rv = flask.send_from_directory(FakePath('static'), FakePath('hello.txt'))
rv.direct_passthrough = False
assert rv.data.strip() == b'Hello Subdomain'
rv.close()
def test_send_from_directory_bad_request(self, app, req_ctx):
app.root_path = os.path.join(os.path.dirname(__file__),
'test_apps', 'subdomaintestmodule')