Chris McDonough
2011-01-16 da358e42a1dda347f04d9331bb1e43f065546133
simplify slightly
3 files modified
141 ■■■■ changed files
docs/api/config.rst 2 ●●●●● patch | view | raw | blame | history
pyramid/config.py 58 ●●●● patch | view | raw | blame | history
pyramid/tests/test_config.py 81 ●●●● patch | view | raw | blame | history
docs/api/config.rst
@@ -76,6 +76,8 @@
     .. automethod:: set_renderer_globals_factory
     .. automethod:: add_directive
     .. automethod:: testing_securitypolicy
     .. automethod:: testing_resources
pyramid/config.py
@@ -2,6 +2,7 @@
import os
import re
import sys
import types
import threading
import traceback
@@ -275,7 +276,6 @@
                 default_permission=None,
                 session_factory=None,
                 default_view_mapper=None,
                 extends = None,
                 autocommit=False,
                 ):
        if package is None:
@@ -303,8 +303,9 @@
                session_factory=session_factory,
                default_view_mapper=default_view_mapper,
                )
        if extends:
            self.extend(*extends)
        if hasattr(registry, '_directives'):
            for name, directive in registry._directives.items():
                self.add_directive(name, directive)
    def _set_settings(self, mapping):
        settings = Settings(mapping or {})
@@ -428,7 +429,6 @@
        context = PyramidConfigurationMachine()
        registerCommonDirectives(context)
        context.registry = self.registry
        context.extends = []
        context.autocommit = autocommit
        return context
@@ -562,33 +562,29 @@
                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)
    def add_directive(self, name, directive):
        """
        Add a directive method to the configurator.
        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)
        Framework extenders can add directive methods to a configurator by
        instructing their users to call ``config.add_directive('somename',
        'some.callable')``.  This will make ``some.callable`` accessible as
        ``config.somename``.  ``some.callable`` should be a function which
        accepts ``config`` as a first argument, and arbitrary positional and
        keyword arguments following.  It should use config.action as
        necessary to perform actions.  Directive methods can then be invoked
        like 'built-in' directives such as ``add_view``, ``add_route``, etc.
        ``add_directive`` does not participate in conflict detection, and
        later calls to ``add_directive`` will override earlier calls.
        """
        c = self.maybe_dotted(directive)
        if not hasattr(self.registry, '_directives'):
            self.registry._directives = {}
        self.registry._directives[name] = c
        c = action_method(c)
        m = types.MethodType(c, self, self.__class__)
        setattr(self, name, m)
    @classmethod
    def with_context(cls, context):
@@ -597,7 +593,7 @@
        :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,
                           extends=context.extends, autocommit=context.autocommit)
                           autocommit=context.autocommit)
        configurator._ctx = context
        return configurator
pyramid/tests/test_config.py
@@ -3216,7 +3216,7 @@
            for confinst in conflict:
                yield confinst[2]
class TestConfiguratorExtender(unittest.TestCase):
class TestConfigurator_add_directive(unittest.TestCase):
    def setUp(self):
        from pyramid.config import Configurator
@@ -3225,9 +3225,8 @@
    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')
        config.add_directive(
            'dummy_extend', 'pyramid.tests.test_config.dummy_extend')
        self.assert_(hasattr(config, 'dummy_extend'))
        config.dummy_extend('discrim')
        context_after = config._ctx
@@ -3237,18 +3236,12 @@
            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)
        config.add_directive(
            'dummy_extend', dummy_extend)
        self.assert_(hasattr(config, 'dummy_extend'))
        config.dummy_extend('discrim')
        context_after = config._ctx
@@ -3258,38 +3251,47 @@
            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
    def test_extend_same_name_doesnt_conflict(self):
        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')
        config.add_directive(
            'dummy_extend', dummy_extend)
        config.add_directive(
            'dummy_extend', dummy_extend2)
        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, config.registry),
            )
    def test_extend_no_conflict_with_two_instance(self):
        from pyramid.config import Configurator
    def test_extend_action_method_successful(self):
        from zope.configuration.config import ConfigurationConflictError
        config = self.config
        config.extend(dummy_extend)
        config2 = Configurator()
        config2.extend(dummy_extend)
        self.assertEqual(config._ctx.extends, config2._ctx.extends)
        config.add_directive(
            'dummy_extend', dummy_extend)
        config.dummy_extend('discrim')
        config.dummy_extend('discrim')
        self.assertRaises(ConfigurationConflictError, config.commit)
    def test_extend_after_with_package(self):
        from pyramid import tests
    def test_directive_persists_across_configurator_creations(self):
        from zope.configuration.config import GroupingContextDecorator
        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)
        config.add_directive('dummy_extend', dummy_extend)
        context = config._make_context(autocommit=False)
        context = GroupingContextDecorator(context)
        config2 = config.with_context(context)
        config2.dummy_extend('discrim')
        context_after = config2._ctx
        actions = context_after.actions
        self.assertEqual(len(actions), 1)
        self.assertEqual(
            context_after.actions[0][:3],
            ('discrim', None, config2.package),
            )
class TestViewDeriver(unittest.TestCase):
    def setUp(self):
@@ -5022,3 +5024,6 @@
def dummy_extend(config, discrim):
    config.action(discrim, None, config.package)
def dummy_extend2(config, discrim):
    config.action(discrim, None, config.registry)