# HG changeset patch
# User David Barts #rem
header, all
header lines may appear only once in a given file.
#end
#errors
#forward
#methods
#methods GET
.#methods GET
.#python
e
error
bottle.HTTPError
object associated with this error.request
bottle.Request
object associated with this error.The #errors
directive takes a list of numeric error codes
- (values from 400 to 599 are allowed); the page is created to handle the
- specified errors. If no error codes are specified, the page will handle all
- errors. The behavior of specifying multiple error pages for the same error code
- is undefined; doing so is best avoided.
The body begins with the first line that does not start with #
and has the exact same syntax that the templates are in for this webapp.
diff -r 0d47859f792a -r 31bb8400e6e3 tincan.py
--- a/tincan.py Mon May 13 12:38:26 2019 -0700
+++ b/tincan.py Mon May 13 14:47:04 2019 -0700
@@ -14,6 +14,7 @@
import io
import py_compile
from stat import S_ISDIR, S_ISREG
+from string import whitespace
import bottle
@@ -69,6 +70,10 @@
line numbering when processing the body. The added newlines are normally
stripped out before the rendered page is sent back to the client.
"""
+ _END = "#end"
+ _LEND = len(_END)
+ _WS = set(whitespace)
+
def __init__(self, raw, encoding='utf-8'):
if isinstance(raw, io.TextIOBase):
self._do_init(raw)
@@ -95,6 +100,8 @@
self._state = self._body
self._state(line)
return
+ if line.startswith(self._END) and (len(line) == self._LEND or line[self._LEND] in self._WS):
+ self._state = self._body
self._hbuf.append(line)
self._bbuf.append("\n")
@@ -129,21 +136,26 @@
try:
rna, rpa = line.split(maxsplit=1)
except ValueError:
- raise TemplateHeaderException("Missing parameter.", count)
+ rna = line.rstrip()
+ rpa = None
# Get name, ignoring remarks.
name = rna[1:]
if name == "rem":
continue
+ if name == "end":
+ break
if name not in nameset:
raise TemplateHeaderException("Invalid directive: {0!r}".format(rna), count)
if name in seen:
raise TemplateHeaderException("Duplicate {0!r} directive.".format(rna), count)
seen.add(name)
# Flags
- if name in self._FLAGS:
+ if name in self._FNAMES:
setattr(self, name, True)
continue
# Get parameter
+ if rpa is None:
+ raise TemplateHeaderException("Missing parameter.", count)
param = rpa.strip()
for i in [ "'", '"']:
if param.startswith(i) and param.endswith(i):
@@ -294,7 +306,7 @@
self._template.prepare()
def __call__(self, e):
- return self._template.render(e=e, request=bottle.request).lstrip('\n')
+ return self._template.render(error=e, request=bottle.request).lstrip('\n')
class _TinCanRoute(object):
"""
@@ -384,7 +396,7 @@
for error in errors:
if error < _ERRMIN or error > _ERRMAX:
raise TinCanError("{0}: bad #errors code".format(self._urlpath))
- self._app.error(code=error, callback=route)
+ self._app.error_handler[error] = route # XXX
def _getclass(self):
pypath = os.path.normpath(os.path.join(self._fsroot, *self._splitpath(self._python)))