From 8a1caa2361b86baeadfe5343b0c74fe9dec2a4ce Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Thu, 29 Jul 2010 16:01:11 +0000 Subject: #6522: add a "decorator" directive to explicitly document decorators, and use it in a few places. --- Doc/documenting/markup.rst | 32 ++++++++++++++++++++++++++++++++ Doc/library/abc.rst | 2 +- Doc/library/contextlib.rst | 2 +- Doc/library/functools.rst | 4 ++-- Doc/library/importlib.rst | 6 +++--- Doc/library/unittest.rst | 16 ++++++++-------- Doc/tools/sphinxext/pyspecific.py | 29 ++++++++++++++++++++++++++++- 7 files changed, 75 insertions(+), 16 deletions(-) diff --git a/Doc/documenting/markup.rst b/Doc/documenting/markup.rst index 34a79d4..e48bb01 100644 --- a/Doc/documenting/markup.rst +++ b/Doc/documenting/markup.rst @@ -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. diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst index aa1cc78..5e87e96 100644 --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -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. diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index 18e5502..35eb882 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -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 diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 6ae175a..a9819f2 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -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 diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 7a2434e..1b4e5fd 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -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 diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index f430c17..8449fd2 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -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. diff --git a/Doc/tools/sphinxext/pyspecific.py b/Doc/tools/sphinxext/pyspecific.py index b7a6012..5ee35b0 100644 --- a/Doc/tools/sphinxext/pyspecific.py +++ b/Doc/tools/sphinxext/pyspecific.py @@ -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) -- cgit v0.12