diff tincan.py @ 3:c6902cded64d draft

Corrections and reorg.
author David Barts <n5jrn@me.com>
date Mon, 13 May 2019 06:53:08 -0700
parents ca6f8ca38cf2
children 0d47859f792a
line wrap: on
line diff
--- a/tincan.py	Sun May 12 22:51:34 2019 -0700
+++ b/tincan.py	Mon May 13 06:53:08 2019 -0700
@@ -321,7 +321,11 @@
             self._template = TemplateFile(self._fspath)
             self._header = TemplateHeader(self._template.header)
             if hidden is None:
+                if self._header.errors is not None:
+                    break
                 hidden = self._header.hidden
+            elif self._header.errors is not None:
+                raise TinCanError("{0}: #forward to #errors not allowed".format(self._origin))
             if self._header.forward is None:
                 break
             self._redirect()
@@ -331,32 +335,53 @@
             return
         # If this is an error page, register it as such.
         if self._header.errors is not None:
-            if self._header.template is not None:
-                tpath = os.path.join(self._fsroot, *self._splitpath(self._header.template))
-                self._template = 
-            try:
-                errors = [ int(i) for i in self._header.errors.split() ]
-            except ValueError as e:
-                raise TinCanError("{0}: bad #errors line".format(self._urlpath)) from e
-            if not errors:
-                errors = range(_ERRMIN, _ERRMAX+1)
-            route = TinCanErrorRoute(self._tclass(source=self._template.body))
-            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._mkerror()
             return  # this implies #hidden
         # Get methods for this route
         if self._header.methods is None:
             methods = [ 'GET' ]
         else:
             methods = [ i.upper() for i in self._header.methods.split() ]
+            if not methods:
+                raise TinCanError("{0}: no #methods specified".format(self._urlpath))
         # Process other header entries
         if self._header.python is not None:
             if not self._header.python.endswith(_PEXTEN):
                 raise TinCanError("{0}: #python files must end in {1}", self._urlpath, _PEXTEN)
             self._python = self._header.python
         # Obtain a class object by importing and introspecting a module.
+        self._getclass()
+        # Build body object (Chameleon template)
+        if self._header.template is not None:
+            if not self._header.template.endswith(_TEXTEN):
+                raise TinCanError("{0}: #template files must end in {1}", self._urlpath, _TEXTEN)
+            tpath = os.path.join(self._fsroot, *self._splitpath(self._header.template))
+            tfile = TemplateFile(tpath)
+            self._body = self._tclass(source=tfile.body)
+        else:
+            self._body = self._tclass(source=self._template.body)
+        self._body.prepare()
+        # Register this thing with Bottle
+        print("adding route:", self._origin)  # debug
+        self._app.route(self._origin, methods, self)
+
+    def _splitpath(self, unsplit):
+        return _normpath(self._subdir, unsplit)
+
+    def _mkerror(self):
+        try:
+            errors = [ int(i) for i in self._header.errors.split() ]
+        except ValueError as e:
+            raise TinCanError("{0}: bad #errors line".format(self._urlpath)) from e
+        if not errors:
+            errors = range(_ERRMIN, _ERRMAX+1)
+        route = TinCanErrorRoute(self._tclass(source=self._template.body))
+        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)
+
+    def _getclass(self):
         pypath = os.path.normpath(os.path.join(self._fsroot, *self._subdir, self._python))
         pycpath = pypath + 'c'
         try:
@@ -381,20 +406,8 @@
                 if self._class is not None:
                     raise TinCanError("{0}: contains multiple Page classes", pypath)
                 self._class = v
-        # Build body object (Chameleon template)
-        if self._header.template is not None:
-            tpath = os.path.join(self._fsroot, *self._splitpath(self._header.template))
-            tfile = TemplateFile(tpath)
-            self._body = self._tclass(source=tfile.body)
-        else:
-            self._body = self._tclass(source=self._template.body)
-        self._body.prepare()
-        # Register this thing with Bottle
-        print("adding route:", self._origin)  # debug
-        self._app.route(self._origin, methods, self)
-
-    def _splitpath(self, unsplit):
-        return _normpath(self._subdir, unsplit)
+        if self._class is None:
+            raise TinCanError("{0}: contains no Page classes", pypath)
 
     def _redirect(self):
         if self._header.forward in self._seen: