'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 ``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'

@action_method
def add_request_method(self, callable=None, name=None, property=False, reify=False):

    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,))
