#6522: add a "decorator" directive to explicitly document decorators, and use it in a few places.

This commit is contained in:
Georg Brandl 2010-07-29 16:01:11 +00:00
parent b0a4e3c1a7
commit 8a1caa2361
7 changed files with 75 additions and 16 deletions

View File

@ -177,6 +177,34 @@ The directives are:
are modified), side effects, and possible exceptions. A small example may be are modified), side effects, and possible exceptions. A small example may be
provided. provided.
.. describe:: decorator
Describes a decorator function. The signature should *not* represent the
signature of the actual function, but the usage as a decorator. For example,
given the functions
.. code-block:: python
def removename(func):
func.__name__ = ''
return func
def setnewname(name):
def decorator(func):
func.__name__ = name
return func
return decorator
the descriptions should look like this::
.. decorator:: removename
Remove name of the decorated function.
.. decorator:: setnewname(name)
Set name of the decorated function to *name*.
.. describe:: class .. describe:: class
Describes a class. The signature can include parentheses with parameters Describes a class. The signature can include parentheses with parameters
@ -194,6 +222,10 @@ The directives are:
parameter. The description should include similar information to that parameter. The description should include similar information to that
described for ``function``. described for ``function``.
.. describe:: decoratormethod
Same as ``decorator``, but for decorators that are methods.
.. describe:: opcode .. describe:: opcode
Describes a Python :term:`bytecode` instruction. Describes a Python :term:`bytecode` instruction.

View File

@ -122,7 +122,7 @@ This module provides the following class:
It also provides the following decorators: It also provides the following decorators:
.. function:: abstractmethod(function) .. decorator:: abstractmethod(function)
A decorator indicating abstract methods. A decorator indicating abstract methods.

View File

@ -12,7 +12,7 @@ statement. For more information see also :ref:`typecontextmanager` and
Functions provided: Functions provided:
.. function:: contextmanager(func) .. decorator:: contextmanager
This function is a :term:`decorator` that can be used to define a factory This function is a :term:`decorator` that can be used to define a factory
function for :keyword:`with` statement context managers, without needing to function for :keyword:`with` statement context managers, without needing to

View File

@ -37,7 +37,7 @@ The :mod:`functools` module defines the following functions:
.. versionadded:: 3.2 .. versionadded:: 3.2
.. function:: total_ordering(cls) .. decorator:: total_ordering
Given a class defining one or more rich comparison ordering methods, this Given a class defining one or more rich comparison ordering methods, this
class decorator supplies the rest. This simplifies the effort involved class decorator supplies the rest. This simplifies the effort involved
@ -122,7 +122,7 @@ The :mod:`functools` module defines the following functions:
than helpful. than helpful.
.. function:: wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES) .. decorator:: wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
This is a convenience function for invoking ``partial(update_wrapper, This is a convenience function for invoking ``partial(update_wrapper,
wrapped=wrapped, assigned=assigned, updated=updated)`` as a function decorator wrapped=wrapped, assigned=assigned, updated=updated)`` as a function decorator

View File

@ -469,7 +469,7 @@ find and load modules.
This module contains the various objects that help in the construction of This module contains the various objects that help in the construction of
an :term:`importer`. an :term:`importer`.
.. function:: module_for_loader(method) .. decorator:: module_for_loader
A :term:`decorator` for a :term:`loader` method, A :term:`decorator` for a :term:`loader` method,
to handle selecting the proper to handle selecting the proper
@ -494,7 +494,7 @@ an :term:`importer`.
Use of this decorator handles all the details of which module object a Use of this decorator handles all the details of which module object a
loader should initialize as specified by :pep:`302`. loader should initialize as specified by :pep:`302`.
.. function:: set_loader(fxn) .. decorator:: set_loader
A :term:`decorator` for a :term:`loader` method, A :term:`decorator` for a :term:`loader` method,
to set the :attr:`__loader__` to set the :attr:`__loader__`
@ -502,7 +502,7 @@ an :term:`importer`.
does nothing. It is assumed that the first positional argument to the does nothing. It is assumed that the first positional argument to the
wrapped method is what :attr:`__loader__` should be set to. wrapped method is what :attr:`__loader__` should be set to.
.. function:: set_package(fxn) .. decorator:: set_package
A :term:`decorator` for a :term:`loader` to set the :attr:`__package__` A :term:`decorator` for a :term:`loader` to set the :attr:`__package__`
attribute on the module returned by the loader. If :attr:`__package__` is attribute on the module returned by the loader. If :attr:`__package__` is

