def map_nonclass(self, view): # We do more work here than appears necessary to avoid wrapping the # view unless it actually requires wrapping (to avoid function call # overhead). mapped_view = view ronly = requestonly(view, self.attr) if ronly: mapped_view = self.map_nonclass_requestonly(view) elif self.attr: mapped_view = self.map_nonclass_attr(view) if inspect.isroutine(mapped_view): # This branch will be true if the view is a function or a method. # We potentially mutate an unwrapped object here if it's a # function. We do this to avoid function call overhead of # injecting another wrapper. However, we must wrap if the # function is a bound method because we can't set attributes on a # bound method. if is_bound_method(view): _mapped_view = mapped_view def mapped_view(context, request): return _mapped_view(context, request) if self.attr is not None: mapped_view.__text__ = 'attr %s of %s' % ( self.attr, object_description(view)) else: mapped_view.__text__ = object_description(view) return mapped_view
def map_class(self, view): ronly = requestonly(view, self.attr) if ronly: mapped_view = self.map_class_requestonly(view) else: mapped_view = self.map_class_native(view) mapped_view.__text__ = "method %s of %s" % (self.attr or "__call__", object_description(view)) return mapped_view
def map_class(self, view): ronly = requestonly(view, self.attr) if ronly: mapped_view = self.map_class_requestonly(view) else: mapped_view = self.map_class_native(view) mapped_view.__text__ = 'method %s of %s' % (self.attr or '__call__', object_description(view)) return mapped_view
def text(self): return getattr( self.func, '__text__', 'custom predicate: %s' % object_description(self.func), )
def _callFUT(self, object): from pyramid.util import object_description return object_description(object)
def add_indexview(config, view, catalog_name, index_name, context=None, attr=None): """ Directive which adds an index view to the configuration state state. The ``view`` argument should be function that is an indeview function, or or a class with a ``__call__`` method that acts as an indexview method. For example:: def title(resource, default): return getattr(resource, 'title', default) config.add_indexview(title, catalog_name='myapp', index_name='title') Or, a class:: class IndexViews(object): def __init__(self, resource): self.resource = resource def __call__(self, default): return getattr(self.resource, 'title', default) config.add_indexview( IndexViews, catalog_name='myapp', index_name='title' ) If an ``attr`` arg is supplied to ``add_indexview``, you can use a different attribute of the class instad of ``__call__``:: class IndexViews(object): def __init__(self, resource): self.resource = resource def title(self, default): return getattr(self.resource, 'title', default) def name(self, default): return getattr(self.resource, 'name', default) config.add_indexview( IndexViews, catalog_name='myapp', index_name='title', attr='title' ) config.add_indexview( IndexViews, catalog_name='myapp', index_name='name', attr='name' ) In this way you can use the same class to represent a bunch of different index views. An index view will be looked up by the cataloging machinery when it wants to insert value into a particular catalog type's index. The ``catalog_name`` you use specify which catalog name this indeview is good for; it should match the string passed to ``add_catalog_factory`` as a ``name``. The ``index_name`` argument should match an index name used within such a catalog. Index view lookups work a bit like Pyramid view lookups: you can use the ``context`` argument to pass an interface or class which should be used to register the index view; such an index view will only be used when the resource being indexed has that class or interface. Eventually we'll provide a way to add predicates other than ``context`` too. The :class:`substanced.catalog.indexview` decorator provides a declarative analogue to using this configuration directive. """ if context is None: context = Interface composite_name = '%s|%s' % (catalog_name, index_name) def register(): mapper = _IndexViewMapper(attr=attr) mapped_view = mapper(view) intr['derived_callable'] = mapped_view config.registry.registerAdapter( mapped_view, (context, ), IIndexView, name=composite_name, ) if inspect.isclass(view) and attr: view_desc = 'method %r of %s' % (attr, object_description(view)) else: view_desc = object_description(view) discriminator = ('sd-index-view', catalog_name, index_name, context) intr = config.introspectable('sd index views', discriminator, view_desc, 'sd index view') intr['catalog_name'] = catalog_name intr['index_name'] = index_name intr['name'] = composite_name intr['callable'] = view intr['attr'] = attr config.action(discriminator, callable=register, introspectables=(intr, ))
def text(self): return getattr( self.func, '__text__', 'custom predicate: %s' % object_description(self.func) )
def view_description(view): try: return view.__text__ except AttributeError: # custom view mappers might not add __text__ return object_description(view)
def add_indexview( config, view, catalog_name, index_name, context=None, attr=None ): """ Directive which adds an index view to the configuration state state. The ``view`` argument should be function that is an indeview function, or or a class with a ``__call__`` method that acts as an indexview method. For example:: def title(resource, default): return getattr(resource, 'title', default) config.add_indexview(title, catalog_name='myapp', index_name='title') Or, a class:: class IndexViews(object): def __init__(self, resource): self.resource = resource def __call__(self, default): return getattr(self.resource, 'title', default) config.add_indexview( IndexViews, catalog_name='myapp', index_name='title' ) If an ``attr`` arg is supplied to ``add_indexview``, you can use a different attribute of the class instad of ``__call__``:: class IndexViews(object): def __init__(self, resource): self.resource = resource def title(self, default): return getattr(self.resource, 'title', default) def name(self, default): return getattr(self.resource, 'name', default) config.add_indexview( IndexViews, catalog_name='myapp', index_name='title', attr='title' ) config.add_indexview( IndexViews, catalog_name='myapp', index_name='name', attr='name' ) In this way you can use the same class to represent a bunch of different index views. An index view will be looked up by the cataloging machinery when it wants to insert value into a particular catalog type's index. The ``catalog_name`` you use specify which catalog name this indeview is good for; it should match the string passed to ``add_catalog_factory`` as a ``name``. The ``index_name`` argument should match an index name used within such a catalog. Index view lookups work a bit like Pyramid view lookups: you can use the ``context`` argument to pass an interface or class which should be used to register the index view; such an index view will only be used when the resource being indexed has that class or interface. Eventually we'll provide a way to add predicates other than ``context`` too. The :class:`substanced.catalog.indexview` decorator provides a declarative analogue to using this configuration directive. """ if context is None: context = Interface composite_name = '%s|%s' % (catalog_name, index_name) def register(): mapper = _IndexViewMapper(attr=attr) mapped_view = mapper(view) intr['derived_callable'] = mapped_view config.registry.registerAdapter( mapped_view, (context,), IIndexView, name=composite_name, ) if inspect.isclass(view) and attr: view_desc = 'method %r of %s' % (attr, object_description(view)) else: view_desc = object_description(view) discriminator = ('sd-index-view', catalog_name, index_name, context) intr = config.introspectable( 'sd index views', discriminator, view_desc, 'sd index view' ) intr['catalog_name'] = catalog_name intr['index_name'] = index_name intr['name'] = composite_name intr['callable'] = view intr['attr'] = attr config.action(discriminator, callable=register, introspectables=(intr,))
def text(self): return getattr(self.func, "__text__", "custom predicate: %s" % object_description(self.func))