From 5e3e1917f701fcc9d88b7c1a7dd50ed485865be1 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 11 Sep 2014 18:30:02 -0400 Subject: intersphinx now with https urls --- documentation/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/conf.py b/documentation/conf.py index fd285c7..7e54287 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -213,5 +213,5 @@ man_pages = [ # -- Intersphinx --------------------------------------------------------------- -intersphinx_mapping = {"py2" : ("http://docs.python.org/2/", None), - "py3" : ("http://docs.python.org/3/", None)} +intersphinx_mapping = {"py2" : ("https://docs.python.org/2/", None), + "py3" : ("https://docs.python.org/3/", None)} -- cgit v1.2.1 From 21604bf0d0856376f45904f60a8364e29e0ccd29 Mon Sep 17 00:00:00 2001 From: Alexander Artemenko Date: Fri, 12 Sep 2014 06:31:34 +0000 Subject: Wrapped some tokens with backquotes to render them nicely in Markdown. --- CHANGES | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index 87315e3..ed97053 100644 --- a/CHANGES +++ b/CHANGES @@ -6,35 +6,35 @@ This file lists the changes in each six version. 1.8.0 ----- -- Issue #90: Add six.moves.shlex_quote. +- Issue #90: Add `six.moves.shlex_quote`. -- Issue #59: Add six.moves.intern. +- Issue #59: Add `six.moves.intern`. -- Add six.urllib.parse.uses_(fragment|netloc|params|query|relative). +- Add `six.urllib.parse.uses_(fragment|netloc|params|query|relative)`. -- Issue #88: Fix add_metaclass when the class has __slots__ containing - "__weakref__" or "__dict__". +- Issue #88: Fix add_metaclass when the class has `__slots__` containing + `__weakref__` or `__dict__`. - Issue #89: Make six use absolute imports. -- Issue #85: Always accept *updated* and *assigned* arguments for wraps(). +- Issue #85: Always accept *updated* and *assigned* arguments for `wraps()`. -- Issue #86: In reraise(), instantiate the exception if the second argument is - None. +- Issue #86: In `reraise()`, instantiate the exception if the second argument is + `None`. -- Pull request #45: Add six.moves.email_mime_nonmultipart. +- Pull request #45: Add `six.moves.email_mime_nonmultipart`. -- Issue #81: Add six.urllib.request.splittag mapping. +- Issue #81: Add `six.urllib.request.splittag` mapping. -- Issue #80: Add six.urllib.request.splituser mapping. +- Issue #80: Add `six.urllib.request.splituser` mapping. 1.7.3 ----- - Issue #77: Fix import six on Python 3.4 with a custom loader. -- Issue #74: six.moves.xmlrpc_server should map to SimpleXMLRPCServer on Python - 2 as documented not xmlrpclib. +- Issue #74: `six.moves.xmlrpc_server` should map to `SimpleXMLRPCServer` on Python + 2 as documented not `xmlrpclib`. 1.7.2 ----- -- cgit v1.2.1 From 61e0bcdf6f57d77c7315a9d801b912359a71eb9a Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 13 Sep 2014 01:38:48 -0400 Subject: add Alexander Artemenko --- CONTRIBUTORS | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 29b0f6a..0cbd0a4 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -3,6 +3,7 @@ acknowledge the following people who submitted bug reports, pull requests, and otherwise worked to improve six: Marc Abramowitz +Alexander Artemenko Aymeric Augustin Ned Batchelder Jason R. Coombs -- cgit v1.2.1 From 4711b7ae8befb52017ed5abdd272f6e5eff61606 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Oct 2014 14:13:36 -0400 Subject: Introduce viewkeys(), viewvalues(), and viewitems(). Closes issue #92 --- .hgignore | 1 + documentation/index.rst | 21 +++++++++++++++++++++ six.py | 22 ++++++++++++++++++++++ test_six.py | 29 +++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+) diff --git a/.hgignore b/.hgignore index 2a22acf..8815294 100644 --- a/.hgignore +++ b/.hgignore @@ -4,3 +4,4 @@ dist MANIFEST documentation/_build .tox +six.egg-info diff --git a/documentation/index.rst b/documentation/index.rst index 0adadc2..594976b 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -203,6 +203,27 @@ functions and methods is the stdlib :mod:`py3:inspect` module. *kwargs* are passed through to the underlying method. +.. function:: viewkeys(dictionary, **kwargs) + + Returns a view over *dictionary*\'s keys. This replaces + ``dictionary.viewkeys()`` on Python 2.7 and ``dictionary.keys()`` on + Python 3. *kwargs* are passed through to the underlying method. + + +.. function:: viewvalues(dictionary, **kwargs) + + Returns a view over *dictionary*\'s values. This replaces + ``dictionary.viewvalues()`` on Python 2.7 and ``dictionary.values()`` on + Python 3. *kwargs* are passed through to the underlying method. + + +.. function:: viewitems(dictionary, **kwargs) + + Returns a view over *dictionary*\'s items. This replaces + ``dictionary.viewitems()`` on Python 2.7 and ``dictionary.items()`` on + Python 3. *kwargs* are passed through to the underlying method. + + .. function:: create_bound_method(func, obj) Return a method object wrapping *func* and bound to *obj*. On both Python 2 diff --git a/six.py b/six.py index 21b0e80..5efb62b 100644 --- a/six.py +++ b/six.py @@ -554,6 +554,15 @@ if PY3: def iterlists(d, **kw): return iter(d.lists(**kw)) + + def viewkeys(d, **kw): + return d.keys(**kw) + + def viewvalues(d, **kw): + return d.values(**kw) + + def viewitems(d, **kw): + return d.items(**kw) else: def iterkeys(d, **kw): return iter(d.iterkeys(**kw)) @@ -567,12 +576,25 @@ else: def iterlists(d, **kw): return iter(d.iterlists(**kw)) + def viewkeys(d, **kw): + return d.viewkeys(**kw) + + def viewvalues(d, **kw): + return d.viewvalues(**kw) + + def viewitems(d, **kw): + return d.viewitems(**kw) + _add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") _add_doc(itervalues, "Return an iterator over the values of a dictionary.") _add_doc(iteritems, "Return an iterator over the (key, value) pairs of a dictionary.") _add_doc(iterlists, "Return an iterator over the (key, [values]) pairs of a dictionary.") +_add_doc(viewkeys, "Return a view over the keys of a dictionary.") +_add_doc(viewvalues, "Retun a view over the values of a dictionary.") +_add_doc(viewitems, + "Return a view over the (key, value) pairs of a dictionary.") if PY3: diff --git a/test_six.py b/test_six.py index 0125d6b..4ca3200 100644 --- a/test_six.py +++ b/test_six.py @@ -389,6 +389,35 @@ def test_dictionary_iterators(monkeypatch): monkeypatch.undo() +def test_dictionary_views(monkeypatch): + if sys.version_info[:2] <= (2, 6): + py.test.skip("view methods on dictionaries only available on 2.7+") + def stock_method_name(viewwhat): + """Given a method suffix like "keys" or "values", return the name + of the dict method that delivers those on the version of Python + we're running in.""" + if six.PY3: + return viewwhat + return 'view' + viewwhat + + class MyDict(dict): + pass + + d = MyDict(zip(range(10), reversed(range(10)))) + for name in "keys", "values", "items": + meth = getattr(six, "view" + name) + view = meth(d) + assert set(view) == set(getattr(d, name)()) + record = [] + def with_kw(*args, **kw): + record.append(kw["kw"]) + return old(*args) + old = getattr(MyDict, stock_method_name(name)) + monkeypatch.setattr(MyDict, stock_method_name(name), with_kw) + meth(d, kw=42) + assert record == [42] + monkeypatch.undo() + def test_advance_iterator(): assert six.next is six.advance_iterator l = [1, 2] -- cgit v1.2.1 From 165e06f7cbb9fd1861aea0cc08ebd331597afff5 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sun, 5 Oct 2014 16:28:21 -0400 Subject: Address PR comments --- documentation/index.rst | 6 +++--- six.py | 22 ++++++---------------- test_six.py | 30 ++++++++++++++++-------------- 3 files changed, 25 insertions(+), 33 deletions(-) diff --git a/documentation/index.rst b/documentation/index.rst index 594976b..1cd87de 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -205,21 +205,21 @@ functions and methods is the stdlib :mod:`py3:inspect` module. .. function:: viewkeys(dictionary, **kwargs) - Returns a view over *dictionary*\'s keys. This replaces + Return a view over *dictionary*\'s keys. This replaces ``dictionary.viewkeys()`` on Python 2.7 and ``dictionary.keys()`` on Python 3. *kwargs* are passed through to the underlying method. .. function:: viewvalues(dictionary, **kwargs) - Returns a view over *dictionary*\'s values. This replaces + Return a view over *dictionary*\'s values. This replaces ``dictionary.viewvalues()`` on Python 2.7 and ``dictionary.values()`` on Python 3. *kwargs* are passed through to the underlying method. .. function:: viewitems(dictionary, **kwargs) - Returns a view over *dictionary*\'s items. This replaces + Return a view over *dictionary*\'s items. This replaces ``dictionary.viewitems()`` on Python 2.7 and ``dictionary.items()`` on Python 3. *kwargs* are passed through to the underlying method. diff --git a/six.py b/six.py index 5efb62b..4252fdf 100644 --- a/six.py +++ b/six.py @@ -555,14 +555,11 @@ if PY3: def iterlists(d, **kw): return iter(d.lists(**kw)) - def viewkeys(d, **kw): - return d.keys(**kw) + viewkeys = operator.methodcaller("keys") - def viewvalues(d, **kw): - return d.values(**kw) + viewvalues = operator.methodcaller("values") - def viewitems(d, **kw): - return d.items(**kw) + viewitems = operator.methodcaller("items") else: def iterkeys(d, **kw): return iter(d.iterkeys(**kw)) @@ -576,14 +573,11 @@ else: def iterlists(d, **kw): return iter(d.iterlists(**kw)) - def viewkeys(d, **kw): - return d.viewkeys(**kw) + viewkeys = operator.methodcaller("viewkeys") - def viewvalues(d, **kw): - return d.viewvalues(**kw) + viewvalues = operator.methodcaller("viewvalues") - def viewitems(d, **kw): - return d.viewitems(**kw) + viewitems = operator.methodcaller("viewitems") _add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") _add_doc(itervalues, "Return an iterator over the values of a dictionary.") @@ -591,10 +585,6 @@ _add_doc(iteritems, "Return an iterator over the (key, value) pairs of a dictionary.") _add_doc(iterlists, "Return an iterator over the (key, [values]) pairs of a dictionary.") -_add_doc(viewkeys, "Return a view over the keys of a dictionary.") -_add_doc(viewvalues, "Retun a view over the values of a dictionary.") -_add_doc(viewitems, - "Return a view over the (key, value) pairs of a dictionary.") if PY3: diff --git a/test_six.py b/test_six.py index 4ca3200..6b2b97e 100644 --- a/test_six.py +++ b/test_six.py @@ -389,9 +389,9 @@ def test_dictionary_iterators(monkeypatch): monkeypatch.undo() -def test_dictionary_views(monkeypatch): - if sys.version_info[:2] <= (2, 6): - py.test.skip("view methods on dictionaries only available on 2.7+") +@py.test.mark.skipIf(sys.version_info[:2] <= (2, 6), + "view methods on dictionaries only available on 2.7+") +def test_dictionary_views(): def stock_method_name(viewwhat): """Given a method suffix like "keys" or "values", return the name of the dict method that delivers those on the version of Python @@ -401,22 +401,24 @@ def test_dictionary_views(monkeypatch): return 'view' + viewwhat class MyDict(dict): - pass + def viewkeys(self, *args, **kw): + record.append(kw) + return super(MyDict, self).viewkeys() - d = MyDict(zip(range(10), reversed(range(10)))) + def keys(self, *args, **kw): + record.append(kw) + return super().keys() + + d = dict(zip(range(10), reversed(range(10)))) for name in "keys", "values", "items": meth = getattr(six, "view" + name) view = meth(d) assert set(view) == set(getattr(d, name)()) - record = [] - def with_kw(*args, **kw): - record.append(kw["kw"]) - return old(*args) - old = getattr(MyDict, stock_method_name(name)) - monkeypatch.setattr(MyDict, stock_method_name(name), with_kw) - meth(d, kw=42) - assert record == [42] - monkeypatch.undo() + d = MyDict() + record = [] + six.viewkeys(d, kw=42) + assert record == [{'kw': 42}] + def test_advance_iterator(): assert six.next is six.advance_iterator -- cgit v1.2.1 From b9deda673f29f6d057b60412164761a63bbc671c Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 10 Oct 2014 10:37:46 -0400 Subject: Drop kwargs tests for view* --- test_six.py | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/test_six.py b/test_six.py index 6b2b97e..1940b5c 100644 --- a/test_six.py +++ b/test_six.py @@ -389,7 +389,7 @@ def test_dictionary_iterators(monkeypatch): monkeypatch.undo() -@py.test.mark.skipIf(sys.version_info[:2] <= (2, 6), +@py.test.mark.skipIf(sys.version_info[:2] < (2, 7), "view methods on dictionaries only available on 2.7+") def test_dictionary_views(): def stock_method_name(viewwhat): @@ -400,24 +400,11 @@ def test_dictionary_views(): return viewwhat return 'view' + viewwhat - class MyDict(dict): - def viewkeys(self, *args, **kw): - record.append(kw) - return super(MyDict, self).viewkeys() - - def keys(self, *args, **kw): - record.append(kw) - return super().keys() - - d = dict(zip(range(10), reversed(range(10)))) + d = dict(zip(range(10), (range(11, 20)))) for name in "keys", "values", "items": meth = getattr(six, "view" + name) view = meth(d) assert set(view) == set(getattr(d, name)()) - d = MyDict() - record = [] - six.viewkeys(d, kw=42) - assert record == [{'kw': 42}] def test_advance_iterator(): -- cgit v1.2.1 From f1755ac0f1837f146a1d95ff3ba9cef91f2ed5b5 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 10 Oct 2014 10:58:26 -0400 Subject: It's skipIf, not skipif --- test_six.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_six.py b/test_six.py index 1940b5c..4163520 100644 --- a/test_six.py +++ b/test_six.py @@ -389,8 +389,8 @@ def test_dictionary_iterators(monkeypatch): monkeypatch.undo() -@py.test.mark.skipIf(sys.version_info[:2] < (2, 7), - "view methods on dictionaries only available on 2.7+") +@py.test.mark.skipif(sys.version_info[:2] < (2, 7), + reason="view methods on dictionaries only available on 2.7+") def test_dictionary_views(): def stock_method_name(viewwhat): """Given a method suffix like "keys" or "values", return the name -- cgit v1.2.1 From ce75a6122644c41e7a8ca5358ca61c12866d142d Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 10 Oct 2014 11:24:35 -0400 Subject: Remove references to kwargs for view* --- documentation/index.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/documentation/index.rst b/documentation/index.rst index 1cd87de..93b1daa 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -203,25 +203,25 @@ functions and methods is the stdlib :mod:`py3:inspect` module. *kwargs* are passed through to the underlying method. -.. function:: viewkeys(dictionary, **kwargs) +.. function:: viewkeys(dictionary) Return a view over *dictionary*\'s keys. This replaces ``dictionary.viewkeys()`` on Python 2.7 and ``dictionary.keys()`` on - Python 3. *kwargs* are passed through to the underlying method. + Python 3. -.. function:: viewvalues(dictionary, **kwargs) +.. function:: viewvalues(dictionary) Return a view over *dictionary*\'s values. This replaces ``dictionary.viewvalues()`` on Python 2.7 and ``dictionary.values()`` on - Python 3. *kwargs* are passed through to the underlying method. + Python 3. -.. function:: viewitems(dictionary, **kwargs) +.. function:: viewitems(dictionary) Return a view over *dictionary*\'s items. This replaces ``dictionary.viewitems()`` on Python 2.7 and ``dictionary.items()`` on - Python 3. *kwargs* are passed through to the underlying method. + Python 3. .. function:: create_bound_method(func, obj) -- cgit v1.2.1 -- cgit v1.2.1 From 46385c80c73671751c72c6c5fb68e34f0d7bdfaf Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Sat, 11 Oct 2014 15:18:45 -0700 Subject: Fix simulatenous delattr When two or more threads enter the descriptor one of them will delete the attribute and the others will not be able to, we should handle that case more gracefully. --- six.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/six.py b/six.py index 4252fdf..0df4538 100644 --- a/six.py +++ b/six.py @@ -88,8 +88,12 @@ class _LazyDescr(object): def __get__(self, obj, tp): result = self._resolve() setattr(obj, self.name, result) # Invokes __set__. - # This is a bit ugly, but it avoids running this again. - delattr(obj.__class__, self.name) + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass return result -- cgit v1.2.1 From 1dcc9c7b25e50647aed75d1e3ef55a410ac298a6 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 12 Oct 2014 14:19:22 -0400 Subject: update changelog --- CHANGES | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES b/CHANGES index ed97053..02a20f0 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,14 @@ Changelog for six This file lists the changes in each six version. +Development version +------------------- + +- Issue #98: Fix `six.moves` race condition in multi-threaded code. + +- Pull request #51: Add `six.view(keys|values|itmes)`, which provide dictionary + views on Python 2.7+. + 1.8.0 ----- -- cgit v1.2.1 From 0ca3d06129aeca4ac508487f6b06f700dc0fe7d3 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 12 Oct 2014 14:24:37 -0400 Subject: link to python docs for dict view methods --- documentation/index.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/index.rst b/documentation/index.rst index 93b1daa..57786ea 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -206,21 +206,21 @@ functions and methods is the stdlib :mod:`py3:inspect` module. .. function:: viewkeys(dictionary) Return a view over *dictionary*\'s keys. This replaces - ``dictionary.viewkeys()`` on Python 2.7 and ``dictionary.keys()`` on + :meth:`py2:dict.viewkeys` on Python 2.7 and :meth:`py3:dict.keys` on Python 3. .. function:: viewvalues(dictionary) Return a view over *dictionary*\'s values. This replaces - ``dictionary.viewvalues()`` on Python 2.7 and ``dictionary.values()`` on + :meth:`py2:dict.viewvalues` on Python 2.7 and :meth:`py3:dict.values` on Python 3. .. function:: viewitems(dictionary) Return a view over *dictionary*\'s items. This replaces - ``dictionary.viewitems()`` on Python 2.7 and ``dictionary.items()`` on + :meth:`py2:dict.viewitems` on Python 2.7 and :meth:`py3:dict.items` on Python 3. -- cgit v1.2.1 From b460b9af7624ee1f3cfdc05e33f1945f04180580 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 12 Oct 2014 14:30:49 -0400 Subject: indicate properly that next = advance_iterator --- documentation/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/index.rst b/documentation/index.rst index 57786ea..c7ca996 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -160,7 +160,7 @@ functions and methods is the stdlib :mod:`py3:inspect` module. .. function:: next(it) -.. function:: advance_iterator(it) + advance_iterator(it) Get the next item of iterator *it*. :exc:`py3:StopIteration` is raised if the iterator is exhausted. This is a replacement for calling ``it.next()`` -- cgit v1.2.1 From 0d77f9165f69e5f46ce364439484157bb193ff11 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 12 Oct 2014 14:33:17 -0400 Subject: optimize iterbytes on Python 2 (fixes #97) Suggested by Wouter Bolsterlee. --- CHANGES | 2 ++ six.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 02a20f0..fa74e77 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,8 @@ This file lists the changes in each six version. Development version ------------------- +- Issue #97: Optimize `six.iterbytes` on Python 2. + - Issue #98: Fix `six.moves` race condition in multi-threaded code. - Pull request #51: Add `six.view(keys|values|itmes)`, which provide dictionary diff --git a/six.py b/six.py index 0df4538..232a0c7 100644 --- a/six.py +++ b/six.py @@ -23,6 +23,7 @@ from __future__ import absolute_import import functools +import itertools import operator import sys import types @@ -621,8 +622,7 @@ else: return ord(bs[0]) def indexbytes(buf, i): return ord(buf[i]) - def iterbytes(buf): - return (ord(byte) for byte in buf) + iterbytes = functools.partial(itertools.imap, ord) import StringIO StringIO = BytesIO = StringIO.StringIO _add_doc(b, """Byte literal""") -- cgit v1.2.1 From 7330876ca5a33ff17d30c430514e00a2650a51de Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 29 Oct 2014 20:54:24 -0400 Subject: add raise_from (fixes #102) Patch from Robert Collins. --- CHANGES | 2 ++ documentation/index.rst | 7 +++++++ six.py | 9 +++++++++ test_six.py | 21 +++++++++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/CHANGES b/CHANGES index fa74e77..cae8ef0 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,8 @@ This file lists the changes in each six version. Development version ------------------- +- Issue #102: Add `raise_from` to abstract out Python 3's raise from syntax. + - Issue #97: Optimize `six.iterbytes` on Python 2. - Issue #98: Fix `six.moves` race condition in multi-threaded code. diff --git a/documentation/index.rst b/documentation/index.rst index c7ca996..7851421 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -282,6 +282,13 @@ Python 2 and 3. ok. :) +.. function:: raise_from(exc_value, exc_value_from) + + Raise an exception from a context. On Python 3, this is equivalent to + ``raise exc_value from exc_value_from``. On Python 2, which does not support + exception chaining, it is equivalent to ``raise exc_value``. + + .. function:: reraise(exc_type, exc_value, exc_traceback=None) Reraise an exception, possibly with a different traceback. In the simple diff --git a/six.py b/six.py index 232a0c7..a8cdb22 100644 --- a/six.py +++ b/six.py @@ -659,6 +659,15 @@ else: """) +if sys.version_info > (3, 2): + exec_("""def raise_from(value, from_value): + raise value from from_value +""") +else: + def raise_from(value, from_value): + raise value + + print_ = getattr(moves.builtins, "print", None) if print_ is None: def print_(*args, **kwargs): diff --git a/test_six.py b/test_six.py index 4163520..b0ccd8d 100644 --- a/test_six.py +++ b/test_six.py @@ -588,6 +588,27 @@ def test_reraise(): assert tb is get_next(tb2) +def test_raise_from(): + try: + try: + raise Exception("blah") + except Exception: + ctx = sys.exc_info()[1] + f = Exception("foo") + six.raise_from(f, None) + except Exception: + tp, val, tb = sys.exc_info() + if sys.version_info[:2] > (3, 0): + # We should have done a raise f from None equivalent. + assert val.__cause__ is None + assert val.__context__ is ctx + if sys.version_info[:2] >= (3, 3): + # And that should suppress the context on the exception. + assert val.__suppress_context__ + # For all versions the outer exception should have raised successfully. + assert str(val) == "foo" + + def test_print_(): save = sys.stdout out = sys.stdout = six.moves.StringIO() -- cgit v1.2.1 From 20d7a1588e851eb8fc35ba481d7018b841ed9953 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 25 Nov 2014 18:22:19 -0500 Subject: Added unittest aliases. --- documentation/index.rst | 33 +++++++++++++++++++++++++++++++++ six.py | 18 ++++++++++++++++++ test_six.py | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/documentation/index.rst b/documentation/index.rst index 7851421..6b3ad1e 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -746,6 +746,39 @@ Contains classes from Python 3's :mod:`py3:urllib.response` and Python 2's: * :class:`py2:urllib.addinfourl` +unittest assertions +<<<<<<<<<<<<<<<<<<< + +.. currentmodule:: six + +Contains compatibility shims for unittest assertions that have been renamed. +The parameters are the same as their aliases, but you must pass the test method +as the first argument. For example:: + + import six + import unittest + + class TestAssertCountEqual(unittest.TestCase): + def test(self): + six.assertCountEqual(self, (1, 2), [2, 1]) + + +.. function:: assertCountEqual() + + Alias for :meth:`~py3:unittest.TestCase.assertCountEqual` on Python 3 and + :meth:`~py2:unittest.TestCase.assertItemsEqual` on Python 2. + +.. function:: assertRaisesRegex() + + Alias for :meth:`~py3:unittest.TestCase.assertRaisesRegex` on Python 3 and + :meth:`~py2:unittest.TestCase.assertRaisesRegexp` on Python 2. + +.. function:: assertRegex() + + Alias for :meth:`~py3:unittest.TestCase.assertRegex` on Python 3 and + :meth:`~py2:unittest.TestCase.assertRegexpMatches` on Python 2. + + Advanced - Customizing renames <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< diff --git a/six.py b/six.py index a8cdb22..303fd2d 100644 --- a/six.py +++ b/six.py @@ -610,6 +610,9 @@ if PY3: import io StringIO = io.StringIO BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" else: def b(s): return s @@ -625,10 +628,25 @@ else: iterbytes = functools.partial(itertools.imap, ord) import StringIO StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" _add_doc(b, """Byte literal""") _add_doc(u, """Text literal""") +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + if PY3: exec_ = getattr(moves.builtins, "exec") diff --git a/test_six.py b/test_six.py index b0ccd8d..c023862 100644 --- a/test_six.py +++ b/test_six.py @@ -1,6 +1,7 @@ import operator import sys import types +import unittest import py @@ -773,3 +774,39 @@ def test_add_metaclass(): __slots__ = "__weakref__", MySlotsWeakref = six.add_metaclass(Meta)(MySlotsWeakref) assert type(MySlotsWeakref) is Meta + + +@py.test.mark.skipif("sys.version_info[:2] < (2, 7)") +def test_assertCountEqual(): + class TestAssertCountEqual(unittest.TestCase): + def test(self): + with self.assertRaises(AssertionError): + six.assertCountEqual(self, (1, 2), [3, 4, 5]) + + six.assertCountEqual(self, (1, 2), [2, 1]) + + TestAssertCountEqual('test').test() + + +def test_assertRegex(): + class TestAssertRegex(unittest.TestCase): + def test(self): + with self.assertRaises(AssertionError): + six.assertRegex(self, 'test', r'^a') + + six.assertRegex(self, 'test', r'^t') + + TestAssertRegex('test').test() + + +def test_assertRaisesRegex(): + class TestAssertRaisesRegex(unittest.TestCase): + def test(self): + with six.assertRaisesRegex(self, AssertionError, '^Foo'): + raise AssertionError('Foo') + + with self.assertRaises(AssertionError): + with six.assertRaisesRegex(self, AssertionError, r'^Foo'): + raise AssertionError('Bar') + + TestAssertRaisesRegex('test').test() -- cgit v1.2.1 From 9f4c34a72ee52326b17cab92cd008399b920a5f6 Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Fri, 5 Dec 2014 20:12:27 -0800 Subject: Ensure wraps passes along the assigned + updated params Fixes issue #105 --- six.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/six.py b/six.py index a8cdb22..11843f8 100644 --- a/six.py +++ b/six.py @@ -729,7 +729,9 @@ if sys.version_info[0:2] < (3, 4): def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, updated=functools.WRAPPER_UPDATES): def wrapper(f): - f = functools.wraps(wrapped)(f) + f = functools.wraps(wrapped, + assigned=assigned, + updated=updated)(f) f.__wrapped__ = wrapped return f return wrapper -- cgit v1.2.1 From d00e00a327483379c13dc8789413d4ef31392259 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 9 Dec 2014 10:42:11 -0500 Subject: http -> https --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index 4de73fa..32bab7c 100644 --- a/README +++ b/README @@ -9,8 +9,8 @@ notice must be retained.) Online documentation is at http://pythonhosted.org/six/. -Bugs can be reported to http://bitbucket.org/gutworth/six. The code can also be -found there. +Bugs can be reported to https://bitbucket.org/gutworth/six. The code can also +be found there. For questions about six or porting in general, email the python-porting mailing list: http://mail.python.org/mailman/listinfo/python-porting -- cgit v1.2.1 From 2a0da34c131bbe1c8633875956b4cb28187b4f66 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 9 Dec 2014 10:59:11 -0500 Subject: use positional arguments in call --- six.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/six.py b/six.py index 11843f8..686c20a 100644 --- a/six.py +++ b/six.py @@ -729,9 +729,7 @@ if sys.version_info[0:2] < (3, 4): def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, updated=functools.WRAPPER_UPDATES): def wrapper(f): - f = functools.wraps(wrapped, - assigned=assigned, - updated=updated)(f) + f = functools.wraps(wrapped, assigned, updated)(f) f.__wrapped__ = wrapped return f return wrapper -- cgit v1.2.1 From cc5097e82156c35c21ab2ecfbad1d326bf9c5459 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 9 Dec 2014 10:59:50 -0500 Subject: add test for issue #105 --- test_six.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test_six.py b/test_six.py index b0ccd8d..d5555e8 100644 --- a/test_six.py +++ b/test_six.py @@ -701,6 +701,18 @@ def test_wraps(): assert k is original_k assert not hasattr(k, '__wrapped__') + def f(g, assign, update): + def w(): + return 42 + w.glue = {"foo" : "bar"} + return six.wraps(g, assign, update)(w) + k.glue = {"melon" : "egg"} + k.turnip = 43 + k = f(k, ["turnip"], ["glue"]) + assert k.__name__ == "w" + assert k.turnip == 43 + assert k.glue == {"melon" : "egg", "foo" : "bar"} + def test_add_metaclass(): class Meta(type): -- cgit v1.2.1 From ec8807c7c3764dc20432898b9732003f60eeb94c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 9 Dec 2014 11:01:02 -0500 Subject: add NEWS note for #105 --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index cae8ef0..25930bd 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,9 @@ This file lists the changes in each six version. Development version ------------------- +- Issue #105 and pull request #58: Ensure `six.wraps` respects the *updated* and + *assigned* arguments. + - Issue #102: Add `raise_from` to abstract out Python 3's raise from syntax. - Issue #97: Optimize `six.iterbytes` on Python 2. -- cgit v1.2.1 From 7736215b48c3687e30784b48ee71bf51efe01b17 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 16 Dec 2014 19:40:49 -0500 Subject: color commentary --- documentation/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/index.rst b/documentation/index.rst index 7851421..f3ee0cc 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -18,7 +18,7 @@ tracker and code hosting is on `BitBucket `_. The name, "six", comes from the fact that 2*3 equals 6. Why not addition? Multiplication is more powerful, and, anyway, "five" has already been snatched -away by the Zope Five project. +away by the (admittedly now moribund) Zope Five project. Indices and tables -- cgit v1.2.1 From aeff5437821ca4b2a8aea2ccf0ef9adcd0bae302 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 2 Jan 2015 09:27:50 -0600 Subject: update changelog --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index 25930bd..e12508a 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,9 @@ This file lists the changes in each six version. Development version ------------------- +- Pull request #57 and issue #50: Add several compatibility methods for unittest + assertions that were renamed between Python 2 and 3. + - Issue #105 and pull request #58: Ensure `six.wraps` respects the *updated* and *assigned* arguments. -- cgit v1.2.1 From 532be7ae72888e7e8c5779d330a8abaa1d94254e Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 2 Jan 2015 09:29:09 -0600 Subject: move unittest assertions section up --- documentation/index.rst | 66 ++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/documentation/index.rst b/documentation/index.rst index 25e5345..806504e 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -437,6 +437,39 @@ string data in all Python versions. :class:`py3:io.BytesIO`. +unittest assertions +>>>>>>>>>>>>>>>>>>> + +.. currentmodule:: six + +Contains compatibility shims for unittest assertions that have been renamed. +The parameters are the same as their aliases, but you must pass the test method +as the first argument. For example:: + + import six + import unittest + + class TestAssertCountEqual(unittest.TestCase): + def test(self): + six.assertCountEqual(self, (1, 2), [2, 1]) + + +.. function:: assertCountEqual() + + Alias for :meth:`~py3:unittest.TestCase.assertCountEqual` on Python 3 and + :meth:`~py2:unittest.TestCase.assertItemsEqual` on Python 2. + +.. function:: assertRaisesRegex() + + Alias for :meth:`~py3:unittest.TestCase.assertRaisesRegex` on Python 3 and + :meth:`~py2:unittest.TestCase.assertRaisesRegexp` on Python 2. + +.. function:: assertRegex() + + Alias for :meth:`~py3:unittest.TestCase.assertRegex` on Python 3 and + :meth:`~py2:unittest.TestCase.assertRegexpMatches` on Python 2. + + Renamed modules and attributes compatibility >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -746,39 +779,6 @@ Contains classes from Python 3's :mod:`py3:urllib.response` and Python 2's: * :class:`py2:urllib.addinfourl` -unittest assertions -<<<<<<<<<<<<<<<<<<< - -.. currentmodule:: six - -Contains compatibility shims for unittest assertions that have been renamed. -The parameters are the same as their aliases, but you must pass the test method -as the first argument. For example:: - - import six - import unittest - - class TestAssertCountEqual(unittest.TestCase): - def test(self): - six.assertCountEqual(self, (1, 2), [2, 1]) - - -.. function:: assertCountEqual() - - Alias for :meth:`~py3:unittest.TestCase.assertCountEqual` on Python 3 and - :meth:`~py2:unittest.TestCase.assertItemsEqual` on Python 2. - -.. function:: assertRaisesRegex() - - Alias for :meth:`~py3:unittest.TestCase.assertRaisesRegex` on Python 3 and - :meth:`~py2:unittest.TestCase.assertRaisesRegexp` on Python 2. - -.. function:: assertRegex() - - Alias for :meth:`~py3:unittest.TestCase.assertRegex` on Python 3 and - :meth:`~py2:unittest.TestCase.assertRegexpMatches` on Python 2. - - Advanced - Customizing renames <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -- cgit v1.2.1 From ba9a72d863d504293de42e4636ea0f805cd4b2af Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 2 Jan 2015 09:30:00 -0600 Subject: add Tim Graham --- CONTRIBUTORS | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 0cbd0a4..1c8181f 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -10,6 +10,7 @@ Jason R. Coombs Julien Danjou Ben Darnell Ben Davis +Tim Graham Joshua Harlow Anselm Kruis Alexander Lukanin -- cgit v1.2.1 From 3acb0acc6d7fc03f53fd8568ececb0db5b56a436 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 2 Jan 2015 09:30:30 -0600 Subject: remove currentmodule directive that is no longer needed --- documentation/index.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/documentation/index.rst b/documentation/index.rst index 806504e..db47905 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -440,8 +440,6 @@ string data in all Python versions. unittest assertions >>>>>>>>>>>>>>>>>>> -.. currentmodule:: six - Contains compatibility shims for unittest assertions that have been renamed. The parameters are the same as their aliases, but you must pass the test method as the first argument. For example:: -- cgit v1.2.1 From 678cfb323729045c73ce405052955c9b0e4edc86 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 2 Jan 2015 09:31:42 -0600 Subject: note that assertCountEqual is newish --- documentation/index.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/documentation/index.rst b/documentation/index.rst index db47905..3317596 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -440,7 +440,7 @@ string data in all Python versions. unittest assertions >>>>>>>>>>>>>>>>>>> -Contains compatibility shims for unittest assertions that have been renamed. +Six contains compatibility shims for unittest assertions that have been renamed. The parameters are the same as their aliases, but you must pass the test method as the first argument. For example:: @@ -455,7 +455,8 @@ as the first argument. For example:: .. function:: assertCountEqual() Alias for :meth:`~py3:unittest.TestCase.assertCountEqual` on Python 3 and - :meth:`~py2:unittest.TestCase.assertItemsEqual` on Python 2. + :meth:`~py2:unittest.TestCase.assertItemsEqual` on Python 2. This method is + only available on Python 2.7 and later. .. function:: assertRaisesRegex() -- cgit v1.2.1