[Zope-Checkins] CVS: Zope3/lib/python/Zope/PageTemplate - EngineConfig.py:1.1.2.1

Shane Hathaway shane@cvs.zope.org
Wed, 13 Mar 2002 22:37:07 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/PageTemplate
In directory cvs.zope.org:/tmp/cvs-serv2925

Added Files:
      Tag: Zope-3x-branch
	EngineConfig.py 
Log Message:
Added a new expression engine configuration module.  It allows you to
assign names to expression engines and choose which one to use per page
template or expression.  This helps solve some problems:

- There was a strong dependency from Zope.PageTemplates to Zope.App.Security
  and Zope.App.Traversing.  Now we can just plug in a restricted expression
  engine.

- Some of the tests want to run with a restricted expression engine, but some
  don't.  Now each test can choose which one to use.

I've also made a metaConfigure module, but I can't check it in until there
are tests for it. :-)


=== Added File Zope3/lib/python/Zope/PageTemplate/EngineConfig.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 1.1 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS 
# FOR A PARTICULAR PURPOSE.
##############################################################################
"""Expression engine configuration and registration.

Each expression engine can have its own expression types and base names.

$Id: EngineConfig.py,v 1.1.2.1 2002/03/14 03:37:06 shane Exp $
"""

from TALES import ExpressionEngine, RegistrationError
from Expressions import PathExpr, StringExpr, NotExpr, DeferExpr
from Expressions import SimpleModuleImporter
from PythonExpr import PythonExpr


_engines = {}          # { name -> expression engine }
_explicit_default = 0  # Set once an explicit default has been defined.


def getEngine(name='default'):
    try:
        return _engines[name]
    except KeyError:
        if not _engines:
            # Create the default engine.
            _initialize()
            return _engines[name]
        else:
            raise


def registerEngine(name, engine):
    global _engines
    if not _engines:
        _initialize()
    if name == 'default':
        # Inform the user that the right approach is to create an
        # engine by a different name then set it as the default.
        raise RegistrationError, 'The name "default" is reserved.'
    if _engines.has_key(name):
        raise RegistrationError, 'An engine named "%s" already exists' % name
    _engines[name] = engine


def setDefaultEngine(name):
    """Selects an explicit default engine."""
    global _engines, _explicit_default
    if not _engines:
        _initialize()
    if _explicit_default:
        raise RegistrationError, (
            'A default engine has already been selected')
    _engines['default'] = _engines[name]
    _explicit_default = 1


def createUnrestrictedEngine():
    e = ExpressionEngine()
    reg = e.registerType
    for pt in PathExpr._default_type_names:
        reg(pt, PathExpr)
    reg('string', StringExpr)
    reg('python', PythonExpr)
    reg('not', NotExpr)
    reg('defer', DeferExpr)
    e.registerBaseName('modules', SimpleModuleImporter())
    return e


def _initialize():
    global _engines, _explicit_default
    _engines.clear()
    _explicit_default = 0
    _engines['unrestricted'] = createUnrestrictedEngine()
    _engines['default'] = _engines['unrestricted']
    try:
        from Zope.RestrictedPython.RestrictedExpressionEngine import \
             createRestrictedEngine
    except ImportError:
        # Use the unrestricted engine as the implicit default.
        pass
    else:
        _engines['restricted'] = createRestrictedEngine()
        # Use the secure engine as the implicit default.
        _engines['default'] = _engines['restricted']


try:
    from Zope.Testing.CleanUp import addCleanUp
except ImportError:
    pass
else:
    # Add to the list of stuff that needs to be cleared after a test
    def _cleanup():
        global _engines, _explicit_default
        _engines.clear()
        _explicit_default = 0

    addCleanUp(_cleanup)