summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGael Pasgrimaud <gael@gawel.org>2011-01-12 19:07:14 +0100
committerGael Pasgrimaud <gael@gawel.org>2011-01-12 19:07:14 +0100
commitcad4e3c917017d43c382df213a1c045523e247b8 (patch)
tree82225d519ec3f10e98d725a9c5796a62a0df5fb7
parent57d300f292b87b67163399db9377fb2920621bd3 (diff)
downloadpyramid-cad4e3c917017d43c382df213a1c045523e247b8.tar.gz
pyramid-cad4e3c917017d43c382df213a1c045523e247b8.tar.bz2
pyramid-cad4e3c917017d43c382df213a1c045523e247b8.zip
add Configurator.extend feature
-rw-r--r--pyramid/config.py27
-rw-r--r--pyramid/tests/__init__.py4
-rw-r--r--pyramid/tests/test_config.py59
3 files changed, 88 insertions, 2 deletions
diff --git a/pyramid/config.py b/pyramid/config.py
index 9604833f3..60197a4c6 100644
--- a/pyramid/config.py
+++ b/pyramid/config.py
@@ -558,6 +558,33 @@ 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)
+
+ klass = self.__class__
+
+ 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(klass, 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 = klass.with_context(context)
+ def extend_wrapper(*args, **kwargs):
+ c(config, *args, **kwargs)
+ extend_wrapper.__name__ = name
+ setattr(klass, name, staticmethod(extend_wrapper))
+
@classmethod
def with_context(cls, context):
"""A classmethod used by ZCML directives,
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..a16323313 100644
--- a/pyramid/tests/test_config.py
+++ b/pyramid/tests/test_config.py
@@ -3216,6 +3216,60 @@ class ConfiguratorTests(unittest.TestCase):
for confinst in conflict:
yield confinst[2]
+class TestConfiguratorExtender(unittest.TestCase):
+
+ def setUp(self):
+ from pyramid.config import Configurator
+ class Config(Configurator): pass
+ self.config = Config()
+
+ 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)
+
+ 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)
+
+ def test_extend_conflict(self):
+ from pyramid import tests
+ 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')
+
class TestViewDeriver(unittest.TestCase):
def setUp(self):
self.config = testing.setUp()
@@ -4943,4 +4997,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)
+