Gael Pasgrimaud
2011-01-12 cad4e3c917017d43c382df213a1c045523e247b8
add Configurator.extend feature
3 files modified
90 ■■■■■ changed files
pyramid/config.py 27 ●●●●● patch | view | raw | blame | history
pyramid/tests/__init__.py 4 ●●● patch | view | raw | blame | history
pyramid/tests/test_config.py 59 ●●●●● patch | view | raw | blame | history
pyramid/config.py
@@ -558,6 +558,33 @@
                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,
pyramid/tests/__init__.py
@@ -1 +1,3 @@
# package
def dummy_extend(*args):
    """used to test Configurator.extend"""
pyramid/tests/test_config.py
@@ -3216,6 +3216,60 @@
            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 @@
def dummy_include(config):
    config.action('discrim', None, config.package)
def dummy_extend(config, discrim):
    config.action(discrim, None, config.package)