[Checkins] SVN: hurry.custom/trunk/src/hurry/custom/ Improve API for looking up collections. Use this API internally and
Martijn Faassen
faassen at startifact.com
Wed Jun 10 09:23:11 EDT 2009
Log message for revision 100795:
Improve API for looking up collections. Use this API internally and
expose it.
Changed:
U hurry.custom/trunk/src/hurry/custom/README.txt
U hurry.custom/trunk/src/hurry/custom/__init__.py
U hurry.custom/trunk/src/hurry/custom/core.py
U hurry.custom/trunk/src/hurry/custom/interfaces.py
-=-
Modified: hurry.custom/trunk/src/hurry/custom/README.txt
===================================================================
--- hurry.custom/trunk/src/hurry/custom/README.txt 2009-06-10 12:40:40 UTC (rev 100794)
+++ hurry.custom/trunk/src/hurry/custom/README.txt 2009-06-10 13:23:11 UTC (rev 100795)
@@ -219,14 +219,20 @@
So far all our work was done in the root (filesystem) database. We can
get it now::
- >>> from zope import component
- >>> from hurry.custom.interfaces import ITemplateDatabase
- >>> root_db = component.getUtility(ITemplateDatabase, name='templates')
+ >>> root_db = custom.root_collection('templates')
+Before any customization database was registered we could also have
+gotten it using ``custom.collection``, which gets the collection in
+context::
+
+ >>> custom.collection('templates') is root_db
+ True
+
Let's now register a customization database for our collection, in a
particular site. This means in such a site, the new customized
template database will be used (with a fallback on the original one if
-no customization can be found).
+no customization can be found or if there is an error in the use of a
+customization).
Let's create a site first::
@@ -237,6 +243,7 @@
database::
>>> mem_db = custom.InMemoryTemplateDatabase('templates', 'Templates')
+ >>> from hurry.custom.interfaces import ITemplateDatabase
>>> sm1 = site1.getSiteManager()
>>> sm1.registerUtility(mem_db, provided=ITemplateDatabase,
... name='templates')
@@ -245,6 +252,23 @@
>>> setSite(site1)
+We can now find this collection using ``custom.collection``::
+
+ >>> custom.collection('templates') is mem_db
+ True
+
+The collection below it is the root collection::
+
+ >>> custom.next_collection('templates', mem_db) is root_db
+ True
+
+Below this, there is no collection and we'll get a lookup error::
+
+ >>> custom.next_collection('templates', root_db)
+ Traceback (most recent call last):
+ ...
+ ComponentLookupError: No collection available for: templates
+
We haven't placed any customization in the customization database
yet, so we'll see the same thing as before when we look up the
template::
@@ -523,3 +547,58 @@
Traceback (most recent call last):
...
ComponentLookupError: (<InterfaceClass hurry.custom.interfaces.ITemplate>, '.unrecognized')
+
+If we try to look up a template in the root collection with a
+CompileError in it, we'll get a CompileError::
+
+ >>> compile_error = os.path.join(templates_path, 'compileerror.st')
+ >>> f = open(compile_error, 'w')
+ >>> f.write('A & compile error')
+ >>> f.close()
+ >>> compile_error_template = custom.lookup('templates', 'compileerror.st')
+ Traceback (most recent call last):
+ ...
+ CompileError: & in template!
+
+The same applies to trying to render it::
+
+ >>> custom.render('templates', 'compileerror.st', {})
+ Traceback (most recent call last):
+ ...
+ CompileError: & in template!
+
+If we try to render a template in the root collection we get a RenderError::
+
+ >>> render_error = os.path.join(templates_path, 'rendererror.st')
+ >>> f = open(render_error, 'w')
+ >>> f.write('A $thang')
+ >>> f.close()
+ >>> custom.render('templates', 'rendererror.st', {'thing': 'thing'})
+ Traceback (most recent call last):
+ ...
+ RenderError: u'thang'
+
+
+We'll get a ComponentLookupError if we look for a collection with an
+unknown id::
+
+ >>> custom.collection('unknown_id')
+ Traceback (most recent call last):
+ ...
+ ComponentLookupError: (<InterfaceClass hurry.custom.interfaces.ITemplateDatabase>, 'unknown_id')
+
+We also can't look for a next collection if the id we specify is
+unknown::
+
+ >>> custom.next_collection('unknown_id', mem_db)
+ Traceback (most recent call last):
+ ...
+ ComponentLookupError: No more utilities for <InterfaceClass hurry.custom.interfaces.ITemplateDatabase>, 'unknown_id' have been found.
+
+Similarly we can't get a root collection if the id is unknown::
+
+ >>> custom.root_collection('unknown_id')
+ Traceback (most recent call last):
+ ...
+ ComponentLookupError: (<InterfaceClass hurry.custom.interfaces.ITemplateDatabase>, 'unknown_id')
+
Modified: hurry.custom/trunk/src/hurry/custom/__init__.py
===================================================================
--- hurry.custom/trunk/src/hurry/custom/__init__.py 2009-06-10 12:40:40 UTC (rev 100794)
+++ hurry.custom/trunk/src/hurry/custom/__init__.py 2009-06-10 13:23:11 UTC (rev 100795)
@@ -4,6 +4,9 @@
lookup,
check,
structure,
+ collection,
+ root_collection,
+ next_collection,
register_language,
register_data_language,
register_collection,
Modified: hurry.custom/trunk/src/hurry/custom/core.py
===================================================================
--- hurry.custom/trunk/src/hurry/custom/core.py 2009-06-10 12:40:40 UTC (rev 100794)
+++ hurry.custom/trunk/src/hurry/custom/core.py 2009-06-10 13:23:11 UTC (rev 100795)
@@ -2,6 +2,7 @@
from datetime import datetime
from zope.interface import implements
from zope import component
+from zope.component.interfaces import ComponentLookupError
from hurry.custom.interfaces import (
ITemplate, IManagedTemplate, ITemplateDatabase, IDataLanguage,
ISampleExtension, CompileError, RenderError, NotSupported)
@@ -36,32 +37,58 @@
while True:
try:
return template(input)
- except RenderError:
- template = lookup(
- id, template_path,
- db=getNextUtility(template.db, ITemplateDatabase, name=id))
+ except RenderError, render_error:
+ try:
+ next_db = next_collection(id, template.db)
+ except ComponentLookupError:
+ # cannot find any next collection, so this error is it
+ raise render_error
+ template = lookup(id, template_path, db=next_db)
def lookup(id, template_path, db=None):
dummy, ext = os.path.splitext(template_path)
template_class = component.getUtility(ITemplate, name=ext)
- db = db or component.getUtility(ITemplateDatabase, name=id)
-
+ db = db or collection(id)
+
while True:
source = db.get_source(template_path)
if source is not None:
try:
return ManagedTemplate(template_class, db, template_path)
- except CompileError:
+ except CompileError, e:
pass
- db = getNextUtility(db, ITemplateDatabase, name=id)
+ try:
+ db = next_collection(id, db)
+ except ComponentLookupError:
+ # if we cannot find a next collection, this means the
+ # last collection had a fatal compilation error
+ raise e
+def collection(id):
+ return component.getUtility(ITemplateDatabase, name=id)
+
+def next_collection(id, db):
+ result = getNextUtility(db, ITemplateDatabase, name=id)
+ if result is db:
+ raise ComponentLookupError("No collection available for: %s" % id)
+ return result
+
+def root_collection(id):
+ db = collection(id)
+ while True:
+ try:
+ next_db = next_collection(id, db)
+ except ComponentLookupError:
+ return db
+ db = next_db
+
def check(id, template_path, source):
dummy, ext = os.path.splitext(template_path)
template_class = component.getUtility(ITemplate, name=ext)
# can raise CompileError
template = template_class(source)
- db = _get_root_database(id)
+ db = root_collection(id)
samples = db.get_samples(template_path)
for key, value in samples.items():
try:
@@ -74,7 +101,7 @@
def structure(id):
extensions = set([extension for
(extension, language) in recognized_languages()])
- db = _get_root_database(id)
+ db = root_collection(id)
return _get_structure_helper(db.path, db.path, extensions)
class ManagedTemplate(object):
@@ -212,13 +239,6 @@
result.append(info)
return result
-def _get_root_database(id):
- # assume root database is always a FilesystemTemplateDatabase
- db = component.getUtility(ITemplateDatabase, name=id)
- while not isinstance(db, FilesystemTemplateDatabase):
- db = getNextUtility(db, ITemplateDatabase, name=id)
- return db
-
# XXX copied from zope.app.component to avoid dependency on it
# note that newer versions of zope.component have this, so
# when the target app depends on that we can switch and
@@ -250,9 +270,9 @@
"""
util = queryNextUtility(context, interface, name, _marker)
if util is _marker:
- raise zope.component.interfaces.ComponentLookupError(
- "No more utilities for %s, '%s' have been found." % (
- interface, name))
+ raise ComponentLookupError(
+ "No more utilities for %s, '%s' have been found." % (
+ interface, name))
return util
# XXX this code comes from Python 2.6 - when switching to this
Modified: hurry.custom/trunk/src/hurry/custom/interfaces.py
===================================================================
--- hurry.custom/trunk/src/hurry/custom/interfaces.py 2009-06-10 12:40:40 UTC (rev 100794)
+++ hurry.custom/trunk/src/hurry/custom/interfaces.py 2009-06-10 13:23:11 UTC (rev 100795)
@@ -47,11 +47,39 @@
def lookup(id, template_path):
"""Look up template.
- id - the id for the collection
+ id - the id of the collection
template_path - the relative path (or filename) of the template
itself, under the path of the collection
"""
+ def collection(id):
+ """Look up ITemplateDatabase for id.
+
+ id - the id of the collection
+
+ Will raise ComponentLookupError if no collection with this id exists.
+ """
+
+ def next_collection(id, db):
+ """Look up the collection below this one.
+
+ id - the id of the collection
+ db - the db below which to look.
+
+ Will raise ComponentLookupError if there is no db below this
+ collection.
+
+ Will also raise ComponentLookupError if no collection with this id exists.
+ """
+
+ def root_collection(id):
+ """Look up the root collection.
+
+ id - the id of the collection.
+
+ Will raise ComponentLookupError if no collection with this id exists.
+ """
+
def check(id, template_path, source):
"""Test a template (before customization).
More information about the Checkins
mailing list