summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-11-19 10:44:55 +0000
committerChris McDonough <chrism@agendaless.com>2009-11-19 10:44:55 +0000
commiteac7c470021b647d63c2e2af8acd6cebd738f2a4 (patch)
tree6d04102c9442c0dd67a26d002ff89ae51b454993
parent4dd55a50a7ed559748661f369313030773d13e75 (diff)
downloadpyramid-eac7c470021b647d63c2e2af8acd6cebd738f2a4.tar.gz
pyramid-eac7c470021b647d63c2e2af8acd6cebd738f2a4.tar.bz2
pyramid-eac7c470021b647d63c2e2af8acd6cebd738f2a4.zip
Rearrange things to try to avoid circular import deps.
-rw-r--r--repoze/bfg/configuration.py71
-rw-r--r--repoze/bfg/router.py43
-rw-r--r--repoze/bfg/testing.py5
-rw-r--r--repoze/bfg/tests/test_configuration.py63
-rw-r--r--repoze/bfg/tests/test_router.py70
-rw-r--r--repoze/bfg/tests/test_traversal.py24
-rw-r--r--repoze/bfg/traversal.py9
-rw-r--r--repoze/bfg/zcml.py17
8 files changed, 135 insertions, 167 deletions
diff --git a/repoze/bfg/configuration.py b/repoze/bfg/configuration.py
index 74c848946..447cb5963 100644
--- a/repoze/bfg/configuration.py
+++ b/repoze/bfg/configuration.py
@@ -5,10 +5,10 @@ import threading
import inspect
import zope.component
+from zope.component.event import dispatch
-from zope.configuration import xmlconfig
from zope.configuration.exceptions import ConfigurationError
-from zope.configuration.config import ConfigurationMachine
+from zope.configuration import xmlconfig
from zope.component import getGlobalSiteManager
from zope.component import getSiteManager
@@ -39,6 +39,7 @@ from repoze.bfg import chameleon_zpt
from repoze.bfg import chameleon_text
from repoze.bfg import renderers
from repoze.bfg.compat import all
+from repoze.bfg.events import WSGIApplicationCreatedEvent
from repoze.bfg.exceptions import Forbidden
from repoze.bfg.exceptions import NotFound
from repoze.bfg.log import make_stream_logger
@@ -51,6 +52,7 @@ from repoze.bfg.static import StaticRootFactory
from repoze.bfg.threadlocal import get_current_registry
from repoze.bfg.threadlocal import manager
from repoze.bfg.traversal import find_interface
+from repoze.bfg.traversal import DefaultRootFactory
from repoze.bfg.urldispatch import RoutesMapper
from repoze.bfg.view import MultiView
from repoze.bfg.view import decorate_view
@@ -61,26 +63,13 @@ from repoze.bfg.view import static as static_view
import martian
-def zcml_configure(name, package):
- """ Given a ZCML filename as ``name`` and a Python package as
- ``package`` which the filename should be relative to, load the
- ZCML into the current ZCML registry.
-
- .. note:: This feature is new as of :mod:`repoze.bfg` 1.1.
- """
- context = ConfigurationMachine()
- xmlconfig.registerCommonDirectives(context)
- context.package = package
- xmlconfig.include(context, name, package)
- context.execute_actions(clear=False)
- return context.actions
-
class Configurator(object):
""" A wrapper around the registry that performs configuration tasks """
def __init__(self, registry=None):
if registry is None:
- registry = self.make_default_registry()
- self.reg = registry
+ self.make_default_registry()
+ else:
+ self.reg = registry
def make_default_registry(self):
self.reg = Registry()
@@ -94,14 +83,31 @@ class Configurator(object):
self.debug_logger(None)
return self.reg
- def default_configuration(self, root_factory, package=None,
- filename='configure.zcml', settings=None,
- debug_logger=None, manager=manager, os=os,
- lock=threading.Lock()):
+ def make_wsgi_app(self, manager=manager, getSiteManager=getSiteManager):
+ from repoze.bfg.router import Router # avoid circdep
+ app = Router(self.reg)
+ # executing sethook means we're taking over getSiteManager for
+ # the lifetime of this process
+ getSiteManager.sethook(get_current_registry)
+ # We push the registry on to the stack here in case any ZCA API is
+ # used in listeners subscribed to the WSGIApplicationCreatedEvent
+ # we send.
+ manager.push({'registry':self.reg, 'request':None})
+ try:
+ # use dispatch here instead of registry.notify to make unit
+ # tests possible
+ dispatch(WSGIApplicationCreatedEvent(app))
+ finally:
+ manager.pop()
+ return app
+
+ def declarative(self, root_factory, package=None,
+ filename='configure.zcml', settings=None,
+ debug_logger=None, os=os, lock=threading.Lock()):
self.make_default_registry()
- # registry, debug_logger, manager, os and lock *only* for unittests
+ # debug_logger, os and lock *only* for unittests
if settings is None:
settings = {}
@@ -120,7 +126,9 @@ class Configurator(object):
self.settings(settings)
self.debug_logger(debug_logger)
self.root_factory(root_factory or DefaultRootFactory)
+ self.load_zcml(filename, package, lock=lock)
+ def load_zcml(self, filename, package=None, lock=threading.Lock()):
# We push our ZCML-defined configuration into an app-local
# component registry in order to allow more than one bfg app to live
# in the same process space without one unnecessarily stomping on
@@ -134,13 +142,12 @@ class Configurator(object):
# site manager API directly in a different thread while we hold the
# lock. Those registrations will end up in our application's
# registry.
-
lock.acquire()
manager.push({'registry':self.reg, 'request':None})
try:
getSiteManager.sethook(get_current_registry)
zope.component.getGlobalSiteManager = get_current_registry
- zcml_configure(filename, package)
+ xmlconfig.file(filename, package, execute=True)
finally:
zope.component.getGlobalSiteManager = getGlobalSiteManager
lock.release()
@@ -567,8 +574,8 @@ class Configurator(object):
def view(context, request):
return {}
else:
- raise ConfigurationError('"view" attribute was not specified and '
- 'no renderer specified')
+ raise ConfigurationError('"view" attribute was not specified '
+ 'and no renderer specified')
derived_view = self.derive_view(view, attr=attr, renderer_name=renderer,
wrapper_viewname=wrapper)
@@ -709,13 +716,3 @@ class BFGViewGrokker(martian.InstanceGrokker):
config.view(view=obj, _info=info, **settings)
return bool(config)
-class DefaultRootFactory:
- __parent__ = None
- __name__ = None
- def __init__(self, request):
- matchdict = getattr(request, 'matchdict', {})
- # provide backwards compatibility for applications which
- # used routes (at least apps without any custom "context
- # factory") in BFG 0.9.X and before
- self.__dict__.update(matchdict)
-
diff --git a/repoze/bfg/router.py b/repoze/bfg/router.py
index b317c9b35..7edf40620 100644
--- a/repoze/bfg/router.py
+++ b/repoze/bfg/router.py
@@ -1,11 +1,7 @@
-from zope.component.event import dispatch
-
from zope.interface import implements
from zope.interface import providedBy
from zope.interface import alsoProvides
-from zope.component import getSiteManager
-
from repoze.bfg.interfaces import IForbiddenView
from repoze.bfg.interfaces import ILogger
from repoze.bfg.interfaces import INotFoundView
@@ -17,24 +13,18 @@ from repoze.bfg.interfaces import ISettings
from repoze.bfg.interfaces import ITraverser
from repoze.bfg.interfaces import IView
-from repoze.bfg.configuration import DefaultRootFactory
-from repoze.bfg.configuration import Configurator
from repoze.bfg.events import AfterTraversal
from repoze.bfg.events import NewRequest
from repoze.bfg.events import NewResponse
-from repoze.bfg.events import WSGIApplicationCreatedEvent
from repoze.bfg.exceptions import Forbidden
from repoze.bfg.exceptions import NotFound
-from repoze.bfg.registry import Registry
from repoze.bfg.request import Request
from repoze.bfg.threadlocal import manager
-from repoze.bfg.threadlocal import get_current_registry
+from repoze.bfg.traversal import DefaultRootFactory
from repoze.bfg.traversal import ModelGraphTraverser
from repoze.bfg.view import default_forbidden_view
from repoze.bfg.view import default_notfound_view
-_marker = object()
-
class Router(object):
""" The main repoze.bfg WSGI application. """
implements(IRouter)
@@ -43,9 +33,6 @@ class Router(object):
threadlocal_manager = manager
def __init__(self, registry):
- # executing sethook means we're taking over getSiteManager for
- # the lifetime of this process
- getSiteManager.sethook(get_current_registry)
q = registry.queryUtility
self.logger = q(ILogger, 'repoze.bfg.debug')
self.notfound_view = q(INotFoundView, default=default_notfound_view)
@@ -162,10 +149,10 @@ class Router(object):
finally:
manager.pop()
-# note that ``options`` is a b/w compat alias for ``settings``
+# note that ``options`` is a b/w compat alias for ``settings`` and
+# ``Configurator`` is a testing dep inj
def make_app(root_factory, package=None, filename='configure.zcml',
- settings=None, options=None, Configurator=Configurator,
- Router=Router, Registry=Registry, manager=manager):
+ settings=None, options=None, Configurator=None):
""" Return a Router object, representing a fully configured
``repoze.bfg`` WSGI application.
@@ -202,20 +189,12 @@ def make_app(root_factory, package=None, filename='configure.zcml',
parameter ``options`` is a backwards compatibility alias for the
``settings`` keyword parameter.
"""
+ if Configurator is None:
+ from repoze.bfg.configuration import Configurator
settings = settings or options
- registry = Registry('make_app')
- config = Configurator(registry)
- config.default_configuration(root_factory, package=package,
- filename=filename, settings=settings)
- app = Router(registry)
- # We push the registry on to the stack here in case any ZCA API is
- # used in listeners subscribed to the WSGIApplicationCreatedEvent
- # we send.
- manager.push({'registry':registry, 'request':None})
- try:
- # use dispatch here instead of registry.notify to make unit
- # tests possible
- dispatch(WSGIApplicationCreatedEvent(app))
- finally:
- manager.pop()
+ config = Configurator()
+ config.declarative(root_factory, package=package,
+ filename=filename, settings=settings)
+ app = config.make_wsgi_app()
return app
+
diff --git a/repoze/bfg/testing.py b/repoze/bfg/testing.py
index af659aca6..128e5cf32 100644
--- a/repoze/bfg/testing.py
+++ b/repoze/bfg/testing.py
@@ -1,6 +1,7 @@
import copy
from zope.configuration.xmlconfig import _clearContext
+
from zope.component import getSiteManager
from zope.deprecation import deprecated
from zope.interface import implements
@@ -8,10 +9,9 @@ from zope.interface import Interface
from repoze.bfg.interfaces import IRequest
-from repoze.bfg.configuration import zcml_configure # API import alias
-from repoze.bfg.registry import Registry
from repoze.bfg.threadlocal import manager
from repoze.bfg.threadlocal import get_current_registry
+from repoze.bfg.zcml import zcml_configure # API
_marker = object()
@@ -535,6 +535,7 @@ def setUp():
.. note:: This feature is new as of :mod:`repoze.bfg` 1.1.
"""
+ from repoze.bfg.registry import Registry
registry = Registry('testing')
manager.clear()
manager.push({'registry':registry, 'request':None})
diff --git a/repoze/bfg/tests/test_configuration.py b/repoze/bfg/tests/test_configuration.py
index 1916fe11d..a1f60a91f 100644
--- a/repoze/bfg/tests/test_configuration.py
+++ b/repoze/bfg/tests/test_configuration.py
@@ -38,7 +38,7 @@ class ConfiguratorTests(unittest.TestCase):
def _callDefaultConfiguration(self, *arg, **kw):
inst = self._makeOne()
- inst.default_configuration(*arg, **kw)
+ inst.declarative(*arg, **kw)
return inst.reg
def _getRouteRequestIface(self, config, name):
@@ -292,7 +292,7 @@ class ConfiguratorTests(unittest.TestCase):
request.params = {'param':'1'}
self.assertEqual(wrapper(ctx, request), 'view8')
- def test_view_with_relative_template_renderer(self):
+ def test_view_with_template_renderer(self):
class view(object):
def __init__(self, context, request):
self.request = request
@@ -302,24 +302,24 @@ class ConfiguratorTests(unittest.TestCase):
return {'a':'1'}
config = self._makeOne()
renderer = self._registerRenderer(config)
- fixture = 'fixtures/minimal.txt'
+ fixture = 'repoze.bfg.tests:fixtures/minimal.txt'
config.view(view=view, renderer=fixture)
wrapper = self._getViewCallable(config)
request = DummyRequest()
result = wrapper(None, request)
self.assertEqual(result.body, 'Hello!')
- self.assertEqual(renderer.path, 'fixtures/minimal.txt')
+ self.assertEqual(renderer.path, 'repoze.bfg.tests:fixtures/minimal.txt')
- def test_view_with_relative_template_renderer_no_callable(self):
+ def test_view_with_template_renderer_no_callable(self):
config = self._makeOne()
renderer = self._registerRenderer(config)
- fixture = 'fixtures/minimal.txt'
+ fixture = 'repoze.bfg.tests:fixtures/minimal.txt'
config.view(view=None, renderer=fixture)
wrapper = self._getViewCallable(config)
request = DummyRequest()
result = wrapper(None, request)
self.assertEqual(result.body, 'Hello!')
- self.assertEqual(renderer.path, 'fixtures/minimal.txt')
+ self.assertEqual(renderer.path, 'repoze.bfg.tests:fixtures/minimal.txt')
def test_view_with_request_type_as_iface(self):
def view(context, request):
@@ -1162,43 +1162,36 @@ class ConfiguratorTests(unittest.TestCase):
self.failUnless(registry.queryUtility(IFixture)) # only in c.zcml
def test_default_config_fixtureapp_explicit_filename(self):
- manager = DummyRegistryManager()
from repoze.bfg.tests import fixtureapp
rootfactory = DummyRootFactory(None)
registry = self._callDefaultConfiguration(
- rootfactory, fixtureapp, filename='another.zcml',
- manager=manager)
+ rootfactory, fixtureapp, filename='another.zcml')
from repoze.bfg.tests.fixtureapp.models import IFixture
self.failIf(registry.queryUtility(IFixture)) # only in c.zcml
def test_default_config_fixtureapp_explicit_filename_in_settings(self):
import os
- manager = DummyRegistryManager()
rootfactory = DummyRootFactory(None)
from repoze.bfg.tests import fixtureapp
zcmlfile = os.path.join(os.path.dirname(fixtureapp.__file__),
'another.zcml')
registry = self._callDefaultConfiguration(
rootfactory, fixtureapp, filename='configure.zcml',
- settings={'configure_zcml':zcmlfile},
- manager=manager)
+ settings={'configure_zcml':zcmlfile})
from repoze.bfg.tests.fixtureapp.models import IFixture
self.failIf(registry.queryUtility(IFixture)) # only in c.zcml
def test_default_config_fixtureapp_explicit_specification_in_settings(self):
- manager = DummyRegistryManager()
rootfactory = DummyRootFactory(None)
from repoze.bfg.tests import fixtureapp
zcmlfile = 'repoze.bfg.tests.fixtureapp.subpackage:yetanother.zcml'
registry = self._callDefaultConfiguration(
rootfactory, fixtureapp, filename='configure.zcml',
- settings={'configure_zcml':zcmlfile},
- manager=manager)
+ settings={'configure_zcml':zcmlfile})
from repoze.bfg.tests.fixtureapp.models import IFixture
self.failIf(registry.queryUtility(IFixture)) # only in c.zcml
def test_default_config_fixtureapp_filename_hascolon_isabs(self):
- manager = DummyRegistryManager()
rootfactory = DummyRootFactory(None)
from repoze.bfg.tests import fixtureapp
zcmlfile = 'repoze.bfg.tests.fixtureapp.subpackage:yetanother.zcml'
@@ -1212,32 +1205,28 @@ class ConfiguratorTests(unittest.TestCase):
fixtureapp,
filename='configure.zcml',
settings={'configure_zcml':zcmlfile},
- manager=manager,
os=os)
def test_default_config_custom_settings(self):
- manager = DummyRegistryManager()
settings = {'mysetting':True}
from repoze.bfg.tests import fixtureapp
rootfactory = DummyRootFactory(None)
registry = self._callDefaultConfiguration(
- rootfactory, fixtureapp, settings=settings,
- manager=manager)
+ rootfactory, fixtureapp, settings=settings)
from repoze.bfg.interfaces import ISettings
settings = registry.getUtility(ISettings)
self.assertEqual(settings.reload_templates, False)
self.assertEqual(settings.debug_authorization, False)
self.assertEqual(settings.mysetting, True)
- def test_default_config_registrations(self):
+ def test_declarative_registrations(self):
manager = DummyRegistryManager()
settings = {'reload_templates':True,
'debug_authorization':True}
from repoze.bfg.tests import fixtureapp
rootfactory = DummyRootFactory(None)
registry = self._callDefaultConfiguration(
- rootfactory, fixtureapp, settings=settings,
- manager=manager)
+ rootfactory, fixtureapp, settings=settings)
from repoze.bfg.interfaces import ISettings
from repoze.bfg.interfaces import ILogger
from repoze.bfg.interfaces import IRootFactory
@@ -1248,7 +1237,6 @@ class ConfiguratorTests(unittest.TestCase):
self.assertEqual(settings.reload_templates, True)
self.assertEqual(settings.debug_authorization, True)
self.assertEqual(rootfactory, rootfactory)
- self.failUnless(manager.pushed and manager.popped)
def test_default_config_routes_in_config(self):
from repoze.bfg.interfaces import ISettings
@@ -1325,31 +1313,6 @@ class TestBFGViewGrokker(unittest.TestCase):
result = grokker.grok('name', obj)
self.assertEqual(result, False)
-class TestDefaultRootFactory(unittest.TestCase):
- def _getTargetClass(self):
- from repoze.bfg.configuration import DefaultRootFactory
- return DefaultRootFactory
-
- def _makeOne(self, environ):
- return self._getTargetClass()(environ)
-
- def test_no_matchdict(self):
- environ = {}
- root = self._makeOne(environ)
- self.assertEqual(root.__parent__, None)
- self.assertEqual(root.__name__, None)
-
- def test_matchdict(self):
- class DummyRequest:
- pass
- request = DummyRequest()
- request.matchdict = {'a':1, 'b':2}
- root = self._makeOne(request)
- self.assertEqual(root.a, 1)
- self.assertEqual(root.b, 2)
-
-
-
class DummyRequest:
pass
diff --git a/repoze/bfg/tests/test_router.py b/repoze/bfg/tests/test_router.py
index 3321af938..f3fe6dd70 100644
--- a/repoze/bfg/tests/test_router.py
+++ b/repoze/bfg/tests/test_router.py
@@ -528,46 +528,26 @@ class TestMakeApp(unittest.TestCase):
return make_app(*arg, **kw)
def test_it(self):
- from repoze.bfg.interfaces import IWSGIApplicationCreatedEvent
- from repoze.bfg.tests import fixtureapp
- from zope.component import getSiteManager
- sm = getSiteManager()
- def subscriber(event):
- event.app.created = True
- manager = DummyRegistryManager()
- sm.registerHandler(subscriber, (IWSGIApplicationCreatedEvent,))
- rootfactory = DummyRootFactory(None)
settings = {'a':1}
- app = self._callFUT(rootfactory, fixtureapp, settings=settings,
- Configurator=DummyConfigurator, manager=manager)
- self.failUnless(app.created)
- self.failUnless(manager.pushed)
- self.failUnless(manager.popped)
- self.assertEqual(app.registry.root_factory, rootfactory)
- self.assertEqual(app.registry.settings, settings)
- self.assertEqual(app.registry.package, fixtureapp)
- self.assertEqual(app.registry.filename, 'configure.zcml')
+ package = object()
+ rootfactory = object()
+ app = self._callFUT(rootfactory, package, settings=settings,
+ Configurator=DummyConfigurator)
+ self.assertEqual(app.root_factory, rootfactory)
+ self.assertEqual(app.settings, settings)
+ self.assertEqual(app.package, package)
+ self.assertEqual(app.filename, 'configure.zcml')
def test_it_options_means_settings(self):
- from repoze.bfg.interfaces import IWSGIApplicationCreatedEvent
- from repoze.bfg.tests import fixtureapp
- from zope.component import getSiteManager
- sm = getSiteManager()
- def subscriber(event):
- event.app.created = True
- manager = DummyRegistryManager()
- sm.registerHandler(subscriber, (IWSGIApplicationCreatedEvent,))
- rootfactory = DummyRootFactory(None)
settings = {'a':1}
- app = self._callFUT(rootfactory, fixtureapp, options=settings,
- Configurator=DummyConfigurator, manager=manager)
- self.failUnless(app.created)
- self.failUnless(manager.pushed)
- self.failUnless(manager.popped)
- self.assertEqual(app.registry.root_factory, rootfactory)
- self.assertEqual(app.registry.settings, settings)
- self.assertEqual(app.registry.package, fixtureapp)
- self.assertEqual(app.registry.filename, 'configure.zcml')
+ package = object()
+ rootfactory = object()
+ app = self._callFUT(rootfactory, package, options=settings,
+ Configurator=DummyConfigurator)
+ self.assertEqual(app.root_factory, rootfactory)
+ self.assertEqual(app.settings, settings)
+ self.assertEqual(app.package, package)
+ self.assertEqual(app.filename, 'configure.zcml')
class DummyContext:
pass
@@ -640,13 +620,13 @@ class DummyRegistryManager:
self.popped = True
class DummyConfigurator(object):
- def __init__(self, registry):
- self.registry = registry
-
- def default_configuration(self, root_factory=None, package=None,
- filename=None, settings=None):
- self.registry.root_factory = root_factory
- self.registry.package = package
- self.registry.filename = filename
- self.registry.settings = settings
+ def make_wsgi_app(self):
+ return self
+
+ def declarative(self, root_factory=None, package=None,
+ filename=None, settings=None):
+ self.root_factory = root_factory
+ self.package = package
+ self.filename = filename
+ self.settings = settings
diff --git a/repoze/bfg/tests/test_traversal.py b/repoze/bfg/tests/test_traversal.py
index aceed1076..a15716d4c 100644
--- a/repoze/bfg/tests/test_traversal.py
+++ b/repoze/bfg/tests/test_traversal.py
@@ -970,6 +970,30 @@ class TraverseTests(unittest.TestCase):
self.assertEqual(result['view_name'], '')
self.assertEqual(result['context'], model)
+class TestDefaultRootFactory(unittest.TestCase):
+ def _getTargetClass(self):
+ from repoze.bfg.traversal import DefaultRootFactory
+ return DefaultRootFactory
+
+ def _makeOne(self, environ):
+ return self._getTargetClass()(environ)
+
+ def test_no_matchdict(self):
+ environ = {}
+ root = self._makeOne(environ)
+ self.assertEqual(root.__parent__, None)
+ self.assertEqual(root.__name__, None)
+
+ def test_matchdict(self):
+ class DummyRequest:
+ pass
+ request = DummyRequest()
+ request.matchdict = {'a':1, 'b':2}
+ root = self._makeOne(request)
+ self.assertEqual(root.a, 1)
+ self.assertEqual(root.b, 2)
+
+
def make_traverser(result):
class DummyTraverser(object):
def __init__(self, context):
diff --git a/repoze/bfg/traversal.py b/repoze/bfg/traversal.py
index 325e41e4b..b46fb83c7 100644
--- a/repoze/bfg/traversal.py
+++ b/repoze/bfg/traversal.py
@@ -632,3 +632,12 @@ class TraversalContextURL(object):
def _join_path_tuple(tuple):
return tuple and '/'.join([quote_path_segment(x) for x in tuple]) or '/'
+class DefaultRootFactory:
+ __parent__ = None
+ __name__ = None
+ def __init__(self, request):
+ matchdict = getattr(request, 'matchdict', {})
+ # provide backwards compatibility for applications which
+ # used routes (at least apps without any custom "context
+ # factory") in BFG 0.9.X and before
+ self.__dict__.update(matchdict)
diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py
index a7c5f2660..eae53c337 100644
--- a/repoze/bfg/zcml.py
+++ b/repoze/bfg/zcml.py
@@ -1,5 +1,7 @@
from zope.configuration.exceptions import ConfigurationError
from zope.configuration.fields import GlobalObject
+from zope.configuration.config import ConfigurationMachine
+from zope.configuration import xmlconfig
from zope.interface import Interface
@@ -22,7 +24,6 @@ from repoze.bfg.authentication import RepozeWho1AuthenticationPolicy
from repoze.bfg.authentication import RemoteUserAuthenticationPolicy
from repoze.bfg.authentication import AuthTktAuthenticationPolicy
from repoze.bfg.authorization import ACLAuthorizationPolicy
-from repoze.bfg.configuration import zcml_configure
from repoze.bfg.configuration import Configurator
from repoze.bfg.path import package_name
from repoze.bfg.request import route_request_iface
@@ -536,5 +537,19 @@ class Uncacheable(object):
""" Include in discriminators of actions which are not cacheable;
this class only exists for backwards compatibility (<0.8.1)"""
+def zcml_configure(name, package):
+ """ Given a ZCML filename as ``name`` and a Python package as
+ ``package`` which the filename should be relative to, load the
+ ZCML into the current ZCML registry.
+
+ .. note:: This feature is new as of :mod:`repoze.bfg` 1.1.
+ """
+ context = ConfigurationMachine()
+ xmlconfig.registerCommonDirectives(context)
+ context.package = package
+ xmlconfig.include(context, name, package)
+ context.execute_actions(clear=False) # the raison d'etre
+ return context.actions
+
file_configure = zcml_configure # backwards compat (>0.8.1)