From c4503bf117e43f780c269e64edbde71fc3d6d72b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 01:56:17 -0500 Subject: break out 'extending config' into exconfig and add stuff about the action method; move startup and router chapters to earlier in toc --- docs/narr/extconfig.rst | 219 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 docs/narr/extconfig.rst (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst new file mode 100644 index 000000000..4a0db85de --- /dev/null +++ b/docs/narr/extconfig.rst @@ -0,0 +1,219 @@ +.. index:: + single: extending configuration + +.. _extconfig_narr: + +Extending Pyramid Configuration +=============================== + +Pyramid allows you to extend its Configurator with custom directives. These +directives can add an :term:`action`, participate in :term:`conflict +resolution`, and can provide some number of :term:`introspectable` objects. + +.. index:: + single: add_directive + pair: configurator; adding directives + +.. _add_directive: + +Adding Methods to the Configurator via ``add_directive`` +-------------------------------------------------------- + +Framework extension writers can add arbitrary methods to a +:term:`Configurator` by using the +:meth:`pyramid.config.Configurator.add_directive` method of the configurator. +Using :meth:`~pyramid.config.Configurator.add_directive` makes it possible to +extend a Pyramid configurator in arbitrary ways, and allows it to perform +application-specific tasks more succinctly. + +The :meth:`~pyramid.config.Configurator.add_directive` method accepts two +positional arguments: a method name and a callable object. The callable +object is usually a function that takes the configurator instance as its +first argument and accepts other arbitrary positional and keyword arguments. +For example: + +.. code-block:: python + :linenos: + + from pyramid.events import NewRequest + from pyramid.config import Configurator + + def add_newrequest_subscriber(config, subscriber): + config.add_subscriber(subscriber, NewRequest). + + if __name__ == '__main__': + config = Configurator() + config.add_directive('add_newrequest_subscriber', + add_newrequest_subscriber) + +Once :meth:`~pyramid.config.Configurator.add_directive` is called, a user can +then call the added directive by its given name as if it were a built-in +method of the Configurator: + +.. code-block:: python + :linenos: + + def mysubscriber(event): + print event.request + + config.add_newrequest_subscriber(mysubscriber) + +A call to :meth:`~pyramid.config.Configurator.add_directive` is often +"hidden" within an ``includeme`` function within a "frameworky" package meant +to be included as per :ref:`including_configuration` via +:meth:`~pyramid.config.Configurator.include`. For example, if you put this +code in a package named ``pyramid_subscriberhelpers``: + +.. code-block:: python + :linenos: + + def includeme(config) + config.add_directive('add_newrequest_subscriber', + add_newrequest_subscriber) + +The user of the add-on package ``pyramid_subscriberhelpers`` would then be +able to install it and subsequently do: + +.. code-block:: python + :linenos: + + def mysubscriber(event): + print event.request + + from pyramid.config import Configurator + config = Configurator() + config.include('pyramid_subscriberhelpers') + config.add_newrequest_subscriber(mysubscriber) + +Using ``config.action`` in a Directive +-------------------------------------- + +If a custom directive can't do its work exclusively in terms of existing +configurator methods (such as +:meth:`pyramid.config.Configurator.add_subscriber`, as above), the directive +may need to make use of the :meth:`pyramid.config.Configurator.action` +method. This method adds an entry to the list of "actions" that Pyramid will +attempt to process when :meth:`pyramid.config.Configurator.commit` is called. +An action is simply a dictionary that includes a :term:`discriminator`, +possibly a callback function, and possibly other metadata used by Pyramid's +action system. + +Here's an example directive which uses the "action" method: + +.. code-block:: python + :linenos: + + def add_jammyjam(config, jammyjam): + def register(): + config.registry.jammyjam = jammyjam + config.action('jammyjam', register) + + if __name__ == '__main__': + config = Configurator() + config.add_directive('add_jammyjam', add_jammyjam) + +Fancy, but what does it do? The action method accepts a number of arguments. +In the above directive named ``add_jammyjam``, we call +:meth:`~pyramid.config.Configurator.action` with two arguments: the string +``jammyjam`` is passed as the first argument, ``discriminator`` and the +closure function named ``register`` is passed as the second argument, +named ``callable``. + +When the :meth:`~pyramid.config.Configurator.action` method is called, it +appends an action to the list of pending configuration actions. All pending +actions with the same discriminator value are potentially in conflict with +one another (see :ref:`conflict_detection`). When the +:meth:`~pyramid.config.Configurator.commit` method of the Configurator is +called (either explicitly or as the result of calling +:meth:`~pyramid.config.Configurator.make_wsgi_app`), conflicting actions are +potentially automatically resolved as per +:ref:`automatic_conflict_resolution`. If a conflict cannot be automatically +resolved, a ConfigurationConflictError is raised and application startup is +prevented. + +In our above example, therefore, if a consumer of our ``add_jammyjam`` +directive did this: + +.. code-block:: python + :linenos: + + config.add_jammyjam('first') + config.add_jammyjam('second') + +When the action list was committed, the user's application would not start, +because the discriminators of the actions generated by the two calls are in +direct conflict. Automatic conflict resolution cannot resolve the conflict, +and the user provided no intermediate +:meth:`pyramid.config.Configurator.commit` call between the calls to +``add_jammyjam`` to ensure that the successive calls did not conflict with +each other. This is the purpose of the discriminator argument to the action +method: it's used to indicate a uniqueness constraint for an action. Two +actions with the same discriminator will conflict unless the conflict is +automatically or manually resolved. A discriminator can be any hashable +object, but it is generally a string or a tuple. + +But let's imagine that a consumer of ``add_jammyjam`` used it in such a way +that no configuration conflicts are generated. + +.. code-block:: python + :linenos: + + config.add_jammyjam('first') + +What happens then? When the ``add_jammyjam`` method is called, an action is +appended to the pending actions list. When the pending configuration actions +are processed during :meth:`~pyramid.config.Configurator.commit`, and no +conflicts occur, the *callable* provided as the second argument to the +:meth:`~pyramid.config.Configurator.action` method within ``add_jammyjam`` is +called with no arguments. The callable in ``add_jammyjam`` is the +``register`` closure function. It simply sets the value +``config.registry.jammyjam`` to whatever the user passed in as the +``jammyjam`` argument to the ``add_jammyjam`` function. Therefore, the +result of the user's call to our directive will set the ``jammyjam`` +attribute of the registry to the string ``first``. A callable is used by a +directive to defer the result of a user's call to a directive until conflict +detection has had a chance to do its job. + +Other arguments exist to the :meth:`~pyramid.config.Configurator.action` +method, including ``args``, ``kw``, ``order``, and ``introspectables``. + +``args`` and ``kw`` exist as values, which, if passed, will be used as +arguments to the ``callable`` function when it is called back. For example +our directive might use them like so: + +.. code-block:: python + :linenos: + + def add_jammyjam(config, jammyjam): + def register(*arg, **kw): + config.registry.jammyjam_args = arg + config.registry.jammyjam_kw = kw + config.registry.jammyjam = jammyjam + config.action('jammyjam', register, args=('one',), kw={'two':'two'}) + +In the above example, when this directive is used to generate an action, and +that action is committed, ``config.registry.jammyjam_args`` will be set to +``('one',)`` and ``config.registry.jammyjam_kw`` will be set to +``{'two':'two'}``. ``args`` and ``kw`` are honestly not very useful when +your ``callable`` is a closure function, because you already usually have +access to every local in the directive without needing them to be passed +back. They can be useful, however, if you don't use a closure as a callable. + +``order`` is a crude order control mechanism. ``order`` defaults to the +integer ``0``; it can be set to any other integer. All actions that share an +order will be called before other actions that share a higher order. This +makes it possible to write a directive with callable logic that relies on the +execution of the callable of another directive being done first. For +example, Pyramid's :meth:`pyramid.config.Configurator.add_view` directive +registers an action with a higher order than the +:meth:`pyramid.config.Configurator.add_route` method. Due to this, the +``add_view`` method's callable can assume that, if a ``route_name`` was +passed to it, that a route by this name was already registered by +``add_route``, and if such a route has not already been registered, it's a +configuration error (a view that names a nonexistent route via its +``route_name`` parameter will never be called). + +``introspectables`` is a sequence of :term:`introspectable` objects. Using +``introspectables`` allows you to plug into Pyramid's configuration +introspection system. + -- cgit v1.2.3 From efd490e1c5bc17da49700f2d4572e64d0a3c0c9a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 01:58:49 -0500 Subject: reword --- docs/narr/extconfig.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 4a0db85de..4468e95b4 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -115,9 +115,9 @@ Here's an example directive which uses the "action" method: Fancy, but what does it do? The action method accepts a number of arguments. In the above directive named ``add_jammyjam``, we call :meth:`~pyramid.config.Configurator.action` with two arguments: the string -``jammyjam`` is passed as the first argument, ``discriminator`` and the -closure function named ``register`` is passed as the second argument, -named ``callable``. +``jammyjam`` is passed as the first argument named ``discriminator``, and the +closure function named ``register`` is passed as the second argument named +``callable``. When the :meth:`~pyramid.config.Configurator.action` method is called, it appends an action to the list of pending configuration actions. All pending -- cgit v1.2.3 From 1c4631864bcb7eb4b81a72fb305f72edc86f56ed Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 02:02:16 -0500 Subject: wording --- docs/narr/extconfig.rst | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 4468e95b4..570d20ec7 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -140,17 +140,22 @@ directive did this: config.add_jammyjam('first') config.add_jammyjam('second') -When the action list was committed, the user's application would not start, -because the discriminators of the actions generated by the two calls are in -direct conflict. Automatic conflict resolution cannot resolve the conflict, -and the user provided no intermediate +When the action list was committed resulting from the set of calls above, our +user's application would not start, because the discriminators of the actions +generated by the two calls are in direct conflict. Automatic conflict +resolution cannot resolve the conflict (because no ``config.include`` is +involved), and the user provided no intermediate :meth:`pyramid.config.Configurator.commit` call between the calls to ``add_jammyjam`` to ensure that the successive calls did not conflict with -each other. This is the purpose of the discriminator argument to the action +each other. + +This demonstrates the purpose of the discriminator argument to the action method: it's used to indicate a uniqueness constraint for an action. Two actions with the same discriminator will conflict unless the conflict is automatically or manually resolved. A discriminator can be any hashable -object, but it is generally a string or a tuple. +object, but it is generally a string or a tuple. *You use a discriminator to +declaratively ensure that the user doesn't provide ambiguous configuration +statements.* But let's imagine that a consumer of ``add_jammyjam`` used it in such a way that no configuration conflicts are generated. @@ -160,7 +165,7 @@ that no configuration conflicts are generated. config.add_jammyjam('first') -What happens then? When the ``add_jammyjam`` method is called, an action is +What happens now? When the ``add_jammyjam`` method is called, an action is appended to the pending actions list. When the pending configuration actions are processed during :meth:`~pyramid.config.Configurator.commit`, and no conflicts occur, the *callable* provided as the second argument to the @@ -170,9 +175,9 @@ called with no arguments. The callable in ``add_jammyjam`` is the ``config.registry.jammyjam`` to whatever the user passed in as the ``jammyjam`` argument to the ``add_jammyjam`` function. Therefore, the result of the user's call to our directive will set the ``jammyjam`` -attribute of the registry to the string ``first``. A callable is used by a -directive to defer the result of a user's call to a directive until conflict -detection has had a chance to do its job. +attribute of the registry to the string ``first``. *A callable is used by a +directive to defer the result of a user's call to the directive until +conflict detection has had a chance to do its job*. Other arguments exist to the :meth:`~pyramid.config.Configurator.action` method, including ``args``, ``kw``, ``order``, and ``introspectables``. -- cgit v1.2.3 From 8015a9f1e05526a4990997f58aab19a5f06b1737 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 02:03:06 -0500 Subject: wording --- docs/narr/extconfig.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 570d20ec7..edc120e39 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -6,9 +6,10 @@ Extending Pyramid Configuration =============================== -Pyramid allows you to extend its Configurator with custom directives. These -directives can add an :term:`action`, participate in :term:`conflict -resolution`, and can provide some number of :term:`introspectable` objects. +Pyramid allows you to extend its Configurator with custom directives. Custom +directives can use other directives, they can add a custom :term:`action`, +they can participate in :term:`conflict resolution`, and they can provide +some number of :term:`introspectable` objects. .. index:: single: add_directive -- cgit v1.2.3 From 6ab90035628ab282ba4e5433f5b9549c98a6df13 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 02:34:39 -0500 Subject: add blather about introspectables --- docs/narr/extconfig.rst | 140 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 137 insertions(+), 3 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index edc120e39..ac8b83baa 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -219,7 +219,141 @@ passed to it, that a route by this name was already registered by configuration error (a view that names a nonexistent route via its ``route_name`` parameter will never be called). -``introspectables`` is a sequence of :term:`introspectable` objects. Using -``introspectables`` allows you to plug into Pyramid's configuration -introspection system. +``introspectables`` is a sequence of :term:`introspectable` objects. You can +pass a sequence of introspectables to the +:meth:`~pyramid.config.Configurator.action` method, which allows you to +augment Pyramid's configuration introspection system. + +.. _introspection: + +Configuration Introspection +--------------------------- + +.. warning:: + + The introspection subsystem is new in Pyramid 1.3. + +Pyramid provides a configuration introspection system that can be used by +debugging tools to provide visibility into the configuration of a running +application. + +All built-in Pyramid directives (such as +:meth:`pyramid.config.Configurator.add_view` and +:meth:`pyramid.config.Configurator.add_route`) register a set of +introspectables when called. For example, when you register a view via +``add_view``, the directive registers at least one introspectable: an +introspectable about the view registration itself, providing human-consumable +values for the arguments it was passed. You can later use the introspection +query system to determine whether a particular view uses a renderer, or +whether a particular view is limited to a particular request method, or which +routes a particular view is registered against. The Pyramid "debug toolbar" +makes use of the introspection system in various ways to display information +to Pyramid developers. + +Introspection values are set when a sequence of :term:`introspectable` +objects is passed to the :meth:`~pyramid.config.Configurator.action` method. +Here's an example of a directive which uses introspectables: + +.. code-block:: python + :linenos: + + def add_jammyjam(config, value): + def register(): + config.registry.jammyjam = value + intr = config.introspectable(category_name='jammyjams', + discriminator='jammyjam', + title='a jammyjam', + type_name=None) + intr['value'] = value + config.action('jammyjam', register, introspectables=(intr,)) + + if __name__ == '__main__': + config = Configurator() + config.add_directive('add_jammyjam', add_jammyjam) + +If you notice, the above directive uses the ``introspectable`` attribute of a +Configurator (:attr:`pyramid.config.Configurator.introspectable`) to create +an introspectable object. The introspectable object's constructor requires +at least four arguments: the ``category_name``, the ``discriminator``, the +``title``, and the ``type_name``. + +The ``category_name`` is a string representing the logical category for this +introspectable. Usually the category_name is a pluralization of the type of +object being added via the action. + +The ``discriminator`` is a value unique **within the category** (unlike the +action discriminator, which must be unique within the entire set of actions). +It is typically a string or tuple representing the values unique to this +introspectable within the category. It is used to generate links and as part +of a relationship-forming target for other introspectables. + +The ``title`` is a human-consumable string that can be used by introspection +system frontends to show a friendly summary of this introspectable. + +The ``type_name`` is a value that can be used to subtype this introspectable +within its category for for sorting and presentation purposes. It can be any +value. + +An introspectable is also dictionary-like. It can contain any set of +key/value pairs, typically related to the arguments passed to its related +directive. While the category_name, discriminator, title and type_name are +*metadata* about the introspectable, the values provided as key/value pairs +are the actual data provided by the introspectable. In the above example, we +set the ``value`` key to the value of the ``value`` argument passed to the +directive. + +Our directive above mutates the introspectable, and passes it in to the +``action`` method as the first element of a tuple as the value of the +``introspectable`` keyword argument. This associates this introspectable +with the action. Introspection tools will then display this introspectable +in their index. + +Introspectable Relationships +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Two introspectables may have relationships between each other. + +.. code-block:: python + :linenos: + + def add_jammyjam(config, value, template): + def register(): + config.registry.jammyjam = (value, template) + intr = config.introspectable(category_name='jammyjams', + discriminator='jammyjam', + title='a jammyjam', + type_name=None) + intr['value'] = value + tmpl_intr = config.introspectable(category_name='jammyjam templates', + discriminator=template, + title=template, + type_name=None) + tmpl_intr['value'] = template + intr.relate('jammyjam templates', template) + config.action('jammyjam', register, introspectables=(intr, tmpl_intr)) + + if __name__ == '__main__': + config = Configurator() + config.add_directive('add_jammyjam', add_jammyjam) + +In the above example, the ``add_jammyjam`` directive registers *two* +introspectables. The first is related to the ``value`` passed to the +directive; the second is related to the ``template`` passed to the directive. +If you believe a concept within a directive is important enough to have its +own introspectable, you can cause the same directive to register more than +one introspectable, registering one introspectable for the "main idea" and +another for a related concept. + +The call to ``intr.relate`` above +(:meth:`pyramid.interfaces.IIntrospectable.relate`) is passed two arguments: +a category name and a directive. The example above effectively indicates +that the directive wishes to form a relationship between the ``intr`` +introspectable and the ``tmpl_intr`` introspectable; the arguments passed to +``relate`` are the category name and discriminator of the ``tmpl_intr`` +introspectable. + +Introspectable relationships will show up in frontend system renderings of +introspection values. For example, if a view registration names a route +name, the introspectable related to the view callable will show a reference +to the route it relates to and vice versa. -- cgit v1.2.3 From 5224059f71d0ad592a611c196a3af7cbd1dc828f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 16:24:34 -0500 Subject: add more content to the introspectables narr chapter; adjust introspection registrations while doing so --- docs/narr/extconfig.rst | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index ac8b83baa..856654377 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -336,7 +336,7 @@ Two introspectables may have relationships between each other. config = Configurator() config.add_directive('add_jammyjam', add_jammyjam) -In the above example, the ``add_jammyjam`` directive registers *two* +In the above example, the ``add_jammyjam`` directive registers two introspectables. The first is related to the ``value`` passed to the directive; the second is related to the ``template`` passed to the directive. If you believe a concept within a directive is important enough to have its @@ -352,8 +352,15 @@ introspectable and the ``tmpl_intr`` introspectable; the arguments passed to ``relate`` are the category name and discriminator of the ``tmpl_intr`` introspectable. +Relationships need not be made between two introspectables created by the +same directive. Instead, a relationship can be formed between an +introspectable created in one directive and another introspectable created in +another by calling ``relate`` on either side with the other directive's +category name and discriminator. An error will be raised at configuration +commit time if you attempt to relate an introspectable with another +nonexistent introspectable, however. + Introspectable relationships will show up in frontend system renderings of introspection values. For example, if a view registration names a route name, the introspectable related to the view callable will show a reference -to the route it relates to and vice versa. - +to the route to which it relates to and vice versa. -- cgit v1.2.3 From 8fe02156794c2cac0cbc6961332f9d8bebc1cb90 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 5 Dec 2011 00:12:38 -0500 Subject: the starter scaffold now uses url dispatch; add a minimal section about using another WSGI server; random docs fixes --- docs/narr/extconfig.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 856654377..a57c78105 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -226,8 +226,8 @@ augment Pyramid's configuration introspection system. .. _introspection: -Configuration Introspection ---------------------------- +Adding Configuration Introspection +---------------------------------- .. warning:: -- cgit v1.2.3 From 47388a2de919f09bb7d4bbc557ca07597d2d04f1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Dec 2011 04:51:30 -0500 Subject: use a better image for toolbar introspection demo; fix typos --- docs/narr/extconfig.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index a57c78105..5fc71bec5 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -40,7 +40,7 @@ For example: from pyramid.config import Configurator def add_newrequest_subscriber(config, subscriber): - config.add_subscriber(subscriber, NewRequest). + config.add_subscriber(subscriber, NewRequest) if __name__ == '__main__': config = Configurator() @@ -68,7 +68,7 @@ code in a package named ``pyramid_subscriberhelpers``: .. code-block:: python :linenos: - def includeme(config) + def includeme(config): config.add_directive('add_newrequest_subscriber', add_newrequest_subscriber) @@ -129,14 +129,13 @@ called (either explicitly or as the result of calling :meth:`~pyramid.config.Configurator.make_wsgi_app`), conflicting actions are potentially automatically resolved as per :ref:`automatic_conflict_resolution`. If a conflict cannot be automatically -resolved, a ConfigurationConflictError is raised and application startup is -prevented. +resolved, a :exc:`ConfigurationConflictError` is raised and application +startup is prevented. In our above example, therefore, if a consumer of our ``add_jammyjam`` directive did this: .. code-block:: python - :linenos: config.add_jammyjam('first') config.add_jammyjam('second') @@ -162,7 +161,6 @@ But let's imagine that a consumer of ``add_jammyjam`` used it in such a way that no configuration conflicts are generated. .. code-block:: python - :linenos: config.add_jammyjam('first') -- cgit v1.2.3 From 7bf4e11335893a95aabbda035c35804b59e037f5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Dec 2011 04:52:55 -0500 Subject: note, not warning --- docs/narr/extconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 5fc71bec5..5e7fe2753 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -227,7 +227,7 @@ augment Pyramid's configuration introspection system. Adding Configuration Introspection ---------------------------------- -.. warning:: +.. note:: The introspection subsystem is new in Pyramid 1.3. -- cgit v1.2.3 From 043ccddb909327106264d10ed5d413760a51770d Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 2 Jan 2013 02:22:52 +0200 Subject: eliminate other repeated words --- docs/narr/extconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 5e7fe2753..875bc9006 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -289,7 +289,7 @@ The ``title`` is a human-consumable string that can be used by introspection system frontends to show a friendly summary of this introspectable. The ``type_name`` is a value that can be used to subtype this introspectable -within its category for for sorting and presentation purposes. It can be any +within its category for sorting and presentation purposes. It can be any value. An introspectable is also dictionary-like. It can contain any set of -- cgit v1.2.3 From 40dbf42a2df1783c3d803adf950380c21512bb91 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 30 Jan 2013 00:41:23 +0200 Subject: use the more appropriate directives --- docs/narr/extconfig.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 875bc9006..f33326279 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -227,9 +227,7 @@ augment Pyramid's configuration introspection system. Adding Configuration Introspection ---------------------------------- -.. note:: - - The introspection subsystem is new in Pyramid 1.3. +.. versionadded:: 1.3 Pyramid provides a configuration introspection system that can be used by debugging tools to provide visibility into the configuration of a running -- cgit v1.2.3 From f5eb753eebbda6fa55ccc5108fcc325931a17f85 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 5 Apr 2013 22:56:48 +0200 Subject: fix some cross-references --- docs/narr/extconfig.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index f33326279..659056952 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -129,8 +129,8 @@ called (either explicitly or as the result of calling :meth:`~pyramid.config.Configurator.make_wsgi_app`), conflicting actions are potentially automatically resolved as per :ref:`automatic_conflict_resolution`. If a conflict cannot be automatically -resolved, a :exc:`ConfigurationConflictError` is raised and application -startup is prevented. +resolved, a :exc:`pyramid.exceptions.ConfigurationConflictError` is raised +and application startup is prevented. In our above example, therefore, if a consumer of our ``add_jammyjam`` directive did this: -- cgit v1.2.3 From edfc4f80a1240f6f5f0c41e53078a8f5d305075f Mon Sep 17 00:00:00 2001 From: Philip Jenvey Date: Thu, 15 Aug 2013 15:57:14 -0700 Subject: prefer the functionish print --- docs/narr/extconfig.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 659056952..6587aef92 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -55,7 +55,7 @@ method of the Configurator: :linenos: def mysubscriber(event): - print event.request + print(event.request) config.add_newrequest_subscriber(mysubscriber) @@ -79,7 +79,7 @@ able to install it and subsequently do: :linenos: def mysubscriber(event): - print event.request + print(event.request) from pyramid.config import Configurator config = Configurator() -- cgit v1.2.3 From c569571bdb6e8c001ab0bc11777a2e0cca72d2fb Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 27 Dec 2014 01:55:25 -0600 Subject: add action-order documentation --- docs/narr/extconfig.rst | 99 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 6587aef92..c4d3e0250 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -215,13 +215,110 @@ registers an action with a higher order than the passed to it, that a route by this name was already registered by ``add_route``, and if such a route has not already been registered, it's a configuration error (a view that names a nonexistent route via its -``route_name`` parameter will never be called). +``route_name`` parameter will never be called). As of Pyramid 1.6 it is +possible for one action to invoke another. See :ref:`ordering_actions` for +more information. ``introspectables`` is a sequence of :term:`introspectable` objects. You can pass a sequence of introspectables to the :meth:`~pyramid.config.Configurator.action` method, which allows you to augment Pyramid's configuration introspection system. +.. _ordering_actions: + +Ordering Actions +---------------- + +In Pyramid every :term:`action` has an inherent ordering relative to other +actions. The logic within actions is deferred until a call to +:meth:`pyramid.config.Configurator.commit` (which is automatically invoked by +:meth:`pyramid.config.Configurator.make_wsgi_app`). This means you may call +``config.add_view(route_name='foo')`` **before** +``config.add_route('foo', '/foo')`` because nothing actually happens until +commit-time when conflicts are resolved, actions are ordered and executed. + +By default, almost every action in Pyramid has an ``order`` of ``0``. Every +action within the same order-level will be executed in the order it was called. +This means that if an action must be reliably executed before or after another +action, the ``order`` must be defined explicitly to make this work. For +example, views are dependent on routes being defined. Thus the action created +by :meth:`pyramid.config.Configurator.add_route` has an ``order`` of +:const:`pyramid.interfaces.PHASE2_CONFIG`. + +Pre-defined Phases +~~~~~~~~~~~~~~~~~~ + +:const:`pyramid.interfaces.PHASE1_CONFIG` + +- :meth:`pyramid.config.Configurator.add_renderer` +- :meth:`pyramid.config.Configurator.add_route_predicate` +- :meth:`pyramid.config.Configurator.add_subscriber_predicate` +- :meth:`pyramid.config.Configurator.add_view_predicate` +- :meth:`pyramid.config.Configurator.set_authorization_policy` +- :meth:`pyramid.config.Configurator.set_default_permission` +- :meth:`pyramid.config.Configurator.set_view_mapper` + +:const:`pyramid.interfaces.PHASE2_CONFIG` + +- :meth:`pyramid.config.Configurator.add_route` +- :meth:`pyramid.config.Configurator.set_authentication_policy` + +``0`` + +- The default for all builtin or custom directives unless otherwise specified. + +Calling Actions From Actions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.6 + +Pyramid's configurator allows actions to be added during a commit-cycle as +long as they are added to the current or a later ``order`` phase. This means +that your custom action can defer decisions until commit-time and then do +things like invoke :meth:`pyramid.config.Configurator.add_route`. It can also +provide better conflict detection if your addon needs to call more than one +other action. + +For example, let's make an addon that invokes ``add_route`` and ``add_view``, +but we want it to conflict with any other call to our addon: + +.. code-block:: python + :linenos: + + from pyramid.interfaces import PHASE1_CONFIG + + PHASE0_CONFIG = PHASE1_CONFIG - 10 + + def includeme(config): + config.add_directive(add_auto_route, 'add_auto_route') + + def add_auto_route(config, name, view): + def register(): + config.add_view(route_name=name, view=view) + config.add_route(name, '/' + name) + config.action(('auto route', name), register, order=PHASE0_CONFIG) + +Now someone else can use your addon and be informed if there is a conflict +between this route and another, or two calls to ``add_auto_route``. +Notice how we had to invoke our action **before** ``add_view`` or +``add_route``. If we tried to invoke this afterward, the subsequent calls to +``add_view`` and ``add_route`` would cause conflicts because that phase had +already been executed, and the configurator cannot go back in time to add more +views during that commit-cycle. + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def main(global_config, **settings): + config = Configurator() + config.include('auto_route_addon') + config.add_auto_route('foo', my_view) + + def my_view(request): + return request.response + .. _introspection: Adding Configuration Introspection -- cgit v1.2.3 From 568a025d3156ee1e7bdf92e14c9eba7390c1dd26 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Feb 2015 18:58:53 -0600 Subject: expose public config phases in pyramid.config --- docs/narr/extconfig.rst | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index c4d3e0250..c805f1572 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -243,12 +243,17 @@ This means that if an action must be reliably executed before or after another action, the ``order`` must be defined explicitly to make this work. For example, views are dependent on routes being defined. Thus the action created by :meth:`pyramid.config.Configurator.add_route` has an ``order`` of -:const:`pyramid.interfaces.PHASE2_CONFIG`. +:const:`pyramid.config.PHASE2_CONFIG`. Pre-defined Phases ~~~~~~~~~~~~~~~~~~ -:const:`pyramid.interfaces.PHASE1_CONFIG` +:const:`pyramid.config.PHASE0_CONFIG` + +- This phase is reserved for developers who want to execute actions prior + to Pyramid's core directives. + +:const:`pyramid.config.PHASE1_CONFIG` - :meth:`pyramid.config.Configurator.add_renderer` - :meth:`pyramid.config.Configurator.add_route_predicate` @@ -258,12 +263,12 @@ Pre-defined Phases - :meth:`pyramid.config.Configurator.set_default_permission` - :meth:`pyramid.config.Configurator.set_view_mapper` -:const:`pyramid.interfaces.PHASE2_CONFIG` +:const:`pyramid.config.PHASE2_CONFIG` - :meth:`pyramid.config.Configurator.add_route` - :meth:`pyramid.config.Configurator.set_authentication_policy` -``0`` +:const:`pyramid.config.PHASE3_CONFIG` - The default for all builtin or custom directives unless otherwise specified. @@ -285,9 +290,7 @@ but we want it to conflict with any other call to our addon: .. code-block:: python :linenos: - from pyramid.interfaces import PHASE1_CONFIG - - PHASE0_CONFIG = PHASE1_CONFIG - 10 + from pyramid.config import PHASE0_CONFIG def includeme(config): config.add_directive(add_auto_route, 'add_auto_route') -- cgit v1.2.3 From c0063b33e3b570120aab09b7d0a0adcf31c8705c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Feb 2015 19:01:15 -0600 Subject: fix odd sentence --- docs/narr/extconfig.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index c805f1572..47f2fcb46 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -235,7 +235,8 @@ actions. The logic within actions is deferred until a call to :meth:`pyramid.config.Configurator.make_wsgi_app`). This means you may call ``config.add_view(route_name='foo')`` **before** ``config.add_route('foo', '/foo')`` because nothing actually happens until -commit-time when conflicts are resolved, actions are ordered and executed. +commit-time. During a commit cycle conflicts are resolved, actions are ordered +and executed. By default, almost every action in Pyramid has an ``order`` of ``0``. Every action within the same order-level will be executed in the order it was called. -- cgit v1.2.3 From bba15920ee77a626c2ea3636d9d3b4f8d571afa6 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Feb 2015 19:02:14 -0600 Subject: avoid saying order=0, instead say PHASE3_CONFIG --- docs/narr/extconfig.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 47f2fcb46..d17842bf2 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -238,8 +238,9 @@ actions. The logic within actions is deferred until a call to commit-time. During a commit cycle conflicts are resolved, actions are ordered and executed. -By default, almost every action in Pyramid has an ``order`` of ``0``. Every -action within the same order-level will be executed in the order it was called. +By default, almost every action in Pyramid has an ``order`` of +:const:`pyramid.config.PHASE3_CONFIG`. Every action within the same order-level +will be executed in the order it was called. This means that if an action must be reliably executed before or after another action, the ``order`` must be defined explicitly to make this work. For example, views are dependent on routes being defined. Thus the action created -- cgit v1.2.3 From 0bf2fded1a5dfa1614120c989f1d051908fa0b56 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Feb 2015 19:03:13 -0600 Subject: fix syntax --- docs/narr/extconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index d17842bf2..a61eca7b7 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -295,7 +295,7 @@ but we want it to conflict with any other call to our addon: from pyramid.config import PHASE0_CONFIG def includeme(config): - config.add_directive(add_auto_route, 'add_auto_route') + config.add_directive('add_auto_route', add_auto_route) def add_auto_route(config, name, view): def register(): -- cgit v1.2.3 From 6bc1bb06dd07e34a2f26cbb26bca6fc7a933b881 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 6 Nov 2015 00:55:11 -0800 Subject: minor grammar, fix .rst markup, insert versionchanged directive, rewrap to 79 columns --- docs/narr/extconfig.rst | 266 ++++++++++++++++++++++++------------------------ 1 file changed, 132 insertions(+), 134 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index a61eca7b7..5a46c8b9e 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -7,9 +7,9 @@ Extending Pyramid Configuration =============================== Pyramid allows you to extend its Configurator with custom directives. Custom -directives can use other directives, they can add a custom :term:`action`, -they can participate in :term:`conflict resolution`, and they can provide -some number of :term:`introspectable` objects. +directives can use other directives, they can add a custom :term:`action`, they +can participate in :term:`conflict resolution`, and they can provide some +number of :term:`introspectable` objects. .. index:: single: add_directive @@ -20,18 +20,17 @@ some number of :term:`introspectable` objects. Adding Methods to the Configurator via ``add_directive`` -------------------------------------------------------- -Framework extension writers can add arbitrary methods to a -:term:`Configurator` by using the -:meth:`pyramid.config.Configurator.add_directive` method of the configurator. -Using :meth:`~pyramid.config.Configurator.add_directive` makes it possible to -extend a Pyramid configurator in arbitrary ways, and allows it to perform -application-specific tasks more succinctly. +Framework extension writers can add arbitrary methods to a :term:`Configurator` +by using the :meth:`pyramid.config.Configurator.add_directive` method of the +configurator. Using :meth:`~pyramid.config.Configurator.add_directive` makes it +possible to extend a Pyramid configurator in arbitrary ways, and allows it to +perform application-specific tasks more succinctly. The :meth:`~pyramid.config.Configurator.add_directive` method accepts two -positional arguments: a method name and a callable object. The callable -object is usually a function that takes the configurator instance as its -first argument and accepts other arbitrary positional and keyword arguments. -For example: +positional arguments: a method name and a callable object. The callable object +is usually a function that takes the configurator instance as its first +argument and accepts other arbitrary positional and keyword arguments. For +example: .. code-block:: python :linenos: @@ -48,8 +47,8 @@ For example: add_newrequest_subscriber) Once :meth:`~pyramid.config.Configurator.add_directive` is called, a user can -then call the added directive by its given name as if it were a built-in -method of the Configurator: +then call the added directive by its given name as if it were a built-in method +of the Configurator: .. code-block:: python :linenos: @@ -59,9 +58,9 @@ method of the Configurator: config.add_newrequest_subscriber(mysubscriber) -A call to :meth:`~pyramid.config.Configurator.add_directive` is often -"hidden" within an ``includeme`` function within a "frameworky" package meant -to be included as per :ref:`including_configuration` via +A call to :meth:`~pyramid.config.Configurator.add_directive` is often "hidden" +within an ``includeme`` function within a "frameworky" package meant to be +included as per :ref:`including_configuration` via :meth:`~pyramid.config.Configurator.include`. For example, if you put this code in a package named ``pyramid_subscriberhelpers``: @@ -72,8 +71,8 @@ code in a package named ``pyramid_subscriberhelpers``: config.add_directive('add_newrequest_subscriber', add_newrequest_subscriber) -The user of the add-on package ``pyramid_subscriberhelpers`` would then be -able to install it and subsequently do: +The user of the add-on package ``pyramid_subscriberhelpers`` would then be able +to install it and subsequently do: .. code-block:: python :linenos: @@ -91,13 +90,12 @@ Using ``config.action`` in a Directive If a custom directive can't do its work exclusively in terms of existing configurator methods (such as -:meth:`pyramid.config.Configurator.add_subscriber`, as above), the directive -may need to make use of the :meth:`pyramid.config.Configurator.action` -method. This method adds an entry to the list of "actions" that Pyramid will -attempt to process when :meth:`pyramid.config.Configurator.commit` is called. -An action is simply a dictionary that includes a :term:`discriminator`, -possibly a callback function, and possibly other metadata used by Pyramid's -action system. +:meth:`pyramid.config.Configurator.add_subscriber` as above), the directive may +need to make use of the :meth:`pyramid.config.Configurator.action` method. This +method adds an entry to the list of "actions" that Pyramid will attempt to +process when :meth:`pyramid.config.Configurator.commit` is called. An action is +simply a dictionary that includes a :term:`discriminator`, possibly a callback +function, and possibly other metadata used by Pyramid's action system. Here's an example directive which uses the "action" method: @@ -122,15 +120,15 @@ closure function named ``register`` is passed as the second argument named When the :meth:`~pyramid.config.Configurator.action` method is called, it appends an action to the list of pending configuration actions. All pending -actions with the same discriminator value are potentially in conflict with -one another (see :ref:`conflict_detection`). When the +actions with the same discriminator value are potentially in conflict with one +another (see :ref:`conflict_detection`). When the :meth:`~pyramid.config.Configurator.commit` method of the Configurator is called (either explicitly or as the result of calling :meth:`~pyramid.config.Configurator.make_wsgi_app`), conflicting actions are -potentially automatically resolved as per -:ref:`automatic_conflict_resolution`. If a conflict cannot be automatically -resolved, a :exc:`pyramid.exceptions.ConfigurationConflictError` is raised -and application startup is prevented. +potentially automatically resolved as per :ref:`automatic_conflict_resolution`. +If a conflict cannot be automatically resolved, a +:exc:`pyramid.exceptions.ConfigurationConflictError` is raised and application +startup is prevented. In our above example, therefore, if a consumer of our ``add_jammyjam`` directive did this: @@ -146,14 +144,14 @@ generated by the two calls are in direct conflict. Automatic conflict resolution cannot resolve the conflict (because no ``config.include`` is involved), and the user provided no intermediate :meth:`pyramid.config.Configurator.commit` call between the calls to -``add_jammyjam`` to ensure that the successive calls did not conflict with -each other. +``add_jammyjam`` to ensure that the successive calls did not conflict with each +other. This demonstrates the purpose of the discriminator argument to the action method: it's used to indicate a uniqueness constraint for an action. Two actions with the same discriminator will conflict unless the conflict is -automatically or manually resolved. A discriminator can be any hashable -object, but it is generally a string or a tuple. *You use a discriminator to +automatically or manually resolved. A discriminator can be any hashable object, +but it is generally a string or a tuple. *You use a discriminator to declaratively ensure that the user doesn't provide ambiguous configuration statements.* @@ -169,21 +167,20 @@ appended to the pending actions list. When the pending configuration actions are processed during :meth:`~pyramid.config.Configurator.commit`, and no conflicts occur, the *callable* provided as the second argument to the :meth:`~pyramid.config.Configurator.action` method within ``add_jammyjam`` is -called with no arguments. The callable in ``add_jammyjam`` is the -``register`` closure function. It simply sets the value -``config.registry.jammyjam`` to whatever the user passed in as the -``jammyjam`` argument to the ``add_jammyjam`` function. Therefore, the -result of the user's call to our directive will set the ``jammyjam`` -attribute of the registry to the string ``first``. *A callable is used by a -directive to defer the result of a user's call to the directive until -conflict detection has had a chance to do its job*. +called with no arguments. The callable in ``add_jammyjam`` is the ``register`` +closure function. It simply sets the value ``config.registry.jammyjam`` to +whatever the user passed in as the ``jammyjam`` argument to the +``add_jammyjam`` function. Therefore, the result of the user's call to our +directive will set the ``jammyjam`` attribute of the registry to the string +``first``. *A callable is used by a directive to defer the result of a user's +call to the directive until conflict detection has had a chance to do its job*. Other arguments exist to the :meth:`~pyramid.config.Configurator.action` -method, including ``args``, ``kw``, ``order``, and ``introspectables``. +method, including ``args``, ``kw``, ``order``, and ``introspectables``. -``args`` and ``kw`` exist as values, which, if passed, will be used as -arguments to the ``callable`` function when it is called back. For example -our directive might use them like so: +``args`` and ``kw`` exist as values, which if passed will be used as arguments +to the ``callable`` function when it is called back. For example, our +directive might use them like so: .. code-block:: python :linenos: @@ -198,31 +195,34 @@ our directive might use them like so: In the above example, when this directive is used to generate an action, and that action is committed, ``config.registry.jammyjam_args`` will be set to ``('one',)`` and ``config.registry.jammyjam_kw`` will be set to -``{'two':'two'}``. ``args`` and ``kw`` are honestly not very useful when -your ``callable`` is a closure function, because you already usually have -access to every local in the directive without needing them to be passed -back. They can be useful, however, if you don't use a closure as a callable. +``{'two':'two'}``. ``args`` and ``kw`` are honestly not very useful when your +``callable`` is a closure function, because you already usually have access to +every local in the directive without needing them to be passed back. They can +be useful, however, if you don't use a closure as a callable. ``order`` is a crude order control mechanism. ``order`` defaults to the integer ``0``; it can be set to any other integer. All actions that share an order will be called before other actions that share a higher order. This makes it possible to write a directive with callable logic that relies on the -execution of the callable of another directive being done first. For -example, Pyramid's :meth:`pyramid.config.Configurator.add_view` directive -registers an action with a higher order than the +execution of the callable of another directive being done first. For example, +Pyramid's :meth:`pyramid.config.Configurator.add_view` directive registers an +action with a higher order than the :meth:`pyramid.config.Configurator.add_route` method. Due to this, the -``add_view`` method's callable can assume that, if a ``route_name`` was -passed to it, that a route by this name was already registered by -``add_route``, and if such a route has not already been registered, it's a -configuration error (a view that names a nonexistent route via its -``route_name`` parameter will never be called). As of Pyramid 1.6 it is -possible for one action to invoke another. See :ref:`ordering_actions` for -more information. - -``introspectables`` is a sequence of :term:`introspectable` objects. You can -pass a sequence of introspectables to the -:meth:`~pyramid.config.Configurator.action` method, which allows you to -augment Pyramid's configuration introspection system. +``add_view`` method's callable can assume that, if a ``route_name`` was passed +to it, that a route by this name was already registered by ``add_route``, and +if such a route has not already been registered, it's a configuration error (a +view that names a nonexistent route via its ``route_name`` parameter will never +be called). + +.. versionchanged:: 1.6 + As of Pyramid 1.6 it is possible for one action to invoke another. + +See :ref:`ordering_actions` for more information. + +Finally, ``introspectables`` is a sequence of :term:`introspectable` objects. +You can pass a sequence of introspectables to the +:meth:`~pyramid.config.Configurator.action` method, which allows you to augment +Pyramid's configuration introspection system. .. _ordering_actions: @@ -233,18 +233,17 @@ In Pyramid every :term:`action` has an inherent ordering relative to other actions. The logic within actions is deferred until a call to :meth:`pyramid.config.Configurator.commit` (which is automatically invoked by :meth:`pyramid.config.Configurator.make_wsgi_app`). This means you may call -``config.add_view(route_name='foo')`` **before** -``config.add_route('foo', '/foo')`` because nothing actually happens until -commit-time. During a commit cycle conflicts are resolved, actions are ordered -and executed. +``config.add_view(route_name='foo')`` **before** ``config.add_route('foo', +'/foo')`` because nothing actually happens until commit-time. During a commit +cycle, conflicts are resolved, and actions are ordered and executed. By default, almost every action in Pyramid has an ``order`` of :const:`pyramid.config.PHASE3_CONFIG`. Every action within the same order-level -will be executed in the order it was called. -This means that if an action must be reliably executed before or after another -action, the ``order`` must be defined explicitly to make this work. For -example, views are dependent on routes being defined. Thus the action created -by :meth:`pyramid.config.Configurator.add_route` has an ``order`` of +will be executed in the order it was called. This means that if an action must +be reliably executed before or after another action, the ``order`` must be +defined explicitly to make this work. For example, views are dependent on +routes being defined. Thus the action created by +:meth:`pyramid.config.Configurator.add_route` has an ``order`` of :const:`pyramid.config.PHASE2_CONFIG`. Pre-defined Phases @@ -252,8 +251,8 @@ Pre-defined Phases :const:`pyramid.config.PHASE0_CONFIG` -- This phase is reserved for developers who want to execute actions prior - to Pyramid's core directives. +- This phase is reserved for developers who want to execute actions prior to + Pyramid's core directives. :const:`pyramid.config.PHASE1_CONFIG` @@ -274,17 +273,17 @@ Pre-defined Phases - The default for all builtin or custom directives unless otherwise specified. -Calling Actions From Actions +Calling Actions from Actions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 1.6 -Pyramid's configurator allows actions to be added during a commit-cycle as -long as they are added to the current or a later ``order`` phase. This means -that your custom action can defer decisions until commit-time and then do -things like invoke :meth:`pyramid.config.Configurator.add_route`. It can also -provide better conflict detection if your addon needs to call more than one -other action. +Pyramid's configurator allows actions to be added during a commit-cycle as long +as they are added to the current or a later ``order`` phase. This means that +your custom action can defer decisions until commit-time and then do things +like invoke :meth:`pyramid.config.Configurator.add_route`. It can also provide +better conflict detection if your addon needs to call more than one other +action. For example, let's make an addon that invokes ``add_route`` and ``add_view``, but we want it to conflict with any other call to our addon: @@ -304,12 +303,12 @@ but we want it to conflict with any other call to our addon: config.action(('auto route', name), register, order=PHASE0_CONFIG) Now someone else can use your addon and be informed if there is a conflict -between this route and another, or two calls to ``add_auto_route``. -Notice how we had to invoke our action **before** ``add_view`` or -``add_route``. If we tried to invoke this afterward, the subsequent calls to -``add_view`` and ``add_route`` would cause conflicts because that phase had -already been executed, and the configurator cannot go back in time to add more -views during that commit-cycle. +between this route and another, or two calls to ``add_auto_route``. Notice how +we had to invoke our action **before** ``add_view`` or ``add_route``. If we +tried to invoke this afterward, the subsequent calls to ``add_view`` and +``add_route`` would cause conflicts because that phase had already been +executed, and the configurator cannot go back in time to add more views during +that commit-cycle. .. code-block:: python :linenos: @@ -341,16 +340,16 @@ All built-in Pyramid directives (such as introspectables when called. For example, when you register a view via ``add_view``, the directive registers at least one introspectable: an introspectable about the view registration itself, providing human-consumable -values for the arguments it was passed. You can later use the introspection -query system to determine whether a particular view uses a renderer, or -whether a particular view is limited to a particular request method, or which -routes a particular view is registered against. The Pyramid "debug toolbar" -makes use of the introspection system in various ways to display information -to Pyramid developers. +values for the arguments passed into it. You can later use the introspection +query system to determine whether a particular view uses a renderer, or whether +a particular view is limited to a particular request method, or against which +routes a particular view is registered. The Pyramid "debug toolbar" makes use +of the introspection system in various ways to display information to Pyramid +developers. -Introspection values are set when a sequence of :term:`introspectable` -objects is passed to the :meth:`~pyramid.config.Configurator.action` method. -Here's an example of a directive which uses introspectables: +Introspection values are set when a sequence of :term:`introspectable` objects +is passed to the :meth:`~pyramid.config.Configurator.action` method. Here's an +example of a directive which uses introspectables: .. code-block:: python :linenos: @@ -370,9 +369,9 @@ Here's an example of a directive which uses introspectables: config.add_directive('add_jammyjam', add_jammyjam) If you notice, the above directive uses the ``introspectable`` attribute of a -Configurator (:attr:`pyramid.config.Configurator.introspectable`) to create -an introspectable object. The introspectable object's constructor requires -at least four arguments: the ``category_name``, the ``discriminator``, the +Configurator (:attr:`pyramid.config.Configurator.introspectable`) to create an +introspectable object. The introspectable object's constructor requires at +least four arguments: the ``category_name``, the ``discriminator``, the ``title``, and the ``type_name``. The ``category_name`` is a string representing the logical category for this @@ -392,19 +391,19 @@ The ``type_name`` is a value that can be used to subtype this introspectable within its category for sorting and presentation purposes. It can be any value. -An introspectable is also dictionary-like. It can contain any set of -key/value pairs, typically related to the arguments passed to its related -directive. While the category_name, discriminator, title and type_name are -*metadata* about the introspectable, the values provided as key/value pairs +An introspectable is also dictionary-like. It can contain any set of key/value +pairs, typically related to the arguments passed to its related directive. +While the ``category_name``, ``discriminator``, ``title``, and ``type_name`` +are *metadata* about the introspectable, the values provided as key/value pairs are the actual data provided by the introspectable. In the above example, we set the ``value`` key to the value of the ``value`` argument passed to the directive. Our directive above mutates the introspectable, and passes it in to the ``action`` method as the first element of a tuple as the value of the -``introspectable`` keyword argument. This associates this introspectable -with the action. Introspection tools will then display this introspectable -in their index. +``introspectable`` keyword argument. This associates this introspectable with +the action. Introspection tools will then display this introspectable in their +index. Introspectable Relationships ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -435,30 +434,29 @@ Two introspectables may have relationships between each other. config.add_directive('add_jammyjam', add_jammyjam) In the above example, the ``add_jammyjam`` directive registers two -introspectables. The first is related to the ``value`` passed to the -directive; the second is related to the ``template`` passed to the directive. -If you believe a concept within a directive is important enough to have its -own introspectable, you can cause the same directive to register more than -one introspectable, registering one introspectable for the "main idea" and -another for a related concept. +introspectables: the first is related to the ``value`` passed to the directive, +and the second is related to the ``template`` passed to the directive. If you +believe a concept within a directive is important enough to have its own +introspectable, you can cause the same directive to register more than one +introspectable, registering one introspectable for the "main idea" and another +for a related concept. The call to ``intr.relate`` above -(:meth:`pyramid.interfaces.IIntrospectable.relate`) is passed two arguments: -a category name and a directive. The example above effectively indicates -that the directive wishes to form a relationship between the ``intr`` -introspectable and the ``tmpl_intr`` introspectable; the arguments passed to -``relate`` are the category name and discriminator of the ``tmpl_intr`` -introspectable. - -Relationships need not be made between two introspectables created by the -same directive. Instead, a relationship can be formed between an -introspectable created in one directive and another introspectable created in -another by calling ``relate`` on either side with the other directive's -category name and discriminator. An error will be raised at configuration -commit time if you attempt to relate an introspectable with another -nonexistent introspectable, however. +(:meth:`pyramid.interfaces.IIntrospectable.relate`) is passed two arguments: a +category name and a directive. The example above effectively indicates that +the directive wishes to form a relationship between the ``intr`` introspectable +and the ``tmpl_intr`` introspectable; the arguments passed to ``relate`` are +the category name and discriminator of the ``tmpl_intr`` introspectable. + +Relationships need not be made between two introspectables created by the same +directive. Instead a relationship can be formed between an introspectable +created in one directive and another introspectable created in another by +calling ``relate`` on either side with the other directive's category name and +discriminator. An error will be raised at configuration commit time if you +attempt to relate an introspectable with another nonexistent introspectable, +however. Introspectable relationships will show up in frontend system renderings of -introspection values. For example, if a view registration names a route -name, the introspectable related to the view callable will show a reference -to the route to which it relates to and vice versa. +introspection values. For example, if a view registration names a route name, +the introspectable related to the view callable will show a reference to the +route to which it relates and vice versa. -- cgit v1.2.3 From 4434b479bcee4d32b8dacaf409bdd756dd7ff8e5 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 6 Nov 2015 01:12:46 -0800 Subject: minor grammar, fix .rst markup, insert versionchanged directive, rewrap to 79 columns --- docs/narr/extconfig.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 5a46c8b9e..fee8d0d3a 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -215,9 +215,8 @@ view that names a nonexistent route via its ``route_name`` parameter will never be called). .. versionchanged:: 1.6 - As of Pyramid 1.6 it is possible for one action to invoke another. - -See :ref:`ordering_actions` for more information. + As of Pyramid 1.6 it is possible for one action to invoke another. See + :ref:`ordering_actions` for more information. Finally, ``introspectables`` is a sequence of :term:`introspectable` objects. You can pass a sequence of introspectables to the -- cgit v1.2.3 From fdd1f8352fc341bc60e0b7d32dadd2b4109a2b41 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 14 Mar 2016 22:08:04 -0500 Subject: first cut at documenting view derivers --- docs/narr/extconfig.rst | 1 + 1 file changed, 1 insertion(+) (limited to 'docs/narr/extconfig.rst') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index fee8d0d3a..af7d0a349 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -259,6 +259,7 @@ Pre-defined Phases - :meth:`pyramid.config.Configurator.add_route_predicate` - :meth:`pyramid.config.Configurator.add_subscriber_predicate` - :meth:`pyramid.config.Configurator.add_view_predicate` +- :meth:`pyramid.config.Configurator.add_view_deriver` - :meth:`pyramid.config.Configurator.set_authorization_policy` - :meth:`pyramid.config.Configurator.set_default_permission` - :meth:`pyramid.config.Configurator.set_view_mapper` -- cgit v1.2.3