summaryrefslogtreecommitdiff
path: root/six.py
diff options
context:
space:
mode:
authorimmerrr again <immerrr@gmail.com>2020-01-07 03:55:42 +0100
committerBenjamin Peterson <benjamin@python.org>2020-01-06 18:55:42 -0800
commit1988faf3f7a7f77c0eccbbc5192f365400d44deb (patch)
treecbb35c98e90da9dcd8f319b16c4ffe607d2c2a50 /six.py
parenta4d9af96b122e98b7be3649b6545e0f6a04c8335 (diff)
downloadsix-git-1988faf3f7a7f77c0eccbbc5192f365400d44deb.tar.gz
Fix wraps handing of missing attrs. (#251)
This is pretty-much a straight backport of Py3 implementations of update_wrapper and (privately) wraps. Fixes #250 Fixes #165 Co-authored-by: Benjamin Peterson <benjamin@python.org>
Diffstat (limited to 'six.py')
-rw-r--r--six.py31
1 files changed, 25 insertions, 6 deletions
diff --git a/six.py b/six.py
index de1fcc5..d68d91c 100644
--- a/six.py
+++ b/six.py
@@ -808,13 +808,33 @@ if sys.version_info[:2] < (3, 3):
_add_doc(reraise, """Reraise an exception.""")
if sys.version_info[0:2] < (3, 4):
+ # This does exactly the same what the :func:`py3:functools.update_wrapper`
+ # function does on Python versions after 3.2. It sets the ``__wrapped__``
+ # attribute on ``wrapper`` object and it doesn't raise an error if any of
+ # the attributes mentioned in ``assigned`` and ``updated`` are missing on
+ # ``wrapped`` object.
+ def _update_wrapper(wrapper, wrapped,
+ assigned=functools.WRAPPER_ASSIGNMENTS,
+ updated=functools.WRAPPER_UPDATES):
+ for attr in assigned:
+ try:
+ value = getattr(wrapped, attr)
+ except AttributeError:
+ continue
+ else:
+ setattr(wrapper, attr, value)
+ for attr in updated:
+ getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
+ wrapper.__wrapped__ = wrapped
+ return wrapper
+ _update_wrapper.__doc__ = functools.update_wrapper.__doc__
+
def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
updated=functools.WRAPPER_UPDATES):
- def wrapper(f):
- f = functools.wraps(wrapped, assigned, updated)(f)
- f.__wrapped__ = wrapped
- return f
- return wrapper
+ return functools.partial(_update_wrapper, wrapped=wrapped,
+ assigned=assigned, updated=updated)
+ wraps.__doc__ = functools.wraps.__doc__
+
else:
wraps = functools.wraps
@@ -919,7 +939,6 @@ def ensure_text(s, encoding='utf-8', errors='strict'):
raise TypeError("not expecting type '%s'" % type(s))
-
def python_2_unicode_compatible(klass):
"""
A class decorator that defines __unicode__ and __str__ methods under Python 2.