summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-01-15 21:08:27 -0500
committerChris McDonough <chrism@plope.com>2011-01-15 21:08:27 -0500
commit492368086ad82ed16aa99a271cca772a106c3f36 (patch)
tree160aa179d8ef552dd1ff1b57cf136b12f29250ff
parentfe847fad6768c9a7f2cb1b61d88164a370f6b2db (diff)
parent035d033169f48d8250afafedd0a078d3e4f62922 (diff)
downloadpyramid-492368086ad82ed16aa99a271cca772a106c3f36.tar.gz
pyramid-492368086ad82ed16aa99a271cca772a106c3f36.tar.bz2
pyramid-492368086ad82ed16aa99a271cca772a106c3f36.zip
Merge branch 'config_extend' of git://github.com/gawel/pyramid into gawel-config_extend
-rw-r--r--pyramid/config.py34
-rw-r--r--pyramid/tests/__init__.py4
-rw-r--r--pyramid/tests/test_config.py80
3 files changed, 115 insertions, 3 deletions
diff --git a/pyramid/config.py b/pyramid/config.py
index 9604833f3..468618c92 100644
--- a/pyramid/config.py
+++ b/pyramid/config.py
@@ -275,6 +275,7 @@ class Configurator(object):
default_permission=None,
session_factory=None,
default_view_mapper=None,
+ extends = None,
autocommit=False,
):
if package is None:
@@ -302,6 +303,8 @@ class Configurator(object):
session_factory=session_factory,
default_view_mapper=default_view_mapper,
)
+ if extends:
+ self.extend(*extends)
def _set_settings(self, mapping):
settings = Settings(mapping or {})
@@ -425,6 +428,7 @@ class Configurator(object):
context = PyramidConfigurationMachine()
registerCommonDirectives(context)
context.registry = self.registry
+ context.extends = []
context.autocommit = autocommit
return context
@@ -558,6 +562,34 @@ class Configurator(object):
config = self.__class__.with_context(context)
c(config)
+ def extend(self, *callables):
+ _context = self._ctx
+ if _context is None:
+ _context = self._ctx = self._make_context(self.autocommit)
+
+ for c in callables:
+ c = self.maybe_dotted(c)
+ name = c.__name__
+ sourcefile = inspect.getsourcefile(c)
+ module = inspect.getmodule(c)
+ spec = module.__name__ + ':' + name
+ if _context.processSpec(spec):
+ if hasattr(self, name):
+ raise ConfigurationError(
+ "Configurator already have a method named %s" % name)
+ context = GroupingContextDecorator(_context)
+ context.basepath = os.path.dirname(sourcefile)
+ context.includepath = _context.includepath + (spec,)
+ context.package = package_of(module)
+ config = self.__class__.with_context(context)
+ wrapped = action_method(c)
+ def wrapper(*args, **kwargs):
+ return wrapped(config, *args, **kwargs)
+ wrapper.__name__ = name
+ wrapper.__doc__ = c.__doc__
+ self.__dict__[name] = wrapper
+ context.extends.append(c)
+
@classmethod
def with_context(cls, context):
"""A classmethod used by ZCML directives,
@@ -565,7 +597,7 @@ class Configurator(object):
:meth:`pyramid.config.Configurator.include` to obtain a configurator
with 'the right' context. Returns a new Configurator instance."""
configurator = cls(registry=context.registry, package=context.package,
- autocommit=context.autocommit)
+ extends=context.extends, autocommit=context.autocommit)
configurator._ctx = context
return configurator
diff --git a/pyramid/tests/__init__.py b/pyramid/tests/__init__.py
index 5bb534f79..a62c29f47 100644
--- a/pyramid/tests/__init__.py
+++ b/pyramid/tests/__init__.py
@@ -1 +1,3 @@
-# package
+
+def dummy_extend(*args):
+ """used to test Configurator.extend"""
diff --git a/pyramid/tests/test_config.py b/pyramid/tests/test_config.py
index ac459d7e3..3fa9b954c 100644
--- a/pyramid/tests/test_config.py
+++ b/pyramid/tests/test_config.py
@@ -3216,6 +3216,81 @@ class ConfiguratorTests(unittest.TestCase):
for confinst in conflict:
yield confinst[2]
+class TestConfiguratorExtender(unittest.TestCase):
+
+ def setUp(self):
+ from pyramid.config import Configurator
+ self.config = Configurator()
+
+ def test_extend_with_dotted_name(self):
+ from pyramid import tests
+ config = self.config
+ context_before = config._make_context()
+ config._ctx = context_before
+ config.extend('pyramid.tests.test_config.dummy_extend')
+ self.assert_(hasattr(config, 'dummy_extend'))
+ config.dummy_extend('discrim')
+ context_after = config._ctx
+ actions = context_after.actions
+ self.assertEqual(len(actions), 1)
+ self.assertEqual(
+ context_after.actions[0][:3],
+ ('discrim', None, tests),
+ )
+ self.assertEqual(context_after.basepath, None)
+ self.assertEqual(context_after.includepath, ())
+ self.failUnless(context_after is context_before)
+ self.assertEqual(len(context_before.extends), 1)
+ self.assertEqual(context_before.extends, context_after.extends)
+
+ def test_extend_with_python_callable(self):
+ from pyramid import tests
+ config = self.config
+ context_before = config._make_context()
+ config._ctx = context_before
+ config.extend(dummy_extend)
+ self.assert_(hasattr(config, 'dummy_extend'))
+ config.dummy_extend('discrim')
+ context_after = config._ctx
+ actions = context_after.actions
+ self.assertEqual(len(actions), 1)
+ self.assertEqual(
+ context_after.actions[0][:3],
+ ('discrim', None, tests),
+ )
+ self.assertEqual(context_after.basepath, None)
+ self.assertEqual(context_after.includepath, ())
+ self.failUnless(context_after is context_before)
+ self.assertEqual(len(context_before.extends), 1)
+ self.assertEqual(context_before.extends, context_after.extends)
+
+ def test_extend_conflict(self):
+ from pyramid.exceptions import ConfigurationError
+ config = self.config
+ context_before = config._make_context()
+ config._ctx = context_before
+ config.extend(dummy_extend)
+ self.assertRaises(ConfigurationError, config.extend, 'pyramid.tests.dummy_extend')
+
+ def test_extend_no_conflict_with_two_instance(self):
+ from pyramid.config import Configurator
+ config = self.config
+ config.extend(dummy_extend)
+ config2 = Configurator()
+ config2.extend(dummy_extend)
+ self.assertEqual(config._ctx.extends, config2._ctx.extends)
+
+ def test_extend_after_with_package(self):
+ from pyramid import tests
+ config = self.config
+ context_before = config._make_context()
+ config._ctx = context_before
+ config.extend(dummy_extend)
+ config2 = config.with_package('pyramid.tests')
+ self.assert_(hasattr(config2, 'dummy_extend'))
+ self.assertEqual(len(config._ctx.extends), 1)
+ self.assertEqual(config._ctx.extends, config2._ctx.extends)
+
class TestViewDeriver(unittest.TestCase):
def setUp(self):
self.config = testing.setUp()
@@ -4943,4 +5018,7 @@ class DummyHandler(object): # pragma: no cover
def dummy_include(config):
config.action('discrim', None, config.package)
-
+
+def dummy_extend(config, discrim):
+ config.action(discrim, None, config.package)
+