View File

@ -621,20 +621,20 @@ the test unless the passed object has a certain attribute: ::
The following decorators implement test skipping and expected failures: The following decorators implement test skipping and expected failures:
.. function:: skip(reason) .. decorator:: skip(reason)
Unconditionally skip the decorated test. *reason* should describe why the Unconditionally skip the decorated test. *reason* should describe why the
test is being skipped. test is being skipped.
.. function:: skipIf(condition, reason) .. decorator:: skipIf(condition, reason)
Skip the decorated test if *condition* is true. Skip the decorated test if *condition* is true.
.. function:: skipUnless(condition, reason) .. decorator:: skipUnless(condition, reason)
Skip the decoratored test unless *condition* is true. Skip the decoratored test unless *condition* is true.
.. function:: expectedFailure .. decorator:: expectedFailure
Mark the test as an expected failure. If the test fails when run, the test Mark the test as an expected failure. If the test fails when run, the test
is not counted as a failure. is not counted as a failure.
@ -1048,11 +1048,11 @@ Test cases
:attr:`exception` attribute. This can be useful if the intention :attr:`exception` attribute. This can be useful if the intention
is to perform additional checks on the exception raised:: is to perform additional checks on the exception raised::
with self.assertRaises(SomeException) as cm: with self.assertRaises(SomeException) as cm:
do_something() do_something()
the_exception = cm.exception the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3) self.assertEqual(the_exception.error_code, 3)
.. versionchanged:: 3.1 .. versionchanged:: 3.1
Added the ability to use :meth:`assertRaises` as a context manager. Added the ability to use :meth:`assertRaises` as a context manager.

View File

@ -72,6 +72,32 @@ class ImplementationDetail(Directive):
return [pnode] return [pnode]
# Support for documenting decorators
from sphinx import addnodes
from sphinx.domains.python import PyModulelevel, PyClassmember
class PyDecoratorMixin(object):
def handle_signature(self, sig, signode):
ret = super(PyDecoratorMixin, self).handle_signature(sig, signode)
signode.insert(0, addnodes.desc_addname('@', '@'))
return ret
def needs_arglist(self):
return False
class PyDecoratorFunction(PyDecoratorMixin, PyModulelevel):
def run(self):
# a decorator function is a function after all
self.name = 'py:function'
return PyModulelevel.run(self)
class PyDecoratorMethod(PyDecoratorMixin, PyClassmember):
def run(self):
self.name = 'py:method'
return PyClassmember.run(self)
# Support for building "topic help" for pydoc # Support for building "topic help" for pydoc
pydoc_topic_labels = [ pydoc_topic_labels = [
@ -147,7 +173,6 @@ import suspicious
# Support for documenting Opcodes # Support for documenting Opcodes
import re import re
from sphinx import addnodes
opcode_sig_re = re.compile(r'(\w+(?:\+\d)?)(?:\s*\((.*)\))?') opcode_sig_re = re.compile(r'(\w+(?:\+\d)?)(?:\s*\((.*)\))?')
@ -197,3 +222,5 @@ def setup(app):
app.add_description_unit('pdbcommand', 'pdbcmd', '%s (pdb command)', app.add_description_unit('pdbcommand', 'pdbcmd', '%s (pdb command)',
parse_pdb_command) parse_pdb_command)
app.add_description_unit('2to3fixer', '2to3fixer', '%s (2to3 fixer)') app.add_description_unit('2to3fixer', '2to3fixer', '%s (2to3 fixer)')
app.add_directive_to_domain('py', 'decorator', PyDecoratorFunction)
app.add_directive_to_domain('py', 'decoratormethod', PyDecoratorMethod)