Merge branch 'release/1.10.10'
This commit is contained in:
132
README.rst
132
README.rst
@@ -3,11 +3,137 @@ wrapt
|
||||
|
||||
|Travis| |Coveralls| |PyPI|
|
||||
|
||||
A Python module for decorators, wrappers and monkey patching.
|
||||
The aim of the **wrapt** module is to provide a transparent object proxy
|
||||
for Python, which can be used as the basis for the construction of function
|
||||
wrappers and decorator functions.
|
||||
|
||||
For full documentation see:
|
||||
The **wrapt** module focuses very much on correctness. It therefore goes
|
||||
way beyond existing mechanisms such as ``functools.wraps()`` to ensure that
|
||||
decorators preserve introspectability, signatures, type checking abilities
|
||||
etc. The decorators that can be constructed using this module will work in
|
||||
far more scenarios than typical decorators and provide more predictable and
|
||||
consistent behaviour.
|
||||
|
||||
https://wrapt.readthedocs.io
|
||||
To ensure that the overhead is as minimal as possible, a C extension module
|
||||
is used for performance critical components. An automatic fallback to a
|
||||
pure Python implementation is also provided where a target system does not
|
||||
have a compiler to allow the C extension to be compiled.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
For further information on the **wrapt** module see:
|
||||
|
||||
* http://wrapt.readthedocs.org/
|
||||
|
||||
Quick Start
|
||||
-----------
|
||||
|
||||
To implement your decorator you need to first define a wrapper function.
|
||||
This will be called each time a decorated function is called. The wrapper
|
||||
function needs to take four positional arguments:
|
||||
|
||||
* ``wrapped`` - The wrapped function which in turns needs to be called by your wrapper function.
|
||||
* ``instance`` - The object to which the wrapped function was bound when it was called.
|
||||
* ``args`` - The list of positional arguments supplied when the decorated function was called.
|
||||
* ``kwargs`` - The dictionary of keyword arguments supplied when the decorated function was called.
|
||||
|
||||
The wrapper function would do whatever it needs to, but would usually in
|
||||
turn call the wrapped function that is passed in via the ``wrapped``
|
||||
argument.
|
||||
|
||||
The decorator ``@wrapt.decorator`` then needs to be applied to the wrapper
|
||||
function to convert it into a decorator which can in turn be applied to
|
||||
other functions.
|
||||
|
||||
::
|
||||
|
||||
import wrapt
|
||||
|
||||
@wrapt.decorator
|
||||
def pass_through(wrapped, instance, args, kwargs):
|
||||
return wrapped(*args, **kwargs)
|
||||
|
||||
@pass_through
|
||||
def function():
|
||||
pass
|
||||
|
||||
If you wish to implement a decorator which accepts arguments, then wrap the
|
||||
definition of the decorator in a function closure. Any arguments supplied
|
||||
to the outer function when the decorator is applied, will be available to
|
||||
the inner wrapper when the wrapped function is called.
|
||||
|
||||
::
|
||||
|
||||
import wrapt
|
||||
|
||||
def with_arguments(myarg1, myarg2):
|
||||
@wrapt.decorator
|
||||
def wrapper(wrapped, instance, args, kwargs):
|
||||
return wrapped(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
@with_arguments(1, 2)
|
||||
def function():
|
||||
pass
|
||||
|
||||
When applied to a normal function or static method, the wrapper function
|
||||
when called will be passed ``None`` as the ``instance`` argument.
|
||||
|
||||
When applied to an instance method, the wrapper function when called will
|
||||
be passed the instance of the class the method is being called on as the
|
||||
``instance`` argument. This will be the case even when the instance method
|
||||
was called explicitly via the class and the instance passed as the first
|
||||
argument. That is, the instance will never be passed as part of ``args``.
|
||||
|
||||
When applied to a class method, the wrapper function when called will be
|
||||
passed the class type as the ``instance`` argument.
|
||||
|
||||
When applied to a class, the wrapper function when called will be passed
|
||||
``None`` as the ``instance`` argument. The ``wrapped`` argument in this
|
||||
case will be the class.
|
||||
|
||||
The above rules can be summarised with the following example.
|
||||
|
||||
::
|
||||
|
||||
import inspect
|
||||
|
||||
@wrapt.decorator
|
||||
def universal(wrapped, instance, args, kwargs):
|
||||
if instance is None:
|
||||
if inspect.isclass(wrapped):
|
||||
# Decorator was applied to a class.
|
||||
return wrapped(*args, **kwargs)
|
||||
else:
|
||||
# Decorator was applied to a function or staticmethod.
|
||||
return wrapped(*args, **kwargs)
|
||||
else:
|
||||
if inspect.isclass(instance):
|
||||
# Decorator was applied to a classmethod.
|
||||
return wrapped(*args, **kwargs)
|
||||
else:
|
||||
# Decorator was applied to an instancemethod.
|
||||
return wrapped(*args, **kwargs)
|
||||
|
||||
Using these checks it is therefore possible to create a universal decorator
|
||||
that can be applied in all situations. It is no longer necessary to create
|
||||
different variants of decorators for normal functions and instance methods,
|
||||
or use additional wrappers to convert a function decorator into one that
|
||||
will work for instance methods.
|
||||
|
||||
In all cases, the wrapped function passed to the wrapper function is called
|
||||
in the same way, with ``args`` and ``kwargs`` being passed. The
|
||||
``instance`` argument doesn't need to be used in calling the wrapped
|
||||
function.
|
||||
|
||||
Repository
|
||||
----------
|
||||
|
||||
Full source code for the **wrapt** module, including documentation files
|
||||
and unit tests, can be obtained from github.
|
||||
|
||||
* https://github.com/GrahamDumpleton/wrapt
|
||||
|
||||
.. |Travis| image:: https://img.shields.io/travis/GrahamDumpleton/wrapt/develop.svg?style=plastic
|
||||
:target: https://travis-ci.org/GrahamDumpleton/wrapt?branch=develop
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
Version 1.10.10
|
||||
---------------
|
||||
|
||||
**Features Changed**
|
||||
|
||||
* Added back missing description and categorisations when releasing to PyPi.
|
||||
|
||||
Version 1.10.9
|
||||
--------------
|
||||
|
||||
**Bugs Fixed**
|
||||
|
||||
* Code for ``inspect.getargspec()`` when using Python 2.6 was missing
|
||||
import of ``sys`` module.
|
||||
|
||||
Version 1.10.8
|
||||
--------------
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ copyright = u'2013-2016, Graham Dumpleton'
|
||||
# The short X.Y version.
|
||||
version = '1.10'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.10.9'
|
||||
release = '1.10.10'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
16
setup.py
16
setup.py
@@ -32,14 +32,28 @@ class optional_build_ext(build_ext):
|
||||
except build_ext_errors:
|
||||
raise BuildExtFailed()
|
||||
|
||||
classifiers = [
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
'Programming Language :: Python :: Implementation :: PyPy',
|
||||
]
|
||||
|
||||
setup_kwargs = dict(
|
||||
name='wrapt',
|
||||
version='1.10.9',
|
||||
version='1.10.10',
|
||||
description='Module for decorators, wrappers and monkey patching.',
|
||||
long_description=open('README.rst').read(),
|
||||
author='Graham Dumpleton',
|
||||
author_email='Graham.Dumpleton@gmail.com',
|
||||
license='BSD',
|
||||
classifiers=classifiers,
|
||||
url='https://github.com/GrahamDumpleton/wrapt',
|
||||
packages=['wrapt'],
|
||||
package_dir={'': 'src'},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
__version_info__ = ('1', '10', '9')
|
||||
__version_info__ = ('1', '10', '10')
|
||||
__version__ = '.'.join(__version_info__)
|
||||
|
||||
from .wrappers import (ObjectProxy, CallableObjectProxy, FunctionWrapper,
|
||||
|
||||
Reference in New Issue
Block a user