Chris McDonough
2011-12-21 ba2a3f87fa51843a8a160f209fb576ae21d0050b
- Add undocumented ``__discriminator__`` API to derived view callables.
e.g. ``adapters.lookup(...).__discriminator__(context, request)``. It will
be used by superdynamic systems that require the discriminator to be used
for introspection after manual view lookup.
3 files modified
54 ■■■■■ changed files
CHANGES.txt 5 ●●●●● patch | view | raw | blame | history
pyramid/config/views.py 13 ●●●●● patch | view | raw | blame | history
pyramid/tests/test_config/test_views.py 36 ●●●●● patch | view | raw | blame | history
CHANGES.txt
@@ -8,6 +8,11 @@
  documented in the "Command-Line Pyramid" chapter in the section entitled
  "Invoking a Request".
- Add undocumented ``__discriminator__`` API to derived view callables.
  e.g. ``adapters.lookup(...).__discriminator__(context, request)``.  It will
  be used by superdynamic systems that require the discriminator to be used
  for introspection after manual view lookup.
Bug Fixes
---------
pyramid/config/views.py
@@ -492,6 +492,15 @@
        self.views = []
        self.accepts = []
    def __discriminator__(self, context, request):
        # used by introspection systems like so:
        # view = adapters.lookup(....)
        # view.__discriminator__(context, request) -> view's discriminator
        # so that superdynamic systems can feed the discriminator to
        # the introspection system to get info about it
        view = self.match(context, request)
        return view.__discriminator__(context, request)
    def add(self, view, order, accept=None, phash=None):
        if phash is not None:
            for i, (s, v, h) in enumerate(list(self.views)):
@@ -1034,6 +1043,10 @@
                                  decorator=decorator,
                                  http_cache=http_cache)
            derived_view = deriver(view)
            derived_view.__discriminator__ = lambda *arg: discriminator
            # __discriminator__ is used by superdynamic systems
            # that require it for introspection after manual view lookup;
            # see also MultiView.__discriminator__
            view_intr['derived_callable'] = derived_view
            registered = self.registry.adapters.registered
pyramid/tests/test_config/test_views.py
@@ -115,6 +115,7 @@
        self.assertEqual(wrapper.__module__, view.__module__)
        self.assertEqual(wrapper.__name__, view.__name__)
        self.assertEqual(wrapper.__doc__, view.__doc__)
        self.assertEqual(wrapper.__discriminator__(None, None)[0], 'view')
    def test_add_view_view_callable_dottedname(self):
        from pyramid.renderers import null_renderer
@@ -875,6 +876,41 @@
        request.params = {'param':'1'}
        self.assertEqual(wrapper(ctx, request), 'view8')
    def test_add_view_multiview___discriminator__(self):
        from pyramid.renderers import null_renderer
        from zope.interface import Interface
        class IFoo(Interface):
            pass
        class IBar(Interface):
            pass
        @implementer(IFoo)
        class Foo(object):
            pass
        @implementer(IBar)
        class Bar(object):
            pass
        foo = Foo()
        bar = Bar()
        from pyramid.interfaces import IRequest
        from pyramid.interfaces import IView
        from pyramid.interfaces import IViewClassifier
        from pyramid.interfaces import IMultiView
        view = lambda *arg: 'OK'
        view.__phash__ = 'abc'
        config = self._makeOne(autocommit=True)
        config.registry.registerAdapter(
            view, (IViewClassifier, IRequest, Interface), IView, name='')
        config.add_view(view=view, renderer=null_renderer,
                        containment=IFoo)
        config.add_view(view=view, renderer=null_renderer,
                        containment=IBar)
        wrapper = self._getViewCallable(config)
        self.assertTrue(IMultiView.providedBy(wrapper))
        request = self._makeRequest(config)
        self.assertEqual(wrapper.__discriminator__(foo, request)[5], IFoo)
        self.assertEqual(wrapper.__discriminator__(bar, request)[5], IBar)
    def test_add_view_with_template_renderer(self):
        from pyramid.tests import test_config
        from pyramid.interfaces import ISettings