Skip to content

Commit 5e94ece

Browse files
committed
Support passing pathlib.Path in some functionalities
1 parent 3d0ace4 commit 5e94ece

File tree

4 files changed

+34
-2
lines changed

4 files changed

+34
-2
lines changed

bottle.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"""
1515

1616
import sys
17+
from pathlib import Path
1718

1819
__author__ = 'Marcel Hellkamp'
1920
__version__ = '0.14-dev'
@@ -2306,10 +2307,16 @@ def load_config(self, filename, **options):
23062307
other sections.
23072308
23082309
:param filename: The path of a config file, or a list of paths.
2310+
Can be a string or a :class:`pathlib.Path` object.
23092311
:param options: All keyword parameters are passed to the underlying
23102312
:class:`python:configparser.ConfigParser` constructor call.
23112313
23122314
"""
2315+
if isinstance(filename, Path):
2316+
filename = str(filename)
2317+
elif isinstance(filename, (list, tuple)):
2318+
filename = [str(f) if isinstance(f, Path) else f for f in filename]
2319+
23132320
options.setdefault('allow_no_value', True)
23142321
options.setdefault('interpolation', configparser.ExtendedInterpolation())
23152322
conf = configparser.ConfigParser(**options)
@@ -2746,8 +2753,9 @@ def static_file(filename, root,
27462753
that can be sent back to the client.
27472754
27482755
:param filename: Name or path of the file to send, relative to ``root``.
2756+
Can be a string or a :class:`pathlib.Path` object.
27492757
:param root: Root path for file lookups. Should be an absolute directory
2750-
path.
2758+
path. Can be a string or a :class:`pathlib.Path` object.
27512759
:param mimetype: Provide the content-type header (default: guess from
27522760
file extension)
27532761
:param download: If True, ask the browser to open a `Save as...` dialog
@@ -2773,6 +2781,11 @@ def static_file(filename, root,
27732781
check or continue partial downloads) are also handled automatically.
27742782
"""
27752783

2784+
if isinstance(root, Path):
2785+
root = str(root)
2786+
if isinstance(filename, Path):
2787+
filename = str(filename)
2788+
27762789
root = os.path.join(os.path.abspath(root), '')
27772790
filename = os.path.abspath(os.path.join(root, filename.strip('/\\')))
27782791
headers = headers.copy() if headers else {}
@@ -3976,7 +3989,10 @@ def __init__(self,
39763989
self.name = name
39773990
self.source = source.read() if hasattr(source, 'read') else source
39783991
self.filename = source.filename if hasattr(source, 'filename') else None
3979-
self.lookup = [os.path.abspath(x) for x in lookup] if lookup else []
3992+
if lookup:
3993+
self.lookup = [os.path.abspath(str(x) if isinstance(x, Path) else x) for x in lookup]
3994+
else:
3995+
self.lookup = []
39803996
self.encoding = encoding
39813997
self.settings = self.settings.copy() # Copy from class variable
39823998
self.settings.update(settings) # Apply
@@ -3999,6 +4015,8 @@ def search(cls, name, lookup=None):
39994015
raise depr(0, 12, "Use of absolute path for template name.",
40004016
"Refer to templates with names or paths relative to the lookup path.")
40014017

4018+
lookup = [str(path) if isinstance(path, Path) else path for path in lookup]
4019+
40024020
for spath in lookup:
40034021
spath = os.path.abspath(spath) + os.sep
40044022
fname = os.path.abspath(os.path.join(spath, name))

test/test_config.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import tempfile
33
import unittest
4+
from pathlib import Path
45
from bottle import ConfigDict
56

67

@@ -198,3 +199,8 @@ def test_load_config(self):
198199
'namespace.section.default': 'otherDefault',
199200
'namespace.section.sub.namespace.key': 'test2',
200201
'port': '8080'}, c)
202+
203+
# Test with pathlib.Path object
204+
c2 = ConfigDict()
205+
c2.load_config(Path(self.config_file.name))
206+
self.assertDictEqual(c, c2)

test/test_sendfile.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import sys
22
import unittest
3+
from pathlib import Path
34
from bottle import static_file, request, response, parse_date, parse_range_header, Bottle, tob
45
import bottle
56
import wsgiref.util
@@ -57,6 +58,9 @@ def test_valid(self):
5758
out = static_file(basename, root=root)
5859
self.assertEqual(open(__file__,'rb').read(), out.body.read())
5960

61+
out_path = static_file(Path(basename), root=Path(root))
62+
self.assertEqual(open(__file__,'rb').read(), out_path.body.read())
63+
6064
def test_invalid(self):
6165
""" SendFile: Invalid requests"""
6266
self.assertEqual(404, static_file('not/a/file', root=root).status_code)

test/test_stpl.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from bottle import SimpleTemplate, TemplateError, view, template, touni, tob, html_quote
55
import re, os
66
import traceback
7+
from pathlib import Path
78
from .tools import chdir
89

910

@@ -24,6 +25,9 @@ def test_file(self):
2425
with chdir(__file__):
2526
t = SimpleTemplate(name='./views/stpl_simple.tpl', lookup=['.'])
2627
self.assertRenders(t, 'start var end\n', var='var')
28+
with chdir(__file__):
29+
t = SimpleTemplate(name='./views/stpl_simple.tpl', lookup=[Path('.')])
30+
self.assertRenders(t, 'start var end\n', var='var')
2731

2832
def test_name(self):
2933
with chdir(__file__):

0 commit comments

Comments
 (0)