from zope.interface import implementer
|
|
from pyramid.interfaces import (
|
IDefaultRootFactory,
|
IExecutionPolicy,
|
IRequestFactory,
|
IResponseFactory,
|
IRequestExtensions,
|
IRootFactory,
|
ISessionFactory,
|
)
|
|
from pyramid.router import default_execution_policy
|
from pyramid.traversal import DefaultRootFactory
|
|
from pyramid.util import get_callable_name, InstancePropertyHelper
|
|
from pyramid.config.actions import action_method
|
|
|
class FactoriesConfiguratorMixin(object):
|
@action_method
|
def set_root_factory(self, factory):
|
""" Add a :term:`root factory` to the current configuration
|
state. If the ``factory`` argument is ``None`` a default root
|
factory will be registered.
|
|
.. note::
|
|
Using the ``root_factory`` argument to the
|
:class:`pyramid.config.Configurator` constructor can be used to
|
achieve the same purpose.
|
"""
|
factory = self.maybe_dotted(factory)
|
if factory is None:
|
factory = DefaultRootFactory
|
|
def register():
|
self.registry.registerUtility(factory, IRootFactory)
|
self.registry.registerUtility(factory, IDefaultRootFactory) # b/c
|
|
intr = self.introspectable(
|
'root factories',
|
None,
|
self.object_description(factory),
|
'root factory',
|
)
|
intr['factory'] = factory
|
self.action(IRootFactory, register, introspectables=(intr,))
|
|
_set_root_factory = set_root_factory # bw compat
|
|
@action_method
|
def set_session_factory(self, factory):
|
"""
|
Configure the application with a :term:`session factory`. If this
|
method is called, the ``factory`` argument must be a session
|
factory callable or a :term:`dotted Python name` to that factory.
|
|
.. note::
|
|
Using the ``session_factory`` argument to the
|
:class:`pyramid.config.Configurator` constructor can be used to
|
achieve the same purpose.
|
"""
|
factory = self.maybe_dotted(factory)
|
|
def register():
|
self.registry.registerUtility(factory, ISessionFactory)
|
|
intr = self.introspectable(
|
'session factory',
|
None,
|
self.object_description(factory),
|
'session factory',
|
)
|
intr['factory'] = factory
|
self.action(ISessionFactory, register, introspectables=(intr,))
|
|
@action_method
|
def set_request_factory(self, factory):
|
""" The object passed as ``factory`` should be an object (or a
|
:term:`dotted Python name` which refers to an object) which
|
will be used by the :app:`Pyramid` router to create all
|
request objects. This factory object must have the same
|
methods and attributes as the
|
:class:`pyramid.request.Request` class (particularly
|
``__call__``, and ``blank``).
|
|
See :meth:`pyramid.config.Configurator.add_request_method`
|
for a less intrusive way to extend the request objects with
|
custom methods and properties.
|
|
.. note::
|
|
Using the ``request_factory`` argument to the
|
:class:`pyramid.config.Configurator` constructor
|
can be used to achieve the same purpose.
|
"""
|
factory = self.maybe_dotted(factory)
|
|
def register():
|
self.registry.registerUtility(factory, IRequestFactory)
|
|
intr = self.introspectable(
|
'request factory',
|
None,
|
self.object_description(factory),
|
'request factory',
|
)
|
intr['factory'] = factory
|
self.action(IRequestFactory, register, introspectables=(intr,))
|
|
@action_method
|
def set_response_factory(self, factory):
|
""" The object passed as ``factory`` should be an object (or a
|
:term:`dotted Python name` which refers to an object) which
|
will be used by the :app:`Pyramid` as the default response
|
objects. The factory should conform to the
|
:class:`pyramid.interfaces.IResponseFactory` interface.
|
|
.. note::
|
|
Using the ``response_factory`` argument to the
|
:class:`pyramid.config.Configurator` constructor
|
can be used to achieve the same purpose.
|
"""
|
factory = self.maybe_dotted(factory)
|
|
def register():
|
self.registry.registerUtility(factory, IResponseFactory)
|
|
intr = self.introspectable(
|
'response factory',
|
None,
|
self.object_description(factory),
|
'response factory',
|
)
|
intr['factory'] = factory
|
self.action(IResponseFactory, register, introspectables=(intr,))
|
|
@action_method
|
def add_request_method(
|
self, callable=None, name=None, property=False, reify=False
|
):
|
""" Add a property or method to the request object.
|
|
When adding a method to the request, ``callable`` may be any
|
function that receives the request object as the first
|
parameter. If ``name`` is ``None`` then it will be computed
|
from the name of the ``callable``.
|
|
When adding a property to the request, ``callable`` can either
|
be a callable that accepts the request as its single positional
|
parameter, or it can be a property descriptor. If ``callable`` is
|
a property descriptor, it has to be an instance of a class which is
|
a subclass of ``property``. If ``name`` is ``None``, the name of
|
the property will be computed from the name of the ``callable``.
|
|
If the ``callable`` is a property descriptor a ``ValueError``
|
will be raised if ``name`` is ``None`` or ``reify`` is ``True``.
|
|
See :meth:`pyramid.request.Request.set_property` for more
|
details on ``property`` vs ``reify``. When ``reify`` is
|
``True``, the value of ``property`` is assumed to also be
|
``True``.
|
|
In all cases, ``callable`` may also be a
|
:term:`dotted Python name` which refers to either a callable or
|
a property descriptor.
|
|
If ``callable`` is ``None`` then the method is only used to
|
assist in conflict detection between different addons requesting
|
the same attribute on the request object.
|
|
This is the recommended method for extending the request object
|
and should be used in favor of providing a custom request
|
factory via
|
:meth:`pyramid.config.Configurator.set_request_factory`.
|
|
.. versionadded:: 1.4
|
"""
|
if callable is not None:
|
callable = self.maybe_dotted(callable)
|
|
property = property or reify
|
if property:
|
name, callable = InstancePropertyHelper.make_property(
|
callable, name=name, reify=reify
|
)
|
elif name is None:
|
name = callable.__name__
|
else:
|
name = get_callable_name(name)
|
|
def register():
|
exts = self.registry.queryUtility(IRequestExtensions)
|
|
if exts is None:
|
exts = _RequestExtensions()
|
self.registry.registerUtility(exts, IRequestExtensions)
|
|
plist = exts.descriptors if property else exts.methods
|
plist[name] = callable
|
|
if callable is None:
|
self.action(('request extensions', name), None)
|
elif property:
|
intr = self.introspectable(
|
'request extensions',
|
name,
|
self.object_description(callable),
|
'request property',
|
)
|
intr['callable'] = callable
|
intr['property'] = True
|
intr['reify'] = reify
|
self.action(
|
('request extensions', name), register, introspectables=(intr,)
|
)
|
else:
|
intr = self.introspectable(
|
'request extensions',
|
name,
|
self.object_description(callable),
|
'request method',
|
)
|
intr['callable'] = callable
|
intr['property'] = False
|
intr['reify'] = False
|
self.action(
|
('request extensions', name), register, introspectables=(intr,)
|
)
|
|
@action_method
|
def set_execution_policy(self, policy):
|
"""
|
Override the :app:`Pyramid` :term:`execution policy` in the
|
current configuration. The ``policy`` argument must be an instance
|
of an :class:`pyramid.interfaces.IExecutionPolicy` or a
|
:term:`dotted Python name` that points at an instance of an
|
execution policy.
|
|
"""
|
policy = self.maybe_dotted(policy)
|
if policy is None:
|
policy = default_execution_policy
|
|
def register():
|
self.registry.registerUtility(policy, IExecutionPolicy)
|
|
intr = self.introspectable(
|
'execution policy',
|
None,
|
self.object_description(policy),
|
'execution policy',
|
)
|
intr['policy'] = policy
|
self.action(IExecutionPolicy, register, introspectables=(intr,))
|
|
|
@implementer(IRequestExtensions)
|
class _RequestExtensions(object):
|
def __init__(self):
|
self.descriptors = {}
|
self.methods = {}
|