Michael Merickel
2018-10-15 81576ee51564c49d5ff3c1c07f214f22a8438231
commit | author | age
d7f34b 1 from zope.interface import implementer
MM 2
ee117e 3 from pyramid.interfaces import (
CM 4     IDefaultRootFactory,
0bee84 5     IExecutionPolicy,
ee117e 6     IRequestFactory,
1236de 7     IResponseFactory,
d7f34b 8     IRequestExtensions,
ee117e 9     IRootFactory,
CM 10     ISessionFactory,
11     )
5bf23f 12
0bee84 13 from pyramid.router import default_execution_policy
5bf23f 14 from pyramid.traversal import DefaultRootFactory
d8d3a9 15
CM 16 from pyramid.util import (
1e0d64 17     get_callable_name,
04cc91 18     InstancePropertyHelper,
d8d3a9 19     )
1e0d64 20
52fde9 21 from pyramid.config.util import action_method
5bf23f 22
CM 23 class FactoriesConfiguratorMixin(object):
24     @action_method
ea824f 25     def set_root_factory(self, factory):
5bf23f 26         """ Add a :term:`root factory` to the current configuration
CM 27         state.  If the ``factory`` argument is ``None`` a default root
adfc23 28         factory will be registered.
CM 29
012b97 30         .. note::
M 31
32            Using the ``root_factory`` argument to the
33            :class:`pyramid.config.Configurator` constructor can be used to
34            achieve the same purpose.
adfc23 35         """
5bf23f 36         factory = self.maybe_dotted(factory)
CM 37         if factory is None:
38             factory = DefaultRootFactory
1e0d64 39
5bf23f 40         def register():
CM 41             self.registry.registerUtility(factory, IRootFactory)
1e0d64 42             self.registry.registerUtility(factory, IDefaultRootFactory)  # b/c
3b5ccb 43
522405 44         intr = self.introspectable('root factories',
CM 45                                    None,
8b6f09 46                                    self.object_description(factory),
5e92f3 47                                    'root factory')
3b5ccb 48         intr['factory'] = factory
CM 49         self.action(IRootFactory, register, introspectables=(intr,))
5bf23f 50
1e0d64 51     _set_root_factory = set_root_factory  # bw compat
ea824f 52
5bf23f 53     @action_method
5e92f3 54     def set_session_factory(self, factory):
5bf23f 55         """
637bda 56         Configure the application with a :term:`session factory`.  If this
5e92f3 57         method is called, the ``factory`` argument must be a session
637bda 58         factory callable or a :term:`dotted Python name` to that factory.
5bf23f 59
012b97 60         .. note::
M 61
62            Using the ``session_factory`` argument to the
63            :class:`pyramid.config.Configurator` constructor can be used to
64            achieve the same purpose.
5bf23f 65         """
5e92f3 66         factory = self.maybe_dotted(factory)
1e0d64 67
5bf23f 68         def register():
5e92f3 69             self.registry.registerUtility(factory, ISessionFactory)
8b6f09 70         intr = self.introspectable('session factory', None,
CM 71                                    self.object_description(factory),
5e92f3 72                                    'session factory')
CM 73         intr['factory'] = factory
3b5ccb 74         self.action(ISessionFactory, register, introspectables=(intr,))
5bf23f 75
CM 76     @action_method
77     def set_request_factory(self, factory):
78         """ The object passed as ``factory`` should be an object (or a
79         :term:`dotted Python name` which refers to an object) which
80         will be used by the :app:`Pyramid` router to create all
81         request objects.  This factory object must have the same
82         methods and attributes as the
83         :class:`pyramid.request.Request` class (particularly
84         ``__call__``, and ``blank``).
85
e0c4bd 86         See :meth:`pyramid.config.Configurator.add_request_method`
6c2e8f 87         for a less intrusive way to extend the request objects with
e0c4bd 88         custom methods and properties.
6c2e8f 89
012b97 90         .. note::
M 91
92            Using the ``request_factory`` argument to the
5bf23f 93            :class:`pyramid.config.Configurator` constructor
CM 94            can be used to achieve the same purpose.
95         """
96         factory = self.maybe_dotted(factory)
1e0d64 97
5bf23f 98         def register():
CM 99             self.registry.registerUtility(factory, IRequestFactory)
8b6f09 100         intr = self.introspectable('request factory', None,
CM 101                                    self.object_description(factory),
5e92f3 102                                    'request factory')
3b5ccb 103         intr['factory'] = factory
CM 104         self.action(IRequestFactory, register, introspectables=(intr,))
5bf23f 105
74d503 106     @action_method
1236de 107     def set_response_factory(self, factory):
JA 108         """ The object passed as ``factory`` should be an object (or a
109         :term:`dotted Python name` which refers to an object) which
110         will be used by the :app:`Pyramid` as the default response
da5f5f 111         objects. The factory should conform to the
MM 112         :class:`pyramid.interfaces.IResponseFactory` interface.
1236de 113
JA 114         .. note::
115
116            Using the ``response_factory`` argument to the
117            :class:`pyramid.config.Configurator` constructor
118            can be used to achieve the same purpose.
119         """
120         factory = self.maybe_dotted(factory)
121
122         def register():
123             self.registry.registerUtility(factory, IResponseFactory)
124
125         intr = self.introspectable('response factory', None,
126                                    self.object_description(factory),
127                                    'response factory')
128         intr['factory'] = factory
129         self.action(IResponseFactory, register, introspectables=(intr,))
130
131     @action_method
023c88 132     def add_request_method(self,
d7f34b 133                            callable=None,
MM 134                            name=None,
b940e4 135                            property=False,
MM 136                            reify=False):
d7f34b 137         """ Add a property or method to the request object.
74d503 138
d7f34b 139         When adding a method to the request, ``callable`` may be any
MM 140         function that receives the request object as the first
141         parameter. If ``name`` is ``None`` then it will be computed
142         from the name of the ``callable``.
143
144         When adding a property to the request, ``callable`` can either
145         be a callable that accepts the request as its single positional
f32dac 146         parameter, or it can be a property descriptor. If ``callable`` is
e33241 147         a property descriptor, it has to be an instance of a class which is
f32dac 148         a subclass of ``property``. If ``name`` is ``None``, the name of
JW 149         the property will be computed from the name of the ``callable``.
74d503 150
MM 151         If the ``callable`` is a property descriptor a ``ValueError``
152         will be raised if ``name`` is ``None`` or ``reify`` is ``True``.
153
154         See :meth:`pyramid.request.Request.set_property` for more
d7f34b 155         details on ``property`` vs ``reify``. When ``reify`` is
MM 156         ``True``, the value of ``property`` is assumed to also be
157         ``True``.
158
159         In all cases, ``callable`` may also be a
160         :term:`dotted Python name` which refers to either a callable or
161         a property descriptor.
162
163         If ``callable`` is ``None`` then the method is only used to
164         assist in conflict detection between different addons requesting
165         the same attribute on the request object.
74d503 166
MM 167         This is the recommended method for extending the request object
168         and should be used in favor of providing a custom request
169         factory via
170         :meth:`pyramid.config.Configurator.set_request_factory`.
171
d7f34b 172         .. versionadded:: 1.4
74d503 173         """
d7f34b 174         if callable is not None:
MM 175             callable = self.maybe_dotted(callable)
74d503 176
d7f34b 177         property = property or reify
MM 178         if property:
04cc91 179             name, callable = InstancePropertyHelper.make_property(
d7f34b 180                 callable, name=name, reify=reify)
MM 181         elif name is None:
182             name = callable.__name__
1e0d64 183         else:
JA 184             name = get_callable_name(name)
74d503 185
MM 186         def register():
d7f34b 187             exts = self.registry.queryUtility(IRequestExtensions)
74d503 188
d7f34b 189             if exts is None:
MM 190                 exts = _RequestExtensions()
191                 self.registry.registerUtility(exts, IRequestExtensions)
74d503 192
d7f34b 193             plist = exts.descriptors if property else exts.methods
b940e4 194             plist[name] = callable
74d503 195
d7f34b 196         if callable is None:
MM 197             self.action(('request extensions', name), None)
198         elif property:
199             intr = self.introspectable('request extensions', name,
200                                        self.object_description(callable),
201                                        'request property')
202             intr['callable'] = callable
203             intr['property'] = True
204             intr['reify'] = reify
205             self.action(('request extensions', name), register,
206                         introspectables=(intr,))
207         else:
208             intr = self.introspectable('request extensions', name,
209                                        self.object_description(callable),
210                                        'request method')
211             intr['callable'] = callable
212             intr['property'] = False
213             intr['reify'] = False
214             self.action(('request extensions', name), register,
215                         introspectables=(intr,))
ba0593 216
0bee84 217     @action_method
MM 218     def set_execution_policy(self, policy):
219         """
220         Override the :app:`Pyramid` :term:`execution policy` in the
221         current configuration.  The ``policy`` argument must be an instance
222         of an :class:`pyramid.interfaces.IExecutionPolicy` or a
223         :term:`dotted Python name` that points at an instance of an
224         execution policy.
225
226         """
227         policy = self.maybe_dotted(policy)
228         if policy is None:
229             policy = default_execution_policy
230
231         def register():
232             self.registry.registerUtility(policy, IExecutionPolicy)
233
234         intr = self.introspectable('execution policy', None,
235                                    self.object_description(policy),
236                                    'execution policy')
237         intr['policy'] = policy
238         self.action(IExecutionPolicy, register, introspectables=(intr,))
239
1e0d64 240
d7f34b 241 @implementer(IRequestExtensions)
MM 242 class _RequestExtensions(object):
243     def __init__(self):
b940e4 244         self.descriptors = {}
MM 245         self.methods = {}