Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: mmerickel/pyramid
...
head fork: mmerickel/pyramid
  • 6 commits
  • 3 files changed
  • 0 commit comments
  • 2 contributors
Showing with 99 additions and 33 deletions.
  1. +3 −0  CHANGES.txt
  2. +89 −30 pyramid/config/factories.py
  3. +7 −3 pyramid/interfaces.py
View
3  CHANGES.txt
@@ -26,3 +26,6 @@ Features
``@view_config(request_method=('GET', 'HEAD', 'POST')``. This is because
HEAD is a variant of GET that omits the body, and WebOb has special support
to return an empty body when a HEAD is used.
+
+- ``config.set_request_property`` now causes less code to be executed at
+ request construction time.
View
119 pyramid/config/factories.py
@@ -1,10 +1,12 @@
+from zope.interface import implementer
+
from pyramid.config.util import action_method
from pyramid.interfaces import (
IDefaultRootFactory,
INewRequest,
IRequestFactory,
- IRequestProperties,
+ IRequestExtensions,
IRootFactory,
ISessionFactory,
)
@@ -93,55 +95,112 @@ def register():
self.action(IRequestFactory, register, introspectables=(intr,))
@action_method
- def set_request_property(self, callable, name=None, reify=False):
- """ Add a property to the request object.
+ def set_request_method(self,
+ callable=None,
+ name=None,
+ property=None,
+ reify=None):
+ """ 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``.
- ``callable`` can either be a callable that accepts the request
- as its single positional parameter, or it can be a property
- descriptor. It may also be a :term:`dotted Python name` which
- refers to either a callable or a property descriptor.
+ 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 ``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``.
- If ``name`` is None, the name of the property will be computed
- from the name of the ``callable``.
-
See :meth:`pyramid.request.Request.set_property` for more
- information on its usage.
+ 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.3
+ .. versionadded:: 1.4
"""
- callable = self.maybe_dotted(callable)
+ if callable is not None:
+ callable = self.maybe_dotted(callable)
- name, callable = InstancePropertyMixin._make_property(
- callable, name=name, reify=reify)
+ property = property or reify
+ if property:
+ name, callable = InstancePropertyMixin._make_property(
+ callable, name=name, reify=reify)
+ elif name is None:
+ name = callable.__name__
def register():
- plist = self.registry.queryUtility(IRequestProperties)
+ exts = self.registry.queryUtility(IRequestExtensions)
- if plist is None:
- plist = []
- self.registry.registerUtility(plist, IRequestProperties)
- self.registry.registerHandler(_set_request_properties,
+ if exts is None:
+ exts = _RequestExtensions()
+ self.registry.registerUtility(exts, IRequestExtensions)
+ self.registry.registerHandler(_set_request_extensions,
(INewRequest,))
+ plist = exts.descriptors if property else exts.methods
plist.append((name, callable))
- intr = self.introspectable('request properties', name,
- self.object_description(callable),
- 'request property')
- intr['callable'] = callable
- intr['reify'] = reify
- self.action(('request properties', name), register,
- introspectables=(intr,))
+ 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_request_property(self, callable, name=None, reify=False):
+ """ Add a property to the request object.
+
+ This method has been superceded by
+ :meth:`pyramid.config.Configurator.set_request_method` in
+ version 1.4, more details can be found there.
+
+ .. versionadded:: 1.3
+ """
+ self.set_request_method(
+ callable, name=name, property=not reify, reify=reify)
+
+@implementer(IRequestExtensions)
+class _RequestExtensions(object):
+ def __init__(self):
+ self.descriptors = []
+ self.methods = []
-def _set_request_properties(event):
+def _set_request_extensions(event):
request = event.request
- plist = request.registry.queryUtility(IRequestProperties)
- request._set_properties(plist)
+ exts = request.registry.queryUtility(IRequestExtensions)
+ for name, method in exts.methods:
+ setattr(request, name, method)
+ request._set_properties(exts.descriptors)
View
10 pyramid/interfaces.py
@@ -513,9 +513,13 @@ def __call__(self, request):
IRequest.combined = IRequest # for exception view lookups
-class IRequestProperties(Interface):
- """ Marker interface for storing a list of request properties which
- will be added to the request object."""
+class IRequestExtensions(Interface):
+ """ Marker interface for storing request extensions (properties and
+ methods) which will be added to the request object."""
+ descriptors = Attribute(
+ """A list of descriptors that will be added to each request.""")
+ methods = Attribute(
+ """A list of methods to be added to each request.""")
class IRouteRequest(Interface):
""" *internal only* interface used as in a utility lookup to find

No commit comments for this range

Something went wrong with that request. Please try again.