From a7e5c71640fb909673fed3a56d0d3c132c53a138 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Mon, 4 Jan 2021 15:35:51 +0900 Subject: [PATCH] Imported Upstream version 1.13.0 --- .travis.yml | 25 ++++---- CHANGES | 13 ++++ CONTRIBUTORS | 6 ++ LICENSE | 2 +- documentation/conf.py | 2 +- documentation/index.rst | 12 +++- setup.py | 2 +- six.py | 17 ++++- test_six.py | 136 +++++++++++++++++++++++++++------------- tox.ini | 2 +- 10 files changed, 152 insertions(+), 65 deletions(-) diff --git a/.travis.yml b/.travis.yml index 45713fc..9423104 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,24 +1,21 @@ os: linux -dist: trusty -sudo: false +dist: xenial language: python python: -- 2.6 - 2.7 -- 3.2 -- 3.3 - 3.4 - 3.5 -- &mainstream_python 3.6 -- 3.6-dev -- 3.7-dev -- pypy2.7-5.8.0 -- pypy3.5-5.8.0 +- 3.6 +- 3.7 +- &mainstream_python 3.8 +- nightly +- pypy +- pypy3 install: - pip install --upgrade --force-reinstall "setuptools; python_version != '3.2' and python_version != '3.3'" "setuptools < 30; python_version == '3.2'" "setuptools < 40; python_version == '3.3'" - pip uninstall --yes six || true - pip install --upgrade --force-reinstall --ignore-installed -e . -- pip install pytest +- pip install pytest==2.9.2 typing - &py_pkg_list pip list --format=columns || pip list script: - py.test @@ -29,6 +26,12 @@ script: jobs: fast_finish: true include: + - python: 2.6 + dist: trusty + - python: 3.2 + dist: trusty + - python: 3.3 + dist: trusty - stage: upload new version of python package to PYPI (only for tagged commits) python: *mainstream_python install: skip diff --git a/CHANGES b/CHANGES index 164f0b5..ffa7026 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,19 @@ Changelog for six This file lists the changes in each six version. +1.13.0 +------ + +- Issue #298, pull request #299: Add `six.moves.dbm_ndbm`. + +- Issue #155: Add `six.moves.collections_abc`, which aliases the `collections` + module on Python 2-3.2 and the `collections.abc` on Python 3.3 and greater. + +- Pull request #304: Re-add distutils fallback in `setup.py`. + +- Pull request #305: On Python 3.7, `with_metaclass` supports classes using PEP + 560 features. + 1.12.0 ------ diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 35596c4..26180de 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -5,6 +5,8 @@ otherwise worked to improve six: Marc Abramowitz Alexander Artemenko Aymeric Augustin +Lee Ball +Ben Bariteau Ned Batchelder Wouter Bolsterlee Brett Cannon @@ -12,11 +14,14 @@ Jason R. Coombs Julien Danjou Ben Darnell Ben Davis +Jon Dufresne Tim Graham Thomas Grainger Max Grender-Jones Joshua Harlow +Toshiki Kataoka Anselm Kruis +Ivan Levkivskyi Alexander Lukanin James Mills Jordan Moldow @@ -26,6 +31,7 @@ Erik Rose Mirko Rossini Peter Ruibal Miroslav Shubernetskiy +Eli Schwartz Anthony Sottile Lucas Wiman Jingxin Zhu diff --git a/LICENSE b/LICENSE index 365d107..4b05a54 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2010-2018 Benjamin Peterson +Copyright (c) 2010-2019 Benjamin Peterson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/documentation/conf.py b/documentation/conf.py index e039301..b3d1328 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -33,7 +33,7 @@ master_doc = "index" # General information about the project. project = u"six" -copyright = u"2010-2018, Benjamin Peterson" +copyright = u"2010-2019, Benjamin Peterson" sys.path.append(os.path.abspath(os.path.join(".", ".."))) from six import __version__ as six_version diff --git a/documentation/index.rst b/documentation/index.rst index 99192a2..b7ec275 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -76,7 +76,9 @@ Six provides constants that may differ between Python versions. Ones ending .. data:: binary_type Type for representing binary data. This is :func:`py2:str` in Python 2 and - :func:`py3:bytes` in Python 3. + :func:`py3:bytes` in Python 3. Python 2.6 and 2.7 include ``bytes`` as a + builtin alias of ``str``, so six’s version is only necessary for Python 2.5 + compatibility. .. data:: MAXSIZE @@ -442,7 +444,7 @@ string data in all Python versions. .. function:: ensure_str(s, encoding='utf-8', errors='strict') - Coerce *s* to ``str``. ``encoding``, ``errors`` are the same + Coerce *s* to ``str``. *encoding*, *errors* are the same as :meth:`py3:str.encode` @@ -582,7 +584,11 @@ Supported renames: +------------------------------+-------------------------------------+---------------------------------------+ | ``cStringIO`` | :func:`py2:cStringIO.StringIO` | :class:`py3:io.StringIO` | +------------------------------+-------------------------------------+---------------------------------------+ -| ``dbm_gnu`` | :func:`py2:gdbm` | :class:`py3:dbm.gnu` | +| ``collections_abc`` | :mod:`py2:collections` | :mod:`py3:collections.abc` (3.3+) | ++------------------------------+-------------------------------------+---------------------------------------+ +| ``dbm_gnu`` | :mod:`py2:gdbm` | :mod:`py3:dbm.gnu` | ++------------------------------+-------------------------------------+---------------------------------------+ +| ``dbm_ndbm`` | :mod:`py2:dbm` | :mod:`py3:dbm.ndbm` | +------------------------------+-------------------------------------+---------------------------------------+ | ``_dummy_thread`` | :mod:`py2:dummy_thread` | :mod:`py3:_dummy_thread` | +------------------------------+-------------------------------------+---------------------------------------+ diff --git a/setup.py b/setup.py index 2596479..97c685b 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2018 Benjamin Peterson +# Copyright (c) 2010-2019 Benjamin Peterson # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/six.py b/six.py index 89b2188..357e624 100644 --- a/six.py +++ b/six.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2018 Benjamin Peterson +# Copyright (c) 2010-2019 Benjamin Peterson # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ import sys import types __author__ = "Benjamin Peterson " -__version__ = "1.12.0" +__version__ = "1.13.0" # Useful for very coarse version differentiation. @@ -255,8 +255,10 @@ _moved_attributes = [ MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), MovedModule("builtins", "__builtin__"), MovedModule("configparser", "ConfigParser"), + MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"), MovedModule("copyreg", "copy_reg"), MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"), MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), MovedModule("http_cookies", "Cookie", "http.cookies"), @@ -637,6 +639,7 @@ if PY3: import io StringIO = io.StringIO BytesIO = io.BytesIO + del io _assertCountEqual = "assertCountEqual" if sys.version_info[1] <= 1: _assertRaisesRegex = "assertRaisesRegexp" @@ -824,7 +827,15 @@ def with_metaclass(meta, *bases): class metaclass(type): def __new__(cls, name, this_bases, d): - return meta(name, bases, d) + if sys.version_info[:2] >= (3, 7): + # This version introduced PEP 560 that requires a bit + # of extra care (we mimic what is done by __build_class__). + resolved_bases = types.resolve_bases(bases) + if resolved_bases is not bases: + d['__orig_bases__'] = bases + else: + resolved_bases = bases + return meta(name, resolved_bases, d) @classmethod def __prepare__(cls, name, this_bases): diff --git a/test_six.py b/test_six.py index 897e232..0b72067 100644 --- a/test_six.py +++ b/test_six.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2018 Benjamin Peterson +# Copyright (c) 2010-2019 Benjamin Peterson # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -22,8 +22,9 @@ import operator import sys import types import unittest +import abc -import py +import pytest import six @@ -80,7 +81,7 @@ def test_MAXSIZE(): except AttributeError: # Before Python 2.6. pass - py.test.raises( + pytest.raises( (ValueError, OverflowError), operator.mul, [None], six.MAXSIZE + 1) @@ -112,7 +113,7 @@ except ImportError: except ImportError: have_gdbm = False -@py.test.mark.parametrize("item_name", +@pytest.mark.parametrize("item_name", [item.name for item in six._moved_attributes]) def test_move_items(item_name): """Ensure that everything loads correctly.""" @@ -122,36 +123,36 @@ def test_move_items(item_name): __import__("six.moves." + item_name) except AttributeError: if item_name == "zip_longest" and sys.version_info < (2, 6): - py.test.skip("zip_longest only available on 2.6+") + pytest.skip("zip_longest only available on 2.6+") except ImportError: if item_name == "winreg" and not sys.platform.startswith("win"): - py.test.skip("Windows only module") + pytest.skip("Windows only module") if item_name.startswith("tkinter"): if not have_tkinter: - py.test.skip("requires tkinter") + pytest.skip("requires tkinter") if item_name == "tkinter_ttk" and sys.version_info[:2] <= (2, 6): - py.test.skip("ttk only available on 2.7+") + pytest.skip("ttk only available on 2.7+") if item_name.startswith("dbm_gnu") and not have_gdbm: - py.test.skip("requires gdbm") + pytest.skip("requires gdbm") raise if sys.version_info[:2] >= (2, 6): assert item_name in dir(six.moves) -@py.test.mark.parametrize("item_name", +@pytest.mark.parametrize("item_name", [item.name for item in six._urllib_parse_moved_attributes]) def test_move_items_urllib_parse(item_name): """Ensure that everything loads correctly.""" if item_name == "ParseResult" and sys.version_info < (2, 5): - py.test.skip("ParseResult is only found on 2.5+") + pytest.skip("ParseResult is only found on 2.5+") if item_name in ("parse_qs", "parse_qsl") and sys.version_info < (2, 6): - py.test.skip("parse_qs[l] is new in 2.6") + pytest.skip("parse_qs[l] is new in 2.6") if sys.version_info[:2] >= (2, 6): assert item_name in dir(six.moves.urllib.parse) getattr(six.moves.urllib.parse, item_name) -@py.test.mark.parametrize("item_name", +@pytest.mark.parametrize("item_name", [item.name for item in six._urllib_error_moved_attributes]) def test_move_items_urllib_error(item_name): """Ensure that everything loads correctly.""" @@ -160,7 +161,7 @@ def test_move_items_urllib_error(item_name): getattr(six.moves.urllib.error, item_name) -@py.test.mark.parametrize("item_name", +@pytest.mark.parametrize("item_name", [item.name for item in six._urllib_request_moved_attributes]) def test_move_items_urllib_request(item_name): """Ensure that everything loads correctly.""" @@ -169,7 +170,7 @@ def test_move_items_urllib_request(item_name): getattr(six.moves.urllib.request, item_name) -@py.test.mark.parametrize("item_name", +@pytest.mark.parametrize("item_name", [item.name for item in six._urllib_response_moved_attributes]) def test_move_items_urllib_response(item_name): """Ensure that everything loads correctly.""" @@ -178,7 +179,7 @@ def test_move_items_urllib_response(item_name): getattr(six.moves.urllib.response, item_name) -@py.test.mark.parametrize("item_name", +@pytest.mark.parametrize("item_name", [item.name for item in six._urllib_robotparser_moved_attributes]) def test_move_items_urllib_robotparser(item_name): """Ensure that everything loads correctly.""" @@ -243,7 +244,7 @@ def test_zip(): assert six.advance_iterator(zip(range(2), range(2))) == (0, 0) -@py.test.mark.skipif("sys.version_info < (2, 6)") +@pytest.mark.skipif("sys.version_info < (2, 6)") def test_zip_longest(): from six.moves import zip_longest it = zip_longest(range(2), range(1)) @@ -321,7 +322,7 @@ class TestCustomizedMoves: def test_empty_remove(self): - py.test.raises(AttributeError, six.remove_move, "eggs") + pytest.raises(AttributeError, six.remove_move, "eggs") def test_get_unbound_function(): @@ -337,7 +338,7 @@ def test_get_method_self(): pass x = X() assert six.get_method_self(x.m) is x - py.test.raises(AttributeError, six.get_method_self, 42) + pytest.raises(AttributeError, six.get_method_self, 42) def test_get_method_function(): @@ -346,7 +347,7 @@ def test_get_method_function(): pass x = X() assert six.get_method_function(x.m) is X.__dict__["m"] - py.test.raises(AttributeError, six.get_method_function, hasattr) + pytest.raises(AttributeError, six.get_method_function, hasattr) def test_get_function_closure(): @@ -364,7 +365,7 @@ def test_get_function_code(): pass assert isinstance(six.get_function_code(f), types.CodeType) if not hasattr(sys, "pypy_version_info"): - py.test.raises(AttributeError, six.get_function_code, hasattr) + pytest.raises(AttributeError, six.get_function_code, hasattr) def test_get_function_defaults(): @@ -404,7 +405,7 @@ def test_dictionary_iterators(monkeypatch): it = meth(d) assert not isinstance(it, list) assert list(it) == list(getattr(d, name)()) - py.test.raises(StopIteration, six.advance_iterator, it) + pytest.raises(StopIteration, six.advance_iterator, it) record = [] def with_kw(*args, **kw): record.append(kw["kw"]) @@ -416,7 +417,7 @@ def test_dictionary_iterators(monkeypatch): monkeypatch.undo() -@py.test.mark.skipif("sys.version_info[:2] < (2, 7)", +@pytest.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): @@ -440,8 +441,8 @@ def test_advance_iterator(): it = iter(l) assert six.next(it) == 1 assert six.next(it) == 2 - py.test.raises(StopIteration, six.next, it) - py.test.raises(StopIteration, six.next, it) + pytest.raises(StopIteration, six.next, it) + pytest.raises(StopIteration, six.next, it) def test_iterator(): @@ -489,7 +490,7 @@ def test_create_unbound_method(): def f(self): return self u = six.create_unbound_method(f, X) - py.test.raises(TypeError, u) + pytest.raises(TypeError, u) if six.PY2: assert isinstance(u, types.MethodType) x = X() @@ -537,13 +538,13 @@ def test_unichr(): def test_int2byte(): assert six.int2byte(3) == six.b("\x03") - py.test.raises(Exception, six.int2byte, 256) + pytest.raises(Exception, six.int2byte, 256) def test_byte2int(): assert six.byte2int(six.b("\x03")) == 3 assert six.byte2int(six.b("\x03\x04")) == 3 - py.test.raises(IndexError, six.byte2int, six.b("")) + pytest.raises(IndexError, six.byte2int, six.b("")) def test_bytesindex(): @@ -554,7 +555,7 @@ def test_bytesiter(): it = six.iterbytes(six.b("hi")) assert six.next(it) == ord("h") assert six.next(it) == ord("i") - py.test.raises(StopIteration, six.next, it) + pytest.raises(StopIteration, six.next, it) def test_StringIO(): @@ -689,7 +690,7 @@ def test_print_(): assert out.flushed -@py.test.mark.skipif("sys.version_info[:2] >= (2, 6)") +@pytest.mark.skipif("sys.version_info[:2] >= (2, 6)") def test_print_encoding(monkeypatch): # Fool the type checking in print_. monkeypatch.setattr(six, "file", six.BytesIO, raising=False) @@ -701,16 +702,16 @@ def test_print_encoding(monkeypatch): out = six.BytesIO() out.encoding = "ascii" out.errors = "strict" - py.test.raises(UnicodeEncodeError, six.print_, six.u("\u053c"), file=out) + pytest.raises(UnicodeEncodeError, six.print_, six.u("\u053c"), file=out) out.errors = "backslashreplace" six.print_(six.u("\u053c"), end="", file=out) assert out.getvalue() == six.b("\\u053c") def test_print_exceptions(): - py.test.raises(TypeError, six.print_, x=3) - py.test.raises(TypeError, six.print_, end=3) - py.test.raises(TypeError, six.print_, sep=42) + pytest.raises(TypeError, six.print_, x=3) + pytest.raises(TypeError, six.print_, end=3) + pytest.raises(TypeError, six.print_, sep=42) def test_with_metaclass(): @@ -744,7 +745,54 @@ def test_with_metaclass(): assert Y.__mro__ == (Y, X, object) -@py.test.mark.skipif("sys.version_info[:2] < (3, 0)") +@pytest.mark.skipif("sys.version_info[:2] < (2, 7)") +def test_with_metaclass_typing(): + try: + import typing + except ImportError: + pytest.skip("typing module required") + class Meta(type): + pass + if sys.version_info[:2] < (3, 7): + # Generics with custom metaclasses were broken on older versions. + class Meta(Meta, typing.GenericMeta): + pass + T = typing.TypeVar('T') + class G(six.with_metaclass(Meta, typing.Generic[T])): + pass + class GA(six.with_metaclass(abc.ABCMeta, typing.Generic[T])): + pass + assert isinstance(G, Meta) + assert isinstance(GA, abc.ABCMeta) + assert G[int] is not G[G[int]] + assert GA[int] is not GA[GA[int]] + assert G.__bases__ == (typing.Generic,) + assert G.__orig_bases__ == (typing.Generic[T],) + + +@pytest.mark.skipif("sys.version_info[:2] < (3, 7)") +def test_with_metaclass_pep_560(): + class Meta(type): + pass + class A: + pass + class B: + pass + class Fake: + def __mro_entries__(self, bases): + return (A, B) + fake = Fake() + class G(six.with_metaclass(Meta, fake)): + pass + class GA(six.with_metaclass(abc.ABCMeta, fake)): + pass + assert isinstance(G, Meta) + assert isinstance(GA, abc.ABCMeta) + assert G.__bases__ == (A, B) + assert G.__orig_bases__ == (fake,) + + +@pytest.mark.skipif("sys.version_info[:2] < (3, 0)") def test_with_metaclass_prepare(): """Test that with_metaclass causes Meta.__prepare__ to be called with the correct arguments.""" @@ -857,7 +905,7 @@ def test_add_metaclass(): assert MySlots.__slots__ == ["a", "b"] instance = MySlots() instance.a = "foo" - py.test.raises(AttributeError, setattr, instance, "c", "baz") + pytest.raises(AttributeError, setattr, instance, "c", "baz") # Test a class with string for slots. class MyStringSlots(object): @@ -866,8 +914,8 @@ def test_add_metaclass(): assert MyStringSlots.__slots__ == "ab" instance = MyStringSlots() instance.ab = "foo" - py.test.raises(AttributeError, setattr, instance, "a", "baz") - py.test.raises(AttributeError, setattr, instance, "b", "baz") + pytest.raises(AttributeError, setattr, instance, "a", "baz") + pytest.raises(AttributeError, setattr, instance, "b", "baz") class MySlotsWeakref(object): __slots__ = "__weakref__", @@ -875,7 +923,7 @@ def test_add_metaclass(): assert type(MySlotsWeakref) is Meta -@py.test.mark.skipif("sys.version_info[:2] < (3, 3)") +@pytest.mark.skipif("sys.version_info[:2] < (3, 3)") def test_add_metaclass_nested(): # Regression test for https://github.com/benjaminp/six/issues/259 class Meta(type): @@ -895,7 +943,7 @@ def test_add_metaclass_nested(): assert A.B.__qualname__ == expected -@py.test.mark.skipif("sys.version_info[:2] < (2, 7) or sys.version_info[:2] in ((3, 0), (3, 1))") +@pytest.mark.skipif("sys.version_info[:2] < (2, 7) or sys.version_info[:2] in ((3, 0), (3, 1))") def test_assertCountEqual(): class TestAssertCountEqual(unittest.TestCase): def test(self): @@ -907,7 +955,7 @@ def test_assertCountEqual(): TestAssertCountEqual('test').test() -@py.test.mark.skipif("sys.version_info[:2] < (2, 7)") +@pytest.mark.skipif("sys.version_info[:2] < (2, 7)") def test_assertRegex(): class TestAssertRegex(unittest.TestCase): def test(self): @@ -919,7 +967,7 @@ def test_assertRegex(): TestAssertRegex('test').test() -@py.test.mark.skipif("sys.version_info[:2] < (2, 7)") +@pytest.mark.skipif("sys.version_info[:2] < (2, 7)") def test_assertRaisesRegex(): class TestAssertRaisesRegex(unittest.TestCase): def test(self): @@ -961,12 +1009,12 @@ class EnsureTests: BINARY_EMOJI = b"\xf0\x9f\x98\x80" def test_ensure_binary_raise_type_error(self): - with py.test.raises(TypeError): + with pytest.raises(TypeError): six.ensure_str(8) def test_errors_and_encoding(self): six.ensure_binary(self.UNICODE_EMOJI, encoding='latin-1', errors='ignore') - with py.test.raises(UnicodeEncodeError): + with pytest.raises(UnicodeEncodeError): six.ensure_binary(self.UNICODE_EMOJI, encoding='latin-1', errors='strict') def test_ensure_binary_raise(self): diff --git a/tox.ini b/tox.ini index f7df78c..292aee8 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist=py26,py27,py31,py32,py33,py34,pypy,flake8 +envlist=py26,py27,py32,py33,py34,py35,py36,py37,py38,pypy,flake8 [testenv] deps= pytest -- 2.34.1