#6522: add a "decorator" directive to explicitly document decorators, and use it...
authorGeorg Brandl <georg@python.org>
Thu, 29 Jul 2010 16:01:11 +0000 (16:01 +0000)
committerGeorg Brandl <georg@python.org>
Thu, 29 Jul 2010 16:01:11 +0000 (16:01 +0000)
Doc/documenting/markup.rst
Doc/library/abc.rst
Doc/library/contextlib.rst
Doc/library/functools.rst
Doc/library/importlib.rst
Doc/library/unittest.rst
Doc/tools/sphinxext/pyspecific.py

index 34a79d4372a6df486c800a45576ad1518d749c1e..e48bb01f724b826bcb83aa29ee75c0e7bf38889b 100644 (file)
@@ -177,6 +177,34 @@ The directives are:
    are modified), side effects, and possible exceptions.  A small example may be
    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
 
    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
    described for ``function``.
 
+.. describe:: decoratormethod
+
+   Same as ``decorator``, but for decorators that are methods.
+
 .. describe:: opcode
 
    Describes a Python :term:`bytecode` instruction.
index aa1cc7871e3fa3ab719db419407434576c9b0a32..5e87e969b544ef9ca56f08bca0ab2df43dd3c305 100644 (file)
@@ -122,7 +122,7 @@ This module provides the following class:
 
 It also provides the following decorators:
 
-.. function:: abstractmethod(function)
+.. decorator:: abstractmethod(function)
 
    A decorator indicating abstract methods.
 
index 18e550212231fd22188f96f94bbde13046463674..35eb882f66319d8f8ecf26c2ec5a0c317e03b2eb 100644 (file)
@@ -12,7 +12,7 @@ statement. For more information see also :ref:`typecontextmanager` and
 Functions provided:
 
 
-.. function:: contextmanager(func)
+.. decorator:: contextmanager
 
    This function is a :term:`decorator` that can be used to define a factory
    function for :keyword:`with` statement context managers, without needing to
index 6ae175a8ec83edc3d5d22f6384af3a6b3540d889..a9819f2ea68ffcc263db0082e8aa72ae3ff35f91 100644 (file)
@@ -37,7 +37,7 @@ The :mod:`functools` module defines the following functions:
 
    .. versionadded:: 3.2
 
-.. function:: total_ordering(cls)
+.. decorator:: total_ordering
 
    Given a class defining one or more rich comparison ordering methods, this
    class decorator supplies the rest.  This simplifies the effort involved
@@ -122,7 +122,7 @@ The :mod:`functools` module defines the following functions:
    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,
    wrapped=wrapped, assigned=assigned, updated=updated)`` as a function decorator
index 7a2434e10b74cb5e28c5c014f6558e8de031d426..1b4e5fd36009dfd851c020743f07b5cd22f61a26 100644 (file)
@@ -469,7 +469,7 @@ find and load modules.
 This module contains the various objects that help in the construction of
 an :term:`importer`.
 
-.. function:: module_for_loader(method)
+.. decorator:: module_for_loader
 
     A :term:`decorator` for a :term:`loader` method,
     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
     loader should initialize as specified by :pep:`302`.
 
-.. function:: set_loader(fxn)
+.. decorator:: set_loader
 
     A :term:`decorator` for a :term:`loader` method,
     to set the :attr:`__loader__`
@@ -502,7 +502,7 @@ an :term:`importer`.
     does nothing. It is assumed that the first positional argument to the
     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__`
     attribute on the module returned by the loader. If :attr:`__package__` is
index f430c1701eae5f664e5958bcecc0db7310272fd3..8449fd2e1f38053f420b6f6c2c4591b0168c1d01 100644 (file)
@@ -621,20 +621,20 @@ the test unless the passed object has a certain attribute: ::
 
 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
    test is being skipped.
 
-.. function:: skipIf(condition, reason)
+.. decorator:: skipIf(condition, reason)
 
    Skip the decorated test if *condition* is true.
 
-.. function:: skipUnless(condition, reason)
+.. decorator:: skipUnless(condition, reason)
 
    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
    is not counted as a failure.
@@ -1048,11 +1048,11 @@ Test cases
       :attr:`exception` attribute.  This can be useful if the intention
       is to perform additional checks on the exception raised::
 
-        with self.assertRaises(SomeException) as cm:
-            do_something()
+         with self.assertRaises(SomeException) as cm:
+             do_something()
 
-        the_exception = cm.exception
-        self.assertEqual(the_exception.error_code, 3)
+         the_exception = cm.exception
+         self.assertEqual(the_exception.error_code, 3)
 
       .. versionchanged:: 3.1
          Added the ability to use :meth:`assertRaises` as a context manager.
index b7a6012c5f772a25ae209bf27caaecf25a5f0baf..5ee35b0332d57ea9438402c445a52dada6984dd0 100644 (file)
@@ -72,6 +72,32 @@ class ImplementationDetail(Directive):
         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
 
 pydoc_topic_labels = [
@@ -147,7 +173,6 @@ import suspicious
 # Support for documenting Opcodes
 
 import re
-from sphinx import addnodes
 
 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)',
                              parse_pdb_command)
     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)