summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichele Simionato <michele.simionato@gmail.com>2021-09-11 06:19:42 +0200
committerMichele Simionato <michele.simionato@gmail.com>2021-09-11 06:19:42 +0200
commit6ff2f891bd379c614c112eb6b6aa81b4b6b86d39 (patch)
treea1c541f3fc83e442496e740bb36011d815608ce7
parent590b55de8040c3af6600443030f0dc43180514c9 (diff)
downloadpython-decorator-git-6ff2f891bd379c614c112eb6b6aa81b4b6b86d39.tar.gz
Fixed some sphinx warnings
-rw-r--r--docs/documentation.md80
-rw-r--r--src/tests/documentation.py181
2 files changed, 104 insertions, 157 deletions
diff --git a/docs/documentation.md b/docs/documentation.md
index 162caae..bd2b4ad 100644
--- a/docs/documentation.md
+++ b/docs/documentation.md
@@ -1,17 +1,15 @@
-Decorators for Humans
-----------------------------------
+# Decorators for Humans
|Author | Michele Simionato|
|---|---|
|E-mail | michele.simionato@gmail.com|
-|Version| 5.0.9 (2021-05-16)|
+|Version| 5.0.9 (2021-09-11)|
|Supports| Python 3.5, 3.6, 3.7, 3.8, 3.9|
|Download page| http://pypi.python.org/pypi/decorator/5.0.9|
|Installation| ``pip install decorator``|
|License | BSD license|
-Introduction
------------------------------------------
+## Introduction
The ``decorator`` module is over ten years old, but still alive and
kicking. It is used by several frameworks (IPython, scipy, authkit,
@@ -22,8 +20,7 @@ supports Python versions greater than 3.4, versions 4.X supports Python
versions back to 2.6; versions 3.X are able to support even Python 2.5 and
2.4.
-What's New in version 5
------------------------
+## What's New in version 5
Version 5 of the decorator module features a major simplification of
the code base made possible by dropping support for Python releases
@@ -35,8 +32,7 @@ functions the traceback is nicer than it used to be. Moreover, it is
now possible to mimic the behavior of decorators defined with
``functool.wraps``: see the section about the ``kwsyntax`` flag below.
-What's New in version 4
------------------------
+## What's New in version 4
- **New documentation**
There is now a single manual for all Python versions, so I took the
@@ -75,8 +71,7 @@ What's New in version 4
From version 4.2 there is facility to define factories of decorators in
a simple way, a feature requested by the users since a long time.
-Usefulness of decorators
-------------------------------------------------
+## Usefulness of decorators
Python decorators are an interesting example of why syntactic sugar
matters. In principle, their introduction in Python 2.4 changed
@@ -106,8 +101,7 @@ You may find the source code for all the examples
discussed here in the ``documentation.py`` file, which contains
the documentation you are reading in the form of doctests.
-Definitions
-------------------------------------
+## Definitions
Technically speaking, any Python object which can be called with one argument
can be used as a decorator. However, this definition is somewhat too large
@@ -136,8 +130,7 @@ obvious, especially if one wants to define proper decorators that
can accept functions with any signature. A simple example will clarify
the issue.
-Statement of the problem
-------------------------------
+## Statement of the problem
A very common use case for decorators is the memoization of functions.
A ``memoize`` decorator works by caching
@@ -146,7 +139,7 @@ the function is called with the same input parameters the result is retrieved
from the cache and not recomputed.
There are many implementations of ``memoize`` in
-https://wiki.python.org/moin/PythonDecoratorLibrary,
+http://www.python.org/moin/PythonDecoratorLibrary,
but they do not preserve the signature. In recent versions of
Python you can find a sophisticated ``lru_cache`` decorator
in the standard library's ``functools``. Here I am just
@@ -222,8 +215,7 @@ TypeError: f1() takes exactly 1 positional argument (2 given)
Notice that ``pydoc`` will give the right signature, but only in Python
versions greater than 3.5.
-The solution
------------------------------------------
+## The solution
The solution is to provide a generic factory of generators, which
hides the complexity of making signature-preserving decorators
@@ -301,8 +293,7 @@ FullArgSpec(args=[], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwo
```
-A ``trace`` decorator
-------------------------------------------------------
+## A ``trace`` decorator
Here is an example of how to define a simple ``trace`` decorator,
which prints a message whenever the traced function is called:
@@ -361,8 +352,7 @@ FullArgSpec(args=['x', 'y'], varargs='args', varkw='kw', defaults=(1,), kwonlyar
```
-Function annotations
----------------------------------------------
+## Function annotations
Python 3 introduced the concept of [function annotations](
http://www.python.org/dev/peps/pep-3107/): the ability
@@ -416,9 +406,7 @@ This attribute exists for consistency with the behavior of
Another attribute copied from the original function is ``__qualname__``,
the qualified name. This attribute was introduced in Python 3.3.
-
-``decorator.decorator``
----------------------------------------------
+## ``decorator.decorator``
It can become tedious to write a caller function (like the above
``_trace`` example) and then a trivial wrapper
@@ -468,8 +456,7 @@ calling func with args (), {}
```
-Mimicking the behavior of functools.wrap
-----------------------------------------
+## Mimicking the behavior of functools.wrap
Often people are confused by the decorator module since, contrarily
to ``functools.wraps`` in the standard library, it tries very hard
@@ -551,8 +538,7 @@ positional, i.e. they belongs to the ``args`` tuple and not to ``kwargs``:
```
-Decorator factories
--------------------------------------------
+## Decorator factories
The `decorator` function can also be used to define factories of decorators,
i.e. functions returning decorators. In general you can just write something
@@ -683,8 +669,7 @@ TypeError: You are decorating a non function: <class '__main__.User'>
Be careful!
-``decorator(cls)``
---------------------------------------------
+## ``decorator(cls)``
The ``decorator`` facility can also produce a decorator starting
from a class with the signature of a caller. In such a case the
@@ -742,8 +727,7 @@ Here is the minimalistic usage:
```
-contextmanager
--------------------------------------
+## contextmanager
Python's standard library has the ``contextmanager`` decorator,
which converts a generator function into a ``GeneratorContextManager``
@@ -780,11 +764,11 @@ a ``__call__`` method, so that they can be used as decorators, like so:
```python
>>> ba = before_after('BEFORE', 'AFTER')
>>>
->>> @ba
+>>> @ba
... def hello():
... print('hello')
...
->>> hello()
+>>> hello()
BEFORE
hello
AFTER
@@ -808,8 +792,7 @@ instances of ``ContextManager``, a subclass of the standard library's
an improved ``__call__`` method, which acts as a signature-preserving
decorator.
-The ``FunctionMaker`` class
----------------------------------------------------------------
+## The ``FunctionMaker`` class
The ``decorator`` module also provides a ``FunctionMaker`` class, which
is able to generate on-the-fly functions
@@ -899,8 +882,7 @@ FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=(None,), kwonlya
```
-Getting the source code
----------------------------------------------------
+## Getting the source code
Internally, ``FunctionMaker.create`` uses ``exec`` to generate the
decorated function. Therefore ``inspect.getsource`` will not work for
@@ -923,8 +905,7 @@ def factorial(n, acc=1):
```
-Dealing with third-party decorators
------------------------------------------------------------------
+## Dealing with third-party decorators
Sometimes on the net you find some cool decorator that you would
like to include in your code. However, more often than not, the cool
@@ -1047,8 +1028,7 @@ following:
- returns a value without making a recursive call; or,
- returns directly the result of a recursive call.
-Python 3.5 coroutines
------------------------
+## Python 3.5 coroutines
I am personally not using Python 3.5 coroutines yet. However, some
users requested support for coroutines and since version 4.1 the
@@ -1118,8 +1098,7 @@ function and the associate decorator was converting coroutines in coroutines;
the caller in ``coro_to_func`` is a regular function and converts
coroutines -> functions.
-Multiple dispatch
--------------------------------------------
+## Multiple dispatch
There has been talk of implementing multiple dispatch functions
(i.e. "generic functions") in Python for over ten years. Last year,
@@ -1315,8 +1294,7 @@ product of the class precedence lists (or *Method Resolution Orders*,
[MRO](http://www.python.org/2.3/mro.html) for short) of ``StrongRock``
and ``Scissors``, respectively.
-Generic functions and virtual ancestors
--------------------------------------------------
+## Generic functions and virtual ancestors
In Python, generic functions are complicated by the existence of
"virtual ancestors": superclasses which are not in the class hierarchy.
@@ -1535,8 +1513,7 @@ call-next-method in Lisp, or to ``super`` in Python.
Finally, let me notice that the decorator module implementation does
not use any cache, whereas the ``singledispatch`` implementation does.
-Caveats and limitations
--------------------------------------------
+## Caveats and limitations
In the present implementation, decorators generated by ``decorator``
can only be used on user-defined Python functions, methods or coroutines.
@@ -1650,8 +1627,7 @@ than the function ``f`` here, so the real life performance penalty
*could* be negligible. As always, the only way to know if there is a
penalty in your specific use case is to measure it.
-LICENSE (2-clause BSD)
----------------------------------------------
+## LICENSE (2-clause BSD)
Copyright (c) 2005-2020, Michele Simionato
All rights reserved.
@@ -1682,4 +1658,4 @@ DAMAGE.
If you use this software and you are happy with it, consider sending me a
note, just to gratify my ego. On the other hand, if you use this software and
-you are unhappy with it, send me a patch!
+you are unhappy with it, send me a patch! \ No newline at end of file
diff --git a/src/tests/documentation.py b/src/tests/documentation.py
index 5323c4e..2befd27 100644
--- a/src/tests/documentation.py
+++ b/src/tests/documentation.py
@@ -9,8 +9,7 @@ import collections.abc as c
from decorator import (decorator, decorate, FunctionMaker,
dispatch_on, __version__)
-doc = r"""Decorators for Humans
-----------------------------------
+doc = r"""# Decorators for Humans
|Author | Michele Simionato|
|---|---|
@@ -21,8 +20,7 @@ doc = r"""Decorators for Humans
|Installation| ``pip install decorator``|
|License | BSD license|
-Introduction
------------------------------------------
+## Introduction
The ``decorator`` module is over ten years old, but still alive and
kicking. It is used by several frameworks (IPython, scipy, authkit,
@@ -33,8 +31,7 @@ supports Python versions greater than 3.4, versions 4.X supports Python
versions back to 2.6; versions 3.X are able to support even Python 2.5 and
2.4.
-What's New in version 5
------------------------
+## What's New in version 5
Version 5 of the decorator module features a major simplification of
the code base made possible by dropping support for Python releases
@@ -46,8 +43,7 @@ functions the traceback is nicer than it used to be. Moreover, it is
now possible to mimic the behavior of decorators defined with
``functool.wraps``: see the section about the ``kwsyntax`` flag below.
-What's New in version 4
------------------------
+## What's New in version 4
- **New documentation**
There is now a single manual for all Python versions, so I took the
@@ -86,8 +82,7 @@ What's New in version 4
From version 4.2 there is facility to define factories of decorators in
a simple way, a feature requested by the users since a long time.
-Usefulness of decorators
-------------------------------------------------
+## Usefulness of decorators
Python decorators are an interesting example of why syntactic sugar
matters. In principle, their introduction in Python 2.4 changed
@@ -117,8 +112,7 @@ You may find the source code for all the examples
discussed here in the ``documentation.py`` file, which contains
the documentation you are reading in the form of doctests.
-Definitions
-------------------------------------
+## Definitions
Technically speaking, any Python object which can be called with one argument
can be used as a decorator. However, this definition is somewhat too large
@@ -147,8 +141,7 @@ obvious, especially if one wants to define proper decorators that
can accept functions with any signature. A simple example will clarify
the issue.
-Statement of the problem
-------------------------------
+## Statement of the problem
A very common use case for decorators is the memoization of functions.
A ``memoize`` decorator works by caching
@@ -212,8 +205,7 @@ TypeError: f1() takes exactly 1 positional argument (2 given)
Notice that ``pydoc`` will give the right signature, but only in Python
versions greater than 3.5.
-The solution
------------------------------------------
+## The solution
The solution is to provide a generic factory of generators, which
hides the complexity of making signature-preserving decorators
@@ -270,8 +262,7 @@ FullArgSpec(args=[], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwo
```
-A ``trace`` decorator
-------------------------------------------------------
+## A ``trace`` decorator
Here is an example of how to define a simple ``trace`` decorator,
which prints a message whenever the traced function is called:
@@ -320,10 +311,61 @@ FullArgSpec(args=['x', 'y'], varargs='args', varkw='kw', defaults=(1,), kwonlyar
```
-$FUNCTION_ANNOTATIONS
+## Function annotations
-``decorator.decorator``
----------------------------------------------
+Python 3 introduced the concept of [function annotations](
+http://www.python.org/dev/peps/pep-3107/): the ability
+to annotate the signature of a function with additional information,
+stored in a dictionary named ``__annotations__``. The ``decorator`` module
+(starting from release 3.3) will understand and preserve these annotations.
+
+Here is an example:
+
+```python
+>>> @trace
+... def f(x: 'the first argument', y: 'default argument'=1, z=2,
+... *args: 'varargs', **kw: 'kwargs'):
+... pass
+
+```
+
+In order to introspect functions with annotations, one needs
+``inspect.getfullargspec`` (introduced in Python 3, then
+deprecated in Python 3.5, then undeprecated in Python 3.6):
+
+```python
+>>> from inspect import getfullargspec
+>>> argspec = getfullargspec(f)
+>>> argspec.args
+['x', 'y', 'z']
+>>> argspec.varargs
+'args'
+>>> argspec.varkw
+'kw'
+>>> argspec.defaults
+(1, 2)
+>>> argspec.kwonlyargs
+[]
+>>> argspec.kwonlydefaults
+
+```
+
+You can check that the ``__annotations__`` dictionary is preserved:
+
+```python
+>>> f.__annotations__ is f.__wrapped__.__annotations__
+True
+
+```
+
+Here ``f.__wrapped__`` is the original undecorated function.
+This attribute exists for consistency with the behavior of
+``functools.update_wrapper``.
+
+Another attribute copied from the original function is ``__qualname__``,
+the qualified name. This attribute was introduced in Python 3.3.
+
+## ``decorator.decorator``
It can become tedious to write a caller function (like the above
``_trace`` example) and then a trivial wrapper
@@ -373,8 +415,7 @@ calling func with args (), {}
```
-Mimicking the behavior of functools.wrap
-----------------------------------------
+## Mimicking the behavior of functools.wrap
Often people are confused by the decorator module since, contrarily
to ``functools.wraps`` in the standard library, it tries very hard
@@ -433,8 +474,7 @@ positional, i.e. they belongs to the ``args`` tuple and not to ``kwargs``:
```
-Decorator factories
--------------------------------------------
+## Decorator factories
The `decorator` function can also be used to define factories of decorators,
i.e. functions returning decorators. In general you can just write something
@@ -524,8 +564,7 @@ TypeError: You are decorating a non function: <class '__main__.User'>
Be careful!
-``decorator(cls)``
---------------------------------------------
+## ``decorator(cls)``
The ``decorator`` facility can also produce a decorator starting
from a class with the signature of a caller. In such a case the
@@ -561,8 +600,7 @@ Here is the minimalistic usage:
```
-contextmanager
--------------------------------------
+## contextmanager
Python's standard library has the ``contextmanager`` decorator,
which converts a generator function into a ``GeneratorContextManager``
@@ -627,8 +665,7 @@ instances of ``ContextManager``, a subclass of the standard library's
an improved ``__call__`` method, which acts as a signature-preserving
decorator.
-The ``FunctionMaker`` class
----------------------------------------------------------------
+## The ``FunctionMaker`` class
The ``decorator`` module also provides a ``FunctionMaker`` class, which
is able to generate on-the-fly functions
@@ -718,8 +755,7 @@ FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=(None,), kwonlya
```
-Getting the source code
----------------------------------------------------
+## Getting the source code
Internally, ``FunctionMaker.create`` uses ``exec`` to generate the
decorated function. Therefore ``inspect.getsource`` will not work for
@@ -742,8 +778,7 @@ def factorial(n, acc=1):
```
-Dealing with third-party decorators
------------------------------------------------------------------
+## Dealing with third-party decorators
Sometimes on the net you find some cool decorator that you would
like to include in your code. However, more often than not, the cool
@@ -807,8 +842,7 @@ following:
- returns a value without making a recursive call; or,
- returns directly the result of a recursive call.
-Python 3.5 coroutines
------------------------
+## Python 3.5 coroutines
I am personally not using Python 3.5 coroutines yet. However, some
users requested support for coroutines and since version 4.1 the
@@ -878,8 +912,7 @@ function and the associate decorator was converting coroutines in coroutines;
the caller in ``coro_to_func`` is a regular function and converts
coroutines -> functions.
-Multiple dispatch
--------------------------------------------
+## Multiple dispatch
There has been talk of implementing multiple dispatch functions
(i.e. "generic functions") in Python for over ten years. Last year,
@@ -1016,8 +1049,7 @@ product of the class precedence lists (or *Method Resolution Orders*,
[MRO](http://www.python.org/2.3/mro.html) for short) of ``StrongRock``
and ``Scissors``, respectively.
-Generic functions and virtual ancestors
--------------------------------------------------
+## Generic functions and virtual ancestors
In Python, generic functions are complicated by the existence of
"virtual ancestors": superclasses which are not in the class hierarchy.
@@ -1161,8 +1193,7 @@ call-next-method in Lisp, or to ``super`` in Python.
Finally, let me notice that the decorator module implementation does
not use any cache, whereas the ``singledispatch`` implementation does.
-Caveats and limitations
--------------------------------------------
+## Caveats and limitations
In the present implementation, decorators generated by ``decorator``
can only be used on user-defined Python functions, methods or coroutines.
@@ -1276,8 +1307,7 @@ than the function ``f`` here, so the real life performance penalty
*could* be negligible. As always, the only way to know if there is a
penalty in your specific use case is to measure it.
-LICENSE (2-clause BSD)
----------------------------------------------
+## LICENSE (2-clause BSD)
Copyright (c) 2005-2020, Michele Simionato
All rights reserved.
@@ -1311,68 +1341,9 @@ note, just to gratify my ego. On the other hand, if you use this software and
you are unhappy with it, send me a patch!
"""
-function_annotations = """Function annotations
----------------------------------------------
-
-Python 3 introduced the concept of [function annotations](
-http://www.python.org/dev/peps/pep-3107/): the ability
-to annotate the signature of a function with additional information,
-stored in a dictionary named ``__annotations__``. The ``decorator`` module
-(starting from release 3.3) will understand and preserve these annotations.
-
-Here is an example:
-
-```python
->>> @trace
-... def f(x: 'the first argument', y: 'default argument'=1, z=2,
-... *args: 'varargs', **kw: 'kwargs'):
-... pass
-
-```
-
-In order to introspect functions with annotations, one needs
-``inspect.getfullargspec`` (introduced in Python 3, then
-deprecated in Python 3.5, then undeprecated in Python 3.6):
-
-```python
->>> from inspect import getfullargspec
->>> argspec = getfullargspec(f)
->>> argspec.args
-['x', 'y', 'z']
->>> argspec.varargs
-'args'
->>> argspec.varkw
-'kw'
->>> argspec.defaults
-(1, 2)
->>> argspec.kwonlyargs
-[]
->>> argspec.kwonlydefaults
-
-```
-
-You can check that the ``__annotations__`` dictionary is preserved:
-
-```python
->>> f.__annotations__ is f.__wrapped__.__annotations__
-True
-
-```
-
-Here ``f.__wrapped__`` is the original undecorated function.
-This attribute exists for consistency with the behavior of
-``functools.update_wrapper``.
-
-Another attribute copied from the original function is ``__qualname__``,
-the qualified name. This attribute was introduced in Python 3.3.
-"""
-if sys.version_info < (3,):
- function_annotations = ''
-
today = time.strftime('%Y-%m-%d')
-__doc__ = (doc.replace('$VERSION', __version__).replace('$DATE', today)
- .replace('$FUNCTION_ANNOTATIONS', function_annotations))
+__doc__ = doc.replace('$VERSION', __version__).replace('$DATE', today)
def decorator_apply(dec, func):