From 26d2d87bc2865a431b5eb30552c3eac4108b3a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Tue, 7 Jan 2020 14:33:31 -0500 Subject: rewrite docs for custom predicates --- docs/narr/hooks.rst | 2 +- docs/narr/urldispatch.rst | 179 ++++++++++++++++++++++--------------------- docs/narr/viewconfig.rst | 18 +++-- docs/quick_tour.rst | 2 +- src/pyramid/config/routes.py | 12 +-- src/pyramid/config/views.py | 12 +-- 6 files changed, 120 insertions(+), 105 deletions(-) diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 4a594a8c9..fbb845447 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1564,7 +1564,7 @@ event type. self.val = val def text(self): - return 'path_startswith = %s' % (self.val,) + return 'request_path_startswith = %s' % (self.val,) phash = text diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 9372163e8..6dd8b1455 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1087,11 +1087,8 @@ A convenience context manager exists to set the route prefix for any Custom Route Predicates ----------------------- -Each of the predicate callables fed to the ``custom_predicates`` argument of -:meth:`~pyramid.config.Configurator.add_route` must be a callable accepting two -arguments. The first argument passed to a custom predicate is a dictionary -conventionally named ``info``. The second argument is the current -:term:`request` object. +A predicate is a callable that accepts two arguments: a dictionary +conventionally named ``info``, and the current :term:`request` object. The ``info`` dictionary has a number of contained values, including ``match`` and ``route``. ``match`` is a dictionary which represents the arguments matched @@ -1100,52 +1097,73 @@ was matched (see :class:`pyramid.interfaces.IRoute` for the API of such a route object). ``info['match']`` is useful when predicates need access to the route match. -For example: +Imagine you want to define a route when a part of the URL matches some +specific values. You could define three view configurations, each one +with its own ``match_param`` value (see :ref:`predicate_view_args`), but +you want to think of it as one route, and associate it with one view. +See this code: .. code-block:: python :linenos: - def any_of(segment_name, *allowed): - def predicate(info, request): - if info['match'][segment_name] in allowed: - return True - return predicate + class AnyOfPredicate: + def __init__(self, val): + self.segment_name = val[0] + self.allowed = tuple(val[0:]) + + def text(self): + args = (self.segment_name,) + self.allowed + return 'any_of = %s' % (args,) + + phash = text + + def __call__(self, info, request): + return info['match'][self.segment_name] in self.allowed + - num_one_two_or_three = any_of('num', 'one', 'two', 'three') + config.add_route_predicate("any_of", AnyOfPredicate) + config.add_route('route_to_num', '/{num}', any_of=('num', 'one', 'two', 'three')) - config.add_route('route_to_num', '/{num}', - custom_predicates=(num_one_two_or_three,)) -The above ``any_of`` function generates a predicate which ensures that the +An instance of the class defined above is a predicate which ensures that the match value named ``segment_name`` is in the set of allowable values -represented by ``allowed``. We use this ``any_of`` function to generate a -predicate function named ``num_one_two_or_three``, which ensures that the -``num`` segment is one of the values ``one``, ``two``, or ``three`` , and use -the result as a custom predicate by feeding it inside a tuple to the -``custom_predicates`` argument to -:meth:`~pyramid.config.Configurator.add_route`. +represented by ``allowed``. We register this class as a *predicate +factory* with the ``any_of`` argument name, then we can use that new +keyword argument with :meth:`~pyramid.config.Configurator.add_route` to +have Pyramid instantiate the class (the ``('num', 'one', 'two', +'three')`` value is passed to the constructor as the argument ``val``) +and use the resulting instance as a custom predicate to check if +incoming requests match the route or not. A custom route predicate may also *modify* the ``match`` dictionary. For instance, a predicate might do some type conversion of values: .. code-block:: python - :linenos: + :linenos: + + class IntegersPredicate: + + def __init__(self, val): + self.segment_names = val + + def text(self): + return 'integers = %s' % (self.segment_names,) - def integers(*segment_names): - def predicate(info, request): - match = info['match'] - for segment_name in segment_names: - try: - match[segment_name] = int(match[segment_name]) - except (TypeError, ValueError): - pass - return True - return predicate + phash = text - ymd_to_int = integers('year', 'month', 'day') + def __call__(self, info, request): + match = info['match'] + for segment_name in self.segment_names: + try: + match[segment_name] = int(match[segment_name]) + except (TypeError, ValueError): + pass + return True - config.add_route('ymd', '/{year}/{month}/{day}', - custom_predicates=(ymd_to_int,)) + + config.add_route_predicate('integers', IntegersPredicate) + config.add_route('ymd', '/{year}/{month}/{day}', + integers=('year', 'month', 'day') Note that a conversion predicate is still a predicate, so it must return ``True`` or ``False``. A predicate that does *only* conversion, such as the one @@ -1157,18 +1175,26 @@ expressions specifying requirements for that marker. For instance: .. code-block:: python :linenos: - def integers(*segment_names): - def predicate(info, request): + class IntegersPredicate: + + def __init__(self, val): + self.segment_names = val + + def text(self): + return 'integers = %s' % (self.segment_names,) + + phash = text + + def __call__(self, info, request): match = info['match'] - for segment_name in segment_names: + for segment_name in self.segment_names: match[segment_name] = int(match[segment_name]) return True - return predicate - ymd_to_int = integers('year', 'month', 'day') + config.add_route_predicate('integers', IntegersPredicate) config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}', - custom_predicates=(ymd_to_int,)) + integers=('year', 'month', 'day') Now the try/except is no longer needed because the route will not match at all unless these markers match ``\d+`` which requires them to be valid digits for @@ -1199,61 +1225,42 @@ route in a set of route predicates: .. code-block:: python :linenos: - def twenty_ten(info, request): - if info['route'].name in ('ymd', 'ym', 'y'): - return info['match']['year'] == '2010' - - config.add_route('y', '/{year}', custom_predicates=(twenty_ten,)) - config.add_route('ym', '/{year}/{month}', custom_predicates=(twenty_ten,)) - config.add_route('ymd', '/{year}/{month}/{day}', - custom_predicates=(twenty_ten,)) - -The above predicate, when added to a number of route configurations ensures -that the year match argument is '2010' if and only if the route name is 'ymd', -'ym', or 'y'. - -You can also caption the predicates by setting the ``__text__`` attribute. This -will help you with the ``pviews`` command (see -:ref:`displaying_application_routes`) and the ``pyramid_debugtoolbar``. - -If a predicate is a class, just add ``__text__`` property in a standard manner. - -.. code-block:: python - :linenos: - - class DummyCustomPredicate1(object): - def __init__(self): - self.__text__ = 'my custom class predicate' + class TwentyTenPredicate: + def text(self): + return "twenty_ten = True" - class DummyCustomPredicate2(object): - __text__ = 'my custom class predicate' + phash = text -If a predicate is a method, you'll need to assign it after method declaration -(see `PEP 232 `_). + def __call__(self, info, request): + if info['route'].name in ('ymd', 'ym', 'y'): + return info['match']['year'] == '2010' -.. code-block:: python - :linenos: + config.add_route_predicate('twenty_ten', TwentyTenPredicate) + config.add_route('y', '/{year}', twenty_ten=True) + config.add_route('ym', '/{year}/{month}', twenty_ten=True) + config.add_route('ymd', '/{year}/{month}/{day}', twenty_ten=True) - def custom_predicate(): - pass - custom_predicate.__text__ = 'my custom method predicate' - -If a predicate is a classmethod, using ``@classmethod`` will not work, but you -can still easily do it by wrapping it in a classmethod call. +The above predicate, when added to a number of route configurations ensures +that the year match argument is ``'2010'`` if and only if the route name is +``'ymd'``, ``'ym'``, or ``'y'``. -.. code-block:: python - :linenos: +The ``text`` method is a way to caption the predicates. This +will help you with the ``pviews`` command (see +:ref:`displaying_application_routes`) and the +:term:`pyramid_debugtoolbar`. - def classmethod_predicate(): - pass - classmethod_predicate.__text__ = 'my classmethod predicate' - classmethod_predicate = classmethod(classmethod_predicate) +The ``phash`` method should return a string that uniquely identifies a +specific predicate (the name means *predicate hash*). A good way to do +that is to use the same argument name and value that in the call to +``add_route``, like in the examples above. -The same will work with ``staticmethod``, using ``staticmethod`` instead of -``classmethod``. +.. XXX add note about predicate matching for boolean custom predicates? .. seealso:: + See :ref:`registering_thirdparty_predicates` for more information about + custom view, route and subscriber predicates. + See also :class:`pyramid.interfaces.IRoute` for more API documentation about route objects. diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 6a49e02a5..eb5233e84 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -317,6 +317,8 @@ Non-Predicate Arguments .. versionadded:: 1.8 +.. _predicate_view_args: + Predicate Arguments +++++++++++++++++++ @@ -506,20 +508,22 @@ configured view. ``custom_predicates`` If ``custom_predicates`` is specified, it must be a sequence of references to - custom predicate callables. Use custom predicates when no set of predefined - predicates do what you need. Custom predicates can be combined with + custom predicate callables. Custom predicates can be combined with predefined predicates as necessary. Each custom predicate callable should accept two arguments, ``context`` and ``request``, and should return either ``True`` or ``False`` after doing arbitrary evaluation of the context resource and/or the request. If all callables return ``True``, the associated view callable will be considered viable for a given request. + This parameter is kept around for backward compatibility. - If ``custom_predicates`` is not specified, no custom predicates are used. + .. deprecated:: 1.5 + See section below for new-style custom predicates. -``predicates`` - Pass a key/value pair here to use a third-party predicate registered via - :meth:`pyramid.config.Configurator.add_view_predicate`. More than one - key/value pair can be used at the same time. See +``**predicates`` + Extra keyword parameters are used to invoke custom predicates, defined + in your app or by third-party packages extending Pyramid and registered via + :meth:`pyramid.config.Configurator.add_view_predicate`. Use custom predicates + when no set of predefined predicates do what you need. See :ref:`view_and_route_predicates` for more information about third-party predicates. diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 062693d24..fdd135331 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -478,7 +478,7 @@ more to offer: - One route leading to multiple views, based on information in the request or data such as ``request_param``, ``request_method``, ``accept``, ``header``, - ``xhr``, ``containment``, and ``custom_predicates`` + ``xhr``, ``containment``, and custom predicates. .. seealso:: See also: :ref:`Quick Tutorial View Classes `, :ref:`Quick diff --git a/src/pyramid/config/routes.py b/src/pyramid/config/routes.py index 44fbb9c46..cc3a87b2e 100644 --- a/src/pyramid/config/routes.py +++ b/src/pyramid/config/routes.py @@ -40,7 +40,7 @@ class RoutesConfiguratorMixin(object): inherit_slash=None, **predicates ): - """ Add a :term:`route configuration` to the current + r""" Add a :term:`route configuration` to the current configuration state, as well as possibly a :term:`view configuration` to be used to specify a :term:`view callable` that will be invoked when this route matches. The arguments @@ -283,6 +283,8 @@ class RoutesConfiguratorMixin(object): .. versionadded:: 1.4a4 + .. deprecated:: 2.0 + custom_predicates .. deprecated:: 1.5 @@ -302,14 +304,14 @@ class RoutesConfiguratorMixin(object): :ref:`custom_route_predicates` for more information about ``info``. - predicates + \*\*predicates - Pass a key/value pair here to use a third-party predicate + Pass extra keyword parameters to use custom or third-party predicates registered via :meth:`pyramid.config.Configurator.add_route_predicate`. More than - one key/value pair can be used at the same time. See + one custom predicate can be used at the same time. See :ref:`view_and_route_predicates` for more information about - third-party predicates. + custom predicates. .. versionadded:: 1.4 diff --git a/src/pyramid/config/views.py b/src/pyramid/config/views.py index 2cc5e8144..20f20b5e8 100644 --- a/src/pyramid/config/views.py +++ b/src/pyramid/config/views.py @@ -266,7 +266,7 @@ class ViewsConfiguratorMixin(object): exception_only=False, **view_options ): - """ Add a :term:`view configuration` to the current + r""" Add a :term:`view configuration` to the current configuration state. Arguments to ``add_view`` are broken down below into *predicate* arguments and *non-predicate* arguments. Predicate arguments narrow the circumstances in @@ -723,6 +723,8 @@ class ViewsConfiguratorMixin(object): .. versionadded:: 1.4a4 + .. deprecated:: 2.0 + custom_predicates .. deprecated:: 1.5 @@ -740,14 +742,14 @@ class ViewsConfiguratorMixin(object): obsoletes this argument, but it is kept around for backwards compatibility. - view_options + \*\*view_options - Pass a key/value pair here to use a third-party predicate or set a - value for a view deriver. See + Pass extra keyword parameters to use custom or third-party predicates + or set a value for a view deriver. See :meth:`pyramid.config.Configurator.add_view_predicate` and :meth:`pyramid.config.Configurator.add_view_deriver`. See :ref:`view_and_route_predicates` for more information about - third-party predicates and :ref:`view_derivers` for information + custom predicates and :ref:`view_derivers` for information about view derivers. .. versionadded: 1.4a1 -- cgit v1.2.3 From b8e1e9191005fbf72427d42eab68b8433fc42949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Wed, 8 Jan 2020 04:35:56 -0500 Subject: first batch of fixes from code review Co-Authored-By: Steve Piercy --- docs/narr/urldispatch.rst | 6 +++--- docs/narr/viewconfig.rst | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 6dd8b1455..dab6a42ec 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1163,7 +1163,7 @@ instance, a predicate might do some type conversion of values: config.add_route_predicate('integers', IntegersPredicate) config.add_route('ymd', '/{year}/{month}/{day}', - integers=('year', 'month', 'day') + integers=('year', 'month', 'day')) Note that a conversion predicate is still a predicate, so it must return ``True`` or ``False``. A predicate that does *only* conversion, such as the one @@ -1194,7 +1194,7 @@ expressions specifying requirements for that marker. For instance: config.add_route_predicate('integers', IntegersPredicate) config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}', - integers=('year', 'month', 'day') + integers=('year', 'month', 'day')) Now the try/except is no longer needed because the route will not match at all unless these markers match ``\d+`` which requires them to be valid digits for @@ -1259,7 +1259,7 @@ that is to use the same argument name and value that in the call to .. seealso:: See :ref:`registering_thirdparty_predicates` for more information about - custom view, route and subscriber predicates. + custom view, route, and subscriber predicates. See also :class:`pyramid.interfaces.IRoute` for more API documentation about route objects. diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index eb5233e84..3e596b030 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -517,7 +517,7 @@ configured view. This parameter is kept around for backward compatibility. .. deprecated:: 1.5 - See section below for new-style custom predicates. + See section below for new-style custom predicates. ``**predicates`` Extra keyword parameters are used to invoke custom predicates, defined -- cgit v1.2.3 From e8890336d1738fb736398356989504f6eb2e8237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sat, 11 Jan 2020 17:02:09 -0500 Subject: second batch of changes --- docs/narr/urldispatch.rst | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index dab6a42ec..df79a645a 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1121,22 +1121,20 @@ See this code: return info['match'][self.segment_name] in self.allowed - config.add_route_predicate("any_of", AnyOfPredicate) + config.add_route_predicate('any_of', AnyOfPredicate) config.add_route('route_to_num', '/{num}', any_of=('num', 'one', 'two', 'three')) -An instance of the class defined above is a predicate which ensures that the -match value named ``segment_name`` is in the set of allowable values -represented by ``allowed``. We register this class as a *predicate -factory* with the ``any_of`` argument name, then we can use that new -keyword argument with :meth:`~pyramid.config.Configurator.add_route` to -have Pyramid instantiate the class (the ``('num', 'one', 'two', -'three')`` value is passed to the constructor as the argument ``val``) -and use the resulting instance as a custom predicate to check if -incoming requests match the route or not. +We register this class as a :term:`predicate factory` with the ``any_of`` keyword argument name. +Then we use that new keyword argument with :meth:`~pyramid.config.Configurator.add_route`. +When the route is requested, Pyramid instantiates the ``AnyOfPredicate`` class using the value passed to the ``any_of`` +argument. The resulting instance is a :term:`predicate`. It will determine whether incoming requests satisfy its condition. +In the example above, a request for ``/three`` would match the route's URL pattern and satisfy the route's predicate +because ``three`` is one of the allowed values, so the route would be matched. However a request for ``/millions`` will +match the route's URL pattern but would not satisfy the route's predicate, and the route would not be matched. -A custom route predicate may also *modify* the ``match`` dictionary. For -instance, a predicate might do some type conversion of values: +A custom route predicate may also *modify* the ``match`` dictionary. +For instance, a predicate might do some type conversion of values: .. code-block:: python :linenos: @@ -1240,21 +1238,16 @@ route in a set of route predicates: config.add_route('ym', '/{year}/{month}', twenty_ten=True) config.add_route('ymd', '/{year}/{month}/{day}', twenty_ten=True) -The above predicate, when added to a number of route configurations ensures -that the year match argument is ``'2010'`` if and only if the route name is -``'ymd'``, ``'ym'``, or ``'y'``. +The above predicate, when added to a number of route configurations ensures that the year match +argument is ``2010`` if and only if the route name is ``ymd``, ``ym``, or ``y``. -The ``text`` method is a way to caption the predicates. This -will help you with the ``pviews`` command (see -:ref:`displaying_application_routes`) and the -:term:`pyramid_debugtoolbar`. +The ``text`` method is a way to caption the predicates. This will help you with the ``pviews`` +command (see :ref:`displaying_application_routes`) and the :term:`pyramid_debugtoolbar`. -The ``phash`` method should return a string that uniquely identifies a -specific predicate (the name means *predicate hash*). A good way to do -that is to use the same argument name and value that in the call to -``add_route``, like in the examples above. +The ``phash`` ("predicate hash") method should return a string that uniquely identifies a specific predicate. +A good way to do that is to use the same argument name and value that are in the call to ``add_route``, +like in the examples above. -.. XXX add note about predicate matching for boolean custom predicates? .. seealso:: -- cgit v1.2.3 From d480c0fe653da0eb265c9ad7edfafc817848caa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sat, 11 Jan 2020 17:39:59 -0500 Subject: change section title --- docs/glossary.rst | 2 +- docs/narr/hooks.rst | 6 +++--- docs/narr/urldispatch.rst | 2 +- docs/whatsnew-1.4.rst | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/glossary.rst b/docs/glossary.rst index 61ba34f45..7137f14a4 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -1091,7 +1091,7 @@ Glossary predicate factory A callable which is used by a third party during the registration of a route, view, or subscriber predicates to extend the configuration - system. See :ref:`registering_thirdparty_predicates` for more + system. See :ref:`registering_custom_predicates` for more information. add-on diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index fbb845447..b6b103eb3 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1416,10 +1416,10 @@ The ``ptweens`` command-line utility can be used to report the current implicit and explicit tween chains used by an application. See :ref:`displaying_tweens`. -.. _registering_thirdparty_predicates: +.. _registering_curstom_predicates: -Adding a Third Party View, Route, or Subscriber Predicate ---------------------------------------------------------- +Adding a Custom View, Route, or Subscriber Predicate +---------------------------------------------------- .. versionadded:: 1.4 diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index df79a645a..c178dd4ce 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1251,7 +1251,7 @@ like in the examples above. .. seealso:: - See :ref:`registering_thirdparty_predicates` for more information about + See :ref:`registering_custom_predicates` for more information about custom view, route, and subscriber predicates. See also :class:`pyramid.interfaces.IRoute` for more API documentation diff --git a/docs/whatsnew-1.4.rst b/docs/whatsnew-1.4.rst index fce889854..6c9a9bf9b 100644 --- a/docs/whatsnew-1.4.rst +++ b/docs/whatsnew-1.4.rst @@ -31,7 +31,7 @@ Third-Party Predicates Similar features exist for :meth:`pyramid.config.Configurator.add_route`, and :meth:`pyramid.config.Configurator.add_subscriber`. See - :ref:`registering_thirdparty_predicates` for more information. + :ref:`registering_custom_predicates` for more information. Easy Custom JSON Serialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From ad65078469770bc698b7b4a0a5634b3895aab971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sat, 11 Jan 2020 18:21:56 -0500 Subject: replace "third-party" with "custom" --- HISTORY.rst | 2 +- docs/narr/hooks.rst | 2 +- docs/narr/viewconfig.rst | 2 +- docs/quick_tour.rst | 4 ++-- src/pyramid/config/routes.py | 5 ++--- src/pyramid/config/views.py | 15 ++++++--------- 6 files changed, 13 insertions(+), 17 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 4fd13119d..8b0028065 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -2530,7 +2530,7 @@ Features @view_config(abc=1) Similar features exist for ``add_route``, and ``add_subscriber``. See - "Adding A Third Party View, Route, or Subscriber Predicate" in the Hooks + "Adding A Custom View, Route, or Subscriber Predicate" in the Hooks chapter for more information. Note that changes made to support the above feature now means that only diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index b6b103eb3..4632c2c0a 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1446,7 +1446,7 @@ Likewise, a similar predicate can be used as a *route* predicate: config.add_route('name', '/foo', request_method='POST') Many other built-in predicates exists (``request_param``, and others). You can -add third-party predicates to the list of available predicates by using one of +add custom predicates to the list of available predicates by using one of :meth:`pyramid.config.Configurator.add_view_predicate` or :meth:`pyramid.config.Configurator.add_route_predicate`. The former adds a view predicate, the latter a route predicate. diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 3e596b030..5ba965def 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -524,7 +524,7 @@ configured view. in your app or by third-party packages extending Pyramid and registered via :meth:`pyramid.config.Configurator.add_view_predicate`. Use custom predicates when no set of predefined predicates do what you need. See - :ref:`view_and_route_predicates` for more information about third-party + :ref:`view_and_route_predicates` for more information about custom predicates. .. versionadded:: 1.4a1 diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index fdd135331..511868ade 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -482,8 +482,8 @@ more to offer: .. seealso:: See also: :ref:`Quick Tutorial View Classes `, :ref:`Quick - Tutorial More View Classes `, and - :ref:`class_as_view`. + Tutorial More View Classes `, :ref:`class_as_view`, + :ref:`view_and_route_predicates`. Quick project startup with cookiecutters diff --git a/src/pyramid/config/routes.py b/src/pyramid/config/routes.py index cc3a87b2e..a508f69a4 100644 --- a/src/pyramid/config/routes.py +++ b/src/pyramid/config/routes.py @@ -306,8 +306,7 @@ class RoutesConfiguratorMixin(object): \*\*predicates - Pass extra keyword parameters to use custom or third-party predicates - registered via + Pass extra keyword parameters to use custom predicates registered via :meth:`pyramid.config.Configurator.add_route_predicate`. More than one custom predicate can be used at the same time. See :ref:`view_and_route_predicates` for more information about @@ -323,7 +322,7 @@ class RoutesConfiguratorMixin(object): 'Configurator.add_route is deprecated as of Pyramid 1.5. ' 'Use "config.add_route_predicate" and use the registered ' 'route predicate as a predicate argument to add_route ' - 'instead. See "Adding A Third Party View, Route, or ' + 'instead. See "Adding A Custom View, Route, or ' 'Subscriber Predicate" in the "Hooks" chapter of the ' 'documentation for more information.' ), diff --git a/src/pyramid/config/views.py b/src/pyramid/config/views.py index 20f20b5e8..bbc4fc5bc 100644 --- a/src/pyramid/config/views.py +++ b/src/pyramid/config/views.py @@ -729,22 +729,19 @@ class ViewsConfiguratorMixin(object): .. deprecated:: 1.5 This value should be a sequence of references to custom - predicate callables. Use custom predicates when no set of - predefined predicates do what you need. Custom predicates - can be combined with predefined predicates as necessary. - Each custom predicate callable should accept two arguments: + predicate callables. Each custom predicate callable + should accept two arguments: ``context`` and ``request`` and should return either ``True`` or ``False`` after doing arbitrary evaluation of - the context and/or the request. The ``predicates`` argument - to this method and the ability to register third-party view - predicates via + the context and/or the request. The ability to register + custom view predicates via :meth:`pyramid.config.Configurator.add_view_predicate` obsoletes this argument, but it is kept around for backwards compatibility. \*\*view_options - Pass extra keyword parameters to use custom or third-party predicates + Pass extra keyword parameters to use custom predicates or set a value for a view deriver. See :meth:`pyramid.config.Configurator.add_view_predicate` and :meth:`pyramid.config.Configurator.add_view_deriver`. See @@ -771,7 +768,7 @@ class ViewsConfiguratorMixin(object): 'Configurator.add_view is deprecated as of Pyramid 1.5. ' 'Use "config.add_view_predicate" and use the registered ' 'view predicate as a predicate argument to add_view ' - 'instead. See "Adding A Third Party View, Route, or ' + 'instead. See "Adding A Custom View, Route, or ' 'Subscriber Predicate" in the "Hooks" chapter of the ' 'documentation for more information.' ), -- cgit v1.2.3 From c1e150d765e33d92ad4d6d5912207ce3ba20991e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sat, 11 Jan 2020 18:22:21 -0500 Subject: remove obsolete bit --- src/pyramid/config/routes.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/pyramid/config/routes.py b/src/pyramid/config/routes.py index a508f69a4..4077ec96b 100644 --- a/src/pyramid/config/routes.py +++ b/src/pyramid/config/routes.py @@ -40,12 +40,9 @@ class RoutesConfiguratorMixin(object): inherit_slash=None, **predicates ): - r""" Add a :term:`route configuration` to the current - configuration state, as well as possibly a :term:`view - configuration` to be used to specify a :term:`view callable` - that will be invoked when this route matches. The arguments - to this method are divided into *predicate*, *non-predicate*, - and *view-related* types. :term:`Route predicate` arguments + r""" Add a :term:`route configuration` to the current configuration state. + The arguments to this method are divided into *predicate* and + *non-predicate* types. :term:`Route predicate` arguments narrow the circumstances in which a route will be match a request; non-predicate arguments are informational. -- cgit v1.2.3 From 517140bac948e9a8bb60ad4c0c80bf45cd2741f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sat, 11 Jan 2020 18:27:43 -0500 Subject: fix typo --- docs/narr/hooks.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 4632c2c0a..c19d26236 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1416,7 +1416,7 @@ The ``ptweens`` command-line utility can be used to report the current implicit and explicit tween chains used by an application. See :ref:`displaying_tweens`. -.. _registering_curstom_predicates: +.. _registering_custom_predicates: Adding a Custom View, Route, or Subscriber Predicate ---------------------------------------------------- -- cgit v1.2.3 From 04440d29082bbbae34fb76b9a8de083d1056e878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Tue, 14 Jan 2020 17:05:02 -0500 Subject: apply more review fixes, minimize some diffs --- docs/narr/urldispatch.rst | 21 +++++++++++++-------- docs/quick_tour.rst | 2 +- src/pyramid/config/routes.py | 10 +++++----- src/pyramid/config/views.py | 4 ++-- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index c178dd4ce..83a186aea 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1107,7 +1107,7 @@ See this code: :linenos: class AnyOfPredicate: - def __init__(self, val): + def __init__(self, val, info): self.segment_name = val[0] self.allowed = tuple(val[0:]) @@ -1127,21 +1127,23 @@ See this code: We register this class as a :term:`predicate factory` with the ``any_of`` keyword argument name. Then we use that new keyword argument with :meth:`~pyramid.config.Configurator.add_route`. -When the route is requested, Pyramid instantiates the ``AnyOfPredicate`` class using the value passed to the ``any_of`` -argument. The resulting instance is a :term:`predicate`. It will determine whether incoming requests satisfy its condition. +When the route is requested, Pyramid instantiates the ``AnyOfPredicate`` class using the value passed to the ``any_of`` argument. +The resulting instance is a :term:`predicate`. +It will determine whether incoming requests satisfy its condition. In the example above, a request for ``/three`` would match the route's URL pattern and satisfy the route's predicate -because ``three`` is one of the allowed values, so the route would be matched. However a request for ``/millions`` will +because ``three`` is one of the allowed values, so the route would be matched. +However a request for ``/millions`` will match the route's URL pattern but would not satisfy the route's predicate, and the route would not be matched. -A custom route predicate may also *modify* the ``match`` dictionary. -For instance, a predicate might do some type conversion of values: +A custom route predicate may also *modify* the ``match`` dictionary. For +instance, a predicate might do some type conversion of values: .. code-block:: python :linenos: class IntegersPredicate: - def __init__(self, val): + def __init__(self, val, info): self.segment_names = val def text(self): @@ -1175,7 +1177,7 @@ expressions specifying requirements for that marker. For instance: class IntegersPredicate: - def __init__(self, val): + def __init__(self, val, info): self.segment_names = val def text(self): @@ -1224,6 +1226,9 @@ route in a set of route predicates: :linenos: class TwentyTenPredicate: + def __init__(self, val, info): + pass + def text(self): return "twenty_ten = True" diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 511868ade..49b61329e 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -483,7 +483,7 @@ more to offer: .. seealso:: See also: :ref:`Quick Tutorial View Classes `, :ref:`Quick Tutorial More View Classes `, :ref:`class_as_view`, - :ref:`view_and_route_predicates`. + and :ref:`view_and_route_predicates`. Quick project startup with cookiecutters diff --git a/src/pyramid/config/routes.py b/src/pyramid/config/routes.py index 4077ec96b..78e708d1e 100644 --- a/src/pyramid/config/routes.py +++ b/src/pyramid/config/routes.py @@ -40,10 +40,10 @@ class RoutesConfiguratorMixin(object): inherit_slash=None, **predicates ): - r""" Add a :term:`route configuration` to the current configuration state. - The arguments to this method are divided into *predicate* and - *non-predicate* types. :term:`Route predicate` arguments - narrow the circumstances in which a route will be match a + """ Add a :term:`route configuration` to the current configuration + state. Arguments to ``add_route`` are divided into *predicate* + and *non-predicate* types. :term:`Route predicate` arguments + narrow the circumstances in which a route will match a request; non-predicate arguments are informational. Non-Predicate Arguments @@ -301,7 +301,7 @@ class RoutesConfiguratorMixin(object): :ref:`custom_route_predicates` for more information about ``info``. - \*\*predicates + \\*\\*predicates Pass extra keyword parameters to use custom predicates registered via :meth:`pyramid.config.Configurator.add_route_predicate`. More than diff --git a/src/pyramid/config/views.py b/src/pyramid/config/views.py index bbc4fc5bc..c4fb54dd8 100644 --- a/src/pyramid/config/views.py +++ b/src/pyramid/config/views.py @@ -266,7 +266,7 @@ class ViewsConfiguratorMixin(object): exception_only=False, **view_options ): - r""" Add a :term:`view configuration` to the current + """ Add a :term:`view configuration` to the current configuration state. Arguments to ``add_view`` are broken down below into *predicate* arguments and *non-predicate* arguments. Predicate arguments narrow the circumstances in @@ -739,7 +739,7 @@ class ViewsConfiguratorMixin(object): obsoletes this argument, but it is kept around for backwards compatibility. - \*\*view_options + \\*\\*view_options Pass extra keyword parameters to use custom predicates or set a value for a view deriver. See -- cgit v1.2.3 From e71e4fc111fe8846ba5050557e6d0e74cd3ce643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Tue, 14 Jan 2020 17:12:45 -0500 Subject: make two missed lines even longer --- docs/narr/urldispatch.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 83a186aea..c41224e99 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1130,10 +1130,8 @@ Then we use that new keyword argument with :meth:`~pyramid.config.Configurator.a When the route is requested, Pyramid instantiates the ``AnyOfPredicate`` class using the value passed to the ``any_of`` argument. The resulting instance is a :term:`predicate`. It will determine whether incoming requests satisfy its condition. -In the example above, a request for ``/three`` would match the route's URL pattern and satisfy the route's predicate -because ``three`` is one of the allowed values, so the route would be matched. -However a request for ``/millions`` will -match the route's URL pattern but would not satisfy the route's predicate, and the route would not be matched. +In the example above, a request for ``/three`` would match the route's URL pattern and satisfy the route's predicate because ``three`` is one of the allowed values, so the route would be matched. +However a request for ``/millions`` will match the route's URL pattern but would not satisfy the route's predicate, and the route would not be matched. A custom route predicate may also *modify* the ``match`` dictionary. For instance, a predicate might do some type conversion of values: -- cgit v1.2.3 From d741e9baca9c6aa76158341aae4b4310b3745b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Wed, 15 Jan 2020 13:42:29 -0500 Subject: better wording --- docs/narr/urldispatch.rst | 2 -- docs/quick_tour.rst | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index c41224e99..9c1495df1 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1140,7 +1140,6 @@ instance, a predicate might do some type conversion of values: :linenos: class IntegersPredicate: - def __init__(self, val, info): self.segment_names = val @@ -1174,7 +1173,6 @@ expressions specifying requirements for that marker. For instance: :linenos: class IntegersPredicate: - def __init__(self, val, info): self.segment_names = val diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 49b61329e..c4ab0b3e8 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -481,9 +481,8 @@ more to offer: ``xhr``, ``containment``, and custom predicates. .. seealso:: See also: - :ref:`Quick Tutorial View Classes `, :ref:`Quick - Tutorial More View Classes `, :ref:`class_as_view`, - and :ref:`view_and_route_predicates`. + :ref:`View Classes ` and :ref:`More View Classes ` + in the Quick Tutorial, :ref:`class_as_view`, and :ref:`view_and_route_predicates`. Quick project startup with cookiecutters -- cgit v1.2.3 From 36164ac5a88a8b878d9c62c652bea840d3e9e461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Fri, 17 Jan 2020 16:04:45 -0500 Subject: say something about the predicate factory info arg --- docs/narr/urldispatch.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 9c1495df1..bc2509e3f 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1128,6 +1128,7 @@ See this code: We register this class as a :term:`predicate factory` with the ``any_of`` keyword argument name. Then we use that new keyword argument with :meth:`~pyramid.config.Configurator.add_route`. When the route is requested, Pyramid instantiates the ``AnyOfPredicate`` class using the value passed to the ``any_of`` argument. +(The ``info`` parameter passed to the factory contains some metadata, you can ignore it for now.) The resulting instance is a :term:`predicate`. It will determine whether incoming requests satisfy its condition. In the example above, a request for ``/three`` would match the route's URL pattern and satisfy the route's predicate because ``three`` is one of the allowed values, so the route would be matched. -- cgit v1.2.3 From 108f026e1dcca554867ff8f7a211a5ce0668a26e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Fri, 17 Jan 2020 16:27:55 -0500 Subject: avoid invalid escape warning --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index bc2509e3f..684e64395 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1190,7 +1190,7 @@ expressions specifying requirements for that marker. For instance: config.add_route_predicate('integers', IntegersPredicate) - config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}', + config.add_route('ymd', r'/{year:\d+}/{month:\d+}/{day:\d+}', integers=('year', 'month', 'day')) Now the try/except is no longer needed because the route will not match at all -- cgit v1.2.3