From 1b8ef510652eec238f835ba8d2b28bfef677833a Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Sat, 20 Jun 2015 00:57:38 +0200 Subject: [PATCH 01/59] Add count from 2.7 to 2.6 The future.types.newrange already has a _count method which is now moved to the backports to allow make this public. --- src/future/backports/misc.py | 10 ++++++ src/future/types/newrange.py | 10 ++---- tests/test_future/test_count.py | 57 +++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 tests/test_future/test_count.py diff --git a/src/future/backports/misc.py b/src/future/backports/misc.py index 03c68c13..71acad27 100644 --- a/src/future/backports/misc.py +++ b/src/future/backports/misc.py @@ -22,6 +22,16 @@ def ceil(x): return int(oldceil(x)) +if PY26: + # itertools.count in Py 2.6 doesn't accept a step parameter + def count(start=0, step=1): + while True: + yield start + start += step +else: + from itertools import count + + # OrderedDict Shim from Raymond Hettinger, python core dev # http://code.activestate.com/recipes/576693-ordered-dictionary-for-py24/ # here to support version 2.6. diff --git a/src/future/types/newrange.py b/src/future/types/newrange.py index 432f11a1..17b6736b 100644 --- a/src/future/types/newrange.py +++ b/src/future/types/newrange.py @@ -21,6 +21,7 @@ from collections import Sequence, Iterator from itertools import islice +from future.backports.misc import count class newrange(Sequence): """ @@ -141,7 +142,7 @@ class range_iterator(Iterator): """An iterator for a :class:`range`. """ def __init__(self, range_): - self._stepper = islice(_count(range_.start, range_.step), len(range_)) + self._stepper = islice(count(range_.start, range_.step), len(range_)) def __iter__(self): return self @@ -150,11 +151,4 @@ def next(self): return next(self._stepper) -# itertools.count in Py 2.6 doesn't accept a step parameter -def _count(start=0, step=1): - while True: - yield start - start += step - - __all__ = ['newrange'] diff --git a/tests/test_future/test_count.py b/tests/test_future/test_count.py new file mode 100644 index 00000000..cc849bd5 --- /dev/null +++ b/tests/test_future/test_count.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +""" +Tests for the backported class:`range` class. +""" +from itertools import count as it_count + +from future.backports.misc import count +from future.tests.base import unittest, skip26 + + +class CountTest(unittest.TestCase): + + """Test the count function.""" + + def _test_count_func(self, func): + self.assertEqual(next(func(1)), 1) + self.assertEqual(next(func(start=1)), 1) + + c = func() + self.assertEqual(next(c), 0) + self.assertEqual(next(c), 1) + self.assertEqual(next(c), 2) + c = func(1, 1) + self.assertEqual(next(c), 1) + self.assertEqual(next(c), 2) + c = func(step=1) + self.assertEqual(next(c), 0) + self.assertEqual(next(c), 1) + c = func(start=1, step=1) + self.assertEqual(next(c), 1) + self.assertEqual(next(c), 2) + + c = func(-1) + self.assertEqual(next(c), -1) + self.assertEqual(next(c), 0) + self.assertEqual(next(c), 1) + c = func(1, -1) + self.assertEqual(next(c), 1) + self.assertEqual(next(c), 0) + self.assertEqual(next(c), -1) + c = func(-1, -1) + self.assertEqual(next(c), -1) + self.assertEqual(next(c), -2) + self.assertEqual(next(c), -3) + + def test_count(self): + """Test the count function.""" + self._test_count_func(count) + + @skip26 + def test_own_count(self): + """Test own count implementation.""" + self._test_count_func(it_count) + + +if __name__ == '__main__': + unittest.main() From 99030ec81309164fefc0cd6b5d090eeb08b4a2f7 Mon Sep 17 00:00:00 2001 From: Mital Ashok Date: Mon, 31 Jul 2017 20:18:15 +0100 Subject: [PATCH 02/59] Fixed newdict checking version every time --- src/future/types/newdict.py | 63 +++++++++---------------------------- 1 file changed, 14 insertions(+), 49 deletions(-) diff --git a/src/future/types/newdict.py b/src/future/types/newdict.py index 5dbcc4b7..7e9cdbc1 100644 --- a/src/future/types/newdict.py +++ b/src/future/types/newdict.py @@ -23,7 +23,7 @@ _builtin_dict = dict -ver = sys.version_info[:2] +ver = sys.version_info class BaseNewDict(type): @@ -38,47 +38,18 @@ class newdict(with_metaclass(BaseNewDict, _builtin_dict)): """ A backport of the Python 3 dict object to Py2 """ - def items(self): - """ - On Python 2.7+: - D.items() -> a set-like object providing a view on D's items - On Python 2.6: - D.items() -> an iterator over D's items - """ - if ver == (2, 7): - return self.viewitems() - elif ver == (2, 6): - return self.iteritems() - elif ver >= (3, 0): - return self.items() - - def keys(self): - """ - On Python 2.7+: - D.keys() -> a set-like object providing a view on D's keys - On Python 2.6: - D.keys() -> an iterator over D's keys - """ - if ver == (2, 7): - return self.viewkeys() - elif ver == (2, 6): - return self.iterkeys() - elif ver >= (3, 0): - return self.keys() - - def values(self): - """ - On Python 2.7+: - D.values() -> a set-like object providing a view on D's values - On Python 2.6: - D.values() -> an iterator over D's values - """ - if ver == (2, 7): - return self.viewvalues() - elif ver == (2, 6): - return self.itervalues() - elif ver >= (3, 0): - return self.values() + + if ver >= (3,): + # Inherit items, keys and values from `dict` in 3.x + pass + elif ver >= (2, 7): + items = dict.viewitems + keys = dict.viewkeys + values = dict.viewvalues + else: + items = dict.iteritems + keys = dict.iterkeys + values = dict.itervalues def __new__(cls, *args, **kwargs): """ @@ -93,13 +64,7 @@ def __new__(cls, *args, **kwargs): in the keyword argument list. For example: dict(one=1, two=2) """ - if len(args) == 0: - return super(newdict, cls).__new__(cls) - elif type(args[0]) == newdict: - value = args[0] - else: - value = args[0] - return super(newdict, cls).__new__(cls, value) + return super(newdict, cls).__new__(cls, *args) def __native__(self): """ From fa73942dfbfa3ca6d56632b70231c1d64daa6291 Mon Sep 17 00:00:00 2001 From: azjps Date: Tue, 16 Jun 2020 02:13:59 -0400 Subject: [PATCH 03/59] Bugfix with undefined children_hooks when package is None touch_import_top() is always called with a package within the futurize codebase, but it does have a code path where package can be None (e.g. import six instead of from six import string_types). Fixed a minor bug in this code path, so that a custom fixer can use it. Change-Id: Iec2891586fe852e35a91c69d2fb146645d7c53dd --- src/libfuturize/fixer_util.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libfuturize/fixer_util.py b/src/libfuturize/fixer_util.py index 48e4689d..b59ad3c2 100644 --- a/src/libfuturize/fixer_util.py +++ b/src/libfuturize/fixer_util.py @@ -390,6 +390,7 @@ def touch_import_top(package, name_to_import, node): break insert_pos = idx + children_hooks = [] if package is None: import_ = Node(syms.import_name, [ Leaf(token.NAME, u"import"), @@ -413,8 +414,6 @@ def touch_import_top(package, name_to_import, node): ] ) children_hooks = [install_hooks, Newline()] - else: - children_hooks = [] # FromImport(package, [Leaf(token.NAME, name_to_import, prefix=u" ")]) From 0d95a40fa7ac86d9e0bd4bd54693b42d25f5c0a5 Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Sun, 30 Aug 2020 19:24:54 -0700 Subject: [PATCH 04/59] improve cmp function, add unittest --- src/past/builtins/misc.py | 63 ++++++++++- tests/test_past/test_misc.py | 39 +++++++ tests/test_past/test_values.py | 201 +++++++++++++++++++++++++++++++++ 3 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 tests/test_past/test_misc.py create mode 100644 tests/test_past/test_values.py diff --git a/src/past/builtins/misc.py b/src/past/builtins/misc.py index ba50aa9e..889e0ff8 100644 --- a/src/past/builtins/misc.py +++ b/src/past/builtins/misc.py @@ -1,6 +1,8 @@ from __future__ import unicode_literals import inspect +import math +import numbers from future.utils import PY2, PY3, exec_ @@ -29,8 +31,67 @@ def cmp(x, y): cmp(x, y) -> integer Return negative if xy. + Python2 had looser comparison allowing cmp None and non Numerical types and collections. + Try to match the old behavior """ - return (x > y) - (x < y) + if isinstance(x, set) and isinstance(y, set): + raise TypeError('cannot compare sets using cmp()',) + try: + if isinstance(x, numbers.Number) and math.isnan(x): + if not isinstance(y, numbers.Number): + raise TypeError(f'cannot compare float("nan"), {type(y)} with cmp') + if isinstance(y, int): + return 1 + else: + return -1 + if isinstance(y, numbers.Number) and math.isnan(y): + if not isinstance(x, numbers.Number): + raise TypeError(f'cannot compare {type(x)}, float("nan") with cmp') + if isinstance(x, int): + return -1 + else: + return 1 + return (x > y) - (x < y) + except TypeError: + if x == y: + return 0 + type_order = [ + type(None), + numbers.Number, + dict, list, + set, + (str, bytes), + ] + x_type_index = y_type_index = None + for i, type_match in enumerate(type_order): + if isinstance(x, type_match): + x_type_index = i + if isinstance(y, type_match): + y_type_index = i + if cmp(x_type_index, y_type_index) == 0: + if isinstance(x, bytes) and isinstance(y, str): + return cmp(x.decode('ascii'), y) + if isinstance(y, bytes) and isinstance(x, str): + return cmp(x, y.decode('ascii')) + elif isinstance(x, list): + # if both arguments are lists take the comparison of the first non equal value + for x_elem, y_elem in zip(x, y): + elem_cmp_val = cmp(x_elem, y_elem) + if elem_cmp_val != 0: + return elem_cmp_val + # if all elements are equal, return equal/0 + return 0 + elif isinstance(x, dict): + if len(x) != len(y): + return cmp(len(x), len(y)) + else: + x_key = min(a for a in x if a not in y or x[a] != y[a]) + y_key = min(b for b in y if b not in x or x[b] != y[b]) + if x_key != y_key: + return cmp(x_key, y_key) + else: + return cmp(x[x_key], y[y_key]) + return cmp(x_type_index, y_type_index) from sys import intern diff --git a/tests/test_past/test_misc.py b/tests/test_past/test_misc.py new file mode 100644 index 00000000..3d1b7a09 --- /dev/null +++ b/tests/test_past/test_misc.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +""" +Tests for the resurrected Py2-like cmp funtion +""" + +from __future__ import absolute_import, unicode_literals, print_function + +import os.path +import sys +import traceback + +from future.tests.base import unittest +from past.builtins import cmp + +_dir = os.path.dirname(os.path.abspath(__file__)) +sys.path.append(_dir) +import test_values + + +class TestCmp(unittest.TestCase): + def test_cmp(self): + for x, y, cmp_python2_value in test_values.cmp_python2_value: + with self.subTest(x=x, y=y): + try: + past_cmp_value = cmp(x, y) + except Exception as ex: + past_cmp_value = traceback.format_exc().strip().split('\n')[-1] + + self.assertEqual(cmp_python2_value, past_cmp_value, + "expected result matching python2 __builtins__.cmp({x!r},{y!r}) " + "== {cmp_python2_value} " + "got past.builtins.cmp({x!r},{y!r}) " + "== {past_cmp_value} " + "".format(x=x, y=y, past_cmp_value=past_cmp_value, + cmp_python2_value=cmp_python2_value)) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_past/test_values.py b/tests/test_past/test_values.py new file mode 100644 index 00000000..393ad761 --- /dev/null +++ b/tests/test_past/test_values.py @@ -0,0 +1,201 @@ +from math import pi + +inf, nan = float('inf'), float('nan') +test_values = [ + 0, 1, 2, -1, -9999999999, 9999999, + 0.0, inf, nan, pi, + # [], [[]], [1,2,3], + set(), set([1, 2, 3]), + " ", "", "1", "dsada saA.", "2", "dsa", b"", b"dsa", b" ", + {5: 3}, dict(), dict(a=99), dict(a=1, b=2, c=3), None +] + +# cmp_python2_values are pre-calculated from running cmp under python2 first values are x and y, last is results of cmp +cmp_python2_value = [[0, 1, -1], [0, 2, -1], [0, -1, 1], [0, -9999999999999999, 1], [0, 9999999999999999, -1], + [0, 0.0, 0], [0, inf, -1], [0, nan, -1], [0, 3.141592653589793, -1], [0, '', -1], [0, ' ', -1], + [0, '1', -1], [0, 'a bee cd.', -1], [0, '', -1], [0, ' ', -1], [0, '1', -1], [0, 'a bee cd.', -1], + [0, set([]), -1], [0, set([1, 2, 3]), -1], [0, {5: 3}, -1], [0, {}, -1], [0, {'a': 99}, -1], + [0, {'a': 1, 'c': 3, 'b': 2}, -1], [0, {'a': 99, 'c': 3, 'b': 5}, -1], [0, None, 1], [1, 0, 1], + [1, 2, -1], [1, -1, 1], [1, -9999999999999999, 1], [1, 9999999999999999, -1], [1, 0.0, 1], + [1, inf, -1], [1, nan, -1], [1, 3.141592653589793, -1], [1, '', -1], [1, ' ', -1], [1, '1', -1], + [1, 'a bee cd.', -1], [1, '', -1], [1, ' ', -1], [1, '1', -1], [1, 'a bee cd.', -1], + [1, set([]), -1], [1, set([1, 2, 3]), -1], [1, {5: 3}, -1], [1, {}, -1], [1, {'a': 99}, -1], + [1, {'a': 1, 'c': 3, 'b': 2}, -1], [1, {'a': 99, 'c': 3, 'b': 5}, -1], [1, None, 1], [2, 0, 1], + [2, 1, 1], [2, -1, 1], [2, -9999999999999999, 1], [2, 9999999999999999, -1], [2, 0.0, 1], + [2, inf, -1], [2, nan, -1], [2, 3.141592653589793, -1], [2, '', -1], [2, ' ', -1], [2, '1', -1], + [2, 'a bee cd.', -1], [2, '', -1], [2, ' ', -1], [2, '1', -1], [2, 'a bee cd.', -1], + [2, set([]), -1], [2, set([1, 2, 3]), -1], [2, {5: 3}, -1], [2, {}, -1], [2, {'a': 99}, -1], + [2, {'a': 1, 'c': 3, 'b': 2}, -1], [2, {'a': 99, 'c': 3, 'b': 5}, -1], [2, None, 1], [-1, 0, -1], + [-1, 1, -1], [-1, 2, -1], [-1, -9999999999999999, 1], [-1, 9999999999999999, -1], [-1, 0.0, -1], + [-1, inf, -1], [-1, nan, -1], [-1, 3.141592653589793, -1], [-1, '', -1], [-1, ' ', -1], + [-1, '1', -1], [-1, 'a bee cd.', -1], [-1, '', -1], [-1, ' ', -1], [-1, '1', -1], + [-1, 'a bee cd.', -1], [-1, set([]), -1], [-1, set([1, 2, 3]), -1], [-1, {5: 3}, -1], [-1, {}, -1], + [-1, {'a': 99}, -1], [-1, {'a': 1, 'c': 3, 'b': 2}, -1], [-1, {'a': 99, 'c': 3, 'b': 5}, -1], + [-1, None, 1], [-9999999999999999, 0, -1], [-9999999999999999, 1, -1], + [-9999999999999999, 2, -1], [-9999999999999999, -1, -1], + [-9999999999999999, 9999999999999999, -1], [-9999999999999999, 0.0, -1], + [-9999999999999999, inf, -1], [-9999999999999999, nan, -1], + [-9999999999999999, 3.141592653589793, -1], [-9999999999999999, '', -1], + [-9999999999999999, ' ', -1], [-9999999999999999, '1', -1], + [-9999999999999999, 'a bee cd.', -1], [-9999999999999999, '', -1], [-9999999999999999, ' ', -1], + [-9999999999999999, '1', -1], [-9999999999999999, 'a bee cd.', -1], + [-9999999999999999, set([]), -1], [-9999999999999999, set([1, 2, 3]), -1], + [-9999999999999999, {5: 3}, -1], [-9999999999999999, {}, -1], + [-9999999999999999, {'a': 99}, -1], [-9999999999999999, {'a': 1, 'c': 3, 'b': 2}, -1], + [-9999999999999999, {'a': 99, 'c': 3, 'b': 5}, -1], [-9999999999999999, None, 1], + [9999999999999999, 0, 1], [9999999999999999, 1, 1], [9999999999999999, 2, 1], + [9999999999999999, -1, 1], [9999999999999999, -9999999999999999, 1], + [9999999999999999, 0.0, 1], [9999999999999999, inf, -1], [9999999999999999, nan, -1], + [9999999999999999, 3.141592653589793, 1], [9999999999999999, '', -1], + [9999999999999999, ' ', -1], [9999999999999999, '1', -1], [9999999999999999, 'a bee cd.', -1], + [9999999999999999, '', -1], [9999999999999999, ' ', -1], [9999999999999999, '1', -1], + [9999999999999999, 'a bee cd.', -1], [9999999999999999, set([]), -1], + [9999999999999999, set([1, 2, 3]), -1], [9999999999999999, {5: 3}, -1], + [9999999999999999, {}, -1], [9999999999999999, {'a': 99}, -1], + [9999999999999999, {'a': 1, 'c': 3, 'b': 2}, -1], + [9999999999999999, {'a': 99, 'c': 3, 'b': 5}, -1], [9999999999999999, None, 1], [0.0, 0, 0], + [0.0, 1, -1], [0.0, 2, -1], [0.0, -1, 1], [0.0, -9999999999999999, 1], + [0.0, 9999999999999999, -1], [0.0, inf, -1], [0.0, nan, 1], [0.0, 3.141592653589793, -1], + [0.0, '', -1], [0.0, ' ', -1], [0.0, '1', -1], [0.0, 'a bee cd.', -1], [0.0, '', -1], + [0.0, ' ', -1], [0.0, '1', -1], [0.0, 'a bee cd.', -1], [0.0, set([]), -1], + [0.0, set([1, 2, 3]), -1], [0.0, {5: 3}, -1], [0.0, {}, -1], [0.0, {'a': 99}, -1], + [0.0, {'a': 1, 'c': 3, 'b': 2}, -1], [0.0, {'a': 99, 'c': 3, 'b': 5}, -1], [0.0, None, 1], + [inf, 0, 1], [inf, 1, 1], [inf, 2, 1], [inf, -1, 1], [inf, -9999999999999999, 1], + [inf, 9999999999999999, 1], [inf, 0.0, 1], [inf, nan, 1], [inf, 3.141592653589793, 1], + [inf, '', -1], [inf, ' ', -1], [inf, '1', -1], [inf, 'a bee cd.', -1], [inf, '', -1], + [inf, ' ', -1], [inf, '1', -1], [inf, 'a bee cd.', -1], [inf, set([]), -1], + [inf, set([1, 2, 3]), -1], [inf, {5: 3}, -1], [inf, {}, -1], [inf, {'a': 99}, -1], + [inf, {'a': 1, 'c': 3, 'b': 2}, -1], [inf, {'a': 99, 'c': 3, 'b': 5}, -1], [inf, None, 1], + [nan, 0, 1], [nan, 1, 1], [nan, 2, 1], [nan, -1, 1], [nan, -9999999999999999, 1], + [nan, 9999999999999999, 1], [nan, 0.0, -1], [nan, inf, -1], [nan, 3.141592653589793, -1], + [nan, '', -1], [nan, ' ', -1], [nan, '1', -1], [nan, 'a bee cd.', -1], [nan, '', -1], + [nan, ' ', -1], [nan, '1', -1], [nan, 'a bee cd.', -1], [nan, set([]), -1], + [nan, set([1, 2, 3]), -1], [nan, {5: 3}, -1], [nan, {}, -1], [nan, {'a': 99}, -1], + [nan, {'a': 1, 'c': 3, 'b': 2}, -1], [nan, {'a': 99, 'c': 3, 'b': 5}, -1], [nan, None, 1], + [3.141592653589793, 0, 1], [3.141592653589793, 1, 1], [3.141592653589793, 2, 1], + [3.141592653589793, -1, 1], [3.141592653589793, -9999999999999999, 1], + [3.141592653589793, 9999999999999999, -1], [3.141592653589793, 0.0, 1], + [3.141592653589793, inf, -1], [3.141592653589793, nan, 1], [3.141592653589793, '', -1], + [3.141592653589793, ' ', -1], [3.141592653589793, '1', -1], [3.141592653589793, 'a bee cd.', -1], + [3.141592653589793, '', -1], [3.141592653589793, ' ', -1], [3.141592653589793, '1', -1], + [3.141592653589793, 'a bee cd.', -1], [3.141592653589793, set([]), -1], + [3.141592653589793, set([1, 2, 3]), -1], [3.141592653589793, {5: 3}, -1], + [3.141592653589793, {}, -1], [3.141592653589793, {'a': 99}, -1], + [3.141592653589793, {'a': 1, 'c': 3, 'b': 2}, -1], + [3.141592653589793, {'a': 99, 'c': 3, 'b': 5}, -1], [3.141592653589793, None, 1], ['', 0, 1], + ['', 1, 1], ['', 2, 1], ['', -1, 1], ['', -9999999999999999, 1], ['', 9999999999999999, 1], + ['', 0.0, 1], ['', inf, 1], ['', nan, 1], ['', 3.141592653589793, 1], ['', ' ', -1], ['', '1', -1], + ['', 'a bee cd.', -1], ['', '', 0], ['', ' ', -1], ['', '1', -1], ['', 'a bee cd.', -1], + ['', set([]), 1], ['', set([1, 2, 3]), 1], ['', {5: 3}, 1], ['', {}, 1], ['', {'a': 99}, 1], + ['', {'a': 1, 'c': 3, 'b': 2}, 1], ['', {'a': 99, 'c': 3, 'b': 5}, 1], ['', None, 1], [' ', 0, 1], + [' ', 1, 1], [' ', 2, 1], [' ', -1, 1], [' ', -9999999999999999, 1], [' ', 9999999999999999, 1], + [' ', 0.0, 1], [' ', inf, 1], [' ', nan, 1], [' ', 3.141592653589793, 1], [' ', '', 1], + [' ', '1', -1], [' ', 'a bee cd.', -1], [' ', '', 1], [' ', ' ', 0], [' ', '1', -1], + [' ', 'a bee cd.', -1], [' ', set([]), 1], [' ', set([1, 2, 3]), 1], [' ', {5: 3}, 1], + [' ', {}, 1], [' ', {'a': 99}, 1], [' ', {'a': 1, 'c': 3, 'b': 2}, 1], + [' ', {'a': 99, 'c': 3, 'b': 5}, 1], [' ', None, 1], ['1', 0, 1], ['1', 1, 1], ['1', 2, 1], + ['1', -1, 1], ['1', -9999999999999999, 1], ['1', 9999999999999999, 1], ['1', 0.0, 1], + ['1', inf, 1], ['1', nan, 1], ['1', 3.141592653589793, 1], ['1', '', 1], ['1', ' ', 1], + ['1', 'a bee cd.', -1], ['1', '', 1], ['1', ' ', 1], ['1', '1', 0], ['1', 'a bee cd.', -1], + ['1', set([]), 1], ['1', set([1, 2, 3]), 1], ['1', {5: 3}, 1], ['1', {}, 1], ['1', {'a': 99}, 1], + ['1', {'a': 1, 'c': 3, 'b': 2}, 1], ['1', {'a': 99, 'c': 3, 'b': 5}, 1], ['1', None, 1], + ['a bee cd.', 0, 1], ['a bee cd.', 1, 1], ['a bee cd.', 2, 1], ['a bee cd.', -1, 1], + ['a bee cd.', -9999999999999999, 1], ['a bee cd.', 9999999999999999, 1], ['a bee cd.', 0.0, 1], + ['a bee cd.', inf, 1], ['a bee cd.', nan, 1], ['a bee cd.', 3.141592653589793, 1], + ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], ['a bee cd.', '1', 1], ['a bee cd.', '', 1], + ['a bee cd.', ' ', 1], ['a bee cd.', '1', 1], ['a bee cd.', 'a bee cd.', 0], + ['a bee cd.', set([]), 1], ['a bee cd.', set([1, 2, 3]), 1], ['a bee cd.', {5: 3}, 1], + ['a bee cd.', {}, 1], ['a bee cd.', {'a': 99}, 1], ['a bee cd.', {'a': 1, 'c': 3, 'b': 2}, 1], + ['a bee cd.', {'a': 99, 'c': 3, 'b': 5}, 1], ['a bee cd.', None, 1], ['', 0, 1], ['', 1, 1], + ['', 2, 1], ['', -1, 1], ['', -9999999999999999, 1], ['', 9999999999999999, 1], ['', 0.0, 1], + ['', inf, 1], ['', nan, 1], ['', 3.141592653589793, 1], ['', '', 0], ['', ' ', -1], ['', '1', -1], + ['', 'a bee cd.', -1], ['', ' ', -1], ['', '1', -1], ['', 'a bee cd.', -1], ['', set([]), 1], + ['', set([1, 2, 3]), 1], ['', {5: 3}, 1], ['', {}, 1], ['', {'a': 99}, 1], + ['', {'a': 1, 'c': 3, 'b': 2}, 1], ['', {'a': 99, 'c': 3, 'b': 5}, 1], ['', None, 1], [' ', 0, 1], + [' ', 1, 1], [' ', 2, 1], [' ', -1, 1], [' ', -9999999999999999, 1], [' ', 9999999999999999, 1], + [' ', 0.0, 1], [' ', inf, 1], [' ', nan, 1], [' ', 3.141592653589793, 1], [' ', '', 1], + [' ', ' ', 0], [' ', '1', -1], [' ', 'a bee cd.', -1], [' ', '', 1], [' ', '1', -1], + [' ', 'a bee cd.', -1], [' ', set([]), 1], [' ', set([1, 2, 3]), 1], [' ', {5: 3}, 1], + [' ', {}, 1], [' ', {'a': 99}, 1], [' ', {'a': 1, 'c': 3, 'b': 2}, 1], + [' ', {'a': 99, 'c': 3, 'b': 5}, 1], [' ', None, 1], ['1', 0, 1], ['1', 1, 1], ['1', 2, 1], + ['1', -1, 1], ['1', -9999999999999999, 1], ['1', 9999999999999999, 1], ['1', 0.0, 1], + ['1', inf, 1], ['1', nan, 1], ['1', 3.141592653589793, 1], ['1', '', 1], ['1', ' ', 1], + ['1', '1', 0], ['1', 'a bee cd.', -1], ['1', '', 1], ['1', ' ', 1], ['1', 'a bee cd.', -1], + ['1', set([]), 1], ['1', set([1, 2, 3]), 1], ['1', {5: 3}, 1], ['1', {}, 1], ['1', {'a': 99}, 1], + ['1', {'a': 1, 'c': 3, 'b': 2}, 1], ['1', {'a': 99, 'c': 3, 'b': 5}, 1], ['1', None, 1], + ['a bee cd.', 0, 1], ['a bee cd.', 1, 1], ['a bee cd.', 2, 1], ['a bee cd.', -1, 1], + ['a bee cd.', -9999999999999999, 1], ['a bee cd.', 9999999999999999, 1], ['a bee cd.', 0.0, 1], + ['a bee cd.', inf, 1], ['a bee cd.', nan, 1], ['a bee cd.', 3.141592653589793, 1], + ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], ['a bee cd.', '1', 1], ['a bee cd.', 'a bee cd.', 0], + ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], ['a bee cd.', '1', 1], ['a bee cd.', set([]), 1], + ['a bee cd.', set([1, 2, 3]), 1], ['a bee cd.', {5: 3}, 1], ['a bee cd.', {}, 1], + ['a bee cd.', {'a': 99}, 1], ['a bee cd.', {'a': 1, 'c': 3, 'b': 2}, 1], + ['a bee cd.', {'a': 99, 'c': 3, 'b': 5}, 1], ['a bee cd.', None, 1], [set([]), 0, 1], + [set([]), 1, 1], [set([]), 2, 1], [set([]), -1, 1], [set([]), -9999999999999999, 1], + [set([]), 9999999999999999, 1], [set([]), 0.0, 1], [set([]), inf, 1], [set([]), nan, 1], + [set([]), 3.141592653589793, 1], [set([]), '', -1], [set([]), ' ', -1], [set([]), '1', -1], + [set([]), 'a bee cd.', -1], [set([]), '', -1], [set([]), ' ', -1], [set([]), '1', -1], + [set([]), 'a bee cd.', -1], + [set([]), set([1, 2, 3]), 'TypeError: cannot compare sets using cmp()'], [set([]), {5: 3}, 1], + [set([]), {}, 1], [set([]), {'a': 99}, 1], [set([]), {'a': 1, 'c': 3, 'b': 2}, 1], + [set([]), {'a': 99, 'c': 3, 'b': 5}, 1], [set([]), None, 1], [set([1, 2, 3]), 0, 1], + [set([1, 2, 3]), 1, 1], [set([1, 2, 3]), 2, 1], [set([1, 2, 3]), -1, 1], + [set([1, 2, 3]), -9999999999999999, 1], [set([1, 2, 3]), 9999999999999999, 1], + [set([1, 2, 3]), 0.0, 1], [set([1, 2, 3]), inf, 1], [set([1, 2, 3]), nan, 1], + [set([1, 2, 3]), 3.141592653589793, 1], [set([1, 2, 3]), '', -1], [set([1, 2, 3]), ' ', -1], + [set([1, 2, 3]), '1', -1], [set([1, 2, 3]), 'a bee cd.', -1], [set([1, 2, 3]), '', -1], + [set([1, 2, 3]), ' ', -1], [set([1, 2, 3]), '1', -1], [set([1, 2, 3]), 'a bee cd.', -1], + [set([1, 2, 3]), set([]), 'TypeError: cannot compare sets using cmp()'], + [set([1, 2, 3]), {5: 3}, 1], [set([1, 2, 3]), {}, 1], [set([1, 2, 3]), {'a': 99}, 1], + [set([1, 2, 3]), {'a': 1, 'c': 3, 'b': 2}, 1], [set([1, 2, 3]), {'a': 99, 'c': 3, 'b': 5}, 1], + [set([1, 2, 3]), None, 1], [{5: 3}, 0, 1], [{5: 3}, 1, 1], [{5: 3}, 2, 1], [{5: 3}, -1, 1], + [{5: 3}, -9999999999999999, 1], [{5: 3}, 9999999999999999, 1], [{5: 3}, 0.0, 1], + [{5: 3}, inf, 1], [{5: 3}, nan, 1], [{5: 3}, 3.141592653589793, 1], [{5: 3}, '', -1], + [{5: 3}, ' ', -1], [{5: 3}, '1', -1], [{5: 3}, 'a bee cd.', -1], [{5: 3}, '', -1], + [{5: 3}, ' ', -1], [{5: 3}, '1', -1], [{5: 3}, 'a bee cd.', -1], [{5: 3}, set([]), -1], + [{5: 3}, set([1, 2, 3]), -1], [{5: 3}, {}, 1], [{5: 3}, {'a': 99}, -1], + [{5: 3}, {'a': 1, 'c': 3, 'b': 2}, -1], [{5: 3}, {'a': 99, 'c': 3, 'b': 5}, -1], [{5: 3}, None, 1], + [{}, 0, 1], [{}, 1, 1], [{}, 2, 1], [{}, -1, 1], [{}, -9999999999999999, 1], + [{}, 9999999999999999, 1], [{}, 0.0, 1], [{}, inf, 1], [{}, nan, 1], [{}, 3.141592653589793, 1], + [{}, '', -1], [{}, ' ', -1], [{}, '1', -1], [{}, 'a bee cd.', -1], [{}, '', -1], [{}, ' ', -1], + [{}, '1', -1], [{}, 'a bee cd.', -1], [{}, set([]), -1], [{}, set([1, 2, 3]), -1], + [{}, {5: 3}, -1], [{}, {'a': 99}, -1], [{}, {'a': 1, 'c': 3, 'b': 2}, -1], + [{}, {'a': 99, 'c': 3, 'b': 5}, -1], [{}, None, 1], [{'a': 99}, 0, 1], [{'a': 99}, 1, 1], + [{'a': 99}, 2, 1], [{'a': 99}, -1, 1], [{'a': 99}, -9999999999999999, 1], + [{'a': 99}, 9999999999999999, 1], [{'a': 99}, 0.0, 1], [{'a': 99}, inf, 1], [{'a': 99}, nan, 1], + [{'a': 99}, 3.141592653589793, 1], [{'a': 99}, '', -1], [{'a': 99}, ' ', -1], [{'a': 99}, '1', -1], + [{'a': 99}, 'a bee cd.', -1], [{'a': 99}, '', -1], [{'a': 99}, ' ', -1], [{'a': 99}, '1', -1], + [{'a': 99}, 'a bee cd.', -1], [{'a': 99}, set([]), -1], [{'a': 99}, set([1, 2, 3]), -1], + [{'a': 99}, {5: 3}, 1], [{'a': 99}, {}, 1], [{'a': 99}, {'a': 1, 'c': 3, 'b': 2}, -1], + [{'a': 99}, {'a': 99, 'c': 3, 'b': 5}, -1], [{'a': 99}, None, 1], [{'a': 1, 'c': 3, 'b': 2}, 0, 1], + [{'a': 1, 'c': 3, 'b': 2}, 1, 1], [{'a': 1, 'c': 3, 'b': 2}, 2, 1], + [{'a': 1, 'c': 3, 'b': 2}, -1, 1], [{'a': 1, 'c': 3, 'b': 2}, -9999999999999999, 1], + [{'a': 1, 'c': 3, 'b': 2}, 9999999999999999, 1], [{'a': 1, 'c': 3, 'b': 2}, 0.0, 1], + [{'a': 1, 'c': 3, 'b': 2}, inf, 1], [{'a': 1, 'c': 3, 'b': 2}, nan, 1], + [{'a': 1, 'c': 3, 'b': 2}, 3.141592653589793, 1], [{'a': 1, 'c': 3, 'b': 2}, '', -1], + [{'a': 1, 'c': 3, 'b': 2}, ' ', -1], [{'a': 1, 'c': 3, 'b': 2}, '1', -1], + [{'a': 1, 'c': 3, 'b': 2}, 'a bee cd.', -1], [{'a': 1, 'c': 3, 'b': 2}, '', -1], + [{'a': 1, 'c': 3, 'b': 2}, ' ', -1], [{'a': 1, 'c': 3, 'b': 2}, '1', -1], + [{'a': 1, 'c': 3, 'b': 2}, 'a bee cd.', -1], [{'a': 1, 'c': 3, 'b': 2}, set([]), -1], + [{'a': 1, 'c': 3, 'b': 2}, set([1, 2, 3]), -1], [{'a': 1, 'c': 3, 'b': 2}, {5: 3}, 1], + [{'a': 1, 'c': 3, 'b': 2}, {}, 1], [{'a': 1, 'c': 3, 'b': 2}, {'a': 99}, 1], + [{'a': 1, 'c': 3, 'b': 2}, {'a': 99, 'c': 3, 'b': 5}, -1], [{'a': 1, 'c': 3, 'b': 2}, None, 1], + [{'a': 99, 'c': 3, 'b': 5}, 0, 1], [{'a': 99, 'c': 3, 'b': 5}, 1, 1], + [{'a': 99, 'c': 3, 'b': 5}, 2, 1], [{'a': 99, 'c': 3, 'b': 5}, -1, 1], + [{'a': 99, 'c': 3, 'b': 5}, -9999999999999999, 1], + [{'a': 99, 'c': 3, 'b': 5}, 9999999999999999, 1], [{'a': 99, 'c': 3, 'b': 5}, 0.0, 1], + [{'a': 99, 'c': 3, 'b': 5}, inf, 1], [{'a': 99, 'c': 3, 'b': 5}, nan, 1], + [{'a': 99, 'c': 3, 'b': 5}, 3.141592653589793, 1], [{'a': 99, 'c': 3, 'b': 5}, '', -1], + [{'a': 99, 'c': 3, 'b': 5}, ' ', -1], [{'a': 99, 'c': 3, 'b': 5}, '1', -1], + [{'a': 99, 'c': 3, 'b': 5}, 'a bee cd.', -1], [{'a': 99, 'c': 3, 'b': 5}, '', -1], + [{'a': 99, 'c': 3, 'b': 5}, ' ', -1], [{'a': 99, 'c': 3, 'b': 5}, '1', -1], + [{'a': 99, 'c': 3, 'b': 5}, 'a bee cd.', -1], [{'a': 99, 'c': 3, 'b': 5}, set([]), -1], + [{'a': 99, 'c': 3, 'b': 5}, set([1, 2, 3]), -1], [{'a': 99, 'c': 3, 'b': 5}, {5: 3}, 1], + [{'a': 99, 'c': 3, 'b': 5}, {}, 1], [{'a': 99, 'c': 3, 'b': 5}, {'a': 99}, 1], + [{'a': 99, 'c': 3, 'b': 5}, {'a': 1, 'c': 3, 'b': 2}, 1], [{'a': 99, 'c': 3, 'b': 5}, None, 1], + [None, 0, -1], [None, 1, -1], [None, 2, -1], [None, -1, -1], [None, -9999999999999999, -1], + [None, 9999999999999999, -1], [None, 0.0, -1], [None, inf, -1], [None, nan, -1], + [None, 3.141592653589793, -1], [None, '', -1], [None, ' ', -1], [None, '1', -1], + [None, 'a bee cd.', -1], [None, '', -1], [None, ' ', -1], [None, '1', -1], [None, 'a bee cd.', -1], + [None, set([]), -1], [None, set([1, 2, 3]), -1], [None, {5: 3}, -1], [None, {}, -1], + [None, {'a': 99}, -1], [None, {'a': 1, 'c': 3, 'b': 2}, -1], [None, {'a': 99, 'c': 3, 'b': 5}, -1]] From 8302d8c8f1f61c9b1cb978337eddcdcc48701310 Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Sun, 30 Aug 2020 19:37:37 -0700 Subject: [PATCH 05/59] minor style/spelling fixes --- src/past/builtins/misc.py | 4 ++-- tests/test_past/test_misc.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/past/builtins/misc.py b/src/past/builtins/misc.py index 889e0ff8..6342a8ec 100644 --- a/src/past/builtins/misc.py +++ b/src/past/builtins/misc.py @@ -103,7 +103,7 @@ def oct(number): return '0' + builtins.oct(number)[2:] raw_input = input - from imp import reload + from importlib import reload unicode = str unichr = chr xrange = range @@ -143,7 +143,7 @@ def execfile(filename, myglobals=None, mylocals=None): if not isinstance(mylocals, Mapping): raise TypeError('locals must be a mapping') with open(filename, "rb") as fin: - source = fin.read() + source = fin.read() code = compile(source, filename, "exec") exec_(code, myglobals, mylocals) diff --git a/tests/test_past/test_misc.py b/tests/test_past/test_misc.py index 3d1b7a09..3952ab19 100644 --- a/tests/test_past/test_misc.py +++ b/tests/test_past/test_misc.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Tests for the resurrected Py2-like cmp funtion +Tests for the resurrected Py2-like cmp function """ from __future__ import absolute_import, unicode_literals, print_function @@ -23,7 +23,7 @@ def test_cmp(self): with self.subTest(x=x, y=y): try: past_cmp_value = cmp(x, y) - except Exception as ex: + except Exception: past_cmp_value = traceback.format_exc().strip().split('\n')[-1] self.assertEqual(cmp_python2_value, past_cmp_value, From 4a687ea190fb3a18e808373fd571adb65218cf9e Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Sun, 30 Aug 2020 20:06:38 -0700 Subject: [PATCH 06/59] replace fstrings with format for python 3.4,3.5 --- src/past/builtins/misc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/past/builtins/misc.py b/src/past/builtins/misc.py index 6342a8ec..dda6ff33 100644 --- a/src/past/builtins/misc.py +++ b/src/past/builtins/misc.py @@ -39,14 +39,14 @@ def cmp(x, y): try: if isinstance(x, numbers.Number) and math.isnan(x): if not isinstance(y, numbers.Number): - raise TypeError(f'cannot compare float("nan"), {type(y)} with cmp') + raise TypeError('cannot compare float("nan"), {type_y} with cmp'.format(type_y=type(y))) if isinstance(y, int): return 1 else: return -1 if isinstance(y, numbers.Number) and math.isnan(y): if not isinstance(x, numbers.Number): - raise TypeError(f'cannot compare {type(x)}, float("nan") with cmp') + raise TypeError('cannot compare {type_x}, float("nan") with cmp'.format(type_x=type(x))) if isinstance(x, int): return -1 else: From fc84fa8dd46d5ccff8d80b5ac1cac68af5c83055 Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Sun, 30 Aug 2020 20:16:59 -0700 Subject: [PATCH 07/59] import from old imp library on older python versions --- src/past/builtins/misc.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/past/builtins/misc.py b/src/past/builtins/misc.py index dda6ff33..3600695c 100644 --- a/src/past/builtins/misc.py +++ b/src/past/builtins/misc.py @@ -103,7 +103,13 @@ def oct(number): return '0' + builtins.oct(number)[2:] raw_input = input - from importlib import reload + + try: + from importlib import reload + except ImportError: + # for python2, python3 <= 3.4 + from imp import reload + unicode = str unichr = chr xrange = range From f006cad1cf66d691086df058698404cd4bdf2216 Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Sun, 30 Aug 2020 20:32:00 -0700 Subject: [PATCH 08/59] fix missing subTest --- tests/test_past/test_misc.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/test_past/test_misc.py b/tests/test_past/test_misc.py index 3952ab19..2bbdea2d 100644 --- a/tests/test_past/test_misc.py +++ b/tests/test_past/test_misc.py @@ -8,6 +8,7 @@ import os.path import sys import traceback +from contextlib import contextmanager from future.tests.base import unittest from past.builtins import cmp @@ -17,10 +18,16 @@ import test_values +@contextmanager +def empty_context_manager(*args, **kwargs): + return dict(args=args, kwargs=kwargs) + + class TestCmp(unittest.TestCase): def test_cmp(self): for x, y, cmp_python2_value in test_values.cmp_python2_value: - with self.subTest(x=x, y=y): + # to get this to run on python <3.4 which lacks subTest + with getattr(self, 'subTest', empty_context_manager)(x=x, y=y): try: past_cmp_value = cmp(x, y) except Exception: From c0510266fd62297ea54629bac89cbb4644c8786f Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Sun, 30 Aug 2020 20:42:10 -0700 Subject: [PATCH 09/59] fix other python2 test issues --- tests/test_past/test_misc.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/test_past/test_misc.py b/tests/test_past/test_misc.py index 2bbdea2d..db07896f 100644 --- a/tests/test_past/test_misc.py +++ b/tests/test_past/test_misc.py @@ -11,7 +11,10 @@ from contextlib import contextmanager from future.tests.base import unittest -from past.builtins import cmp +from future.utils import PY3 + +if PY3: + from past.builtins import cmp _dir = os.path.dirname(os.path.abspath(__file__)) sys.path.append(_dir) @@ -20,7 +23,7 @@ @contextmanager def empty_context_manager(*args, **kwargs): - return dict(args=args, kwargs=kwargs) + yield dict(args=args, kwargs=kwargs) class TestCmp(unittest.TestCase): From e3f1a128a978e23b2993222cc3379a2e64f54e9a Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Sun, 30 Aug 2020 21:10:26 -0700 Subject: [PATCH 10/59] include list test values --- tests/test_past/test_values.py | 281 +++++++++++++++++++-------------- 1 file changed, 160 insertions(+), 121 deletions(-) diff --git a/tests/test_past/test_values.py b/tests/test_past/test_values.py index 393ad761..7c85a8f2 100644 --- a/tests/test_past/test_values.py +++ b/tests/test_past/test_values.py @@ -4,7 +4,7 @@ test_values = [ 0, 1, 2, -1, -9999999999, 9999999, 0.0, inf, nan, pi, - # [], [[]], [1,2,3], + [], [[]], [1, 2, 3], set(), set([1, 2, 3]), " ", "", "1", "dsada saA.", "2", "dsa", b"", b"dsa", b" ", {5: 3}, dict(), dict(a=99), dict(a=1, b=2, c=3), None @@ -12,62 +12,65 @@ # cmp_python2_values are pre-calculated from running cmp under python2 first values are x and y, last is results of cmp cmp_python2_value = [[0, 1, -1], [0, 2, -1], [0, -1, 1], [0, -9999999999999999, 1], [0, 9999999999999999, -1], - [0, 0.0, 0], [0, inf, -1], [0, nan, -1], [0, 3.141592653589793, -1], [0, '', -1], [0, ' ', -1], - [0, '1', -1], [0, 'a bee cd.', -1], [0, '', -1], [0, ' ', -1], [0, '1', -1], [0, 'a bee cd.', -1], - [0, set([]), -1], [0, set([1, 2, 3]), -1], [0, {5: 3}, -1], [0, {}, -1], [0, {'a': 99}, -1], - [0, {'a': 1, 'c': 3, 'b': 2}, -1], [0, {'a': 99, 'c': 3, 'b': 5}, -1], [0, None, 1], [1, 0, 1], - [1, 2, -1], [1, -1, 1], [1, -9999999999999999, 1], [1, 9999999999999999, -1], [1, 0.0, 1], - [1, inf, -1], [1, nan, -1], [1, 3.141592653589793, -1], [1, '', -1], [1, ' ', -1], [1, '1', -1], - [1, 'a bee cd.', -1], [1, '', -1], [1, ' ', -1], [1, '1', -1], [1, 'a bee cd.', -1], - [1, set([]), -1], [1, set([1, 2, 3]), -1], [1, {5: 3}, -1], [1, {}, -1], [1, {'a': 99}, -1], - [1, {'a': 1, 'c': 3, 'b': 2}, -1], [1, {'a': 99, 'c': 3, 'b': 5}, -1], [1, None, 1], [2, 0, 1], - [2, 1, 1], [2, -1, 1], [2, -9999999999999999, 1], [2, 9999999999999999, -1], [2, 0.0, 1], - [2, inf, -1], [2, nan, -1], [2, 3.141592653589793, -1], [2, '', -1], [2, ' ', -1], [2, '1', -1], + [0, 0.0, 0], [0, inf, -1], [0, nan, -1], [0, 3.141592653589793, -1], [0, [], -1], [0, [[]], -1], + [0, [1, 2, 3], -1], [0, '', -1], [0, ' ', -1], [0, '1', -1], [0, 'a bee cd.', -1], [0, '', -1], + [0, ' ', -1], [0, '1', -1], [0, 'a bee cd.', -1], [0, set([]), -1], [0, set([1, 2, 3]), -1], + [0, {5: 3}, -1], [0, {}, -1], [0, {'a': 99}, -1], [0, {'a': 1, 'c': 3, 'b': 2}, -1], + [0, {'a': 99, 'c': 3, 'b': 5}, -1], [0, None, 1], [1, 0, 1], [1, 2, -1], [1, -1, 1], + [1, -9999999999999999, 1], [1, 9999999999999999, -1], [1, 0.0, 1], [1, inf, -1], [1, nan, -1], + [1, 3.141592653589793, -1], [1, [], -1], [1, [[]], -1], [1, [1, 2, 3], -1], [1, '', -1], + [1, ' ', -1], [1, '1', -1], [1, 'a bee cd.', -1], [1, '', -1], [1, ' ', -1], [1, '1', -1], + [1, 'a bee cd.', -1], [1, set([]), -1], [1, set([1, 2, 3]), -1], [1, {5: 3}, -1], [1, {}, -1], + [1, {'a': 99}, -1], [1, {'a': 1, 'c': 3, 'b': 2}, -1], [1, {'a': 99, 'c': 3, 'b': 5}, -1], + [1, None, 1], [2, 0, 1], [2, 1, 1], [2, -1, 1], [2, -9999999999999999, 1], + [2, 9999999999999999, -1], [2, 0.0, 1], [2, inf, -1], [2, nan, -1], [2, 3.141592653589793, -1], + [2, [], -1], [2, [[]], -1], [2, [1, 2, 3], -1], [2, '', -1], [2, ' ', -1], [2, '1', -1], [2, 'a bee cd.', -1], [2, '', -1], [2, ' ', -1], [2, '1', -1], [2, 'a bee cd.', -1], [2, set([]), -1], [2, set([1, 2, 3]), -1], [2, {5: 3}, -1], [2, {}, -1], [2, {'a': 99}, -1], [2, {'a': 1, 'c': 3, 'b': 2}, -1], [2, {'a': 99, 'c': 3, 'b': 5}, -1], [2, None, 1], [-1, 0, -1], [-1, 1, -1], [-1, 2, -1], [-1, -9999999999999999, 1], [-1, 9999999999999999, -1], [-1, 0.0, -1], - [-1, inf, -1], [-1, nan, -1], [-1, 3.141592653589793, -1], [-1, '', -1], [-1, ' ', -1], - [-1, '1', -1], [-1, 'a bee cd.', -1], [-1, '', -1], [-1, ' ', -1], [-1, '1', -1], - [-1, 'a bee cd.', -1], [-1, set([]), -1], [-1, set([1, 2, 3]), -1], [-1, {5: 3}, -1], [-1, {}, -1], - [-1, {'a': 99}, -1], [-1, {'a': 1, 'c': 3, 'b': 2}, -1], [-1, {'a': 99, 'c': 3, 'b': 5}, -1], - [-1, None, 1], [-9999999999999999, 0, -1], [-9999999999999999, 1, -1], - [-9999999999999999, 2, -1], [-9999999999999999, -1, -1], - [-9999999999999999, 9999999999999999, -1], [-9999999999999999, 0.0, -1], - [-9999999999999999, inf, -1], [-9999999999999999, nan, -1], - [-9999999999999999, 3.141592653589793, -1], [-9999999999999999, '', -1], - [-9999999999999999, ' ', -1], [-9999999999999999, '1', -1], - [-9999999999999999, 'a bee cd.', -1], [-9999999999999999, '', -1], [-9999999999999999, ' ', -1], - [-9999999999999999, '1', -1], [-9999999999999999, 'a bee cd.', -1], - [-9999999999999999, set([]), -1], [-9999999999999999, set([1, 2, 3]), -1], - [-9999999999999999, {5: 3}, -1], [-9999999999999999, {}, -1], - [-9999999999999999, {'a': 99}, -1], [-9999999999999999, {'a': 1, 'c': 3, 'b': 2}, -1], + [-1, inf, -1], [-1, nan, -1], [-1, 3.141592653589793, -1], [-1, [], -1], [-1, [[]], -1], + [-1, [1, 2, 3], -1], [-1, '', -1], [-1, ' ', -1], [-1, '1', -1], [-1, 'a bee cd.', -1], + [-1, '', -1], [-1, ' ', -1], [-1, '1', -1], [-1, 'a bee cd.', -1], [-1, set([]), -1], + [-1, set([1, 2, 3]), -1], [-1, {5: 3}, -1], [-1, {}, -1], [-1, {'a': 99}, -1], + [-1, {'a': 1, 'c': 3, 'b': 2}, -1], [-1, {'a': 99, 'c': 3, 'b': 5}, -1], [-1, None, 1], + [-9999999999999999, 0, -1], [-9999999999999999, 1, -1], [-9999999999999999, 2, -1], + [-9999999999999999, -1, -1], [-9999999999999999, 9999999999999999, -1], + [-9999999999999999, 0.0, -1], [-9999999999999999, inf, -1], [-9999999999999999, nan, -1], + [-9999999999999999, 3.141592653589793, -1], [-9999999999999999, [], -1], + [-9999999999999999, [[]], -1], [-9999999999999999, [1, 2, 3], -1], [-9999999999999999, '', -1], + [-9999999999999999, ' ', -1], [-9999999999999999, '1', -1], [-9999999999999999, 'a bee cd.', -1], + [-9999999999999999, '', -1], [-9999999999999999, ' ', -1], [-9999999999999999, '1', -1], + [-9999999999999999, 'a bee cd.', -1], [-9999999999999999, set([]), -1], + [-9999999999999999, set([1, 2, 3]), -1], [-9999999999999999, {5: 3}, -1], + [-9999999999999999, {}, -1], [-9999999999999999, {'a': 99}, -1], + [-9999999999999999, {'a': 1, 'c': 3, 'b': 2}, -1], [-9999999999999999, {'a': 99, 'c': 3, 'b': 5}, -1], [-9999999999999999, None, 1], [9999999999999999, 0, 1], [9999999999999999, 1, 1], [9999999999999999, 2, 1], - [9999999999999999, -1, 1], [9999999999999999, -9999999999999999, 1], - [9999999999999999, 0.0, 1], [9999999999999999, inf, -1], [9999999999999999, nan, -1], - [9999999999999999, 3.141592653589793, 1], [9999999999999999, '', -1], - [9999999999999999, ' ', -1], [9999999999999999, '1', -1], [9999999999999999, 'a bee cd.', -1], + [9999999999999999, -1, 1], [9999999999999999, -9999999999999999, 1], [9999999999999999, 0.0, 1], + [9999999999999999, inf, -1], [9999999999999999, nan, -1], [9999999999999999, 3.141592653589793, 1], + [9999999999999999, [], -1], [9999999999999999, [[]], -1], [9999999999999999, [1, 2, 3], -1], [9999999999999999, '', -1], [9999999999999999, ' ', -1], [9999999999999999, '1', -1], - [9999999999999999, 'a bee cd.', -1], [9999999999999999, set([]), -1], - [9999999999999999, set([1, 2, 3]), -1], [9999999999999999, {5: 3}, -1], - [9999999999999999, {}, -1], [9999999999999999, {'a': 99}, -1], - [9999999999999999, {'a': 1, 'c': 3, 'b': 2}, -1], + [9999999999999999, 'a bee cd.', -1], [9999999999999999, '', -1], [9999999999999999, ' ', -1], + [9999999999999999, '1', -1], [9999999999999999, 'a bee cd.', -1], [9999999999999999, set([]), -1], + [9999999999999999, set([1, 2, 3]), -1], [9999999999999999, {5: 3}, -1], [9999999999999999, {}, -1], + [9999999999999999, {'a': 99}, -1], [9999999999999999, {'a': 1, 'c': 3, 'b': 2}, -1], [9999999999999999, {'a': 99, 'c': 3, 'b': 5}, -1], [9999999999999999, None, 1], [0.0, 0, 0], - [0.0, 1, -1], [0.0, 2, -1], [0.0, -1, 1], [0.0, -9999999999999999, 1], - [0.0, 9999999999999999, -1], [0.0, inf, -1], [0.0, nan, 1], [0.0, 3.141592653589793, -1], - [0.0, '', -1], [0.0, ' ', -1], [0.0, '1', -1], [0.0, 'a bee cd.', -1], [0.0, '', -1], - [0.0, ' ', -1], [0.0, '1', -1], [0.0, 'a bee cd.', -1], [0.0, set([]), -1], + [0.0, 1, -1], [0.0, 2, -1], [0.0, -1, 1], [0.0, -9999999999999999, 1], [0.0, 9999999999999999, -1], + [0.0, inf, -1], [0.0, nan, 1], [0.0, 3.141592653589793, -1], [0.0, [], -1], [0.0, [[]], -1], + [0.0, [1, 2, 3], -1], [0.0, '', -1], [0.0, ' ', -1], [0.0, '1', -1], [0.0, 'a bee cd.', -1], + [0.0, '', -1], [0.0, ' ', -1], [0.0, '1', -1], [0.0, 'a bee cd.', -1], [0.0, set([]), -1], [0.0, set([1, 2, 3]), -1], [0.0, {5: 3}, -1], [0.0, {}, -1], [0.0, {'a': 99}, -1], [0.0, {'a': 1, 'c': 3, 'b': 2}, -1], [0.0, {'a': 99, 'c': 3, 'b': 5}, -1], [0.0, None, 1], [inf, 0, 1], [inf, 1, 1], [inf, 2, 1], [inf, -1, 1], [inf, -9999999999999999, 1], [inf, 9999999999999999, 1], [inf, 0.0, 1], [inf, nan, 1], [inf, 3.141592653589793, 1], - [inf, '', -1], [inf, ' ', -1], [inf, '1', -1], [inf, 'a bee cd.', -1], [inf, '', -1], - [inf, ' ', -1], [inf, '1', -1], [inf, 'a bee cd.', -1], [inf, set([]), -1], - [inf, set([1, 2, 3]), -1], [inf, {5: 3}, -1], [inf, {}, -1], [inf, {'a': 99}, -1], - [inf, {'a': 1, 'c': 3, 'b': 2}, -1], [inf, {'a': 99, 'c': 3, 'b': 5}, -1], [inf, None, 1], - [nan, 0, 1], [nan, 1, 1], [nan, 2, 1], [nan, -1, 1], [nan, -9999999999999999, 1], - [nan, 9999999999999999, 1], [nan, 0.0, -1], [nan, inf, -1], [nan, 3.141592653589793, -1], + [inf, [], -1], [inf, [[]], -1], [inf, [1, 2, 3], -1], [inf, '', -1], [inf, ' ', -1], + [inf, '1', -1], [inf, 'a bee cd.', -1], [inf, '', -1], [inf, ' ', -1], [inf, '1', -1], + [inf, 'a bee cd.', -1], [inf, set([]), -1], [inf, set([1, 2, 3]), -1], [inf, {5: 3}, -1], + [inf, {}, -1], [inf, {'a': 99}, -1], [inf, {'a': 1, 'c': 3, 'b': 2}, -1], + [inf, {'a': 99, 'c': 3, 'b': 5}, -1], [inf, None, 1], [nan, 0, 1], [nan, 1, 1], [nan, 2, 1], + [nan, -1, 1], [nan, -9999999999999999, 1], [nan, 9999999999999999, 1], [nan, 0.0, -1], + [nan, inf, -1], [nan, 3.141592653589793, -1], [nan, [], -1], [nan, [[]], -1], [nan, [1, 2, 3], -1], [nan, '', -1], [nan, ' ', -1], [nan, '1', -1], [nan, 'a bee cd.', -1], [nan, '', -1], [nan, ' ', -1], [nan, '1', -1], [nan, 'a bee cd.', -1], [nan, set([]), -1], [nan, set([1, 2, 3]), -1], [nan, {5: 3}, -1], [nan, {}, -1], [nan, {'a': 99}, -1], @@ -75,95 +78,126 @@ [3.141592653589793, 0, 1], [3.141592653589793, 1, 1], [3.141592653589793, 2, 1], [3.141592653589793, -1, 1], [3.141592653589793, -9999999999999999, 1], [3.141592653589793, 9999999999999999, -1], [3.141592653589793, 0.0, 1], - [3.141592653589793, inf, -1], [3.141592653589793, nan, 1], [3.141592653589793, '', -1], + [3.141592653589793, inf, -1], [3.141592653589793, nan, 1], [3.141592653589793, [], -1], + [3.141592653589793, [[]], -1], [3.141592653589793, [1, 2, 3], -1], [3.141592653589793, '', -1], [3.141592653589793, ' ', -1], [3.141592653589793, '1', -1], [3.141592653589793, 'a bee cd.', -1], [3.141592653589793, '', -1], [3.141592653589793, ' ', -1], [3.141592653589793, '1', -1], [3.141592653589793, 'a bee cd.', -1], [3.141592653589793, set([]), -1], [3.141592653589793, set([1, 2, 3]), -1], [3.141592653589793, {5: 3}, -1], [3.141592653589793, {}, -1], [3.141592653589793, {'a': 99}, -1], [3.141592653589793, {'a': 1, 'c': 3, 'b': 2}, -1], - [3.141592653589793, {'a': 99, 'c': 3, 'b': 5}, -1], [3.141592653589793, None, 1], ['', 0, 1], - ['', 1, 1], ['', 2, 1], ['', -1, 1], ['', -9999999999999999, 1], ['', 9999999999999999, 1], - ['', 0.0, 1], ['', inf, 1], ['', nan, 1], ['', 3.141592653589793, 1], ['', ' ', -1], ['', '1', -1], - ['', 'a bee cd.', -1], ['', '', 0], ['', ' ', -1], ['', '1', -1], ['', 'a bee cd.', -1], - ['', set([]), 1], ['', set([1, 2, 3]), 1], ['', {5: 3}, 1], ['', {}, 1], ['', {'a': 99}, 1], - ['', {'a': 1, 'c': 3, 'b': 2}, 1], ['', {'a': 99, 'c': 3, 'b': 5}, 1], ['', None, 1], [' ', 0, 1], - [' ', 1, 1], [' ', 2, 1], [' ', -1, 1], [' ', -9999999999999999, 1], [' ', 9999999999999999, 1], - [' ', 0.0, 1], [' ', inf, 1], [' ', nan, 1], [' ', 3.141592653589793, 1], [' ', '', 1], - [' ', '1', -1], [' ', 'a bee cd.', -1], [' ', '', 1], [' ', ' ', 0], [' ', '1', -1], - [' ', 'a bee cd.', -1], [' ', set([]), 1], [' ', set([1, 2, 3]), 1], [' ', {5: 3}, 1], - [' ', {}, 1], [' ', {'a': 99}, 1], [' ', {'a': 1, 'c': 3, 'b': 2}, 1], + [3.141592653589793, {'a': 99, 'c': 3, 'b': 5}, -1], [3.141592653589793, None, 1], [[], 0, 1], + [[], 1, 1], [[], 2, 1], [[], -1, 1], [[], -9999999999999999, 1], [[], 9999999999999999, 1], + [[], 0.0, 1], [[], inf, 1], [[], nan, 1], [[], 3.141592653589793, 1], [[], [[]], -1], + [[], [1, 2, 3], -1], [[], '', -1], [[], ' ', -1], [[], '1', -1], [[], 'a bee cd.', -1], + [[], '', -1], [[], ' ', -1], [[], '1', -1], [[], 'a bee cd.', -1], [[], set([]), -1], + [[], set([1, 2, 3]), -1], [[], {5: 3}, 1], [[], {}, 1], [[], {'a': 99}, 1], + [[], {'a': 1, 'c': 3, 'b': 2}, 1], [[], {'a': 99, 'c': 3, 'b': 5}, 1], [[], None, 1], [[[]], 0, 1], + [[[]], 1, 1], [[[]], 2, 1], [[[]], -1, 1], [[[]], -9999999999999999, 1], + [[[]], 9999999999999999, 1], [[[]], 0.0, 1], [[[]], inf, 1], [[[]], nan, 1], + [[[]], 3.141592653589793, 1], [[[]], [], 1], [[[]], [1, 2, 3], 1], [[[]], '', -1], [[[]], ' ', -1], + [[[]], '1', -1], [[[]], 'a bee cd.', -1], [[[]], '', -1], [[[]], ' ', -1], [[[]], '1', -1], + [[[]], 'a bee cd.', -1], [[[]], set([]), -1], [[[]], set([1, 2, 3]), -1], [[[]], {5: 3}, 1], + [[[]], {}, 1], [[[]], {'a': 99}, 1], [[[]], {'a': 1, 'c': 3, 'b': 2}, 1], + [[[]], {'a': 99, 'c': 3, 'b': 5}, 1], [[[]], None, 1], [[1, 2, 3], 0, 1], [[1, 2, 3], 1, 1], + [[1, 2, 3], 2, 1], [[1, 2, 3], -1, 1], [[1, 2, 3], -9999999999999999, 1], + [[1, 2, 3], 9999999999999999, 1], [[1, 2, 3], 0.0, 1], [[1, 2, 3], inf, 1], [[1, 2, 3], nan, 1], + [[1, 2, 3], 3.141592653589793, 1], [[1, 2, 3], [], 1], [[1, 2, 3], [[]], -1], [[1, 2, 3], '', -1], + [[1, 2, 3], ' ', -1], [[1, 2, 3], '1', -1], [[1, 2, 3], 'a bee cd.', -1], [[1, 2, 3], '', -1], + [[1, 2, 3], ' ', -1], [[1, 2, 3], '1', -1], [[1, 2, 3], 'a bee cd.', -1], [[1, 2, 3], set([]), -1], + [[1, 2, 3], set([1, 2, 3]), -1], [[1, 2, 3], {5: 3}, 1], [[1, 2, 3], {}, 1], + [[1, 2, 3], {'a': 99}, 1], [[1, 2, 3], {'a': 1, 'c': 3, 'b': 2}, 1], + [[1, 2, 3], {'a': 99, 'c': 3, 'b': 5}, 1], [[1, 2, 3], None, 1], ['', 0, 1], ['', 1, 1], + ['', 2, 1], ['', -1, 1], ['', -9999999999999999, 1], ['', 9999999999999999, 1], ['', 0.0, 1], + ['', inf, 1], ['', nan, 1], ['', 3.141592653589793, 1], ['', [], 1], ['', [[]], 1], + ['', [1, 2, 3], 1], ['', ' ', -1], ['', '1', -1], ['', 'a bee cd.', -1], ['', '', 0], + ['', ' ', -1], ['', '1', -1], ['', 'a bee cd.', -1], ['', set([]), 1], ['', set([1, 2, 3]), 1], + ['', {5: 3}, 1], ['', {}, 1], ['', {'a': 99}, 1], ['', {'a': 1, 'c': 3, 'b': 2}, 1], + ['', {'a': 99, 'c': 3, 'b': 5}, 1], ['', None, 1], [' ', 0, 1], [' ', 1, 1], [' ', 2, 1], + [' ', -1, 1], [' ', -9999999999999999, 1], [' ', 9999999999999999, 1], [' ', 0.0, 1], + [' ', inf, 1], [' ', nan, 1], [' ', 3.141592653589793, 1], [' ', [], 1], [' ', [[]], 1], + [' ', [1, 2, 3], 1], [' ', '', 1], [' ', '1', -1], [' ', 'a bee cd.', -1], [' ', '', 1], + [' ', ' ', 0], [' ', '1', -1], [' ', 'a bee cd.', -1], [' ', set([]), 1], [' ', set([1, 2, 3]), 1], + [' ', {5: 3}, 1], [' ', {}, 1], [' ', {'a': 99}, 1], [' ', {'a': 1, 'c': 3, 'b': 2}, 1], [' ', {'a': 99, 'c': 3, 'b': 5}, 1], [' ', None, 1], ['1', 0, 1], ['1', 1, 1], ['1', 2, 1], ['1', -1, 1], ['1', -9999999999999999, 1], ['1', 9999999999999999, 1], ['1', 0.0, 1], - ['1', inf, 1], ['1', nan, 1], ['1', 3.141592653589793, 1], ['1', '', 1], ['1', ' ', 1], - ['1', 'a bee cd.', -1], ['1', '', 1], ['1', ' ', 1], ['1', '1', 0], ['1', 'a bee cd.', -1], - ['1', set([]), 1], ['1', set([1, 2, 3]), 1], ['1', {5: 3}, 1], ['1', {}, 1], ['1', {'a': 99}, 1], - ['1', {'a': 1, 'c': 3, 'b': 2}, 1], ['1', {'a': 99, 'c': 3, 'b': 5}, 1], ['1', None, 1], - ['a bee cd.', 0, 1], ['a bee cd.', 1, 1], ['a bee cd.', 2, 1], ['a bee cd.', -1, 1], - ['a bee cd.', -9999999999999999, 1], ['a bee cd.', 9999999999999999, 1], ['a bee cd.', 0.0, 1], - ['a bee cd.', inf, 1], ['a bee cd.', nan, 1], ['a bee cd.', 3.141592653589793, 1], - ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], ['a bee cd.', '1', 1], ['a bee cd.', '', 1], - ['a bee cd.', ' ', 1], ['a bee cd.', '1', 1], ['a bee cd.', 'a bee cd.', 0], - ['a bee cd.', set([]), 1], ['a bee cd.', set([1, 2, 3]), 1], ['a bee cd.', {5: 3}, 1], - ['a bee cd.', {}, 1], ['a bee cd.', {'a': 99}, 1], ['a bee cd.', {'a': 1, 'c': 3, 'b': 2}, 1], - ['a bee cd.', {'a': 99, 'c': 3, 'b': 5}, 1], ['a bee cd.', None, 1], ['', 0, 1], ['', 1, 1], - ['', 2, 1], ['', -1, 1], ['', -9999999999999999, 1], ['', 9999999999999999, 1], ['', 0.0, 1], - ['', inf, 1], ['', nan, 1], ['', 3.141592653589793, 1], ['', '', 0], ['', ' ', -1], ['', '1', -1], - ['', 'a bee cd.', -1], ['', ' ', -1], ['', '1', -1], ['', 'a bee cd.', -1], ['', set([]), 1], - ['', set([1, 2, 3]), 1], ['', {5: 3}, 1], ['', {}, 1], ['', {'a': 99}, 1], - ['', {'a': 1, 'c': 3, 'b': 2}, 1], ['', {'a': 99, 'c': 3, 'b': 5}, 1], ['', None, 1], [' ', 0, 1], - [' ', 1, 1], [' ', 2, 1], [' ', -1, 1], [' ', -9999999999999999, 1], [' ', 9999999999999999, 1], - [' ', 0.0, 1], [' ', inf, 1], [' ', nan, 1], [' ', 3.141592653589793, 1], [' ', '', 1], + ['1', inf, 1], ['1', nan, 1], ['1', 3.141592653589793, 1], ['1', [], 1], ['1', [[]], 1], + ['1', [1, 2, 3], 1], ['1', '', 1], ['1', ' ', 1], ['1', 'a bee cd.', -1], ['1', '', 1], + ['1', ' ', 1], ['1', '1', 0], ['1', 'a bee cd.', -1], ['1', set([]), 1], ['1', set([1, 2, 3]), 1], + ['1', {5: 3}, 1], ['1', {}, 1], ['1', {'a': 99}, 1], ['1', {'a': 1, 'c': 3, 'b': 2}, 1], + ['1', {'a': 99, 'c': 3, 'b': 5}, 1], ['1', None, 1], ['a bee cd.', 0, 1], ['a bee cd.', 1, 1], + ['a bee cd.', 2, 1], ['a bee cd.', -1, 1], ['a bee cd.', -9999999999999999, 1], + ['a bee cd.', 9999999999999999, 1], ['a bee cd.', 0.0, 1], ['a bee cd.', inf, 1], + ['a bee cd.', nan, 1], ['a bee cd.', 3.141592653589793, 1], ['a bee cd.', [], 1], + ['a bee cd.', [[]], 1], ['a bee cd.', [1, 2, 3], 1], ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], + ['a bee cd.', '1', 1], ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], ['a bee cd.', '1', 1], + ['a bee cd.', 'a bee cd.', 0], ['a bee cd.', set([]), 1], ['a bee cd.', set([1, 2, 3]), 1], + ['a bee cd.', {5: 3}, 1], ['a bee cd.', {}, 1], ['a bee cd.', {'a': 99}, 1], + ['a bee cd.', {'a': 1, 'c': 3, 'b': 2}, 1], ['a bee cd.', {'a': 99, 'c': 3, 'b': 5}, 1], + ['a bee cd.', None, 1], ['', 0, 1], ['', 1, 1], ['', 2, 1], ['', -1, 1], + ['', -9999999999999999, 1], ['', 9999999999999999, 1], ['', 0.0, 1], ['', inf, 1], ['', nan, 1], + ['', 3.141592653589793, 1], ['', [], 1], ['', [[]], 1], ['', [1, 2, 3], 1], ['', '', 0], + ['', ' ', -1], ['', '1', -1], ['', 'a bee cd.', -1], ['', ' ', -1], ['', '1', -1], + ['', 'a bee cd.', -1], ['', set([]), 1], ['', set([1, 2, 3]), 1], ['', {5: 3}, 1], ['', {}, 1], + ['', {'a': 99}, 1], ['', {'a': 1, 'c': 3, 'b': 2}, 1], ['', {'a': 99, 'c': 3, 'b': 5}, 1], + ['', None, 1], [' ', 0, 1], [' ', 1, 1], [' ', 2, 1], [' ', -1, 1], [' ', -9999999999999999, 1], + [' ', 9999999999999999, 1], [' ', 0.0, 1], [' ', inf, 1], [' ', nan, 1], + [' ', 3.141592653589793, 1], [' ', [], 1], [' ', [[]], 1], [' ', [1, 2, 3], 1], [' ', '', 1], [' ', ' ', 0], [' ', '1', -1], [' ', 'a bee cd.', -1], [' ', '', 1], [' ', '1', -1], [' ', 'a bee cd.', -1], [' ', set([]), 1], [' ', set([1, 2, 3]), 1], [' ', {5: 3}, 1], [' ', {}, 1], [' ', {'a': 99}, 1], [' ', {'a': 1, 'c': 3, 'b': 2}, 1], [' ', {'a': 99, 'c': 3, 'b': 5}, 1], [' ', None, 1], ['1', 0, 1], ['1', 1, 1], ['1', 2, 1], ['1', -1, 1], ['1', -9999999999999999, 1], ['1', 9999999999999999, 1], ['1', 0.0, 1], - ['1', inf, 1], ['1', nan, 1], ['1', 3.141592653589793, 1], ['1', '', 1], ['1', ' ', 1], - ['1', '1', 0], ['1', 'a bee cd.', -1], ['1', '', 1], ['1', ' ', 1], ['1', 'a bee cd.', -1], - ['1', set([]), 1], ['1', set([1, 2, 3]), 1], ['1', {5: 3}, 1], ['1', {}, 1], ['1', {'a': 99}, 1], - ['1', {'a': 1, 'c': 3, 'b': 2}, 1], ['1', {'a': 99, 'c': 3, 'b': 5}, 1], ['1', None, 1], - ['a bee cd.', 0, 1], ['a bee cd.', 1, 1], ['a bee cd.', 2, 1], ['a bee cd.', -1, 1], - ['a bee cd.', -9999999999999999, 1], ['a bee cd.', 9999999999999999, 1], ['a bee cd.', 0.0, 1], - ['a bee cd.', inf, 1], ['a bee cd.', nan, 1], ['a bee cd.', 3.141592653589793, 1], - ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], ['a bee cd.', '1', 1], ['a bee cd.', 'a bee cd.', 0], - ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], ['a bee cd.', '1', 1], ['a bee cd.', set([]), 1], - ['a bee cd.', set([1, 2, 3]), 1], ['a bee cd.', {5: 3}, 1], ['a bee cd.', {}, 1], - ['a bee cd.', {'a': 99}, 1], ['a bee cd.', {'a': 1, 'c': 3, 'b': 2}, 1], - ['a bee cd.', {'a': 99, 'c': 3, 'b': 5}, 1], ['a bee cd.', None, 1], [set([]), 0, 1], - [set([]), 1, 1], [set([]), 2, 1], [set([]), -1, 1], [set([]), -9999999999999999, 1], - [set([]), 9999999999999999, 1], [set([]), 0.0, 1], [set([]), inf, 1], [set([]), nan, 1], - [set([]), 3.141592653589793, 1], [set([]), '', -1], [set([]), ' ', -1], [set([]), '1', -1], - [set([]), 'a bee cd.', -1], [set([]), '', -1], [set([]), ' ', -1], [set([]), '1', -1], - [set([]), 'a bee cd.', -1], + ['1', inf, 1], ['1', nan, 1], ['1', 3.141592653589793, 1], ['1', [], 1], ['1', [[]], 1], + ['1', [1, 2, 3], 1], ['1', '', 1], ['1', ' ', 1], ['1', '1', 0], ['1', 'a bee cd.', -1], + ['1', '', 1], ['1', ' ', 1], ['1', 'a bee cd.', -1], ['1', set([]), 1], ['1', set([1, 2, 3]), 1], + ['1', {5: 3}, 1], ['1', {}, 1], ['1', {'a': 99}, 1], ['1', {'a': 1, 'c': 3, 'b': 2}, 1], + ['1', {'a': 99, 'c': 3, 'b': 5}, 1], ['1', None, 1], ['a bee cd.', 0, 1], ['a bee cd.', 1, 1], + ['a bee cd.', 2, 1], ['a bee cd.', -1, 1], ['a bee cd.', -9999999999999999, 1], + ['a bee cd.', 9999999999999999, 1], ['a bee cd.', 0.0, 1], ['a bee cd.', inf, 1], + ['a bee cd.', nan, 1], ['a bee cd.', 3.141592653589793, 1], ['a bee cd.', [], 1], + ['a bee cd.', [[]], 1], ['a bee cd.', [1, 2, 3], 1], ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], + ['a bee cd.', '1', 1], ['a bee cd.', 'a bee cd.', 0], ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], + ['a bee cd.', '1', 1], ['a bee cd.', set([]), 1], ['a bee cd.', set([1, 2, 3]), 1], + ['a bee cd.', {5: 3}, 1], ['a bee cd.', {}, 1], ['a bee cd.', {'a': 99}, 1], + ['a bee cd.', {'a': 1, 'c': 3, 'b': 2}, 1], ['a bee cd.', {'a': 99, 'c': 3, 'b': 5}, 1], + ['a bee cd.', None, 1], [set([]), 0, 1], [set([]), 1, 1], [set([]), 2, 1], [set([]), -1, 1], + [set([]), -9999999999999999, 1], [set([]), 9999999999999999, 1], [set([]), 0.0, 1], + [set([]), inf, 1], [set([]), nan, 1], [set([]), 3.141592653589793, 1], [set([]), [], 1], + [set([]), [[]], 1], [set([]), [1, 2, 3], 1], [set([]), '', -1], [set([]), ' ', -1], + [set([]), '1', -1], [set([]), 'a bee cd.', -1], [set([]), '', -1], [set([]), ' ', -1], + [set([]), '1', -1], [set([]), 'a bee cd.', -1], [set([]), set([1, 2, 3]), 'TypeError: cannot compare sets using cmp()'], [set([]), {5: 3}, 1], [set([]), {}, 1], [set([]), {'a': 99}, 1], [set([]), {'a': 1, 'c': 3, 'b': 2}, 1], [set([]), {'a': 99, 'c': 3, 'b': 5}, 1], [set([]), None, 1], [set([1, 2, 3]), 0, 1], [set([1, 2, 3]), 1, 1], [set([1, 2, 3]), 2, 1], [set([1, 2, 3]), -1, 1], [set([1, 2, 3]), -9999999999999999, 1], [set([1, 2, 3]), 9999999999999999, 1], [set([1, 2, 3]), 0.0, 1], [set([1, 2, 3]), inf, 1], [set([1, 2, 3]), nan, 1], - [set([1, 2, 3]), 3.141592653589793, 1], [set([1, 2, 3]), '', -1], [set([1, 2, 3]), ' ', -1], + [set([1, 2, 3]), 3.141592653589793, 1], [set([1, 2, 3]), [], 1], [set([1, 2, 3]), [[]], 1], + [set([1, 2, 3]), [1, 2, 3], 1], [set([1, 2, 3]), '', -1], [set([1, 2, 3]), ' ', -1], [set([1, 2, 3]), '1', -1], [set([1, 2, 3]), 'a bee cd.', -1], [set([1, 2, 3]), '', -1], [set([1, 2, 3]), ' ', -1], [set([1, 2, 3]), '1', -1], [set([1, 2, 3]), 'a bee cd.', -1], [set([1, 2, 3]), set([]), 'TypeError: cannot compare sets using cmp()'], [set([1, 2, 3]), {5: 3}, 1], [set([1, 2, 3]), {}, 1], [set([1, 2, 3]), {'a': 99}, 1], [set([1, 2, 3]), {'a': 1, 'c': 3, 'b': 2}, 1], [set([1, 2, 3]), {'a': 99, 'c': 3, 'b': 5}, 1], [set([1, 2, 3]), None, 1], [{5: 3}, 0, 1], [{5: 3}, 1, 1], [{5: 3}, 2, 1], [{5: 3}, -1, 1], - [{5: 3}, -9999999999999999, 1], [{5: 3}, 9999999999999999, 1], [{5: 3}, 0.0, 1], - [{5: 3}, inf, 1], [{5: 3}, nan, 1], [{5: 3}, 3.141592653589793, 1], [{5: 3}, '', -1], - [{5: 3}, ' ', -1], [{5: 3}, '1', -1], [{5: 3}, 'a bee cd.', -1], [{5: 3}, '', -1], - [{5: 3}, ' ', -1], [{5: 3}, '1', -1], [{5: 3}, 'a bee cd.', -1], [{5: 3}, set([]), -1], - [{5: 3}, set([1, 2, 3]), -1], [{5: 3}, {}, 1], [{5: 3}, {'a': 99}, -1], - [{5: 3}, {'a': 1, 'c': 3, 'b': 2}, -1], [{5: 3}, {'a': 99, 'c': 3, 'b': 5}, -1], [{5: 3}, None, 1], - [{}, 0, 1], [{}, 1, 1], [{}, 2, 1], [{}, -1, 1], [{}, -9999999999999999, 1], - [{}, 9999999999999999, 1], [{}, 0.0, 1], [{}, inf, 1], [{}, nan, 1], [{}, 3.141592653589793, 1], + [{5: 3}, -9999999999999999, 1], [{5: 3}, 9999999999999999, 1], [{5: 3}, 0.0, 1], [{5: 3}, inf, 1], + [{5: 3}, nan, 1], [{5: 3}, 3.141592653589793, 1], [{5: 3}, [], -1], [{5: 3}, [[]], -1], + [{5: 3}, [1, 2, 3], -1], [{5: 3}, '', -1], [{5: 3}, ' ', -1], [{5: 3}, '1', -1], + [{5: 3}, 'a bee cd.', -1], [{5: 3}, '', -1], [{5: 3}, ' ', -1], [{5: 3}, '1', -1], + [{5: 3}, 'a bee cd.', -1], [{5: 3}, set([]), -1], [{5: 3}, set([1, 2, 3]), -1], [{5: 3}, {}, 1], + [{5: 3}, {'a': 99}, -1], [{5: 3}, {'a': 1, 'c': 3, 'b': 2}, -1], + [{5: 3}, {'a': 99, 'c': 3, 'b': 5}, -1], [{5: 3}, None, 1], [{}, 0, 1], [{}, 1, 1], [{}, 2, 1], + [{}, -1, 1], [{}, -9999999999999999, 1], [{}, 9999999999999999, 1], [{}, 0.0, 1], [{}, inf, 1], + [{}, nan, 1], [{}, 3.141592653589793, 1], [{}, [], -1], [{}, [[]], -1], [{}, [1, 2, 3], -1], [{}, '', -1], [{}, ' ', -1], [{}, '1', -1], [{}, 'a bee cd.', -1], [{}, '', -1], [{}, ' ', -1], [{}, '1', -1], [{}, 'a bee cd.', -1], [{}, set([]), -1], [{}, set([1, 2, 3]), -1], [{}, {5: 3}, -1], [{}, {'a': 99}, -1], [{}, {'a': 1, 'c': 3, 'b': 2}, -1], [{}, {'a': 99, 'c': 3, 'b': 5}, -1], [{}, None, 1], [{'a': 99}, 0, 1], [{'a': 99}, 1, 1], [{'a': 99}, 2, 1], [{'a': 99}, -1, 1], [{'a': 99}, -9999999999999999, 1], [{'a': 99}, 9999999999999999, 1], [{'a': 99}, 0.0, 1], [{'a': 99}, inf, 1], [{'a': 99}, nan, 1], - [{'a': 99}, 3.141592653589793, 1], [{'a': 99}, '', -1], [{'a': 99}, ' ', -1], [{'a': 99}, '1', -1], + [{'a': 99}, 3.141592653589793, 1], [{'a': 99}, [], -1], [{'a': 99}, [[]], -1], + [{'a': 99}, [1, 2, 3], -1], [{'a': 99}, '', -1], [{'a': 99}, ' ', -1], [{'a': 99}, '1', -1], [{'a': 99}, 'a bee cd.', -1], [{'a': 99}, '', -1], [{'a': 99}, ' ', -1], [{'a': 99}, '1', -1], [{'a': 99}, 'a bee cd.', -1], [{'a': 99}, set([]), -1], [{'a': 99}, set([1, 2, 3]), -1], [{'a': 99}, {5: 3}, 1], [{'a': 99}, {}, 1], [{'a': 99}, {'a': 1, 'c': 3, 'b': 2}, -1], @@ -172,30 +206,35 @@ [{'a': 1, 'c': 3, 'b': 2}, -1, 1], [{'a': 1, 'c': 3, 'b': 2}, -9999999999999999, 1], [{'a': 1, 'c': 3, 'b': 2}, 9999999999999999, 1], [{'a': 1, 'c': 3, 'b': 2}, 0.0, 1], [{'a': 1, 'c': 3, 'b': 2}, inf, 1], [{'a': 1, 'c': 3, 'b': 2}, nan, 1], - [{'a': 1, 'c': 3, 'b': 2}, 3.141592653589793, 1], [{'a': 1, 'c': 3, 'b': 2}, '', -1], - [{'a': 1, 'c': 3, 'b': 2}, ' ', -1], [{'a': 1, 'c': 3, 'b': 2}, '1', -1], - [{'a': 1, 'c': 3, 'b': 2}, 'a bee cd.', -1], [{'a': 1, 'c': 3, 'b': 2}, '', -1], - [{'a': 1, 'c': 3, 'b': 2}, ' ', -1], [{'a': 1, 'c': 3, 'b': 2}, '1', -1], - [{'a': 1, 'c': 3, 'b': 2}, 'a bee cd.', -1], [{'a': 1, 'c': 3, 'b': 2}, set([]), -1], - [{'a': 1, 'c': 3, 'b': 2}, set([1, 2, 3]), -1], [{'a': 1, 'c': 3, 'b': 2}, {5: 3}, 1], - [{'a': 1, 'c': 3, 'b': 2}, {}, 1], [{'a': 1, 'c': 3, 'b': 2}, {'a': 99}, 1], + [{'a': 1, 'c': 3, 'b': 2}, 3.141592653589793, 1], [{'a': 1, 'c': 3, 'b': 2}, [], -1], + [{'a': 1, 'c': 3, 'b': 2}, [[]], -1], [{'a': 1, 'c': 3, 'b': 2}, [1, 2, 3], -1], + [{'a': 1, 'c': 3, 'b': 2}, '', -1], [{'a': 1, 'c': 3, 'b': 2}, ' ', -1], + [{'a': 1, 'c': 3, 'b': 2}, '1', -1], [{'a': 1, 'c': 3, 'b': 2}, 'a bee cd.', -1], + [{'a': 1, 'c': 3, 'b': 2}, '', -1], [{'a': 1, 'c': 3, 'b': 2}, ' ', -1], + [{'a': 1, 'c': 3, 'b': 2}, '1', -1], [{'a': 1, 'c': 3, 'b': 2}, 'a bee cd.', -1], + [{'a': 1, 'c': 3, 'b': 2}, set([]), -1], [{'a': 1, 'c': 3, 'b': 2}, set([1, 2, 3]), -1], + [{'a': 1, 'c': 3, 'b': 2}, {5: 3}, 1], [{'a': 1, 'c': 3, 'b': 2}, {}, 1], + [{'a': 1, 'c': 3, 'b': 2}, {'a': 99}, 1], [{'a': 1, 'c': 3, 'b': 2}, {'a': 99, 'c': 3, 'b': 5}, -1], [{'a': 1, 'c': 3, 'b': 2}, None, 1], [{'a': 99, 'c': 3, 'b': 5}, 0, 1], [{'a': 99, 'c': 3, 'b': 5}, 1, 1], [{'a': 99, 'c': 3, 'b': 5}, 2, 1], [{'a': 99, 'c': 3, 'b': 5}, -1, 1], [{'a': 99, 'c': 3, 'b': 5}, -9999999999999999, 1], [{'a': 99, 'c': 3, 'b': 5}, 9999999999999999, 1], [{'a': 99, 'c': 3, 'b': 5}, 0.0, 1], [{'a': 99, 'c': 3, 'b': 5}, inf, 1], [{'a': 99, 'c': 3, 'b': 5}, nan, 1], - [{'a': 99, 'c': 3, 'b': 5}, 3.141592653589793, 1], [{'a': 99, 'c': 3, 'b': 5}, '', -1], - [{'a': 99, 'c': 3, 'b': 5}, ' ', -1], [{'a': 99, 'c': 3, 'b': 5}, '1', -1], - [{'a': 99, 'c': 3, 'b': 5}, 'a bee cd.', -1], [{'a': 99, 'c': 3, 'b': 5}, '', -1], - [{'a': 99, 'c': 3, 'b': 5}, ' ', -1], [{'a': 99, 'c': 3, 'b': 5}, '1', -1], - [{'a': 99, 'c': 3, 'b': 5}, 'a bee cd.', -1], [{'a': 99, 'c': 3, 'b': 5}, set([]), -1], - [{'a': 99, 'c': 3, 'b': 5}, set([1, 2, 3]), -1], [{'a': 99, 'c': 3, 'b': 5}, {5: 3}, 1], - [{'a': 99, 'c': 3, 'b': 5}, {}, 1], [{'a': 99, 'c': 3, 'b': 5}, {'a': 99}, 1], + [{'a': 99, 'c': 3, 'b': 5}, 3.141592653589793, 1], [{'a': 99, 'c': 3, 'b': 5}, [], -1], + [{'a': 99, 'c': 3, 'b': 5}, [[]], -1], [{'a': 99, 'c': 3, 'b': 5}, [1, 2, 3], -1], + [{'a': 99, 'c': 3, 'b': 5}, '', -1], [{'a': 99, 'c': 3, 'b': 5}, ' ', -1], + [{'a': 99, 'c': 3, 'b': 5}, '1', -1], [{'a': 99, 'c': 3, 'b': 5}, 'a bee cd.', -1], + [{'a': 99, 'c': 3, 'b': 5}, '', -1], [{'a': 99, 'c': 3, 'b': 5}, ' ', -1], + [{'a': 99, 'c': 3, 'b': 5}, '1', -1], [{'a': 99, 'c': 3, 'b': 5}, 'a bee cd.', -1], + [{'a': 99, 'c': 3, 'b': 5}, set([]), -1], [{'a': 99, 'c': 3, 'b': 5}, set([1, 2, 3]), -1], + [{'a': 99, 'c': 3, 'b': 5}, {5: 3}, 1], [{'a': 99, 'c': 3, 'b': 5}, {}, 1], + [{'a': 99, 'c': 3, 'b': 5}, {'a': 99}, 1], [{'a': 99, 'c': 3, 'b': 5}, {'a': 1, 'c': 3, 'b': 2}, 1], [{'a': 99, 'c': 3, 'b': 5}, None, 1], [None, 0, -1], [None, 1, -1], [None, 2, -1], [None, -1, -1], [None, -9999999999999999, -1], [None, 9999999999999999, -1], [None, 0.0, -1], [None, inf, -1], [None, nan, -1], - [None, 3.141592653589793, -1], [None, '', -1], [None, ' ', -1], [None, '1', -1], - [None, 'a bee cd.', -1], [None, '', -1], [None, ' ', -1], [None, '1', -1], [None, 'a bee cd.', -1], - [None, set([]), -1], [None, set([1, 2, 3]), -1], [None, {5: 3}, -1], [None, {}, -1], - [None, {'a': 99}, -1], [None, {'a': 1, 'c': 3, 'b': 2}, -1], [None, {'a': 99, 'c': 3, 'b': 5}, -1]] + [None, 3.141592653589793, -1], [None, [], -1], [None, [[]], -1], [None, [1, 2, 3], -1], + [None, '', -1], [None, ' ', -1], [None, '1', -1], [None, 'a bee cd.', -1], [None, '', -1], + [None, ' ', -1], [None, '1', -1], [None, 'a bee cd.', -1], [None, set([]), -1], + [None, set([1, 2, 3]), -1], [None, {5: 3}, -1], [None, {}, -1], [None, {'a': 99}, -1], + [None, {'a': 1, 'c': 3, 'b': 2}, -1], [None, {'a': 99, 'c': 3, 'b': 5}, -1]] From 4dbded1fa5a25087acf1dc073268f2d427fba402 Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Sun, 30 Aug 2020 21:23:37 -0700 Subject: [PATCH 11/59] remove nan test --- tests/test_past/test_values.py | 275 ++++++++++++++++----------------- 1 file changed, 130 insertions(+), 145 deletions(-) diff --git a/tests/test_past/test_values.py b/tests/test_past/test_values.py index 7c85a8f2..11872084 100644 --- a/tests/test_past/test_values.py +++ b/tests/test_past/test_values.py @@ -3,7 +3,7 @@ inf, nan = float('inf'), float('nan') test_values = [ 0, 1, 2, -1, -9999999999, 9999999, - 0.0, inf, nan, pi, + 0.0, inf, pi, [], [[]], [1, 2, 3], set(), set([1, 2, 3]), " ", "", "1", "dsada saA.", "2", "dsa", b"", b"dsa", b" ", @@ -12,96 +12,86 @@ # cmp_python2_values are pre-calculated from running cmp under python2 first values are x and y, last is results of cmp cmp_python2_value = [[0, 1, -1], [0, 2, -1], [0, -1, 1], [0, -9999999999999999, 1], [0, 9999999999999999, -1], - [0, 0.0, 0], [0, inf, -1], [0, nan, -1], [0, 3.141592653589793, -1], [0, [], -1], [0, [[]], -1], + [0, 0.0, 0], [0, inf, -1], [0, 3.141592653589793, -1], [0, [], -1], [0, [[]], -1], [0, [1, 2, 3], -1], [0, '', -1], [0, ' ', -1], [0, '1', -1], [0, 'a bee cd.', -1], [0, '', -1], [0, ' ', -1], [0, '1', -1], [0, 'a bee cd.', -1], [0, set([]), -1], [0, set([1, 2, 3]), -1], [0, {5: 3}, -1], [0, {}, -1], [0, {'a': 99}, -1], [0, {'a': 1, 'c': 3, 'b': 2}, -1], [0, {'a': 99, 'c': 3, 'b': 5}, -1], [0, None, 1], [1, 0, 1], [1, 2, -1], [1, -1, 1], - [1, -9999999999999999, 1], [1, 9999999999999999, -1], [1, 0.0, 1], [1, inf, -1], [1, nan, -1], + [1, -9999999999999999, 1], [1, 9999999999999999, -1], [1, 0.0, 1], [1, inf, -1], [1, 3.141592653589793, -1], [1, [], -1], [1, [[]], -1], [1, [1, 2, 3], -1], [1, '', -1], [1, ' ', -1], [1, '1', -1], [1, 'a bee cd.', -1], [1, '', -1], [1, ' ', -1], [1, '1', -1], [1, 'a bee cd.', -1], [1, set([]), -1], [1, set([1, 2, 3]), -1], [1, {5: 3}, -1], [1, {}, -1], [1, {'a': 99}, -1], [1, {'a': 1, 'c': 3, 'b': 2}, -1], [1, {'a': 99, 'c': 3, 'b': 5}, -1], [1, None, 1], [2, 0, 1], [2, 1, 1], [2, -1, 1], [2, -9999999999999999, 1], - [2, 9999999999999999, -1], [2, 0.0, 1], [2, inf, -1], [2, nan, -1], [2, 3.141592653589793, -1], - [2, [], -1], [2, [[]], -1], [2, [1, 2, 3], -1], [2, '', -1], [2, ' ', -1], [2, '1', -1], - [2, 'a bee cd.', -1], [2, '', -1], [2, ' ', -1], [2, '1', -1], [2, 'a bee cd.', -1], - [2, set([]), -1], [2, set([1, 2, 3]), -1], [2, {5: 3}, -1], [2, {}, -1], [2, {'a': 99}, -1], + [2, 9999999999999999, -1], [2, 0.0, 1], [2, inf, -1], [2, 3.141592653589793, -1], [2, [], -1], + [2, [[]], -1], [2, [1, 2, 3], -1], [2, '', -1], [2, ' ', -1], [2, '1', -1], [2, 'a bee cd.', -1], + [2, '', -1], [2, ' ', -1], [2, '1', -1], [2, 'a bee cd.', -1], [2, set([]), -1], + [2, set([1, 2, 3]), -1], [2, {5: 3}, -1], [2, {}, -1], [2, {'a': 99}, -1], [2, {'a': 1, 'c': 3, 'b': 2}, -1], [2, {'a': 99, 'c': 3, 'b': 5}, -1], [2, None, 1], [-1, 0, -1], [-1, 1, -1], [-1, 2, -1], [-1, -9999999999999999, 1], [-1, 9999999999999999, -1], [-1, 0.0, -1], - [-1, inf, -1], [-1, nan, -1], [-1, 3.141592653589793, -1], [-1, [], -1], [-1, [[]], -1], - [-1, [1, 2, 3], -1], [-1, '', -1], [-1, ' ', -1], [-1, '1', -1], [-1, 'a bee cd.', -1], - [-1, '', -1], [-1, ' ', -1], [-1, '1', -1], [-1, 'a bee cd.', -1], [-1, set([]), -1], - [-1, set([1, 2, 3]), -1], [-1, {5: 3}, -1], [-1, {}, -1], [-1, {'a': 99}, -1], - [-1, {'a': 1, 'c': 3, 'b': 2}, -1], [-1, {'a': 99, 'c': 3, 'b': 5}, -1], [-1, None, 1], - [-9999999999999999, 0, -1], [-9999999999999999, 1, -1], [-9999999999999999, 2, -1], - [-9999999999999999, -1, -1], [-9999999999999999, 9999999999999999, -1], - [-9999999999999999, 0.0, -1], [-9999999999999999, inf, -1], [-9999999999999999, nan, -1], - [-9999999999999999, 3.141592653589793, -1], [-9999999999999999, [], -1], - [-9999999999999999, [[]], -1], [-9999999999999999, [1, 2, 3], -1], [-9999999999999999, '', -1], - [-9999999999999999, ' ', -1], [-9999999999999999, '1', -1], [-9999999999999999, 'a bee cd.', -1], + [-1, inf, -1], [-1, 3.141592653589793, -1], [-1, [], -1], [-1, [[]], -1], [-1, [1, 2, 3], -1], + [-1, '', -1], [-1, ' ', -1], [-1, '1', -1], [-1, 'a bee cd.', -1], [-1, '', -1], [-1, ' ', -1], + [-1, '1', -1], [-1, 'a bee cd.', -1], [-1, set([]), -1], [-1, set([1, 2, 3]), -1], + [-1, {5: 3}, -1], [-1, {}, -1], [-1, {'a': 99}, -1], [-1, {'a': 1, 'c': 3, 'b': 2}, -1], + [-1, {'a': 99, 'c': 3, 'b': 5}, -1], [-1, None, 1], [-9999999999999999, 0, -1], + [-9999999999999999, 1, -1], [-9999999999999999, 2, -1], [-9999999999999999, -1, -1], + [-9999999999999999, 9999999999999999, -1], [-9999999999999999, 0.0, -1], + [-9999999999999999, inf, -1], [-9999999999999999, 3.141592653589793, -1], + [-9999999999999999, [], -1], [-9999999999999999, [[]], -1], [-9999999999999999, [1, 2, 3], -1], [-9999999999999999, '', -1], [-9999999999999999, ' ', -1], [-9999999999999999, '1', -1], - [-9999999999999999, 'a bee cd.', -1], [-9999999999999999, set([]), -1], - [-9999999999999999, set([1, 2, 3]), -1], [-9999999999999999, {5: 3}, -1], - [-9999999999999999, {}, -1], [-9999999999999999, {'a': 99}, -1], + [-9999999999999999, 'a bee cd.', -1], [-9999999999999999, '', -1], [-9999999999999999, ' ', -1], + [-9999999999999999, '1', -1], [-9999999999999999, 'a bee cd.', -1], + [-9999999999999999, set([]), -1], [-9999999999999999, set([1, 2, 3]), -1], + [-9999999999999999, {5: 3}, -1], [-9999999999999999, {}, -1], [-9999999999999999, {'a': 99}, -1], [-9999999999999999, {'a': 1, 'c': 3, 'b': 2}, -1], [-9999999999999999, {'a': 99, 'c': 3, 'b': 5}, -1], [-9999999999999999, None, 1], [9999999999999999, 0, 1], [9999999999999999, 1, 1], [9999999999999999, 2, 1], [9999999999999999, -1, 1], [9999999999999999, -9999999999999999, 1], [9999999999999999, 0.0, 1], - [9999999999999999, inf, -1], [9999999999999999, nan, -1], [9999999999999999, 3.141592653589793, 1], - [9999999999999999, [], -1], [9999999999999999, [[]], -1], [9999999999999999, [1, 2, 3], -1], + [9999999999999999, inf, -1], [9999999999999999, 3.141592653589793, 1], [9999999999999999, [], -1], + [9999999999999999, [[]], -1], [9999999999999999, [1, 2, 3], -1], [9999999999999999, '', -1], + [9999999999999999, ' ', -1], [9999999999999999, '1', -1], [9999999999999999, 'a bee cd.', -1], [9999999999999999, '', -1], [9999999999999999, ' ', -1], [9999999999999999, '1', -1], - [9999999999999999, 'a bee cd.', -1], [9999999999999999, '', -1], [9999999999999999, ' ', -1], - [9999999999999999, '1', -1], [9999999999999999, 'a bee cd.', -1], [9999999999999999, set([]), -1], + [9999999999999999, 'a bee cd.', -1], [9999999999999999, set([]), -1], [9999999999999999, set([1, 2, 3]), -1], [9999999999999999, {5: 3}, -1], [9999999999999999, {}, -1], [9999999999999999, {'a': 99}, -1], [9999999999999999, {'a': 1, 'c': 3, 'b': 2}, -1], [9999999999999999, {'a': 99, 'c': 3, 'b': 5}, -1], [9999999999999999, None, 1], [0.0, 0, 0], [0.0, 1, -1], [0.0, 2, -1], [0.0, -1, 1], [0.0, -9999999999999999, 1], [0.0, 9999999999999999, -1], - [0.0, inf, -1], [0.0, nan, 1], [0.0, 3.141592653589793, -1], [0.0, [], -1], [0.0, [[]], -1], - [0.0, [1, 2, 3], -1], [0.0, '', -1], [0.0, ' ', -1], [0.0, '1', -1], [0.0, 'a bee cd.', -1], - [0.0, '', -1], [0.0, ' ', -1], [0.0, '1', -1], [0.0, 'a bee cd.', -1], [0.0, set([]), -1], + [0.0, inf, -1], [0.0, 3.141592653589793, -1], [0.0, [], -1], [0.0, [[]], -1], [0.0, [1, 2, 3], -1], + [0.0, '', -1], [0.0, ' ', -1], [0.0, '1', -1], [0.0, 'a bee cd.', -1], [0.0, '', -1], + [0.0, ' ', -1], [0.0, '1', -1], [0.0, 'a bee cd.', -1], [0.0, set([]), -1], [0.0, set([1, 2, 3]), -1], [0.0, {5: 3}, -1], [0.0, {}, -1], [0.0, {'a': 99}, -1], [0.0, {'a': 1, 'c': 3, 'b': 2}, -1], [0.0, {'a': 99, 'c': 3, 'b': 5}, -1], [0.0, None, 1], [inf, 0, 1], [inf, 1, 1], [inf, 2, 1], [inf, -1, 1], [inf, -9999999999999999, 1], - [inf, 9999999999999999, 1], [inf, 0.0, 1], [inf, nan, 1], [inf, 3.141592653589793, 1], - [inf, [], -1], [inf, [[]], -1], [inf, [1, 2, 3], -1], [inf, '', -1], [inf, ' ', -1], - [inf, '1', -1], [inf, 'a bee cd.', -1], [inf, '', -1], [inf, ' ', -1], [inf, '1', -1], - [inf, 'a bee cd.', -1], [inf, set([]), -1], [inf, set([1, 2, 3]), -1], [inf, {5: 3}, -1], - [inf, {}, -1], [inf, {'a': 99}, -1], [inf, {'a': 1, 'c': 3, 'b': 2}, -1], - [inf, {'a': 99, 'c': 3, 'b': 5}, -1], [inf, None, 1], [nan, 0, 1], [nan, 1, 1], [nan, 2, 1], - [nan, -1, 1], [nan, -9999999999999999, 1], [nan, 9999999999999999, 1], [nan, 0.0, -1], - [nan, inf, -1], [nan, 3.141592653589793, -1], [nan, [], -1], [nan, [[]], -1], [nan, [1, 2, 3], -1], - [nan, '', -1], [nan, ' ', -1], [nan, '1', -1], [nan, 'a bee cd.', -1], [nan, '', -1], - [nan, ' ', -1], [nan, '1', -1], [nan, 'a bee cd.', -1], [nan, set([]), -1], - [nan, set([1, 2, 3]), -1], [nan, {5: 3}, -1], [nan, {}, -1], [nan, {'a': 99}, -1], - [nan, {'a': 1, 'c': 3, 'b': 2}, -1], [nan, {'a': 99, 'c': 3, 'b': 5}, -1], [nan, None, 1], - [3.141592653589793, 0, 1], [3.141592653589793, 1, 1], [3.141592653589793, 2, 1], + [inf, 9999999999999999, 1], [inf, 0.0, 1], [inf, 3.141592653589793, 1], [inf, [], -1], + [inf, [[]], -1], [inf, [1, 2, 3], -1], [inf, '', -1], [inf, ' ', -1], [inf, '1', -1], + [inf, 'a bee cd.', -1], [inf, '', -1], [inf, ' ', -1], [inf, '1', -1], [inf, 'a bee cd.', -1], + [inf, set([]), -1], [inf, set([1, 2, 3]), -1], [inf, {5: 3}, -1], [inf, {}, -1], + [inf, {'a': 99}, -1], [inf, {'a': 1, 'c': 3, 'b': 2}, -1], [inf, {'a': 99, 'c': 3, 'b': 5}, -1], + [inf, None, 1], [3.141592653589793, 0, 1], [3.141592653589793, 1, 1], [3.141592653589793, 2, 1], [3.141592653589793, -1, 1], [3.141592653589793, -9999999999999999, 1], [3.141592653589793, 9999999999999999, -1], [3.141592653589793, 0.0, 1], - [3.141592653589793, inf, -1], [3.141592653589793, nan, 1], [3.141592653589793, [], -1], - [3.141592653589793, [[]], -1], [3.141592653589793, [1, 2, 3], -1], [3.141592653589793, '', -1], + [3.141592653589793, inf, -1], [3.141592653589793, [], -1], [3.141592653589793, [[]], -1], + [3.141592653589793, [1, 2, 3], -1], [3.141592653589793, '', -1], [3.141592653589793, ' ', -1], + [3.141592653589793, '1', -1], [3.141592653589793, 'a bee cd.', -1], [3.141592653589793, '', -1], [3.141592653589793, ' ', -1], [3.141592653589793, '1', -1], [3.141592653589793, 'a bee cd.', -1], - [3.141592653589793, '', -1], [3.141592653589793, ' ', -1], [3.141592653589793, '1', -1], - [3.141592653589793, 'a bee cd.', -1], [3.141592653589793, set([]), -1], - [3.141592653589793, set([1, 2, 3]), -1], [3.141592653589793, {5: 3}, -1], - [3.141592653589793, {}, -1], [3.141592653589793, {'a': 99}, -1], + [3.141592653589793, set([]), -1], [3.141592653589793, set([1, 2, 3]), -1], + [3.141592653589793, {5: 3}, -1], [3.141592653589793, {}, -1], [3.141592653589793, {'a': 99}, -1], [3.141592653589793, {'a': 1, 'c': 3, 'b': 2}, -1], [3.141592653589793, {'a': 99, 'c': 3, 'b': 5}, -1], [3.141592653589793, None, 1], [[], 0, 1], [[], 1, 1], [[], 2, 1], [[], -1, 1], [[], -9999999999999999, 1], [[], 9999999999999999, 1], - [[], 0.0, 1], [[], inf, 1], [[], nan, 1], [[], 3.141592653589793, 1], [[], [[]], -1], - [[], [1, 2, 3], -1], [[], '', -1], [[], ' ', -1], [[], '1', -1], [[], 'a bee cd.', -1], - [[], '', -1], [[], ' ', -1], [[], '1', -1], [[], 'a bee cd.', -1], [[], set([]), -1], - [[], set([1, 2, 3]), -1], [[], {5: 3}, 1], [[], {}, 1], [[], {'a': 99}, 1], - [[], {'a': 1, 'c': 3, 'b': 2}, 1], [[], {'a': 99, 'c': 3, 'b': 5}, 1], [[], None, 1], [[[]], 0, 1], - [[[]], 1, 1], [[[]], 2, 1], [[[]], -1, 1], [[[]], -9999999999999999, 1], - [[[]], 9999999999999999, 1], [[[]], 0.0, 1], [[[]], inf, 1], [[[]], nan, 1], - [[[]], 3.141592653589793, 1], [[[]], [], 1], [[[]], [1, 2, 3], 1], [[[]], '', -1], [[[]], ' ', -1], - [[[]], '1', -1], [[[]], 'a bee cd.', -1], [[[]], '', -1], [[[]], ' ', -1], [[[]], '1', -1], - [[[]], 'a bee cd.', -1], [[[]], set([]), -1], [[[]], set([1, 2, 3]), -1], [[[]], {5: 3}, 1], - [[[]], {}, 1], [[[]], {'a': 99}, 1], [[[]], {'a': 1, 'c': 3, 'b': 2}, 1], + [[], 0.0, 1], [[], inf, 1], [[], 3.141592653589793, 1], [[], [[]], -1], [[], [1, 2, 3], -1], + [[], '', -1], [[], ' ', -1], [[], '1', -1], [[], 'a bee cd.', -1], [[], '', -1], [[], ' ', -1], + [[], '1', -1], [[], 'a bee cd.', -1], [[], set([]), -1], [[], set([1, 2, 3]), -1], [[], {5: 3}, 1], + [[], {}, 1], [[], {'a': 99}, 1], [[], {'a': 1, 'c': 3, 'b': 2}, 1], + [[], {'a': 99, 'c': 3, 'b': 5}, 1], [[], None, 1], [[[]], 0, 1], [[[]], 1, 1], [[[]], 2, 1], + [[[]], -1, 1], [[[]], -9999999999999999, 1], [[[]], 9999999999999999, 1], [[[]], 0.0, 1], + [[[]], inf, 1], [[[]], 3.141592653589793, 1], [[[]], [], 1], [[[]], [1, 2, 3], 1], [[[]], '', -1], + [[[]], ' ', -1], [[[]], '1', -1], [[[]], 'a bee cd.', -1], [[[]], '', -1], [[[]], ' ', -1], + [[[]], '1', -1], [[[]], 'a bee cd.', -1], [[[]], set([]), -1], [[[]], set([1, 2, 3]), -1], + [[[]], {5: 3}, 1], [[[]], {}, 1], [[[]], {'a': 99}, 1], [[[]], {'a': 1, 'c': 3, 'b': 2}, 1], [[[]], {'a': 99, 'c': 3, 'b': 5}, 1], [[[]], None, 1], [[1, 2, 3], 0, 1], [[1, 2, 3], 1, 1], [[1, 2, 3], 2, 1], [[1, 2, 3], -1, 1], [[1, 2, 3], -9999999999999999, 1], - [[1, 2, 3], 9999999999999999, 1], [[1, 2, 3], 0.0, 1], [[1, 2, 3], inf, 1], [[1, 2, 3], nan, 1], + [[1, 2, 3], 9999999999999999, 1], [[1, 2, 3], 0.0, 1], [[1, 2, 3], inf, 1], [[1, 2, 3], 3.141592653589793, 1], [[1, 2, 3], [], 1], [[1, 2, 3], [[]], -1], [[1, 2, 3], '', -1], [[1, 2, 3], ' ', -1], [[1, 2, 3], '1', -1], [[1, 2, 3], 'a bee cd.', -1], [[1, 2, 3], '', -1], [[1, 2, 3], ' ', -1], [[1, 2, 3], '1', -1], [[1, 2, 3], 'a bee cd.', -1], [[1, 2, 3], set([]), -1], @@ -109,53 +99,51 @@ [[1, 2, 3], {'a': 99}, 1], [[1, 2, 3], {'a': 1, 'c': 3, 'b': 2}, 1], [[1, 2, 3], {'a': 99, 'c': 3, 'b': 5}, 1], [[1, 2, 3], None, 1], ['', 0, 1], ['', 1, 1], ['', 2, 1], ['', -1, 1], ['', -9999999999999999, 1], ['', 9999999999999999, 1], ['', 0.0, 1], - ['', inf, 1], ['', nan, 1], ['', 3.141592653589793, 1], ['', [], 1], ['', [[]], 1], - ['', [1, 2, 3], 1], ['', ' ', -1], ['', '1', -1], ['', 'a bee cd.', -1], ['', '', 0], - ['', ' ', -1], ['', '1', -1], ['', 'a bee cd.', -1], ['', set([]), 1], ['', set([1, 2, 3]), 1], - ['', {5: 3}, 1], ['', {}, 1], ['', {'a': 99}, 1], ['', {'a': 1, 'c': 3, 'b': 2}, 1], - ['', {'a': 99, 'c': 3, 'b': 5}, 1], ['', None, 1], [' ', 0, 1], [' ', 1, 1], [' ', 2, 1], - [' ', -1, 1], [' ', -9999999999999999, 1], [' ', 9999999999999999, 1], [' ', 0.0, 1], - [' ', inf, 1], [' ', nan, 1], [' ', 3.141592653589793, 1], [' ', [], 1], [' ', [[]], 1], - [' ', [1, 2, 3], 1], [' ', '', 1], [' ', '1', -1], [' ', 'a bee cd.', -1], [' ', '', 1], - [' ', ' ', 0], [' ', '1', -1], [' ', 'a bee cd.', -1], [' ', set([]), 1], [' ', set([1, 2, 3]), 1], - [' ', {5: 3}, 1], [' ', {}, 1], [' ', {'a': 99}, 1], [' ', {'a': 1, 'c': 3, 'b': 2}, 1], - [' ', {'a': 99, 'c': 3, 'b': 5}, 1], [' ', None, 1], ['1', 0, 1], ['1', 1, 1], ['1', 2, 1], - ['1', -1, 1], ['1', -9999999999999999, 1], ['1', 9999999999999999, 1], ['1', 0.0, 1], - ['1', inf, 1], ['1', nan, 1], ['1', 3.141592653589793, 1], ['1', [], 1], ['1', [[]], 1], - ['1', [1, 2, 3], 1], ['1', '', 1], ['1', ' ', 1], ['1', 'a bee cd.', -1], ['1', '', 1], - ['1', ' ', 1], ['1', '1', 0], ['1', 'a bee cd.', -1], ['1', set([]), 1], ['1', set([1, 2, 3]), 1], - ['1', {5: 3}, 1], ['1', {}, 1], ['1', {'a': 99}, 1], ['1', {'a': 1, 'c': 3, 'b': 2}, 1], - ['1', {'a': 99, 'c': 3, 'b': 5}, 1], ['1', None, 1], ['a bee cd.', 0, 1], ['a bee cd.', 1, 1], - ['a bee cd.', 2, 1], ['a bee cd.', -1, 1], ['a bee cd.', -9999999999999999, 1], - ['a bee cd.', 9999999999999999, 1], ['a bee cd.', 0.0, 1], ['a bee cd.', inf, 1], - ['a bee cd.', nan, 1], ['a bee cd.', 3.141592653589793, 1], ['a bee cd.', [], 1], + ['', inf, 1], ['', 3.141592653589793, 1], ['', [], 1], ['', [[]], 1], ['', [1, 2, 3], 1], + ['', ' ', -1], ['', '1', -1], ['', 'a bee cd.', -1], ['', '', 0], ['', ' ', -1], ['', '1', -1], + ['', 'a bee cd.', -1], ['', set([]), 1], ['', set([1, 2, 3]), 1], ['', {5: 3}, 1], ['', {}, 1], + ['', {'a': 99}, 1], ['', {'a': 1, 'c': 3, 'b': 2}, 1], ['', {'a': 99, 'c': 3, 'b': 5}, 1], + ['', None, 1], [' ', 0, 1], [' ', 1, 1], [' ', 2, 1], [' ', -1, 1], [' ', -9999999999999999, 1], + [' ', 9999999999999999, 1], [' ', 0.0, 1], [' ', inf, 1], [' ', 3.141592653589793, 1], + [' ', [], 1], [' ', [[]], 1], [' ', [1, 2, 3], 1], [' ', '', 1], [' ', '1', -1], + [' ', 'a bee cd.', -1], [' ', '', 1], [' ', ' ', 0], [' ', '1', -1], [' ', 'a bee cd.', -1], + [' ', set([]), 1], [' ', set([1, 2, 3]), 1], [' ', {5: 3}, 1], [' ', {}, 1], [' ', {'a': 99}, 1], + [' ', {'a': 1, 'c': 3, 'b': 2}, 1], [' ', {'a': 99, 'c': 3, 'b': 5}, 1], [' ', None, 1], + ['1', 0, 1], ['1', 1, 1], ['1', 2, 1], ['1', -1, 1], ['1', -9999999999999999, 1], + ['1', 9999999999999999, 1], ['1', 0.0, 1], ['1', inf, 1], ['1', 3.141592653589793, 1], + ['1', [], 1], ['1', [[]], 1], ['1', [1, 2, 3], 1], ['1', '', 1], ['1', ' ', 1], + ['1', 'a bee cd.', -1], ['1', '', 1], ['1', ' ', 1], ['1', '1', 0], ['1', 'a bee cd.', -1], + ['1', set([]), 1], ['1', set([1, 2, 3]), 1], ['1', {5: 3}, 1], ['1', {}, 1], ['1', {'a': 99}, 1], + ['1', {'a': 1, 'c': 3, 'b': 2}, 1], ['1', {'a': 99, 'c': 3, 'b': 5}, 1], ['1', None, 1], + ['a bee cd.', 0, 1], ['a bee cd.', 1, 1], ['a bee cd.', 2, 1], ['a bee cd.', -1, 1], + ['a bee cd.', -9999999999999999, 1], ['a bee cd.', 9999999999999999, 1], ['a bee cd.', 0.0, 1], + ['a bee cd.', inf, 1], ['a bee cd.', 3.141592653589793, 1], ['a bee cd.', [], 1], ['a bee cd.', [[]], 1], ['a bee cd.', [1, 2, 3], 1], ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], ['a bee cd.', '1', 1], ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], ['a bee cd.', '1', 1], ['a bee cd.', 'a bee cd.', 0], ['a bee cd.', set([]), 1], ['a bee cd.', set([1, 2, 3]), 1], ['a bee cd.', {5: 3}, 1], ['a bee cd.', {}, 1], ['a bee cd.', {'a': 99}, 1], ['a bee cd.', {'a': 1, 'c': 3, 'b': 2}, 1], ['a bee cd.', {'a': 99, 'c': 3, 'b': 5}, 1], ['a bee cd.', None, 1], ['', 0, 1], ['', 1, 1], ['', 2, 1], ['', -1, 1], - ['', -9999999999999999, 1], ['', 9999999999999999, 1], ['', 0.0, 1], ['', inf, 1], ['', nan, 1], + ['', -9999999999999999, 1], ['', 9999999999999999, 1], ['', 0.0, 1], ['', inf, 1], ['', 3.141592653589793, 1], ['', [], 1], ['', [[]], 1], ['', [1, 2, 3], 1], ['', '', 0], ['', ' ', -1], ['', '1', -1], ['', 'a bee cd.', -1], ['', ' ', -1], ['', '1', -1], ['', 'a bee cd.', -1], ['', set([]), 1], ['', set([1, 2, 3]), 1], ['', {5: 3}, 1], ['', {}, 1], ['', {'a': 99}, 1], ['', {'a': 1, 'c': 3, 'b': 2}, 1], ['', {'a': 99, 'c': 3, 'b': 5}, 1], ['', None, 1], [' ', 0, 1], [' ', 1, 1], [' ', 2, 1], [' ', -1, 1], [' ', -9999999999999999, 1], - [' ', 9999999999999999, 1], [' ', 0.0, 1], [' ', inf, 1], [' ', nan, 1], - [' ', 3.141592653589793, 1], [' ', [], 1], [' ', [[]], 1], [' ', [1, 2, 3], 1], [' ', '', 1], - [' ', ' ', 0], [' ', '1', -1], [' ', 'a bee cd.', -1], [' ', '', 1], [' ', '1', -1], - [' ', 'a bee cd.', -1], [' ', set([]), 1], [' ', set([1, 2, 3]), 1], [' ', {5: 3}, 1], - [' ', {}, 1], [' ', {'a': 99}, 1], [' ', {'a': 1, 'c': 3, 'b': 2}, 1], - [' ', {'a': 99, 'c': 3, 'b': 5}, 1], [' ', None, 1], ['1', 0, 1], ['1', 1, 1], ['1', 2, 1], - ['1', -1, 1], ['1', -9999999999999999, 1], ['1', 9999999999999999, 1], ['1', 0.0, 1], - ['1', inf, 1], ['1', nan, 1], ['1', 3.141592653589793, 1], ['1', [], 1], ['1', [[]], 1], - ['1', [1, 2, 3], 1], ['1', '', 1], ['1', ' ', 1], ['1', '1', 0], ['1', 'a bee cd.', -1], - ['1', '', 1], ['1', ' ', 1], ['1', 'a bee cd.', -1], ['1', set([]), 1], ['1', set([1, 2, 3]), 1], - ['1', {5: 3}, 1], ['1', {}, 1], ['1', {'a': 99}, 1], ['1', {'a': 1, 'c': 3, 'b': 2}, 1], - ['1', {'a': 99, 'c': 3, 'b': 5}, 1], ['1', None, 1], ['a bee cd.', 0, 1], ['a bee cd.', 1, 1], - ['a bee cd.', 2, 1], ['a bee cd.', -1, 1], ['a bee cd.', -9999999999999999, 1], - ['a bee cd.', 9999999999999999, 1], ['a bee cd.', 0.0, 1], ['a bee cd.', inf, 1], - ['a bee cd.', nan, 1], ['a bee cd.', 3.141592653589793, 1], ['a bee cd.', [], 1], + [' ', 9999999999999999, 1], [' ', 0.0, 1], [' ', inf, 1], [' ', 3.141592653589793, 1], + [' ', [], 1], [' ', [[]], 1], [' ', [1, 2, 3], 1], [' ', '', 1], [' ', ' ', 0], [' ', '1', -1], + [' ', 'a bee cd.', -1], [' ', '', 1], [' ', '1', -1], [' ', 'a bee cd.', -1], [' ', set([]), 1], + [' ', set([1, 2, 3]), 1], [' ', {5: 3}, 1], [' ', {}, 1], [' ', {'a': 99}, 1], + [' ', {'a': 1, 'c': 3, 'b': 2}, 1], [' ', {'a': 99, 'c': 3, 'b': 5}, 1], [' ', None, 1], + ['1', 0, 1], ['1', 1, 1], ['1', 2, 1], ['1', -1, 1], ['1', -9999999999999999, 1], + ['1', 9999999999999999, 1], ['1', 0.0, 1], ['1', inf, 1], ['1', 3.141592653589793, 1], + ['1', [], 1], ['1', [[]], 1], ['1', [1, 2, 3], 1], ['1', '', 1], ['1', ' ', 1], ['1', '1', 0], + ['1', 'a bee cd.', -1], ['1', '', 1], ['1', ' ', 1], ['1', 'a bee cd.', -1], ['1', set([]), 1], + ['1', set([1, 2, 3]), 1], ['1', {5: 3}, 1], ['1', {}, 1], ['1', {'a': 99}, 1], + ['1', {'a': 1, 'c': 3, 'b': 2}, 1], ['1', {'a': 99, 'c': 3, 'b': 5}, 1], ['1', None, 1], + ['a bee cd.', 0, 1], ['a bee cd.', 1, 1], ['a bee cd.', 2, 1], ['a bee cd.', -1, 1], + ['a bee cd.', -9999999999999999, 1], ['a bee cd.', 9999999999999999, 1], ['a bee cd.', 0.0, 1], + ['a bee cd.', inf, 1], ['a bee cd.', 3.141592653589793, 1], ['a bee cd.', [], 1], ['a bee cd.', [[]], 1], ['a bee cd.', [1, 2, 3], 1], ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], ['a bee cd.', '1', 1], ['a bee cd.', 'a bee cd.', 0], ['a bee cd.', '', 1], ['a bee cd.', ' ', 1], ['a bee cd.', '1', 1], ['a bee cd.', set([]), 1], ['a bee cd.', set([1, 2, 3]), 1], @@ -163,40 +151,39 @@ ['a bee cd.', {'a': 1, 'c': 3, 'b': 2}, 1], ['a bee cd.', {'a': 99, 'c': 3, 'b': 5}, 1], ['a bee cd.', None, 1], [set([]), 0, 1], [set([]), 1, 1], [set([]), 2, 1], [set([]), -1, 1], [set([]), -9999999999999999, 1], [set([]), 9999999999999999, 1], [set([]), 0.0, 1], - [set([]), inf, 1], [set([]), nan, 1], [set([]), 3.141592653589793, 1], [set([]), [], 1], - [set([]), [[]], 1], [set([]), [1, 2, 3], 1], [set([]), '', -1], [set([]), ' ', -1], - [set([]), '1', -1], [set([]), 'a bee cd.', -1], [set([]), '', -1], [set([]), ' ', -1], - [set([]), '1', -1], [set([]), 'a bee cd.', -1], + [set([]), inf, 1], [set([]), 3.141592653589793, 1], [set([]), [], 1], [set([]), [[]], 1], + [set([]), [1, 2, 3], 1], [set([]), '', -1], [set([]), ' ', -1], [set([]), '1', -1], + [set([]), 'a bee cd.', -1], [set([]), '', -1], [set([]), ' ', -1], [set([]), '1', -1], + [set([]), 'a bee cd.', -1], [set([]), set([1, 2, 3]), 'TypeError: cannot compare sets using cmp()'], [set([]), {5: 3}, 1], [set([]), {}, 1], [set([]), {'a': 99}, 1], [set([]), {'a': 1, 'c': 3, 'b': 2}, 1], [set([]), {'a': 99, 'c': 3, 'b': 5}, 1], [set([]), None, 1], [set([1, 2, 3]), 0, 1], [set([1, 2, 3]), 1, 1], [set([1, 2, 3]), 2, 1], [set([1, 2, 3]), -1, 1], [set([1, 2, 3]), -9999999999999999, 1], [set([1, 2, 3]), 9999999999999999, 1], - [set([1, 2, 3]), 0.0, 1], [set([1, 2, 3]), inf, 1], [set([1, 2, 3]), nan, 1], - [set([1, 2, 3]), 3.141592653589793, 1], [set([1, 2, 3]), [], 1], [set([1, 2, 3]), [[]], 1], - [set([1, 2, 3]), [1, 2, 3], 1], [set([1, 2, 3]), '', -1], [set([1, 2, 3]), ' ', -1], - [set([1, 2, 3]), '1', -1], [set([1, 2, 3]), 'a bee cd.', -1], [set([1, 2, 3]), '', -1], - [set([1, 2, 3]), ' ', -1], [set([1, 2, 3]), '1', -1], [set([1, 2, 3]), 'a bee cd.', -1], + [set([1, 2, 3]), 0.0, 1], [set([1, 2, 3]), inf, 1], [set([1, 2, 3]), 3.141592653589793, 1], + [set([1, 2, 3]), [], 1], [set([1, 2, 3]), [[]], 1], [set([1, 2, 3]), [1, 2, 3], 1], + [set([1, 2, 3]), '', -1], [set([1, 2, 3]), ' ', -1], [set([1, 2, 3]), '1', -1], + [set([1, 2, 3]), 'a bee cd.', -1], [set([1, 2, 3]), '', -1], [set([1, 2, 3]), ' ', -1], + [set([1, 2, 3]), '1', -1], [set([1, 2, 3]), 'a bee cd.', -1], [set([1, 2, 3]), set([]), 'TypeError: cannot compare sets using cmp()'], [set([1, 2, 3]), {5: 3}, 1], [set([1, 2, 3]), {}, 1], [set([1, 2, 3]), {'a': 99}, 1], [set([1, 2, 3]), {'a': 1, 'c': 3, 'b': 2}, 1], [set([1, 2, 3]), {'a': 99, 'c': 3, 'b': 5}, 1], [set([1, 2, 3]), None, 1], [{5: 3}, 0, 1], [{5: 3}, 1, 1], [{5: 3}, 2, 1], [{5: 3}, -1, 1], [{5: 3}, -9999999999999999, 1], [{5: 3}, 9999999999999999, 1], [{5: 3}, 0.0, 1], [{5: 3}, inf, 1], - [{5: 3}, nan, 1], [{5: 3}, 3.141592653589793, 1], [{5: 3}, [], -1], [{5: 3}, [[]], -1], - [{5: 3}, [1, 2, 3], -1], [{5: 3}, '', -1], [{5: 3}, ' ', -1], [{5: 3}, '1', -1], - [{5: 3}, 'a bee cd.', -1], [{5: 3}, '', -1], [{5: 3}, ' ', -1], [{5: 3}, '1', -1], - [{5: 3}, 'a bee cd.', -1], [{5: 3}, set([]), -1], [{5: 3}, set([1, 2, 3]), -1], [{5: 3}, {}, 1], - [{5: 3}, {'a': 99}, -1], [{5: 3}, {'a': 1, 'c': 3, 'b': 2}, -1], - [{5: 3}, {'a': 99, 'c': 3, 'b': 5}, -1], [{5: 3}, None, 1], [{}, 0, 1], [{}, 1, 1], [{}, 2, 1], - [{}, -1, 1], [{}, -9999999999999999, 1], [{}, 9999999999999999, 1], [{}, 0.0, 1], [{}, inf, 1], - [{}, nan, 1], [{}, 3.141592653589793, 1], [{}, [], -1], [{}, [[]], -1], [{}, [1, 2, 3], -1], - [{}, '', -1], [{}, ' ', -1], [{}, '1', -1], [{}, 'a bee cd.', -1], [{}, '', -1], [{}, ' ', -1], - [{}, '1', -1], [{}, 'a bee cd.', -1], [{}, set([]), -1], [{}, set([1, 2, 3]), -1], - [{}, {5: 3}, -1], [{}, {'a': 99}, -1], [{}, {'a': 1, 'c': 3, 'b': 2}, -1], - [{}, {'a': 99, 'c': 3, 'b': 5}, -1], [{}, None, 1], [{'a': 99}, 0, 1], [{'a': 99}, 1, 1], - [{'a': 99}, 2, 1], [{'a': 99}, -1, 1], [{'a': 99}, -9999999999999999, 1], - [{'a': 99}, 9999999999999999, 1], [{'a': 99}, 0.0, 1], [{'a': 99}, inf, 1], [{'a': 99}, nan, 1], - [{'a': 99}, 3.141592653589793, 1], [{'a': 99}, [], -1], [{'a': 99}, [[]], -1], + [{5: 3}, 3.141592653589793, 1], [{5: 3}, [], -1], [{5: 3}, [[]], -1], [{5: 3}, [1, 2, 3], -1], + [{5: 3}, '', -1], [{5: 3}, ' ', -1], [{5: 3}, '1', -1], [{5: 3}, 'a bee cd.', -1], + [{5: 3}, '', -1], [{5: 3}, ' ', -1], [{5: 3}, '1', -1], [{5: 3}, 'a bee cd.', -1], + [{5: 3}, set([]), -1], [{5: 3}, set([1, 2, 3]), -1], [{5: 3}, {}, 1], [{5: 3}, {'a': 99}, -1], + [{5: 3}, {'a': 1, 'c': 3, 'b': 2}, -1], [{5: 3}, {'a': 99, 'c': 3, 'b': 5}, -1], [{5: 3}, None, 1], + [{}, 0, 1], [{}, 1, 1], [{}, 2, 1], [{}, -1, 1], [{}, -9999999999999999, 1], + [{}, 9999999999999999, 1], [{}, 0.0, 1], [{}, inf, 1], [{}, 3.141592653589793, 1], [{}, [], -1], + [{}, [[]], -1], [{}, [1, 2, 3], -1], [{}, '', -1], [{}, ' ', -1], [{}, '1', -1], + [{}, 'a bee cd.', -1], [{}, '', -1], [{}, ' ', -1], [{}, '1', -1], [{}, 'a bee cd.', -1], + [{}, set([]), -1], [{}, set([1, 2, 3]), -1], [{}, {5: 3}, -1], [{}, {'a': 99}, -1], + [{}, {'a': 1, 'c': 3, 'b': 2}, -1], [{}, {'a': 99, 'c': 3, 'b': 5}, -1], [{}, None, 1], + [{'a': 99}, 0, 1], [{'a': 99}, 1, 1], [{'a': 99}, 2, 1], [{'a': 99}, -1, 1], + [{'a': 99}, -9999999999999999, 1], [{'a': 99}, 9999999999999999, 1], [{'a': 99}, 0.0, 1], + [{'a': 99}, inf, 1], [{'a': 99}, 3.141592653589793, 1], [{'a': 99}, [], -1], [{'a': 99}, [[]], -1], [{'a': 99}, [1, 2, 3], -1], [{'a': 99}, '', -1], [{'a': 99}, ' ', -1], [{'a': 99}, '1', -1], [{'a': 99}, 'a bee cd.', -1], [{'a': 99}, '', -1], [{'a': 99}, ' ', -1], [{'a': 99}, '1', -1], [{'a': 99}, 'a bee cd.', -1], [{'a': 99}, set([]), -1], [{'a': 99}, set([1, 2, 3]), -1], @@ -205,36 +192,34 @@ [{'a': 1, 'c': 3, 'b': 2}, 1, 1], [{'a': 1, 'c': 3, 'b': 2}, 2, 1], [{'a': 1, 'c': 3, 'b': 2}, -1, 1], [{'a': 1, 'c': 3, 'b': 2}, -9999999999999999, 1], [{'a': 1, 'c': 3, 'b': 2}, 9999999999999999, 1], [{'a': 1, 'c': 3, 'b': 2}, 0.0, 1], - [{'a': 1, 'c': 3, 'b': 2}, inf, 1], [{'a': 1, 'c': 3, 'b': 2}, nan, 1], - [{'a': 1, 'c': 3, 'b': 2}, 3.141592653589793, 1], [{'a': 1, 'c': 3, 'b': 2}, [], -1], - [{'a': 1, 'c': 3, 'b': 2}, [[]], -1], [{'a': 1, 'c': 3, 'b': 2}, [1, 2, 3], -1], - [{'a': 1, 'c': 3, 'b': 2}, '', -1], [{'a': 1, 'c': 3, 'b': 2}, ' ', -1], - [{'a': 1, 'c': 3, 'b': 2}, '1', -1], [{'a': 1, 'c': 3, 'b': 2}, 'a bee cd.', -1], - [{'a': 1, 'c': 3, 'b': 2}, '', -1], [{'a': 1, 'c': 3, 'b': 2}, ' ', -1], - [{'a': 1, 'c': 3, 'b': 2}, '1', -1], [{'a': 1, 'c': 3, 'b': 2}, 'a bee cd.', -1], - [{'a': 1, 'c': 3, 'b': 2}, set([]), -1], [{'a': 1, 'c': 3, 'b': 2}, set([1, 2, 3]), -1], - [{'a': 1, 'c': 3, 'b': 2}, {5: 3}, 1], [{'a': 1, 'c': 3, 'b': 2}, {}, 1], - [{'a': 1, 'c': 3, 'b': 2}, {'a': 99}, 1], + [{'a': 1, 'c': 3, 'b': 2}, inf, 1], [{'a': 1, 'c': 3, 'b': 2}, 3.141592653589793, 1], + [{'a': 1, 'c': 3, 'b': 2}, [], -1], [{'a': 1, 'c': 3, 'b': 2}, [[]], -1], + [{'a': 1, 'c': 3, 'b': 2}, [1, 2, 3], -1], [{'a': 1, 'c': 3, 'b': 2}, '', -1], + [{'a': 1, 'c': 3, 'b': 2}, ' ', -1], [{'a': 1, 'c': 3, 'b': 2}, '1', -1], + [{'a': 1, 'c': 3, 'b': 2}, 'a bee cd.', -1], [{'a': 1, 'c': 3, 'b': 2}, '', -1], + [{'a': 1, 'c': 3, 'b': 2}, ' ', -1], [{'a': 1, 'c': 3, 'b': 2}, '1', -1], + [{'a': 1, 'c': 3, 'b': 2}, 'a bee cd.', -1], [{'a': 1, 'c': 3, 'b': 2}, set([]), -1], + [{'a': 1, 'c': 3, 'b': 2}, set([1, 2, 3]), -1], [{'a': 1, 'c': 3, 'b': 2}, {5: 3}, 1], + [{'a': 1, 'c': 3, 'b': 2}, {}, 1], [{'a': 1, 'c': 3, 'b': 2}, {'a': 99}, 1], [{'a': 1, 'c': 3, 'b': 2}, {'a': 99, 'c': 3, 'b': 5}, -1], [{'a': 1, 'c': 3, 'b': 2}, None, 1], [{'a': 99, 'c': 3, 'b': 5}, 0, 1], [{'a': 99, 'c': 3, 'b': 5}, 1, 1], [{'a': 99, 'c': 3, 'b': 5}, 2, 1], [{'a': 99, 'c': 3, 'b': 5}, -1, 1], [{'a': 99, 'c': 3, 'b': 5}, -9999999999999999, 1], [{'a': 99, 'c': 3, 'b': 5}, 9999999999999999, 1], [{'a': 99, 'c': 3, 'b': 5}, 0.0, 1], - [{'a': 99, 'c': 3, 'b': 5}, inf, 1], [{'a': 99, 'c': 3, 'b': 5}, nan, 1], - [{'a': 99, 'c': 3, 'b': 5}, 3.141592653589793, 1], [{'a': 99, 'c': 3, 'b': 5}, [], -1], - [{'a': 99, 'c': 3, 'b': 5}, [[]], -1], [{'a': 99, 'c': 3, 'b': 5}, [1, 2, 3], -1], - [{'a': 99, 'c': 3, 'b': 5}, '', -1], [{'a': 99, 'c': 3, 'b': 5}, ' ', -1], - [{'a': 99, 'c': 3, 'b': 5}, '1', -1], [{'a': 99, 'c': 3, 'b': 5}, 'a bee cd.', -1], - [{'a': 99, 'c': 3, 'b': 5}, '', -1], [{'a': 99, 'c': 3, 'b': 5}, ' ', -1], - [{'a': 99, 'c': 3, 'b': 5}, '1', -1], [{'a': 99, 'c': 3, 'b': 5}, 'a bee cd.', -1], - [{'a': 99, 'c': 3, 'b': 5}, set([]), -1], [{'a': 99, 'c': 3, 'b': 5}, set([1, 2, 3]), -1], - [{'a': 99, 'c': 3, 'b': 5}, {5: 3}, 1], [{'a': 99, 'c': 3, 'b': 5}, {}, 1], - [{'a': 99, 'c': 3, 'b': 5}, {'a': 99}, 1], + [{'a': 99, 'c': 3, 'b': 5}, inf, 1], [{'a': 99, 'c': 3, 'b': 5}, 3.141592653589793, 1], + [{'a': 99, 'c': 3, 'b': 5}, [], -1], [{'a': 99, 'c': 3, 'b': 5}, [[]], -1], + [{'a': 99, 'c': 3, 'b': 5}, [1, 2, 3], -1], [{'a': 99, 'c': 3, 'b': 5}, '', -1], + [{'a': 99, 'c': 3, 'b': 5}, ' ', -1], [{'a': 99, 'c': 3, 'b': 5}, '1', -1], + [{'a': 99, 'c': 3, 'b': 5}, 'a bee cd.', -1], [{'a': 99, 'c': 3, 'b': 5}, '', -1], + [{'a': 99, 'c': 3, 'b': 5}, ' ', -1], [{'a': 99, 'c': 3, 'b': 5}, '1', -1], + [{'a': 99, 'c': 3, 'b': 5}, 'a bee cd.', -1], [{'a': 99, 'c': 3, 'b': 5}, set([]), -1], + [{'a': 99, 'c': 3, 'b': 5}, set([1, 2, 3]), -1], [{'a': 99, 'c': 3, 'b': 5}, {5: 3}, 1], + [{'a': 99, 'c': 3, 'b': 5}, {}, 1], [{'a': 99, 'c': 3, 'b': 5}, {'a': 99}, 1], [{'a': 99, 'c': 3, 'b': 5}, {'a': 1, 'c': 3, 'b': 2}, 1], [{'a': 99, 'c': 3, 'b': 5}, None, 1], [None, 0, -1], [None, 1, -1], [None, 2, -1], [None, -1, -1], [None, -9999999999999999, -1], - [None, 9999999999999999, -1], [None, 0.0, -1], [None, inf, -1], [None, nan, -1], - [None, 3.141592653589793, -1], [None, [], -1], [None, [[]], -1], [None, [1, 2, 3], -1], - [None, '', -1], [None, ' ', -1], [None, '1', -1], [None, 'a bee cd.', -1], [None, '', -1], - [None, ' ', -1], [None, '1', -1], [None, 'a bee cd.', -1], [None, set([]), -1], - [None, set([1, 2, 3]), -1], [None, {5: 3}, -1], [None, {}, -1], [None, {'a': 99}, -1], - [None, {'a': 1, 'c': 3, 'b': 2}, -1], [None, {'a': 99, 'c': 3, 'b': 5}, -1]] + [None, 9999999999999999, -1], [None, 0.0, -1], [None, inf, -1], [None, 3.141592653589793, -1], + [None, [], -1], [None, [[]], -1], [None, [1, 2, 3], -1], [None, '', -1], [None, ' ', -1], + [None, '1', -1], [None, 'a bee cd.', -1], [None, '', -1], [None, ' ', -1], [None, '1', -1], + [None, 'a bee cd.', -1], [None, set([]), -1], [None, set([1, 2, 3]), -1], [None, {5: 3}, -1], + [None, {}, -1], [None, {'a': 99}, -1], [None, {'a': 1, 'c': 3, 'b': 2}, -1], + [None, {'a': 99, 'c': 3, 'b': 5}, -1]] From 3f1ff7eddff8df70137bcd7d627e7af59c8816ed Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Sun, 30 Aug 2020 22:01:21 -0700 Subject: [PATCH 12/59] fix 2.6 test --- tests/test_past/test_misc.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_past/test_misc.py b/tests/test_past/test_misc.py index db07896f..ab67bfdd 100644 --- a/tests/test_past/test_misc.py +++ b/tests/test_past/test_misc.py @@ -11,7 +11,7 @@ from contextlib import contextmanager from future.tests.base import unittest -from future.utils import PY3 +from future.utils import PY3, PY26 if PY3: from past.builtins import cmp @@ -29,6 +29,10 @@ def empty_context_manager(*args, **kwargs): class TestCmp(unittest.TestCase): def test_cmp(self): for x, y, cmp_python2_value in test_values.cmp_python2_value: + if PY26: + # set comparison works a bit differently in 2.6 + if isinstance(x, set) or isinstance(y, set): + continue # to get this to run on python <3.4 which lacks subTest with getattr(self, 'subTest', empty_context_manager)(x=x, y=y): try: From ddedcb9abf98fd1cc85fb43ee35a12b2e898a5d7 Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Sun, 30 Aug 2020 22:06:42 -0700 Subject: [PATCH 13/59] fix 2.6 test, better comment --- tests/test_past/test_misc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_past/test_misc.py b/tests/test_past/test_misc.py index ab67bfdd..0367b3db 100644 --- a/tests/test_past/test_misc.py +++ b/tests/test_past/test_misc.py @@ -30,7 +30,7 @@ class TestCmp(unittest.TestCase): def test_cmp(self): for x, y, cmp_python2_value in test_values.cmp_python2_value: if PY26: - # set comparison works a bit differently in 2.6 + # set cmp works a bit differently in 2.6, we try to emulate 2.7 behavior, so skip set cmp tests if isinstance(x, set) or isinstance(y, set): continue # to get this to run on python <3.4 which lacks subTest From bee0247d43a7e7fafaaa18a1557ab4815ed072d6 Mon Sep 17 00:00:00 2001 From: Jon Parise Date: Thu, 8 Oct 2020 09:07:51 -0700 Subject: [PATCH 14/59] Add PY37_PLUS, PY38_PLUS, and PY39_PLUS This extend the set of existing PY3?_PLUS constants to include recent Python 3.x releases. --- src/future/utils/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/future/utils/__init__.py b/src/future/utils/__init__.py index 846d5da6..ec1b1027 100644 --- a/src/future/utils/__init__.py +++ b/src/future/utils/__init__.py @@ -61,6 +61,9 @@ PY34_PLUS = sys.version_info[0:2] >= (3, 4) PY35_PLUS = sys.version_info[0:2] >= (3, 5) PY36_PLUS = sys.version_info[0:2] >= (3, 6) +PY37_PLUS = sys.version_info[0:2] >= (3, 7) +PY38_PLUS = sys.version_info[0:2] >= (3, 8) +PY39_PLUS = sys.version_info[0:2] >= (3, 9) PY2 = sys.version_info[0] == 2 PY26 = sys.version_info[0:2] == (2, 6) PY27 = sys.version_info[0:2] == (2, 7) From c341d5497788923cc6ea0bd1358279f2147aa167 Mon Sep 17 00:00:00 2001 From: Alexander Shadchin Date: Sun, 15 Nov 2020 13:01:39 +0300 Subject: [PATCH 15/59] Add support Python 3.9 --- src/future/backports/xmlrpc/client.py | 7 ++++--- src/future/moves/_dummy_thread.py | 5 ++++- src/future/standard_library/__init__.py | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/future/backports/xmlrpc/client.py b/src/future/backports/xmlrpc/client.py index b78e5bad..0bcd90c9 100644 --- a/src/future/backports/xmlrpc/client.py +++ b/src/future/backports/xmlrpc/client.py @@ -134,10 +134,11 @@ from future.builtins import bytes, dict, int, range, str import base64 -# Py2.7 compatibility hack -base64.encodebytes = base64.encodestring -base64.decodebytes = base64.decodestring import sys +if sys.version_info < (3, 9): + # Py2.7 compatibility hack + base64.encodebytes = base64.encodestring + base64.decodebytes = base64.decodestring import time from datetime import datetime from future.backports.http import client as http_client diff --git a/src/future/moves/_dummy_thread.py b/src/future/moves/_dummy_thread.py index 688d249b..e5dca348 100644 --- a/src/future/moves/_dummy_thread.py +++ b/src/future/moves/_dummy_thread.py @@ -2,7 +2,10 @@ from future.utils import PY3 if PY3: - from _dummy_thread import * + try: + from _dummy_thread import * + except ImportError: + from _thread import * else: __future_module__ = True from dummy_thread import * diff --git a/src/future/standard_library/__init__.py b/src/future/standard_library/__init__.py index cff02f95..41c4f36d 100644 --- a/src/future/standard_library/__init__.py +++ b/src/future/standard_library/__init__.py @@ -125,7 +125,7 @@ # 'Tkinter': 'tkinter', '_winreg': 'winreg', 'thread': '_thread', - 'dummy_thread': '_dummy_thread', + 'dummy_thread': '_dummy_thread' if sys.version_info < (3, 9) else '_thread', # 'anydbm': 'dbm', # causes infinite import loop # 'whichdb': 'dbm', # causes infinite import loop # anydbm and whichdb are handled by fix_imports2 From c4411998f3935b5588ef0ba2fdff09b11edf2bcd Mon Sep 17 00:00:00 2001 From: Alexander Shadchin Date: Sun, 15 Nov 2020 13:04:51 +0300 Subject: [PATCH 16/59] Add Python 3.8 and 3.9 in .travis.yml --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1be7fac8..e77b37aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,8 +22,13 @@ matrix: env: TOXENV=py36 - python: 3.7 env: TOXENV=py37 - dist: xenial # required for Python 3.7 (travis-ci/travis-ci#9069) - sudo: required # required for Python 3.7 (travis-ci/travis-ci#9069) + dist: xenial + - python: 3.8 + env: TOXENV=py38 + dist: xenial + - python: 3.9 + env: TOXENV=py39 + dist: bionic install: - pip install typing==3.7.4.1 # required for Python 3.3 From 90e3e4d7146324bd88a5453ba17a43412174f013 Mon Sep 17 00:00:00 2001 From: Alexander Shadchin Date: Sun, 15 Nov 2020 13:09:44 +0300 Subject: [PATCH 17/59] Fix tests --- tests/test_future/test_standard_library.py | 3 ++- tests/test_future/test_urllib_toplevel.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/test_future/test_standard_library.py b/tests/test_future/test_standard_library.py index 3ac5d2d7..820bf47a 100644 --- a/tests/test_future/test_standard_library.py +++ b/tests/test_future/test_standard_library.py @@ -422,7 +422,8 @@ def test_urllib_imports_install_hooks(self): def test_underscore_prefixed_modules(self): import _thread - import _dummy_thread + if sys.version_info < (3, 9): + import _dummy_thread import _markupbase self.assertTrue(True) diff --git a/tests/test_future/test_urllib_toplevel.py b/tests/test_future/test_urllib_toplevel.py index 11e77201..68bc4c96 100644 --- a/tests/test_future/test_urllib_toplevel.py +++ b/tests/test_future/test_urllib_toplevel.py @@ -781,8 +781,9 @@ def test_unquoting(self): "%s" % result) self.assertRaises((TypeError, AttributeError), urllib_parse.unquote, None) self.assertRaises((TypeError, AttributeError), urllib_parse.unquote, ()) - with support.check_warnings(('', BytesWarning), quiet=True): - self.assertRaises((TypeError, AttributeError), urllib_parse.unquote, bytes(b'')) + if sys.version_info < (3, 9): + with support.check_warnings(('', BytesWarning), quiet=True): + self.assertRaises((TypeError, AttributeError), urllib_parse.unquote, bytes(b'')) def test_unquoting_badpercent(self): # Test unquoting on bad percent-escapes From 3e43aa2cdb7a25cf7a8c5cb382f3aa5ee8793918 Mon Sep 17 00:00:00 2001 From: Alexander Shadchin Date: Sun, 15 Nov 2020 13:16:00 +0300 Subject: [PATCH 18/59] Add Python 3.8 and 3.9 in tox.ini --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 1ca3286b..48e17601 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{26,27,33,34,35,36,37}, + py{26,27,33,34,35,36,37,38,39}, docs [testenv] From 32641e1e8f22e326f8cb77dbcd8b2172ece797e2 Mon Sep 17 00:00:00 2001 From: Alexander Shadchin Date: Sun, 15 Nov 2020 13:30:06 +0300 Subject: [PATCH 19/59] Fix test_pow for Python 3.8+ --- tests/test_future/test_builtins.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_future/test_builtins.py b/tests/test_future/test_builtins.py index 3921a608..f5dbec64 100644 --- a/tests/test_future/test_builtins.py +++ b/tests/test_future/test_builtins.py @@ -1304,7 +1304,8 @@ def test_pow(self): self.assertAlmostEqual(pow(-1, 1/3), 0.5 + 0.8660254037844386j) # Raises TypeError in Python < v3.5, ValueError in v3.5: - self.assertRaises((TypeError, ValueError), pow, -1, -2, 3) + if sys.version_info < (3, 8): + self.assertRaises((TypeError, ValueError), pow, -1, -2, 3) self.assertRaises(ValueError, pow, 1, 2, 0) self.assertRaises(TypeError, pow) From e7a2f76afa12ac4201c25dac9f93197016a19a7c Mon Sep 17 00:00:00 2001 From: Alexander Shadchin Date: Sun, 15 Nov 2020 13:53:28 +0300 Subject: [PATCH 20/59] Fix test_ftp for Python 3.8+ --- tests/test_future/test_urllib2.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/test_future/test_urllib2.py b/tests/test_future/test_urllib2.py index 2d69dad1..bd8e75c5 100644 --- a/tests/test_future/test_urllib2.py +++ b/tests/test_future/test_urllib2.py @@ -691,10 +691,6 @@ def connect_ftp(self, user, passwd, host, port, dirs, h = NullFTPHandler(data) h.parent = MockOpener() - # MIME guessing works in Python 3.8! - guessed_mime = None - if sys.hexversion >= 0x03080000: - guessed_mime = "image/gif" for url, host, port, user, passwd, type_, dirs, filename, mimetype in [ ("ftp://localhost/foo/bar/baz.html", "localhost", ftplib.FTP_PORT, "", "", "I", @@ -713,7 +709,10 @@ def connect_ftp(self, user, passwd, host, port, dirs, ["foo", "bar"], "", None), ("ftp://localhost/baz.gif;type=a", "localhost", ftplib.FTP_PORT, "", "", "A", - [], "baz.gif", guessed_mime), + [], "baz.gif", None), + ("ftp://localhost/baz.gif", + "localhost", ftplib.FTP_PORT, "", "", "I", + [], "baz.gif", "image/gif"), ]: req = Request(url) req.timeout = None From 5f9893f1207380754a85be51e86652bc6d2b8ecc Mon Sep 17 00:00:00 2001 From: Liuyang Wan Date: Mon, 23 Nov 2020 22:25:52 +0800 Subject: [PATCH 21/59] Add docs/requirements.txt --- docs/requirements.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 docs/requirements.txt diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..c5e7e301 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +sphinx==3.2.1 +sphinx_bootstrap_theme==0.7.1 From 18ecc5a199c324b344bfc2f99f9456f806acde41 Mon Sep 17 00:00:00 2001 From: Liuyang Wan Date: Mon, 23 Nov 2020 22:36:39 +0800 Subject: [PATCH 22/59] Use same docs requirements in tox --- tox.ini | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 1ca3286b..bc3300ab 100644 --- a/tox.ini +++ b/tox.ini @@ -12,6 +12,5 @@ commands = pytest {posargs} [testenv:docs] deps = - sphinx - sphinx_bootstrap_theme + -rdocs/requirements.txt commands = sphinx-build docs build From 3f40bd75d6cc3efee1e72413bc685e7bbf9b5a46 Mon Sep 17 00:00:00 2001 From: Liuyang Wan Date: Mon, 23 Nov 2020 22:50:38 +0800 Subject: [PATCH 23/59] Add docs build status badge to README.md --- README.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 5c090804..1ab43e53 100644 --- a/README.rst +++ b/README.rst @@ -3,6 +3,12 @@ Overview: Easy, clean, reliable Python 2/3 compatibility ======================================================== +.. image:: https://travis-ci.org/PythonCharmers/python-future.svg?branch=master + :target: https://travis-ci.org/PythonCharmers/python-future + +.. image:: https://readthedocs.org/projects/python-future/badge/?version=latest + :target: https://python-future.readthedocs.io/en/latest/?badge=latest + ``python-future`` is the missing compatibility layer between Python 2 and Python 3. It allows you to use a single, clean Python 3.x-compatible codebase to support both Python 2 and Python 3 with minimal overhead. @@ -22,9 +28,6 @@ are `Mezzanine `_ and `ObsPy Features -------- -.. image:: https://travis-ci.org/PythonCharmers/python-future.svg?branch=master - :target: https://travis-ci.org/PythonCharmers/python-future - - ``future.builtins`` package (also available as ``builtins`` on Py2) provides backports and remappings for 20 builtins with different semantics on Py3 versus Py2 From 42b30253a6968193965414d9eff82aca1d98094a Mon Sep 17 00:00:00 2001 From: Jordan Adler Date: Fri, 10 Jul 2020 00:42:47 +0000 Subject: [PATCH 24/59] Build System --- .gitignore | 2 ++ .travis.yml | 47 ++++++----------------------------------------- Dockerfile | 38 ++++++++++++++++++++++++++++++++++++++ TESTING.txt | 8 +++----- build.sh | 14 ++++++++++++++ lint.sh | 3 +++ setup.sh | 20 ++++++++++++++++++++ tox.ini | 16 ---------------- 8 files changed, 86 insertions(+), 62 deletions(-) create mode 100644 Dockerfile create mode 100755 build.sh create mode 100644 lint.sh create mode 100755 setup.sh delete mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index 3b7bce98..01c37c9c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,8 @@ develop-eggs .installed.cfg lib lib64 +MANIFEST +MANIFEST.in # Backup files *.bak diff --git a/.travis.yml b/.travis.yml index 1be7fac8..d3a8b5ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,46 +1,11 @@ -sudo: false -language: python -cache: pip +language: generic - -matrix: - include: - - python: 2.6 - env: TOXENV=py26 - dist: trusty - - python: 2.7 - env: TOXENV=py27 - - python: 3.3 - env: TOXENV=py33 - dist: trusty - sudo: false - - python: 3.4 - env: TOXENV=py34 - - python: 3.5 - env: TOXENV=py35 - - python: 3.6 - env: TOXENV=py36 - - python: 3.7 - env: TOXENV=py37 - dist: xenial # required for Python 3.7 (travis-ci/travis-ci#9069) - sudo: required # required for Python 3.7 (travis-ci/travis-ci#9069) - -install: - - pip install typing==3.7.4.1 # required for Python 3.3 - - pip install tox==2.9.1 - - pip install virtualenv==15.2.0 - - pip install py==1.4.30 - - pip install pluggy==0.5.2 +services: + - docker before_script: - # Run flake8 tests only on Python 2.7 and 3.7... - # 1) stop the build if there are Python syntax errors or undefined names - # 2) exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - - if [[ $TRAVIS_PYTHON_VERSION == *.7 ]]; then - pip install flake8; - flake8 . --count --exit-zero --select=E901,E999,F821,F822,F823 --show-source --statistics; - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics; - fi + - docker pull jmadler/python-future-builder:latest script: - - tox + - ./lint.sh + - ./build.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..5ed3387f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,38 @@ +FROM debian:9 +# This docker image has a copy of a wide array of Pythons installed +RUN apt-get update +RUN apt-get install --yes --no-install-recommends make build-essential zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libffi-dev liblzma-dev libssl1.0-dev +RUN apt-get install --yes git vim +RUN apt-get install --yes python3-pip +ENV PYENV_ROOT=/opt/pyenv +RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash +RUN echo export PATH="/opt/pyenv/bin:$PATH" >> ~/.bashrc +RUN echo 'eval "$(pyenv init -)"' >> ~/.bashrc +RUN echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc +# venv 15.2.0 is the last to support Python 2.6. +RUN pip3 install virtualenv==15.2.0 +RUN PATH=/opt/pyenv/bin:$PATH pyenv install 2.6.9 +RUN virtualenv /root/py26 --python /opt/pyenv/versions/2.6.9/bin/python +RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.3.7 +RUN virtualenv /root/py33 --python /opt/pyenv/versions/3.3.7/bin/python +RUN pip3 install virtualenv==20.0.21 +RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.4.10 +RUN virtualenv /root/py34 --python /opt/pyenv/versions/3.4.10/bin/python +RUN apt-get install --yes libssl-dev libxmlsec1-dev +RUN PATH=/opt/pyenv/bin:$PATH pyenv install 2.7.18 +RUN virtualenv /root/py27 --python /opt/pyenv/versions/2.7.18/bin/python +RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.5.9 +RUN virtualenv /root/py35 --python /opt/pyenv/versions/3.5.9/bin/python +RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.6.10 +RUN virtualenv /root/py36 --python /opt/pyenv/versions/3.6.10/bin/python +RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.7.7 +RUN virtualenv /root/py37 --python /opt/pyenv/versions/3.7.7/bin/python +RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.8.3 +RUN virtualenv /root/py38 --python /opt/pyenv/versions/3.8.3/bin/python +RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.9.0 +RUN virtualenv /root/py39 --python /opt/pyenv/versions/3.9.0/bin/python +RUN ln -s /usr/bin/python3 /usr/bin/python +ENV LC_ALL=C.UTF-8 +ENV LANG=C.UTF-8 +WORKDIR /root/python-future +ADD . /root/python-future diff --git a/TESTING.txt b/TESTING.txt index 0e9b96a3..b2ad5c65 100644 --- a/TESTING.txt +++ b/TESTING.txt @@ -1,8 +1,6 @@ -Currently the tests are passing on OS X and Linux on Python 2.7 and 3.4. +A docker image, python-future-builder, is used to do testing and building. The test suite can be run with: -The test suite can be run with: - - $ tox + $ bash build.sh which tests the module under a number of different python versions, where available, or with: @@ -10,4 +8,4 @@ which tests the module under a number of different python versions, where availa To execute a single test: - $ pytest -k test_chained_exceptions_stacktrace \ No newline at end of file + $ pytest -k test_chained_exceptions_stacktrace diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..9dbba568 --- /dev/null +++ b/build.sh @@ -0,0 +1,14 @@ +# XXX: TODO: we should make this include -e once tests pass +set -xuo pipefail + +docker build . -t jmadler/python-future-builder + +version=0.18.2 + +for i in py26 py27 py33 py34 py35 py36 py37 py38 py39; do + docker run -ti -v $(realpath dist):/root/python-future/dist python-future-builder /root/python-future/setup.sh $version $(basename $i) +done + +python setup.py sdist +python setup.py clean +echo You may now run: "twine upload dist/*" diff --git a/lint.sh b/lint.sh new file mode 100644 index 00000000..234b3f14 --- /dev/null +++ b/lint.sh @@ -0,0 +1,3 @@ +# Run under Python 2.7 and 3.7 +flake8 . --count --exit-zero --select=E901,E999,F821,F822,F823 --show-source --statistics +flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics diff --git a/setup.sh b/setup.sh new file mode 100755 index 00000000..8e8dc150 --- /dev/null +++ b/setup.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -exo pipefail + +version=$1 +pytag=$2 + +if [ $pytag = 'py33' ]; then + pip3 install virtualenv==16.2.0 +fi + +source /root/$pytag/bin/activate + +if [ $pytag = 'py26' ]; then + pip install importlib +fi +pip install pytest unittest2 +python setup.py bdist_wheel --python-tag=$pytag +pip install dist/future-$version-$pytag-none-any.whl +pytest tests/ diff --git a/tox.ini b/tox.ini deleted file mode 100644 index bc3300ab..00000000 --- a/tox.ini +++ /dev/null @@ -1,16 +0,0 @@ -[tox] -envlist = - py{26,27,33,34,35,36,37}, - docs - -[testenv] -deps = - pytest - unittest2 - py26: importlib -commands = pytest {posargs} - -[testenv:docs] -deps = - -rdocs/requirements.txt -commands = sphinx-build docs build From 01e8440942888dd44a10bc8fe976633a707721e2 Mon Sep 17 00:00:00 2001 From: Jordan Adler Date: Fri, 27 Nov 2020 11:13:19 -0800 Subject: [PATCH 25/59] Add docker push to optimize CI --- build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sh b/build.sh index 9dbba568..04737215 100755 --- a/build.sh +++ b/build.sh @@ -2,6 +2,7 @@ set -xuo pipefail docker build . -t jmadler/python-future-builder +docker push jmadler/python-future-builder:latest version=0.18.2 From 58cc9849c7cbee1f6e9884190be82da55792d3ae Mon Sep 17 00:00:00 2001 From: Jordan Adler Date: Fri, 27 Nov 2020 13:16:11 -0800 Subject: [PATCH 26/59] Make lint.sh executable --- lint.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 lint.sh diff --git a/lint.sh b/lint.sh old mode 100644 new mode 100755 From 046ff1842a0b4464ebb0cdc936a24e626494968a Mon Sep 17 00:00:00 2001 From: Jordan Adler Date: Fri, 27 Nov 2020 17:36:13 -0800 Subject: [PATCH 27/59] Add flake8 to image --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 5ed3387f..6b94c0a8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,6 +31,8 @@ RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.8.3 RUN virtualenv /root/py38 --python /opt/pyenv/versions/3.8.3/bin/python RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.9.0 RUN virtualenv /root/py39 --python /opt/pyenv/versions/3.9.0/bin/python +# Lint tools +RUN pip3 install flake8 RUN ln -s /usr/bin/python3 /usr/bin/python ENV LC_ALL=C.UTF-8 ENV LANG=C.UTF-8 From f96a219a966d04f7b60a05501ecee52ca5326055 Mon Sep 17 00:00:00 2001 From: Jordan Adler Date: Fri, 27 Nov 2020 18:52:15 -0800 Subject: [PATCH 28/59] fix order --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d3a8b5ad..3fe6a983 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,5 +7,5 @@ before_script: - docker pull jmadler/python-future-builder:latest script: - - ./lint.sh - ./build.sh + - ./lint.sh From 45cf38295a36fb8b59bd1921c926b940764492f3 Mon Sep 17 00:00:00 2001 From: Jordan Adler Date: Fri, 27 Nov 2020 21:32:17 -0800 Subject: [PATCH 29/59] Update docker image and parcel out to constant variable. Add comment to update version constant --- build.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/build.sh b/build.sh index 04737215..d17fa7ce 100755 --- a/build.sh +++ b/build.sh @@ -1,13 +1,15 @@ # XXX: TODO: we should make this include -e once tests pass set -xuo pipefail -docker build . -t jmadler/python-future-builder -docker push jmadler/python-future-builder:latest - +DOCKER_IMAGE=jmadler/python-future-builder +# XXX: TODO: Perhaps this version shouldn't be hardcoded version=0.18.2 +docker build . -t $DOCKER_IMAGE +docker push $DOCKER_IMAGE:latest + for i in py26 py27 py33 py34 py35 py36 py37 py38 py39; do - docker run -ti -v $(realpath dist):/root/python-future/dist python-future-builder /root/python-future/setup.sh $version $(basename $i) + docker run -ti -v $(realpath dist):/root/python-future/dist $DOCKER_IMAGE /root/python-future/setup.sh $version $(basename $i) done python setup.py sdist From 2abe00d562445f93f72a7cdc00439b7539cc0402 Mon Sep 17 00:00:00 2001 From: Jordan Adler Date: Sat, 28 Nov 2020 09:46:28 -0800 Subject: [PATCH 30/59] Pass if lint fails --- lint.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lint.sh b/lint.sh index 234b3f14..667b258f 100755 --- a/lint.sh +++ b/lint.sh @@ -1,3 +1,3 @@ -# Run under Python 2.7 and 3.7 -flake8 . --count --exit-zero --select=E901,E999,F821,F822,F823 --show-source --statistics -flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics +# TODO: Run under Python 2.7 and 3.7 +flake8 . --count --exit-zero --select=E901,E999,F821,F822,F823 --show-source --statistics || true +flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics || true From c780bf5e15ce00939d0eb7b477b4236a54447c85 Mon Sep 17 00:00:00 2001 From: Tomer Chachamu Date: Tue, 29 Dec 2020 14:10:28 +0000 Subject: [PATCH 31/59] Correct __eq__ --- src/future/types/newrange.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/future/types/newrange.py b/src/future/types/newrange.py index eda01a5a..6d4ebe2f 100644 --- a/src/future/types/newrange.py +++ b/src/future/types/newrange.py @@ -87,7 +87,7 @@ def __eq__(self, other): return (isinstance(other, newrange) and (self._len == 0 == other._len or (self._start, self._step, self._len) == - (other._start, other._step, self._len))) + (other._start, other._step, other._len))) def __len__(self): return self._len From 974eb1ff2fb3982498574bbb8d8084501c477527 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Thu, 31 Dec 2020 07:30:41 +1100 Subject: [PATCH 32/59] docs: fix simple typo, reqest -> request There is a small typo in tests/test_future/test_urllibnet.py. Should read `request` rather than `reqest`. --- tests/test_future/test_urllibnet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_future/test_urllibnet.py b/tests/test_future/test_urllibnet.py index f9639bfc..6a7b6d64 100644 --- a/tests/test_future/test_urllibnet.py +++ b/tests/test_future/test_urllibnet.py @@ -38,7 +38,7 @@ def testURLread(self): class urlopenNetworkTests(unittest.TestCase): - """Tests urllib.reqest.urlopen using the network. + """Tests urllib.request.urlopen using the network. These tests are not exhaustive. Assuming that testing using files does a good job overall of some of the basic interface features. There are no From 6e27aacadfcee99607894b84e219ba4c571688ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20Andr=C3=A9?= Date: Wed, 20 Jan 2021 19:45:30 +0100 Subject: [PATCH 33/59] Fix bug in super() with metaclasses --- src/future/builtins/newsuper.py | 71 ++++++++++++++++----------------- tests/test_future/test_super.py | 12 ++++++ 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/future/builtins/newsuper.py b/src/future/builtins/newsuper.py index 5d3402bd..3e8cc80f 100644 --- a/src/future/builtins/newsuper.py +++ b/src/future/builtins/newsuper.py @@ -60,44 +60,15 @@ def newsuper(typ=_SENTINEL, type_or_obj=_SENTINEL, framedepth=1): raise RuntimeError('super() used in a function with no args') try: - # Get the MRO so we can crawl it. - mro = type_or_obj.__mro__ - except (AttributeError, RuntimeError): # see issue #160 + typ = find_owner(type_or_obj, f.f_code) + except (AttributeError, RuntimeError, TypeError): + # see issues #160, #267 try: - mro = type_or_obj.__class__.__mro__ + typ = find_owner(type_or_obj.__class__, f.f_code) except AttributeError: - raise RuntimeError('super() used with a non-newstyle class') - - # A ``for...else`` block? Yes! It's odd, but useful. - # If unfamiliar with for...else, see: - # - # http://psung.blogspot.com/2007/12/for-else-in-python.html - for typ in mro: - # Find the class that owns the currently-executing method. - for meth in typ.__dict__.values(): - # Drill down through any wrappers to the underlying func. - # This handles e.g. classmethod() and staticmethod(). - try: - while not isinstance(meth,FunctionType): - if isinstance(meth, property): - # Calling __get__ on the property will invoke - # user code which might throw exceptions or have - # side effects - meth = meth.fget - else: - try: - meth = meth.__func__ - except AttributeError: - meth = meth.__get__(type_or_obj, typ) - except (AttributeError, TypeError): - continue - if meth.func_code is f.f_code: - break # Aha! Found you. - else: - continue # Not found! Move onto the next class in MRO. - break # Found! Break out of the search loop. - else: - raise RuntimeError('super() called outside a method') + raise RuntimeError('super() used with an old-style class') + except TypeError: + raise RuntimeError('super() called outside a method') # Dispatch to builtin super(). if type_or_obj is not _SENTINEL: @@ -105,6 +76,34 @@ def newsuper(typ=_SENTINEL, type_or_obj=_SENTINEL, framedepth=1): return _builtin_super(typ) +def find_owner(cls, code): + '''Find the class that owns the currently-executing method. + ''' + for typ in cls.__mro__: + for meth in typ.__dict__.values(): + # Drill down through any wrappers to the underlying func. + # This handles e.g. classmethod() and staticmethod(). + try: + while not isinstance(meth,FunctionType): + if isinstance(meth, property): + # Calling __get__ on the property will invoke + # user code which might throw exceptions or have + # side effects + meth = meth.fget + else: + try: + meth = meth.__func__ + except AttributeError: + meth = meth.__get__(cls, typ) + except (AttributeError, TypeError): + continue + if meth.func_code is code: + return typ # Aha! Found you. + # Not found! Move onto the next class in MRO. + + raise TypeError + + def superm(*args, **kwds): f = sys._getframe(1) nm = f.f_code.co_name diff --git a/tests/test_future/test_super.py b/tests/test_future/test_super.py index 0376c1d8..3cb23d69 100644 --- a/tests/test_future/test_super.py +++ b/tests/test_future/test_super.py @@ -170,6 +170,18 @@ class Elite(Dangerous): self.assertEqual(Elite().walk(), 'Defused') + def test_metaclass(self): + class Meta(type): + def __init__(cls, name, bases, clsdict): + super().__init__(name, bases, clsdict) + + try: + class Base(object): + __metaclass__ = Meta + except Exception as e: + self.fail('raised %s with a custom metaclass' + % type(e).__name__) + class TestSuperFromTestDescrDotPy(unittest.TestCase): """ From fe645ba312a02e6d676265ece5dbf5aa31512e9a Mon Sep 17 00:00:00 2001 From: zihzihtw Date: Fri, 16 Apr 2021 16:36:27 +0800 Subject: [PATCH 34/59] Fix newint bool in py3 --- src/future/types/newint.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/future/types/newint.py b/src/future/types/newint.py index 748dba9d..04a411e9 100644 --- a/src/future/types/newint.py +++ b/src/future/types/newint.py @@ -284,6 +284,9 @@ def __bool__(self): """ So subclasses can override this, Py3-style """ + if PY3: + return super(newint, self).__bool__() + return super(newint, self).__nonzero__() def __native__(self): From 21ae5c76eb49edfff73d5a2319bf42ab0378da48 Mon Sep 17 00:00:00 2001 From: Alexander Shadchin Date: Fri, 11 Jun 2021 22:03:18 +0300 Subject: [PATCH 35/59] Fix tests --- tests/test_future/test_urllib_toplevel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_future/test_urllib_toplevel.py b/tests/test_future/test_urllib_toplevel.py index 68bc4c96..923b2e8a 100644 --- a/tests/test_future/test_urllib_toplevel.py +++ b/tests/test_future/test_urllib_toplevel.py @@ -120,7 +120,7 @@ def setUp(self): finally: f.close() self.pathname = support.TESTFN - self.returned_obj = urlopen("file:%s" % self.pathname) + self.returned_obj = urlopen("file:%s" % urllib_parse.quote(self.pathname)) def tearDown(self): """Shut down the open object""" @@ -167,7 +167,7 @@ def test_info(self): self.assertIsInstance(self.returned_obj.info(), email_message.Message) def test_geturl(self): - self.assertEqual(self.returned_obj.geturl(), self.pathname) + self.assertEqual(self.returned_obj.geturl(), urllib_parse.quote(self.pathname)) def test_getcode(self): self.assertIsNone(self.returned_obj.getcode()) From 3401099e77d5838715044902b1b6ef8ae118b2fd Mon Sep 17 00:00:00 2001 From: Andrew Bjonnes Date: Wed, 3 Nov 2021 21:02:35 -0400 Subject: [PATCH 36/59] Fix bug in fix_raise.py fixer The replacement node for the fix of a raise statement with an unknown value should inherit the prefix of the source node. --- src/libfuturize/fixes/fix_raise.py | 2 +- tests/test_future/test_libfuturize_fixers.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/libfuturize/fixes/fix_raise.py b/src/libfuturize/fixes/fix_raise.py index f7518416..d113401c 100644 --- a/src/libfuturize/fixes/fix_raise.py +++ b/src/libfuturize/fixes/fix_raise.py @@ -94,7 +94,7 @@ def transform(self, node, results): args = [exc, Comma(), val] if tb is not None: args += [Comma(), tb] - return Call(Name(u"raise_"), args) + return Call(Name(u"raise_"), args, prefix=node.prefix) if tb is not None: tb.prefix = "" diff --git a/tests/test_future/test_libfuturize_fixers.py b/tests/test_future/test_libfuturize_fixers.py index 4ac0b7e1..2080696a 100644 --- a/tests/test_future/test_libfuturize_fixers.py +++ b/tests/test_future/test_libfuturize_fixers.py @@ -767,6 +767,20 @@ def test_unknown_value_with_traceback_with_comments(self): raise_(E, Func(arg1, arg2, arg3), tb) # foo""" self.check(b, a) + def test_unknown_value_with_indent(self): + b = """ + while True: + print() # another expression in the same block triggers different parsing + raise E, V + """ + a = """ + from future.utils import raise_ + while True: + print() # another expression in the same block triggers different parsing + raise_(E, V) + """ + self.check(b, a) + # These should produce a warning def test_string_exc(self): From dffc579dbb7c882fc01fa0c0dfa6b59acef7827d Mon Sep 17 00:00:00 2001 From: Andrew Bjonnes Date: Wed, 10 Nov 2021 22:19:41 -0500 Subject: [PATCH 37/59] Fix bug in fix_print.py fixer When the print ends with a non-space whitespace character, an extra space character should not be printed at the end. --- src/libfuturize/fixes/fix_print.py | 10 +++++++ tests/test_future/test_libfuturize_fixers.py | 31 ++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/libfuturize/fixes/fix_print.py b/src/libfuturize/fixes/fix_print.py index 247b91b8..2554717c 100644 --- a/src/libfuturize/fixes/fix_print.py +++ b/src/libfuturize/fixes/fix_print.py @@ -57,6 +57,16 @@ def transform(self, node, results): if args and args[-1] == Comma(): args = args[:-1] end = " " + + # try to determine if the string ends in a non-space whitespace character, in which + # case there should be no space at the end of the conversion + string_leaves = [leaf for leaf in args[-1].leaves() if leaf.type == token.STRING] + if ( + string_leaves + and string_leaves[-1].value[0] != "r" # "raw" string + and string_leaves[-1].value[-3:-1] in (r"\t", r"\n", r"\r") + ): + end = "" if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, u">>"): assert len(args) >= 2 file = args[1].clone() diff --git a/tests/test_future/test_libfuturize_fixers.py b/tests/test_future/test_libfuturize_fixers.py index 2080696a..2146d1f2 100644 --- a/tests/test_future/test_libfuturize_fixers.py +++ b/tests/test_future/test_libfuturize_fixers.py @@ -307,6 +307,37 @@ def test_trailing_comma_3(self): a = """print(1, end=' ')""" self.check(b, a) + def test_trailing_comma_4(self): + b = """print "a ",""" + a = """print("a ", end=' ')""" + self.check(b, a) + + def test_trailing_comma_5(self): + b = r"""print "b\t",""" + a = r"""print("b\t", end='')""" + self.check(b, a) + + def test_trailing_comma_6(self): + b = r"""print "c\n",""" + a = r"""print("c\n", end='')""" + self.check(b, a) + + def test_trailing_comma_7(self): + b = r"""print "d\r",""" + a = r"""print("d\r", end='')""" + self.check(b, a) + + def test_trailing_comma_8(self): + b = r"""print "%s\n" % (1,),""" + a = r"""print("%s\n" % (1,), end='')""" + self.check(b, a) + + + def test_trailing_comma_9(self): + b = r"""print r"e\n",""" + a = r"""print(r"e\n", end=' ')""" + self.check(b, a) + # >> stuff def test_vargs_without_trailing_comma(self): From f16e1c18821532aa7635265a590fbd7ad967d514 Mon Sep 17 00:00:00 2001 From: Kian-Meng Ang Date: Wed, 12 Jan 2022 19:38:48 +0800 Subject: [PATCH 38/59] Fix typos --- docs/3rd-party-py3k-compat-code/jinja2_compat.py | 2 +- docs/notebooks/object special methods (next, bool, ...).ipynb | 2 +- docs/standard_library_imports.rst | 2 +- docs/whatsnew.rst | 4 ++-- src/future/backports/datetime.py | 2 +- src/future/backports/email/_header_value_parser.py | 2 +- src/future/backports/email/parser.py | 4 ++-- src/future/backports/http/cookiejar.py | 2 +- src/future/backports/xmlrpc/client.py | 2 +- src/future/standard_library/__init__.py | 2 +- src/future/types/newint.py | 2 +- src/future/types/newrange.py | 2 +- src/libfuturize/fixer_util.py | 2 +- src/libfuturize/fixes/fix_metaclass.py | 4 ++-- tests/test_future/test_http_cookiejar.py | 4 ++-- tests/test_future/test_standard_library.py | 2 +- tests/test_future/test_urllib.py | 4 ++-- tests/test_future/test_urllib_toplevel.py | 4 ++-- 18 files changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/3rd-party-py3k-compat-code/jinja2_compat.py b/docs/3rd-party-py3k-compat-code/jinja2_compat.py index 1326cbc6..0456faae 100644 --- a/docs/3rd-party-py3k-compat-code/jinja2_compat.py +++ b/docs/3rd-party-py3k-compat-code/jinja2_compat.py @@ -85,7 +85,7 @@ def encode_filename(filename): def with_metaclass(meta, *bases): # This requires a bit of explanation: the basic idea is to make a - # dummy metaclass for one level of class instanciation that replaces + # dummy metaclass for one level of class instantiation that replaces # itself with the actual metaclass. Because of internal type checks # we also need to make sure that we downgrade the custom metaclass # for one level to something closer to type (that's why __call__ and diff --git a/docs/notebooks/object special methods (next, bool, ...).ipynb b/docs/notebooks/object special methods (next, bool, ...).ipynb index 5729ddc5..7da31856 100644 --- a/docs/notebooks/object special methods (next, bool, ...).ipynb +++ b/docs/notebooks/object special methods (next, bool, ...).ipynb @@ -63,7 +63,7 @@ "collapsed": false, "input": [ "# Py3-style iterators written as new-style classes (subclasses of\n", - "# future.builtins.object) are backward compatibile with Py2:\n", + "# future.builtins.object) are backward compatible with Py2:\n", "class Upper(object):\n", " def __init__(self, iterable):\n", " self._iter = iter(iterable)\n", diff --git a/docs/standard_library_imports.rst b/docs/standard_library_imports.rst index 60442541..c09e9e30 100644 --- a/docs/standard_library_imports.rst +++ b/docs/standard_library_imports.rst @@ -15,7 +15,7 @@ As of version 0.14, the ``future`` package comes with top-level packages for Python 2.x that provide access to the reorganized standard library modules under their Python 3.x names. -Direct imports are the preferred mechanism for accesing the renamed standard +Direct imports are the preferred mechanism for accessing the renamed standard library modules in Python 2/3 compatible code. For example, the following clean Python 3 code runs unchanged on Python 2 after installing ``future``:: diff --git a/docs/whatsnew.rst b/docs/whatsnew.rst index c6fa8f86..c9df5120 100644 --- a/docs/whatsnew.rst +++ b/docs/whatsnew.rst @@ -33,7 +33,7 @@ This is a major bug-fix and feature release, including: - Fix an issue with copyreg import under Py3 that results in unexposed stdlib functionality - Export and document types in future.utils - Update behavior of newstr.__eq__() to match str.__eq__() as per reference docs -- Fix raising and the raising fixer to handle cases where the syntax is ambigious +- Fix raising and the raising fixer to handle cases where the syntax is ambiguous - Allow "default" parameter in min() and max() (Issue #334) - Implement __hash__() in newstr (Issue #454) - Future proof some version checks to handle the fact that Py4 won't be a major breaking release @@ -65,7 +65,7 @@ This is a major bug-fix release, including: - Fix ``past.translation`` on read-only file systems - Fix Tkinter import bug introduced in Python 2.7.4 (issue #262) - Correct TypeError to ValueError in a specific edge case for newrange -- Support inequality tests betwen newstrs and newbytes +- Support inequality tests between newstrs and newbytes - Add type check to __get__ in newsuper - Fix fix_divsion_safe to support better conversion of complex expressions, and skip obvious float division. diff --git a/src/future/backports/datetime.py b/src/future/backports/datetime.py index 3261014e..8cd62ddf 100644 --- a/src/future/backports/datetime.py +++ b/src/future/backports/datetime.py @@ -689,7 +689,7 @@ def today(cls): @classmethod def fromordinal(cls, n): - """Contruct a date from a proleptic Gregorian ordinal. + """Construct a date from a proleptic Gregorian ordinal. January 1 of year 1 is day 1. Only the year, month and day are non-zero in the result. diff --git a/src/future/backports/email/_header_value_parser.py b/src/future/backports/email/_header_value_parser.py index 43957edc..59b1b318 100644 --- a/src/future/backports/email/_header_value_parser.py +++ b/src/future/backports/email/_header_value_parser.py @@ -2867,7 +2867,7 @@ def parse_content_type_header(value): _find_mime_parameters(ctype, value) return ctype ctype.append(token) - # XXX: If we really want to follow the formal grammer we should make + # XXX: If we really want to follow the formal grammar we should make # mantype and subtype specialized TokenLists here. Probably not worth it. if not value or value[0] != '/': ctype.defects.append(errors.InvalidHeaderDefect( diff --git a/src/future/backports/email/parser.py b/src/future/backports/email/parser.py index df1c6e28..79f0e5a3 100644 --- a/src/future/backports/email/parser.py +++ b/src/future/backports/email/parser.py @@ -26,7 +26,7 @@ def __init__(self, _class=Message, **_3to2kwargs): textual representation of the message. The string must be formatted as a block of RFC 2822 headers and header - continuation lines, optionally preceeded by a `Unix-from' header. The + continuation lines, optionally preceded by a `Unix-from' header. The header block is terminated either by the end of the string or by a blank line. @@ -92,7 +92,7 @@ def __init__(self, *args, **kw): textual representation of the message. The input must be formatted as a block of RFC 2822 headers and header - continuation lines, optionally preceeded by a `Unix-from' header. The + continuation lines, optionally preceded by a `Unix-from' header. The header block is terminated either by the end of the input or by a blank line. diff --git a/src/future/backports/http/cookiejar.py b/src/future/backports/http/cookiejar.py index af3ef415..1d301b1c 100644 --- a/src/future/backports/http/cookiejar.py +++ b/src/future/backports/http/cookiejar.py @@ -1845,7 +1845,7 @@ def lwp_cookie_str(cookie): class LWPCookieJar(FileCookieJar): """ The LWPCookieJar saves a sequence of "Set-Cookie3" lines. - "Set-Cookie3" is the format used by the libwww-perl libary, not known + "Set-Cookie3" is the format used by the libwww-perl library, not known to be compatible with any browser, but which is easy to read and doesn't lose information about RFC 2965 cookies. diff --git a/src/future/backports/xmlrpc/client.py b/src/future/backports/xmlrpc/client.py index b78e5bad..cab75390 100644 --- a/src/future/backports/xmlrpc/client.py +++ b/src/future/backports/xmlrpc/client.py @@ -1251,7 +1251,7 @@ def close(self): # Send HTTP request. # # @param host Host descriptor (URL or (URL, x509 info) tuple). - # @param handler Targer RPC handler (a path relative to host) + # @param handler Target RPC handler (a path relative to host) # @param request_body The XML-RPC request body # @param debug Enable debugging if debug is true. # @return An HTTPConnection. diff --git a/src/future/standard_library/__init__.py b/src/future/standard_library/__init__.py index cff02f95..24124b26 100644 --- a/src/future/standard_library/__init__.py +++ b/src/future/standard_library/__init__.py @@ -17,7 +17,7 @@ import socketserver import winreg # on Windows only import test.support - import html, html.parser, html.entites + import html, html.parser, html.entities import http, http.client, http.server import http.cookies, http.cookiejar import urllib.parse, urllib.request, urllib.response, urllib.error, urllib.robotparser diff --git a/src/future/types/newint.py b/src/future/types/newint.py index 04a411e9..2c86ce18 100644 --- a/src/future/types/newint.py +++ b/src/future/types/newint.py @@ -318,7 +318,7 @@ def to_bytes(self, length, byteorder='big', signed=False): bits = length * 8 num = (2**bits) + self if num <= 0: - raise OverflowError("int too smal to convert") + raise OverflowError("int too small to convert") else: if self < 0: raise OverflowError("can't convert negative int to unsigned") diff --git a/src/future/types/newrange.py b/src/future/types/newrange.py index 6d4ebe2f..dc5eb802 100644 --- a/src/future/types/newrange.py +++ b/src/future/types/newrange.py @@ -105,7 +105,7 @@ def index(self, value): raise ValueError('%r is not in range' % value) def count(self, value): - """Return the number of ocurrences of integer `value` + """Return the number of occurrences of integer `value` in the sequence this range represents.""" # a value can occur exactly zero or one times return int(value in self) diff --git a/src/libfuturize/fixer_util.py b/src/libfuturize/fixer_util.py index 48e4689d..cf646b61 100644 --- a/src/libfuturize/fixer_util.py +++ b/src/libfuturize/fixer_util.py @@ -116,7 +116,7 @@ def suitify(parent): """ for node in parent.children: if node.type == syms.suite: - # already in the prefered format, do nothing + # already in the preferred format, do nothing return # One-liners have no suite node, we have to fake one up diff --git a/src/libfuturize/fixes/fix_metaclass.py b/src/libfuturize/fixes/fix_metaclass.py index 2ac41c97..a7eee40d 100644 --- a/src/libfuturize/fixes/fix_metaclass.py +++ b/src/libfuturize/fixes/fix_metaclass.py @@ -37,7 +37,7 @@ def has_metaclass(parent): """ we have to check the cls_node without changing it. - There are two possiblities: + There are two possibilities: 1) clsdef => suite => simple_stmt => expr_stmt => Leaf('__meta') 2) clsdef => simple_stmt => expr_stmt => Leaf('__meta') """ @@ -63,7 +63,7 @@ def fixup_parse_tree(cls_node): # already in the preferred format, do nothing return - # !%@#! oneliners have no suite node, we have to fake one up + # !%@#! one-liners have no suite node, we have to fake one up for i, node in enumerate(cls_node.children): if node.type == token.COLON: break diff --git a/tests/test_future/test_http_cookiejar.py b/tests/test_future/test_http_cookiejar.py index 079026bc..8a98ed68 100644 --- a/tests/test_future/test_http_cookiejar.py +++ b/tests/test_future/test_http_cookiejar.py @@ -380,7 +380,7 @@ class CookieTests(unittest.TestCase): ## comma-separated list, it'll be a headache to parse (at least my head ## starts hurting every time I think of that code). ## - Expires: You'll get all sorts of date formats in the expires, -## including emtpy expires attributes ("expires="). Be as flexible as you +## including empty expires attributes ("expires="). Be as flexible as you ## can, and certainly don't expect the weekday to be there; if you can't ## parse it, just ignore it and pretend it's a session cookie. ## - Domain-matching: Netscape uses the 2-dot rule for _all_ domains, not @@ -1734,7 +1734,7 @@ def test_session_cookies(self): key = "%s_after" % cookie.value counter[key] = counter[key] + 1 - # a permanent cookie got lost accidently + # a permanent cookie got lost accidentally self.assertEqual(counter["perm_after"], counter["perm_before"]) # a session cookie hasn't been cleared self.assertEqual(counter["session_after"], 0) diff --git a/tests/test_future/test_standard_library.py b/tests/test_future/test_standard_library.py index 3ac5d2d7..44c61a9b 100644 --- a/tests/test_future/test_standard_library.py +++ b/tests/test_future/test_standard_library.py @@ -591,7 +591,7 @@ def test_future_moves_dbm(self): from future.moves.dbm import ndbm -# Running the following tkinter test causes the following bizzare test failure: +# Running the following tkinter test causes the following bizarre test failure: # # ====================================================================== # FAIL: test_open_default_encoding (future.tests.test_builtins.BuiltinTest) diff --git a/tests/test_future/test_urllib.py b/tests/test_future/test_urllib.py index 278bafb5..64e89760 100644 --- a/tests/test_future/test_urllib.py +++ b/tests/test_future/test_urllib.py @@ -1,4 +1,4 @@ -"""Regresssion tests for urllib""" +"""Regression tests for urllib""" from __future__ import absolute_import, division, unicode_literals import io @@ -1229,7 +1229,7 @@ def open_spam(self, url): # Everywhere else they work ok, but on those machines, sometimes # fail in one of the tests, sometimes in other. I have a linux, and # the tests go ok. -# If anybody has one of the problematic enviroments, please help! +# If anybody has one of the problematic environments, please help! # . Facundo # # def server(evt): diff --git a/tests/test_future/test_urllib_toplevel.py b/tests/test_future/test_urllib_toplevel.py index 11e77201..86c75619 100644 --- a/tests/test_future/test_urllib_toplevel.py +++ b/tests/test_future/test_urllib_toplevel.py @@ -1,4 +1,4 @@ -"""Regresssion tests for urllib""" +"""Regression tests for urllib""" from __future__ import absolute_import, division, unicode_literals import io @@ -1244,7 +1244,7 @@ def open_spam(self, url): # Everywhere else they work ok, but on those machines, sometimes # fail in one of the tests, sometimes in other. I have a linux, and # the tests go ok. -# If anybody has one of the problematic enviroments, please help! +# If anybody has one of the problematic environments, please help! # . Facundo # # def server(evt): From 4cafc9d860d19135f5edb6e9d35ddf9f11b6d989 Mon Sep 17 00:00:00 2001 From: Linux User Date: Sun, 27 Feb 2022 05:30:15 +0000 Subject: [PATCH 39/59] modified fix_unpacking.py to support both the python2 unicode function and use the str function instead on python3 --- src/libpasteurize/fixes/fix_unpacking.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libpasteurize/fixes/fix_unpacking.py b/src/libpasteurize/fixes/fix_unpacking.py index c2d3207a..e47efe0e 100644 --- a/src/libpasteurize/fixes/fix_unpacking.py +++ b/src/libpasteurize/fixes/fix_unpacking.py @@ -18,8 +18,14 @@ def assignment_source(num_pre, num_post, LISTNAME, ITERNAME): Returns a source fit for Assign() from fixer_util """ children = [] - pre = unicode(num_pre) - post = unicode(num_post) + try: + pre = unicode(num_pre) + except NameError: + pre = str(num_pre) + try: + post = unicode(num_post) + except NameError: + post = str(num_post) # This code builds the assignment source from lib2to3 tree primitives. # It's not very readable, but it seems like the most correct way to do it. if num_pre > 0: From 8e5ea186d385dbdc89b16cd81f58754ac05ad0a0 Mon Sep 17 00:00:00 2001 From: Linux User Date: Sun, 27 Feb 2022 06:42:43 +0000 Subject: [PATCH 40/59] condensed/refactored fix_unpacking.py change --- src/libpasteurize/fixes/fix_unpacking.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libpasteurize/fixes/fix_unpacking.py b/src/libpasteurize/fixes/fix_unpacking.py index e47efe0e..6e839e6b 100644 --- a/src/libpasteurize/fixes/fix_unpacking.py +++ b/src/libpasteurize/fixes/fix_unpacking.py @@ -20,11 +20,9 @@ def assignment_source(num_pre, num_post, LISTNAME, ITERNAME): children = [] try: pre = unicode(num_pre) - except NameError: - pre = str(num_pre) - try: post = unicode(num_post) except NameError: + pre = str(num_pre) post = str(num_post) # This code builds the assignment source from lib2to3 tree primitives. # It's not very readable, but it seems like the most correct way to do it. From 33977e4c10cd68cce2ab262a73d565173d06c0a6 Mon Sep 17 00:00:00 2001 From: Andrii Oriekhov Date: Mon, 28 Feb 2022 15:04:59 +0200 Subject: [PATCH 41/59] add GitHub URL for PyPi --- setup.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.py b/setup.py index 11d694c2..41b0df96 100755 --- a/setup.py +++ b/setup.py @@ -161,6 +161,9 @@ author=AUTHOR, author_email=AUTHOR_EMAIL, url=URL, + project_urls={ + 'Source': 'https://github.com/PythonCharmers/python-future', + }, description=DESCRIPTION, long_description=LONG_DESC, license=LICENSE, From f1100c8b9eda51e7c242d6153b04946517080f3c Mon Sep 17 00:00:00 2001 From: matthew Date: Fri, 18 Mar 2022 09:31:05 -0700 Subject: [PATCH 42/59] future cannot install without setuptools Signed-off-by: matthew --- docs/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/requirements.txt b/docs/requirements.txt index c5e7e301..0f06b13f 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,2 +1,3 @@ sphinx==3.2.1 sphinx_bootstrap_theme==0.7.1 +setuptools==0.18.2 From c91d70b34ef0402aef3e9d04364ba98509dca76f Mon Sep 17 00:00:00 2001 From: Will Shanks Date: Fri, 23 Dec 2022 13:38:26 -0500 Subject: [PATCH 43/59] Backport fix for bpo-38804 The regex http.cookiejar.LOOSE_HTTP_DATE_RE was vulnerable to regular expression denial of service (REDoS). The regex contained multiple overlapping \s* capture groups. A long sequence of spaces can trigger bad performance. See https://github.com/python/cpython/pull/17157 and https://pyup.io/posts/pyup-discovers-redos-vulnerabilities-in-top-python-packages/ --- src/future/backports/http/cookiejar.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/future/backports/http/cookiejar.py b/src/future/backports/http/cookiejar.py index af3ef415..0ad80a02 100644 --- a/src/future/backports/http/cookiejar.py +++ b/src/future/backports/http/cookiejar.py @@ -225,10 +225,14 @@ def _str2time(day, mon, yr, hr, min, sec, tz): (?::(\d\d))? # optional seconds )? # optional clock \s* - ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+)? # timezone + (?: + ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+) # timezone + \s* + )? + (?: + \(\w+\) # ASCII representation of timezone in parens. \s* - (?:\(\w+\))? # ASCII representation of timezone in parens. - \s*$""", re.X | re.ASCII) + )?$""", re.X | re.ASCII) def http2time(text): """Returns time in seconds since epoch of time represented by a string. @@ -298,9 +302,11 @@ def http2time(text): (?::?(\d\d(?:\.\d*)?))? # optional seconds (and fractional) )? # optional clock \s* - ([-+]?\d\d?:?(:?\d\d)? - |Z|z)? # timezone (Z is "zero meridian", i.e. GMT) - \s*$""", re.X | re. ASCII) + (?: + ([-+]?\d\d?:?(:?\d\d)? + |Z|z) # timezone (Z is "zero meridian", i.e. GMT) + \s* + )?$""", re.X | re. ASCII) def iso2time(text): """ As for http2time, but parses the ISO 8601 formats: From 079ee9b75441d36447cec9981fa1b0032862f64d Mon Sep 17 00:00:00 2001 From: Liuyang Wan Date: Fri, 13 Jan 2023 11:11:30 +0800 Subject: [PATCH 44/59] Prepare for 0.18.3 release --- Dockerfile | 5 ++-- build.sh | 2 +- docs/whatsnew.rst | 56 ++++++++++++++++++++++++++++++++++++++++++ src/future/__init__.py | 2 +- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6b94c0a8..678de2e2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,8 +11,9 @@ RUN echo 'eval "$(pyenv init -)"' >> ~/.bashrc RUN echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc # venv 15.2.0 is the last to support Python 2.6. RUN pip3 install virtualenv==15.2.0 -RUN PATH=/opt/pyenv/bin:$PATH pyenv install 2.6.9 -RUN virtualenv /root/py26 --python /opt/pyenv/versions/2.6.9/bin/python +# Can't get python 2.6 to build anymore +# RUN PATH=/opt/pyenv/bin:$PATH pyenv install 2.6.9 +# RUN virtualenv /root/py26 --python /opt/pyenv/versions/2.6.9/bin/python RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.3.7 RUN virtualenv /root/py33 --python /opt/pyenv/versions/3.3.7/bin/python RUN pip3 install virtualenv==20.0.21 diff --git a/build.sh b/build.sh index d17fa7ce..df1f00f7 100755 --- a/build.sh +++ b/build.sh @@ -3,7 +3,7 @@ set -xuo pipefail DOCKER_IMAGE=jmadler/python-future-builder # XXX: TODO: Perhaps this version shouldn't be hardcoded -version=0.18.2 +version=0.18.3 docker build . -t $DOCKER_IMAGE docker push $DOCKER_IMAGE:latest diff --git a/docs/whatsnew.rst b/docs/whatsnew.rst index c6fa8f86..40f7191f 100644 --- a/docs/whatsnew.rst +++ b/docs/whatsnew.rst @@ -3,6 +3,62 @@ What's New ********** +What's new in version 0.18.3 (2023-01-13) +========================================= +This is a minor bug-fix release containing a number of fixes: + +- Backport fix for bpo-38804 (c91d70b) +- Fix bug in fix_print.py fixer (dffc579) +- Fix bug in fix_raise.py fixer (3401099) +- Fix newint bool in py3 (fe645ba) +- Fix bug in super() with metaclasses (6e27aac) +- docs: fix simple typo, reqest -> request (974eb1f) +- Correct __eq__ (c780bf5) +- Pass if lint fails (2abe00d) +- Update docker image and parcel out to constant variable. Add comment to update version constant (45cf382) +- fix order (f96a219) +- Add flake8 to image (046ff18) +- Make lint.sh executable (58cc984) +- Add docker push to optimize CI (01e8440) +- Build System (42b3025) +- Add docs build status badge to README.md (3f40bd7) +- Use same docs requirements in tox (18ecc5a) +- Add docs/requirements.txt (5f9893f) +- Add PY37_PLUS, PY38_PLUS, and PY39_PLUS (bee0247) +- fix 2.6 test, better comment (ddedcb9) +- fix 2.6 test (3f1ff7e) +- remove nan test (4dbded1) +- include list test values (e3f1a12) +- fix other python2 test issues (c051026) +- fix missing subTest (f006cad) +- import from old imp library on older python versions (fc84fa8) +- replace fstrings with format for python 3.4,3.5 (4a687ea) +- minor style/spelling fixes (8302d8c) +- improve cmp function, add unittest (0d95a40) +- Pin typing==3.7.4.1 for Python 3.3 compatiblity (1a48f1b) +- Fix various py26 unit test failures (9ca5a14) +- Add initial contributing guide with docs build instruction (e55f915) +- Add docs building to tox.ini (3ee9e7f) +- Support NumPy's specialized int types in builtins.round (b4b54f0) +- Added r""" to the docstring to avoid warnings in python3 (5f94572) +- Add __subclasscheck__ for past.types.basestring (c9bc0ff) +- Correct example in README (681e78c) +- Add simple documentation (6c6e3ae) +- Add pre-commit hooks (a9c6a37) +- Handling of __next__ and next by future.utils.get_next was reversed (52b0ff9) +- Add a test for our fix (461d77e) +- Compare headers to correct definition of str (3eaa8fd) +- #322 Add support for negative ndigits in round; additionally, fixing a bug so that it handles passing in Decimal properly (a4911b9) +- Add tkFileDialog to future.movers.tkinter (f6a6549) +- Sort before comparing dicts in TestChainMap (6126997) +- Fix typo (4dfa099) +- Fix formatting in "What's new" (1663dfa) +- Fix typo (4236061) +- Avoid DeprecationWarning caused by invalid escape (e4b7fa1) +- Fixup broken link to external django documentation re: porting to Python 3 and unicode_literals (d87713e) +- Fixed newdict checking version every time (99030ec) +- Add count from 2.7 to 2.6 (1b8ef51) + What's new in version 0.18.2 (2019-10-30) ========================================= This is a minor bug-fix release containing a number of fixes: diff --git a/src/future/__init__.py b/src/future/__init__.py index ad419d67..b609299a 100644 --- a/src/future/__init__.py +++ b/src/future/__init__.py @@ -87,7 +87,7 @@ __copyright__ = 'Copyright 2013-2019 Python Charmers Pty Ltd' __ver_major__ = 0 __ver_minor__ = 18 -__ver_patch__ = 2 +__ver_patch__ = 3 __ver_sub__ = '' __version__ = "%d.%d.%d%s" % (__ver_major__, __ver_minor__, __ver_patch__, __ver_sub__) From a914e33e9f48a77356006cd54e538d9d36ba8629 Mon Sep 17 00:00:00 2001 From: slycordinator <68940237+slycordinator@users.noreply.github.com> Date: Thu, 23 Feb 2023 16:13:34 +0900 Subject: [PATCH 45/59] Fixes according to output from shellcheck * Added "!#" to top of files that didn't have it. * Added quotes around variables/commands as recommended * Changed some to be /bin/sh instead of /bin/bash for portability * removed -o pipefail, especiallly because the scripts seem to not have any piped commands, but also due to it being a bashism --- build.sh | 9 +++++---- lint.sh | 1 + setup.sh | 14 +++++++------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/build.sh b/build.sh index df1f00f7..71e1cdec 100755 --- a/build.sh +++ b/build.sh @@ -1,15 +1,16 @@ +#!/bin/sh # XXX: TODO: we should make this include -e once tests pass -set -xuo pipefail +set -xu DOCKER_IMAGE=jmadler/python-future-builder # XXX: TODO: Perhaps this version shouldn't be hardcoded version=0.18.3 -docker build . -t $DOCKER_IMAGE -docker push $DOCKER_IMAGE:latest +docker build . -t "$DOCKER_IMAGE" +docker push "$DOCKER_IMAGE:latest" for i in py26 py27 py33 py34 py35 py36 py37 py38 py39; do - docker run -ti -v $(realpath dist):/root/python-future/dist $DOCKER_IMAGE /root/python-future/setup.sh $version $(basename $i) + docker run -ti -v "$(realpath dist)":/root/python-future/dist "$DOCKER_IMAGE" /root/python-future/setup.sh "$version" "$i" done python setup.py sdist diff --git a/lint.sh b/lint.sh index 667b258f..b3c41cd4 100755 --- a/lint.sh +++ b/lint.sh @@ -1,3 +1,4 @@ +#!/bin/sh # TODO: Run under Python 2.7 and 3.7 flake8 . --count --exit-zero --select=E901,E999,F821,F822,F823 --show-source --statistics || true flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics || true diff --git a/setup.sh b/setup.sh index 8e8dc150..767cbd55 100755 --- a/setup.sh +++ b/setup.sh @@ -1,20 +1,20 @@ -#!/bin/bash +#!/bin/sh -set -exo pipefail +set -ex version=$1 pytag=$2 -if [ $pytag = 'py33' ]; then +if [ "$pytag" = 'py33' ]; then pip3 install virtualenv==16.2.0 fi -source /root/$pytag/bin/activate +. /root/"$pytag"/bin/activate -if [ $pytag = 'py26' ]; then +if [ "$pytag" = 'py26' ]; then pip install importlib fi pip install pytest unittest2 -python setup.py bdist_wheel --python-tag=$pytag -pip install dist/future-$version-$pytag-none-any.whl +python setup.py bdist_wheel --python-tag="$pytag" +pip install "dist/future-$version-$pytag-none-any.whl" pytest tests/ From 61f6cf1d999dddc8e1b1dddbbf53e929b0df1cdb Mon Sep 17 00:00:00 2001 From: lilinjie Date: Mon, 3 Apr 2023 10:36:37 +0800 Subject: [PATCH 46/59] fix typo Signed-off-by: lilinjie --- src/future/backports/http/cookiejar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/future/backports/http/cookiejar.py b/src/future/backports/http/cookiejar.py index 0ad80a02..a39242c0 100644 --- a/src/future/backports/http/cookiejar.py +++ b/src/future/backports/http/cookiejar.py @@ -1851,7 +1851,7 @@ def lwp_cookie_str(cookie): class LWPCookieJar(FileCookieJar): """ The LWPCookieJar saves a sequence of "Set-Cookie3" lines. - "Set-Cookie3" is the format used by the libwww-perl libary, not known + "Set-Cookie3" is the format used by the libwww-perl library, not known to be compatible with any browser, but which is easy to read and doesn't lose information about RFC 2965 cookies. From a6135542dffb6b1b8254d6daac779d119d4fc08c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Wed, 17 May 2023 14:03:26 +0200 Subject: [PATCH 47/59] Adjust tests to the repr changes in CPython --- tests/test_future/test_backports.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/test_future/test_backports.py b/tests/test_future/test_backports.py index 63b1afea..5d46b115 100644 --- a/tests/test_future/test_backports.py +++ b/tests/test_future/test_backports.py @@ -599,8 +599,12 @@ def test_yaml_linkage(self): def test_repr(self): od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]) - self.assertEqual(repr(od), - "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])") + if sys.version_info[0] == 3 and sys.version_info[1] >= 12: + self.assertEqual(repr(od), + "OrderedDict({'c': 1, 'b': 2, 'a': 3, 'd': 4, 'e': 5, 'f': 6})") + else: + self.assertEqual(repr(od), + "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])") self.assertEqual(eval(repr(od)), od) self.assertEqual(repr(OrderedDict()), "OrderedDict()") @@ -608,8 +612,12 @@ def test_repr_recursive(self): # See issue #9826 od = OrderedDict.fromkeys('abc') od['x'] = od - self.assertEqual(repr(od), - "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])") + if sys.version_info[0] == 3 and sys.version_info[1] >= 12: + self.assertEqual(repr(od), + "OrderedDict({'a': None, 'b': None, 'c': None, 'x': ...})") + else: + self.assertEqual(repr(od), + "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])") def test_setdefault(self): pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] From d7dc44e88b77fea57b9001421428cd7d95abb3bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Wed, 17 May 2023 14:42:09 +0200 Subject: [PATCH 48/59] Adjust test to the change in CPython, parser now raises SyntaxError instead of ValueError when source code contains null bytes --- tests/test_future/test_builtins.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_future/test_builtins.py b/tests/test_future/test_builtins.py index 3921a608..d41d1254 100644 --- a/tests/test_future/test_builtins.py +++ b/tests/test_future/test_builtins.py @@ -523,8 +523,8 @@ def test_compile(self): self.assertRaises(TypeError, compile) self.assertRaises(ValueError, compile, 'print(42)\n', '', 'badmode') self.assertRaises(ValueError, compile, 'print(42)\n', '', 'single', 0xff) - # Raises TypeError in Python < v3.5, ValueError in v3.5: - self.assertRaises((TypeError, ValueError), compile, chr(0), 'f', 'exec') + # Raises TypeError in Python < v3.5, ValueError in v3.5, SyntaxError in >= 3.12: + self.assertRaises((TypeError, ValueError, SyntaxError), compile, chr(0), 'f', 'exec') self.assertRaises(TypeError, compile, 'pass', '?', 'exec', mode='eval', source='0', filename='tmp') compile('print("\xe5")\n', '', 'exec') From 331d5fb105a70bce1e2c415218fbaf5a002b1f9a Mon Sep 17 00:00:00 2001 From: Gabriela Gutierrez Date: Mon, 5 Jun 2023 15:04:38 -0300 Subject: [PATCH 49/59] Create SECURITY.md Signed-off-by: Gabriela Gutierrez --- .github/SECURITY.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/SECURITY.md diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 00000000..e4f0e0b3 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,13 @@ +# Security Policy + +## Supported Versions + +Security updates are applied only to the latest release. + +## Reporting a Vulnerability + +If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released. + +Please disclose it at [security advisory](https://github.com/PythonCharmers/python-future/security/advisories/new). + +This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure. From 36ad5ba6df8c3e71b30c66d707e156b67c785eb5 Mon Sep 17 00:00:00 2001 From: Greg Roodt Date: Sun, 13 Aug 2023 14:47:27 +1000 Subject: [PATCH 50/59] Clarify how distributions are built and uploaded --- Dockerfile | 40 +--------------------------------------- build.sh | 4 ++-- setup.py | 5 ----- setup.sh | 25 ++++++++++--------------- 4 files changed, 13 insertions(+), 61 deletions(-) diff --git a/Dockerfile b/Dockerfile index 678de2e2..cf9ffd3c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,41 +1,3 @@ -FROM debian:9 -# This docker image has a copy of a wide array of Pythons installed -RUN apt-get update -RUN apt-get install --yes --no-install-recommends make build-essential zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libffi-dev liblzma-dev libssl1.0-dev -RUN apt-get install --yes git vim -RUN apt-get install --yes python3-pip -ENV PYENV_ROOT=/opt/pyenv -RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash -RUN echo export PATH="/opt/pyenv/bin:$PATH" >> ~/.bashrc -RUN echo 'eval "$(pyenv init -)"' >> ~/.bashrc -RUN echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc -# venv 15.2.0 is the last to support Python 2.6. -RUN pip3 install virtualenv==15.2.0 -# Can't get python 2.6 to build anymore -# RUN PATH=/opt/pyenv/bin:$PATH pyenv install 2.6.9 -# RUN virtualenv /root/py26 --python /opt/pyenv/versions/2.6.9/bin/python -RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.3.7 -RUN virtualenv /root/py33 --python /opt/pyenv/versions/3.3.7/bin/python -RUN pip3 install virtualenv==20.0.21 -RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.4.10 -RUN virtualenv /root/py34 --python /opt/pyenv/versions/3.4.10/bin/python -RUN apt-get install --yes libssl-dev libxmlsec1-dev -RUN PATH=/opt/pyenv/bin:$PATH pyenv install 2.7.18 -RUN virtualenv /root/py27 --python /opt/pyenv/versions/2.7.18/bin/python -RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.5.9 -RUN virtualenv /root/py35 --python /opt/pyenv/versions/3.5.9/bin/python -RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.6.10 -RUN virtualenv /root/py36 --python /opt/pyenv/versions/3.6.10/bin/python -RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.7.7 -RUN virtualenv /root/py37 --python /opt/pyenv/versions/3.7.7/bin/python -RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.8.3 -RUN virtualenv /root/py38 --python /opt/pyenv/versions/3.8.3/bin/python -RUN PATH=/opt/pyenv/bin:$PATH pyenv install 3.9.0 -RUN virtualenv /root/py39 --python /opt/pyenv/versions/3.9.0/bin/python -# Lint tools -RUN pip3 install flake8 -RUN ln -s /usr/bin/python3 /usr/bin/python -ENV LC_ALL=C.UTF-8 -ENV LANG=C.UTF-8 +FROM quay.io/pypa/manylinux1_x86_64 WORKDIR /root/python-future ADD . /root/python-future diff --git a/build.sh b/build.sh index df1f00f7..15dac763 100755 --- a/build.sh +++ b/build.sh @@ -6,9 +6,9 @@ DOCKER_IMAGE=jmadler/python-future-builder version=0.18.3 docker build . -t $DOCKER_IMAGE -docker push $DOCKER_IMAGE:latest +#docker push $DOCKER_IMAGE:latest -for i in py26 py27 py33 py34 py35 py36 py37 py38 py39; do +for i in cp27-cp27m cp35-cp35m cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39; do docker run -ti -v $(realpath dist):/root/python-future/dist $DOCKER_IMAGE /root/python-future/setup.sh $version $(basename $i) done diff --git a/setup.py b/setup.py index 41b0df96..eef5d230 100755 --- a/setup.py +++ b/setup.py @@ -13,11 +13,6 @@ from distutils.core import setup -if sys.argv[-1] == 'publish': - os.system('python setup.py sdist upload') - sys.exit() - - NAME = "future" PACKAGES = ["future", "future.builtins", diff --git a/setup.sh b/setup.sh index 8e8dc150..047dd953 100755 --- a/setup.sh +++ b/setup.sh @@ -3,18 +3,13 @@ set -exo pipefail version=$1 -pytag=$2 - -if [ $pytag = 'py33' ]; then - pip3 install virtualenv==16.2.0 -fi - -source /root/$pytag/bin/activate - -if [ $pytag = 'py26' ]; then - pip install importlib -fi -pip install pytest unittest2 -python setup.py bdist_wheel --python-tag=$pytag -pip install dist/future-$version-$pytag-none-any.whl -pytest tests/ +pyabitag=$2 + +py="/opt/python/${pyabitag}/bin/python" +pytag=${pyabitag%-*} +pytag="${pytag//cp/py}" +$py -m pip install pytest unittest2 +$py setup.py bdist_wheel --python-tag=$pytag +$py -m pip install dist/future-$version-$pytag-none-any.whl +# Ignore test failures for now +$py -m pytest tests/ || true From 1901c1c347bcad603e8404b64656994eb2cc0439 Mon Sep 17 00:00:00 2001 From: David Bern Date: Tue, 10 Oct 2023 22:13:54 -0500 Subject: [PATCH 51/59] WIP Python 3.12 support for removal of imp module --- build.sh | 2 +- docs/whatsnew.rst | 6 ++++++ src/future/__init__.py | 2 +- src/future/backports/test/support.py | 11 +++++++---- src/future/standard_library/__init__.py | 12 +++++++++--- src/past/translation/__init__.py | 5 ++++- tests/test_future/test_standard_library.py | 11 ++++++++--- 7 files changed, 36 insertions(+), 13 deletions(-) diff --git a/build.sh b/build.sh index df1f00f7..ef52cb41 100755 --- a/build.sh +++ b/build.sh @@ -3,7 +3,7 @@ set -xuo pipefail DOCKER_IMAGE=jmadler/python-future-builder # XXX: TODO: Perhaps this version shouldn't be hardcoded -version=0.18.3 +version=0.18.4 docker build . -t $DOCKER_IMAGE docker push $DOCKER_IMAGE:latest diff --git a/docs/whatsnew.rst b/docs/whatsnew.rst index 40f7191f..9018fdfe 100644 --- a/docs/whatsnew.rst +++ b/docs/whatsnew.rst @@ -3,6 +3,12 @@ What's New ********** +What's new in version 0.18.4 (2023-10-10) +========================================= +This is a minor bug-fix release containing a number of fixes: + +- Fix for Python 3.12's removal of the imp module + What's new in version 0.18.3 (2023-01-13) ========================================= This is a minor bug-fix release containing a number of fixes: diff --git a/src/future/__init__.py b/src/future/__init__.py index b609299a..64b66f43 100644 --- a/src/future/__init__.py +++ b/src/future/__init__.py @@ -87,7 +87,7 @@ __copyright__ = 'Copyright 2013-2019 Python Charmers Pty Ltd' __ver_major__ = 0 __ver_minor__ = 18 -__ver_patch__ = 3 +__ver_patch__ = 4 __ver_sub__ = '' __version__ = "%d.%d.%d%s" % (__ver_major__, __ver_minor__, __ver_patch__, __ver_sub__) diff --git a/src/future/backports/test/support.py b/src/future/backports/test/support.py index 1999e208..08b59829 100644 --- a/src/future/backports/test/support.py +++ b/src/future/backports/test/support.py @@ -28,7 +28,10 @@ # import collections.abc # not present on Py2.7 import re import subprocess -import imp +try: + from imp import cache_from_source +except ImportError: + from importlib.util import cache_from_source import time try: import sysconfig @@ -351,7 +354,7 @@ def make_legacy_pyc(source): does not need to exist, however the PEP 3147 pyc file must exist. :return: The file system path to the legacy pyc file. """ - pyc_file = imp.cache_from_source(source) + pyc_file = cache_from_source(source) up_one = os.path.dirname(os.path.abspath(source)) legacy_pyc = os.path.join(up_one, source + ('c' if __debug__ else 'o')) os.rename(pyc_file, legacy_pyc) @@ -370,8 +373,8 @@ def forget(modname): # combinations of PEP 3147 and legacy pyc and pyo files. unlink(source + 'c') unlink(source + 'o') - unlink(imp.cache_from_source(source, debug_override=True)) - unlink(imp.cache_from_source(source, debug_override=False)) + unlink(cache_from_source(source, debug_override=True)) + unlink(cache_from_source(source, debug_override=False)) # On some platforms, should not run gui test even if it is allowed # in `use_resources'. diff --git a/src/future/standard_library/__init__.py b/src/future/standard_library/__init__.py index cff02f95..24d9287f 100644 --- a/src/future/standard_library/__init__.py +++ b/src/future/standard_library/__init__.py @@ -62,7 +62,10 @@ import sys import logging -import imp +try: + import importlib +except ImportError: + import imp import contextlib import types import copy @@ -297,8 +300,11 @@ def _find_and_load_module(self, name, path=None): flog.debug('What to do here?') name = bits[0] - module_info = imp.find_module(name, path) - return imp.load_module(name, *module_info) + try: + module_info = imp.find_module(name, path) + return imp.load_module(name, *module_info) + except AttributeError: + return importlib.import_module(name, path) class hooks(object): diff --git a/src/past/translation/__init__.py b/src/past/translation/__init__.py index 7c678866..6e6ccf74 100644 --- a/src/past/translation/__init__.py +++ b/src/past/translation/__init__.py @@ -32,7 +32,10 @@ Inspired by and based on ``uprefix`` by Vinay M. Sajip. """ -import imp +try: + import imp +except ImportError: + import importlib import logging import marshal import os diff --git a/tests/test_future/test_standard_library.py b/tests/test_future/test_standard_library.py index 3ac5d2d7..f3477210 100644 --- a/tests/test_future/test_standard_library.py +++ b/tests/test_future/test_standard_library.py @@ -447,9 +447,14 @@ def test_reload(self): """ reload has been moved to the imp module """ - import imp - imp.reload(imp) - self.assertTrue(True) + try: + import imp + imp.reload(imp) + self.assertTrue(True) + except ImportError: + import importlib + importlib.reload(importlib) + self.assertTrue(True) def test_install_aliases(self): """ From 4fcbe2e873100e1fdc064edd23f8501f65c4eae8 Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Fri, 19 Jan 2024 15:09:45 +0000 Subject: [PATCH 52/59] Use importlib instead of imp for Python 3.12 support Also remove some unused imports. --- src/future/backports/test/support.py | 35 --- src/future/standard_library/__init__.py | 15 +- src/past/translation/__init__.py | 254 +++++++++------------ tests/test_future/test_standard_library.py | 11 +- tests/test_past/test_builtins.py | 1 - tests/test_past/test_translation.py | 20 +- 6 files changed, 126 insertions(+), 210 deletions(-) diff --git a/src/future/backports/test/support.py b/src/future/backports/test/support.py index 08b59829..6639372b 100644 --- a/src/future/backports/test/support.py +++ b/src/future/backports/test/support.py @@ -28,10 +28,6 @@ # import collections.abc # not present on Py2.7 import re import subprocess -try: - from imp import cache_from_source -except ImportError: - from importlib.util import cache_from_source import time try: import sysconfig @@ -344,37 +340,6 @@ def rmtree(path): if error.errno != errno.ENOENT: raise -def make_legacy_pyc(source): - """Move a PEP 3147 pyc/pyo file to its legacy pyc/pyo location. - - The choice of .pyc or .pyo extension is done based on the __debug__ flag - value. - - :param source: The file system path to the source file. The source file - does not need to exist, however the PEP 3147 pyc file must exist. - :return: The file system path to the legacy pyc file. - """ - pyc_file = cache_from_source(source) - up_one = os.path.dirname(os.path.abspath(source)) - legacy_pyc = os.path.join(up_one, source + ('c' if __debug__ else 'o')) - os.rename(pyc_file, legacy_pyc) - return legacy_pyc - -def forget(modname): - """'Forget' a module was ever imported. - - This removes the module from sys.modules and deletes any PEP 3147 or - legacy .pyc and .pyo files. - """ - unload(modname) - for dirname in sys.path: - source = os.path.join(dirname, modname + '.py') - # It doesn't matter if they exist or not, unlink all possible - # combinations of PEP 3147 and legacy pyc and pyo files. - unlink(source + 'c') - unlink(source + 'o') - unlink(cache_from_source(source, debug_override=True)) - unlink(cache_from_source(source, debug_override=False)) # On some platforms, should not run gui test even if it is allowed # in `use_resources'. diff --git a/src/future/standard_library/__init__.py b/src/future/standard_library/__init__.py index 24d9287f..2cee75db 100644 --- a/src/future/standard_library/__init__.py +++ b/src/future/standard_library/__init__.py @@ -62,12 +62,7 @@ import sys import logging -try: - import importlib -except ImportError: - import imp import contextlib -import types import copy import os @@ -82,6 +77,9 @@ from future.utils import PY2, PY3 +if PY2: + import imp + # The modules that are defined under the same names on Py3 but with # different contents in a significant way (e.g. submodules) are: # pickle (fast one) @@ -300,11 +298,8 @@ def _find_and_load_module(self, name, path=None): flog.debug('What to do here?') name = bits[0] - try: - module_info = imp.find_module(name, path) - return imp.load_module(name, *module_info) - except AttributeError: - return importlib.import_module(name, path) + module_info = imp.find_module(name, path) + return imp.load_module(name, *module_info) class hooks(object): diff --git a/src/past/translation/__init__.py b/src/past/translation/__init__.py index 6e6ccf74..db96982b 100644 --- a/src/past/translation/__init__.py +++ b/src/past/translation/__init__.py @@ -32,12 +32,7 @@ Inspired by and based on ``uprefix`` by Vinay M. Sajip. """ -try: - import imp -except ImportError: - import importlib import logging -import marshal import os import sys import copy @@ -46,6 +41,17 @@ from libfuturize import fixes +try: + from importlib.machinery import ( + PathFinder, + SourceFileLoader, + ) +except ImportError: + PathFinder = None + SourceFileLoader = object + +if sys.version_info[:2] < (3, 4): + import imp logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) @@ -228,6 +234,81 @@ def detect_python2(source, pathname): return False +def transform(source, pathname): + # This implementation uses lib2to3, + # you can override and use something else + # if that's better for you + + # lib2to3 likes a newline at the end + RTs.setup() + source += '\n' + try: + tree = RTs._rt.refactor_string(source, pathname) + except ParseError as e: + if e.msg != 'bad input' or e.value != '=': + raise + tree = RTs._rtp.refactor_string(source, pathname) + # could optimise a bit for only doing str(tree) if + # getattr(tree, 'was_changed', False) returns True + return str(tree)[:-1] # remove added newline + + +class PastSourceFileLoader(SourceFileLoader): + exclude_paths = [] + include_paths = [] + + def _convert_needed(self): + fullname = self.name + if any(fullname.startswith(path) for path in self.exclude_paths): + convert = False + elif any(fullname.startswith(path) for path in self.include_paths): + convert = True + else: + convert = False + return convert + + def _exec_transformed_module(self, module): + source = self.get_source(self.name) + pathname = self.path + if detect_python2(source, pathname): + source = transform(source, pathname) + code = compile(source, pathname, "exec") + exec(code, module.__dict__) + + # For Python 3.3 + def load_module(self, fullname): + logger.debug("Running load_module for %s", fullname) + if fullname in sys.modules: + mod = sys.modules[fullname] + else: + if self._convert_needed(): + logger.debug("Autoconverting %s", fullname) + mod = imp.new_module(fullname) + sys.modules[fullname] = mod + + # required by PEP 302 + mod.__file__ = self.path + mod.__loader__ = self + if self.is_package(fullname): + mod.__path__ = [] + mod.__package__ = fullname + else: + mod.__package__ = fullname.rpartition('.')[0] + self._exec_transformed_module(mod) + else: + mod = super().load_module(fullname) + return mod + + # For Python >=3.4 + def exec_module(self, module): + logger.debug("Running exec_module for %s", module) + if self._convert_needed(): + logger.debug("Autoconverting %s", self.name) + self._exec_transformed_module(module) + else: + super().exec_module(module) + + class Py2Fixer(object): """ An import hook class that uses lib2to3 for source-to-source translation of @@ -261,151 +342,30 @@ def exclude(self, paths): """ self.exclude_paths += paths + # For Python 3.3 def find_module(self, fullname, path=None): - logger.debug('Running find_module: {0}...'.format(fullname)) - if '.' in fullname: - parent, child = fullname.rsplit('.', 1) - if path is None: - loader = self.find_module(parent, path) - mod = loader.load_module(parent) - path = mod.__path__ - fullname = child - - # Perhaps we should try using the new importlib functionality in Python - # 3.3: something like this? - # thing = importlib.machinery.PathFinder.find_module(fullname, path) - try: - self.found = imp.find_module(fullname, path) - except Exception as e: - logger.debug('Py2Fixer could not find {0}') - logger.debug('Exception was: {0})'.format(fullname, e)) + logger.debug("Running find_module: (%s, %s)", fullname, path) + loader = PathFinder.find_module(fullname, path) + if not loader: + logger.debug("Py2Fixer could not find %s", fullname) return None - self.kind = self.found[-1][-1] - if self.kind == imp.PKG_DIRECTORY: - self.pathname = os.path.join(self.found[1], '__init__.py') - elif self.kind == imp.PY_SOURCE: - self.pathname = self.found[1] - return self - - def transform(self, source): - # This implementation uses lib2to3, - # you can override and use something else - # if that's better for you - - # lib2to3 likes a newline at the end - RTs.setup() - source += '\n' - try: - tree = RTs._rt.refactor_string(source, self.pathname) - except ParseError as e: - if e.msg != 'bad input' or e.value != '=': - raise - tree = RTs._rtp.refactor_string(source, self.pathname) - # could optimise a bit for only doing str(tree) if - # getattr(tree, 'was_changed', False) returns True - return str(tree)[:-1] # remove added newline - - def load_module(self, fullname): - logger.debug('Running load_module for {0}...'.format(fullname)) - if fullname in sys.modules: - mod = sys.modules[fullname] - else: - if self.kind in (imp.PY_COMPILED, imp.C_EXTENSION, imp.C_BUILTIN, - imp.PY_FROZEN): - convert = False - # elif (self.pathname.startswith(_stdlibprefix) - # and 'site-packages' not in self.pathname): - # # We assume it's a stdlib package in this case. Is this too brittle? - # # Please file a bug report at https://github.com/PythonCharmers/python-future - # # if so. - # convert = False - # in theory, other paths could be configured to be excluded here too - elif any([fullname.startswith(path) for path in self.exclude_paths]): - convert = False - elif any([fullname.startswith(path) for path in self.include_paths]): - convert = True - else: - convert = False - if not convert: - logger.debug('Excluded {0} from translation'.format(fullname)) - mod = imp.load_module(fullname, *self.found) - else: - logger.debug('Autoconverting {0} ...'.format(fullname)) - mod = imp.new_module(fullname) - sys.modules[fullname] = mod - - # required by PEP 302 - mod.__file__ = self.pathname - mod.__name__ = fullname - mod.__loader__ = self - - # This: - # mod.__package__ = '.'.join(fullname.split('.')[:-1]) - # seems to result in "SystemError: Parent module '' not loaded, - # cannot perform relative import" for a package's __init__.py - # file. We use the approach below. Another option to try is the - # minimal load_module pattern from the PEP 302 text instead. - - # Is the test in the next line more or less robust than the - # following one? Presumably less ... - # ispkg = self.pathname.endswith('__init__.py') - - if self.kind == imp.PKG_DIRECTORY: - mod.__path__ = [ os.path.dirname(self.pathname) ] - mod.__package__ = fullname - else: - #else, regular module - mod.__path__ = [] - mod.__package__ = fullname.rpartition('.')[0] + loader.__class__ = PastSourceFileLoader + loader.exclude_paths = self.exclude_paths + loader.include_paths = self.include_paths + return loader + + # For Python >=3.4 + def find_spec(self, fullname, path=None, target=None): + logger.debug("Running find_spec: (%s, %s, %s)", fullname, path, target) + spec = PathFinder.find_spec(fullname, path, target) + if not spec: + logger.debug("Py2Fixer could not find %s", fullname) + return None + spec.loader.__class__ = PastSourceFileLoader + spec.loader.exclude_paths = self.exclude_paths + spec.loader.include_paths = self.include_paths + return spec - try: - cachename = imp.cache_from_source(self.pathname) - if not os.path.exists(cachename): - update_cache = True - else: - sourcetime = os.stat(self.pathname).st_mtime - cachetime = os.stat(cachename).st_mtime - update_cache = cachetime < sourcetime - # # Force update_cache to work around a problem with it being treated as Py3 code??? - # update_cache = True - if not update_cache: - with open(cachename, 'rb') as f: - data = f.read() - try: - code = marshal.loads(data) - except Exception: - # pyc could be corrupt. Regenerate it - update_cache = True - if update_cache: - if self.found[0]: - source = self.found[0].read() - elif self.kind == imp.PKG_DIRECTORY: - with open(self.pathname) as f: - source = f.read() - - if detect_python2(source, self.pathname): - source = self.transform(source) - - code = compile(source, self.pathname, 'exec') - - dirname = os.path.dirname(cachename) - try: - if not os.path.exists(dirname): - os.makedirs(dirname) - with open(cachename, 'wb') as f: - data = marshal.dumps(code) - f.write(data) - except Exception: # could be write-protected - pass - exec(code, mod.__dict__) - except Exception as e: - # must remove module from sys.modules - del sys.modules[fullname] - raise # keep it simple - - if self.found[0]: - self.found[0].close() - return mod _hook = Py2Fixer() diff --git a/tests/test_future/test_standard_library.py b/tests/test_future/test_standard_library.py index f3477210..1028f6fc 100644 --- a/tests/test_future/test_standard_library.py +++ b/tests/test_future/test_standard_library.py @@ -9,7 +9,6 @@ import sys import tempfile -import os import copy import textwrap from subprocess import CalledProcessError @@ -448,13 +447,11 @@ def test_reload(self): reload has been moved to the imp module """ try: - import imp - imp.reload(imp) - self.assertTrue(True) + from importlib import reload except ImportError: - import importlib - importlib.reload(importlib) - self.assertTrue(True) + from imp import reload + reload(sys) + self.assertTrue(True) def test_install_aliases(self): """ diff --git a/tests/test_past/test_builtins.py b/tests/test_past/test_builtins.py index d16978ee..98d3c8c1 100644 --- a/tests/test_past/test_builtins.py +++ b/tests/test_past/test_builtins.py @@ -6,7 +6,6 @@ from past.builtins import apply, cmp, execfile, intern, raw_input from past.builtins import reduce, reload, unichr, unicode, xrange -from future import standard_library from future.backports.test.support import TESTFN #, run_unittest import tempfile import os diff --git a/tests/test_past/test_translation.py b/tests/test_past/test_translation.py index 2b442d96..58d8d000 100644 --- a/tests/test_past/test_translation.py +++ b/tests/test_past/test_translation.py @@ -7,18 +7,18 @@ import os import textwrap import sys -import pprint import tempfile -import os import io -from subprocess import Popen, PIPE - -from past import utils -from past.builtins import basestring, str as oldstr, unicode +from future.tests.base import ( + expectedFailurePY3, + unittest, +) +from past.builtins import ( + str as oldstr, + unicode, +) from past.translation import install_hooks, remove_hooks, common_substring -from future.tests.base import (unittest, CodeHandler, skip26, - expectedFailurePY3, expectedFailurePY26) class TestTranslate(unittest.TestCase): @@ -58,8 +58,8 @@ def write_and_import(self, code, modulename='mymodule'): sys.path.insert(0, self.tempdir) try: module = __import__(modulename) - except SyntaxError: - print('Bombed!') + except SyntaxError as e: + print('Import failed: %s' % e) else: print('Succeeded!') finally: From 74d834334d1f97cf5f874d601e88edae978da578 Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Fri, 19 Jan 2024 17:51:46 +0000 Subject: [PATCH 53/59] Test fixes --- src/future/moves/test/support.py | 9 +++++++++ tests/test_future/test_builtins.py | 7 +++++-- tests/test_future/test_urllib2.py | 6 +----- tests/test_future/test_urllib_toplevel.py | 7 +++++-- tests/test_future/test_utils.py | 2 +- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/future/moves/test/support.py b/src/future/moves/test/support.py index e9aa0f48..f70c9d7d 100644 --- a/src/future/moves/test/support.py +++ b/src/future/moves/test/support.py @@ -1,9 +1,18 @@ from __future__ import absolute_import + +import sys + from future.standard_library import suspend_hooks from future.utils import PY3 if PY3: from test.support import * + if sys.version_info[:2] >= (3, 10): + from test.support.os_helper import ( + EnvironmentVarGuard, + TESTFN, + ) + from test.support.warnings_helper import check_warnings else: __future_module__ = True with suspend_hooks(): diff --git a/tests/test_future/test_builtins.py b/tests/test_future/test_builtins.py index 3921a608..0bf2a520 100644 --- a/tests/test_future/test_builtins.py +++ b/tests/test_future/test_builtins.py @@ -1303,8 +1303,11 @@ def test_pow(self): self.assertAlmostEqual(pow(-1, 0.5), 1j) self.assertAlmostEqual(pow(-1, 1/3), 0.5 + 0.8660254037844386j) - # Raises TypeError in Python < v3.5, ValueError in v3.5: - self.assertRaises((TypeError, ValueError), pow, -1, -2, 3) + # Raises TypeError in Python < v3.5, ValueError in v3.5-v3.7: + if sys.version_info[:2] < (3, 8): + self.assertRaises((TypeError, ValueError), pow, -1, -2, 3) + else: + self.assertEqual(pow(-1, -2, 3), 1) self.assertRaises(ValueError, pow, 1, 2, 0) self.assertRaises(TypeError, pow) diff --git a/tests/test_future/test_urllib2.py b/tests/test_future/test_urllib2.py index 2d69dad1..87bc585a 100644 --- a/tests/test_future/test_urllib2.py +++ b/tests/test_future/test_urllib2.py @@ -691,10 +691,6 @@ def connect_ftp(self, user, passwd, host, port, dirs, h = NullFTPHandler(data) h.parent = MockOpener() - # MIME guessing works in Python 3.8! - guessed_mime = None - if sys.hexversion >= 0x03080000: - guessed_mime = "image/gif" for url, host, port, user, passwd, type_, dirs, filename, mimetype in [ ("ftp://localhost/foo/bar/baz.html", "localhost", ftplib.FTP_PORT, "", "", "I", @@ -713,7 +709,7 @@ def connect_ftp(self, user, passwd, host, port, dirs, ["foo", "bar"], "", None), ("ftp://localhost/baz.gif;type=a", "localhost", ftplib.FTP_PORT, "", "", "A", - [], "baz.gif", guessed_mime), + [], "baz.gif", None), ]: req = Request(url) req.timeout = None diff --git a/tests/test_future/test_urllib_toplevel.py b/tests/test_future/test_urllib_toplevel.py index 11e77201..93364e6d 100644 --- a/tests/test_future/test_urllib_toplevel.py +++ b/tests/test_future/test_urllib_toplevel.py @@ -781,8 +781,11 @@ def test_unquoting(self): "%s" % result) self.assertRaises((TypeError, AttributeError), urllib_parse.unquote, None) self.assertRaises((TypeError, AttributeError), urllib_parse.unquote, ()) - with support.check_warnings(('', BytesWarning), quiet=True): - self.assertRaises((TypeError, AttributeError), urllib_parse.unquote, bytes(b'')) + if sys.version_info[:2] < (3, 9): + with support.check_warnings(('', BytesWarning), quiet=True): + self.assertRaises((TypeError, AttributeError), urllib_parse.unquote, bytes(b'')) + else: + self.assertEqual(urllib_parse.unquote(bytes(b"")), "") def test_unquoting_badpercent(self): # Test unquoting on bad percent-escapes diff --git a/tests/test_future/test_utils.py b/tests/test_future/test_utils.py index 46f5196c..a496bcaf 100644 --- a/tests/test_future/test_utils.py +++ b/tests/test_future/test_utils.py @@ -150,7 +150,7 @@ class Timeout(BaseException): self.assertRaises(Timeout, raise_, Timeout()) if PY3: - self.assertRaisesRegexp( + self.assertRaisesRegex( TypeError, "class must derive from BaseException", raise_, int) From 9ef05b386ce45dd40d2dab5915aec3ed78d81ed9 Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Mon, 22 Jan 2024 15:50:50 +0000 Subject: [PATCH 54/59] Add Python 3.8-3.12 classifiers --- setup.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/setup.py b/setup.py index 41b0df96..9c62269b 100755 --- a/setup.py +++ b/setup.py @@ -103,6 +103,11 @@ "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "License :: OSI Approved", "License :: OSI Approved :: MIT License", "Development Status :: 4 - Beta", From 343f952f3a1eb6df902c201581d36268cf144a93 Mon Sep 17 00:00:00 2001 From: Ed Schofield Date: Wed, 21 Feb 2024 13:14:03 +1100 Subject: [PATCH 55/59] Update instructions for uploading docs --- docs/other/upload_future_docs.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/other/upload_future_docs.sh b/docs/other/upload_future_docs.sh index d5c272d2..c5201f90 100644 --- a/docs/other/upload_future_docs.sh +++ b/docs/other/upload_future_docs.sh @@ -3,14 +3,14 @@ git checkout v0.16.0 # or whatever rm -Rf docs/build/ cd docs; make html -cp cheatsheet.pdf /shared/ +cp cheatsheet.pdf ~/shared/ cd build -touch /shared/python-future-html-docs.zip -rm /shared/python-future-html-docs.zip -zip -r /shared/python-future-html-docs.zip * +touch ~/shared/python-future-html-docs.zip +rm ~/shared/python-future-html-docs.zip +zip -r ~/shared/python-future-html-docs.zip * -scp /shared/python-future-html-docs.zip python-future.org: -scp /shared/cheatsheet.pdf python-future.org: +scp ~/shared/python-future-html-docs.zip python-future.org: +scp ~/shared/cheatsheet.pdf python-future.org: ssh python-future.org From 8b930f5725fb1f4e9947c2364511c9abd528a33c Mon Sep 17 00:00:00 2001 From: Ed Schofield Date: Wed, 21 Feb 2024 13:59:30 +1100 Subject: [PATCH 56/59] Update whatsnew.rst --- docs/whatsnew.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/whatsnew.rst b/docs/whatsnew.rst index 9018fdfe..a86c9bfd 100644 --- a/docs/whatsnew.rst +++ b/docs/whatsnew.rst @@ -3,11 +3,12 @@ What's New ********** -What's new in version 0.18.4 (2023-10-10) +What's new in version 0.18.4 (2024-02-21) ========================================= This is a minor bug-fix release containing a number of fixes: - Fix for Python 3.12's removal of the imp module +- Small updates to the docs What's new in version 0.18.3 (2023-01-13) ========================================= From 3f96b16ca5f220e07e0f90aa2480ac3cbce44e2a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 03:16:14 +0000 Subject: [PATCH 57/59] Bump setuptools from 0.18.2 to 65.5.1 in /docs Bumps [setuptools](https://github.com/pypa/setuptools) from 0.18.2 to 65.5.1. - [Release notes](https://github.com/pypa/setuptools/releases) - [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst) - [Commits](https://github.com/pypa/setuptools/commits/v65.5.1) --- updated-dependencies: - dependency-name: setuptools dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 0f06b13f..de74d8b2 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ sphinx==3.2.1 sphinx_bootstrap_theme==0.7.1 -setuptools==0.18.2 +setuptools==65.5.1 From d6785dd102876eecbbf5ae8b4ff47bc66b14fba6 Mon Sep 17 00:00:00 2001 From: Ed Schofield Date: Wed, 21 Feb 2024 14:45:01 +1100 Subject: [PATCH 58/59] Add more meaningful comments about Python deprecations Thanks to Bruno Alla (@browniebroke) --- src/future/moves/_dummy_thread.py | 2 ++ tests/test_future/test_builtins.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/future/moves/_dummy_thread.py b/src/future/moves/_dummy_thread.py index e5dca348..96cf99e1 100644 --- a/src/future/moves/_dummy_thread.py +++ b/src/future/moves/_dummy_thread.py @@ -2,6 +2,8 @@ from future.utils import PY3 if PY3: + # _dummy_thread and dummy_threading modules were both deprecated in + # Python 3.7 and removed in Python 3.9 try: from _dummy_thread import * except ImportError: diff --git a/tests/test_future/test_builtins.py b/tests/test_future/test_builtins.py index d4e4f977..0da3fc2d 100644 --- a/tests/test_future/test_builtins.py +++ b/tests/test_future/test_builtins.py @@ -1307,6 +1307,9 @@ def test_pow(self): if sys.version_info[:2] < (3, 8): self.assertRaises((TypeError, ValueError), pow, -1, -2, 3) else: + # Changed in version 3.8: For int operands, the three-argument form + # of pow now allows the second argument to be negative, permitting + # computation of modular inverses. self.assertEqual(pow(-1, -2, 3), 1) self.assertRaises(ValueError, pow, 1, 2, 0) From 8cd11e8cdb8e096989a384787c739fa5c82739d3 Mon Sep 17 00:00:00 2001 From: Ed Schofield Date: Wed, 21 Feb 2024 15:00:32 +1100 Subject: [PATCH 59/59] Move CI to GitHub Actions & split Python versions into jobs (#603) Thanks to Bruno Alla (@browniebroke) --- .github/workflows/ci.yml | 46 +++++++++++++++++++++++++++++++ .travis.yml | 11 -------- 2.6.Dockerfile | 26 +++++++++++++++++ Dockerfile | 6 +++- README.rst | 4 +-- build.sh | 18 ------------ lint.sh | 4 --- setup.sh | 21 -------------- src/future/moves/_dummy_thread.py | 10 +++---- test.sh | 18 ++++++++++++ 10 files changed, 102 insertions(+), 62 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml create mode 100644 2.6.Dockerfile delete mode 100755 build.sh delete mode 100755 lint.sh delete mode 100755 setup.sh create mode 100755 test.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..fb7f5064 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,46 @@ +name: CI + +on: + pull_request: + push: + +concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + test: + strategy: + fail-fast: false + matrix: + versions: + - python: "2.6" + - python: "2.7" + - python: "3.3" + - python: "3.4" + - python: "3.5" + - python: "3.6" + - python: "3.7" + - python: "3.8" + - python: "3.9" + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - if: ${{ matrix.versions.python != '2.6' }} + run: | + docker build \ + . \ + --build-arg PYTHON_VERSION=${{ matrix.versions.python }} \ + -t jmadler/python-future-builder:${{ matrix.versions.python }} + - if: ${{ matrix.versions.python == '2.6' }} + run: | + docker build \ + . \ + -f 2.6.Dockerfile \ + -t jmadler/python-future-builder:${{ matrix.versions.python }} + - run: | + docker run \ + -e PYTHON_VERSION=${{ matrix.versions.python }} \ + jmadler/python-future-builder:${{ matrix.versions.python }} \ + /root/python-future/test.sh \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3fe6a983..00000000 --- a/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: generic - -services: - - docker - -before_script: - - docker pull jmadler/python-future-builder:latest - -script: - - ./build.sh - - ./lint.sh diff --git a/2.6.Dockerfile b/2.6.Dockerfile new file mode 100644 index 00000000..efaf3809 --- /dev/null +++ b/2.6.Dockerfile @@ -0,0 +1,26 @@ +FROM mrupgrade/deadsnakes:2.6 + +RUN mkdir -p ~/.pip/ && echo '[global] \n\ +trusted-host = pypi.python.org\n\ + pypi.org\n\ + files.pythonhosted.org\n\ +' >> ~/.pip/pip.conf + +RUN apt-get update && \ + apt-get install -y curl + +RUN mkdir -p /root/pip && \ + cd /root/pip && \ + curl -O https://files.pythonhosted.org/packages/8a/e9/8468cd68b582b06ef554be0b96b59f59779627131aad48f8a5bce4b13450/wheel-0.29.0-py2.py3-none-any.whl && \ + curl -O https://files.pythonhosted.org/packages/31/77/3781f65cafe55480b56914def99022a5d2965a4bb269655c89ef2f1de3cd/importlib-1.0.4.zip && \ + curl -O https://files.pythonhosted.org/packages/ef/41/d8a61f1b2ba308e96b36106e95024977e30129355fd12087f23e4b9852a1/pytest-3.2.5-py2.py3-none-any.whl && \ + curl -O https://files.pythonhosted.org/packages/f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl && \ + curl -O https://files.pythonhosted.org/packages/72/20/7f0f433060a962200b7272b8c12ba90ef5b903e218174301d0abfd523813/unittest2-1.1.0-py2.py3-none-any.whl && \ + curl -O https://files.pythonhosted.org/packages/53/67/9620edf7803ab867b175e4fd23c7b8bd8eba11cb761514dcd2e726ef07da/py-1.4.34-py2.py3-none-any.whl && \ + curl -O https://files.pythonhosted.org/packages/53/25/ef88e8e45db141faa9598fbf7ad0062df8f50f881a36ed6a0073e1572126/ordereddict-1.1.tar.gz && \ + curl -O https://files.pythonhosted.org/packages/17/0a/6ac05a3723017a967193456a2efa0aa9ac4b51456891af1e2353bb9de21e/traceback2-1.4.0-py2.py3-none-any.whl && \ + curl -O https://files.pythonhosted.org/packages/65/26/32b8464df2a97e6dd1b656ed26b2c194606c16fe163c695a992b36c11cdf/six-1.13.0-py2.py3-none-any.whl && \ + curl -O https://files.pythonhosted.org/packages/c7/a3/c5da2a44c85bfbb6eebcfc1dde24933f8704441b98fdde6528f4831757a6/linecache2-1.0.0-py2.py3-none-any.whl + +WORKDIR /root/python-future +ADD . /root/python-future \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index cf9ffd3c..c859757f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,7 @@ -FROM quay.io/pypa/manylinux1_x86_64 +ARG PYTHON_VERSION +FROM python:${PYTHON_VERSION}-slim + +ENV LC_ALL=C.UTF-8 + WORKDIR /root/python-future ADD . /root/python-future diff --git a/README.rst b/README.rst index 1ab43e53..cce7605c 100644 --- a/README.rst +++ b/README.rst @@ -3,8 +3,8 @@ Overview: Easy, clean, reliable Python 2/3 compatibility ======================================================== -.. image:: https://travis-ci.org/PythonCharmers/python-future.svg?branch=master - :target: https://travis-ci.org/PythonCharmers/python-future +.. image:: https://github.com/PythonCharmers/python-future/actions/workflows/ci.yml/badge.svg?branch=master + :target: https://github.com/PythonCharmers/python-future/actions/workflows/ci.yml?query=branch%3Amaster .. image:: https://readthedocs.org/projects/python-future/badge/?version=latest :target: https://python-future.readthedocs.io/en/latest/?badge=latest diff --git a/build.sh b/build.sh deleted file mode 100755 index d4b92d9a..00000000 --- a/build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh -# XXX: TODO: we should make this include -e once tests pass -set -xu - -DOCKER_IMAGE=jmadler/python-future-builder -# XXX: TODO: Perhaps this version shouldn't be hardcoded -version=0.18.4 - -docker build . -t "$DOCKER_IMAGE" -#docker push "$DOCKER_IMAGE:latest" - -for i in cp27-cp27m cp35-cp35m cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39; do - docker run -ti -v "$(realpath dist)":/root/python-future/dist "$DOCKER_IMAGE" /root/python-future/setup.sh "$version" $(basename $i) -done - -python setup.py sdist -python setup.py clean -echo You may now run: "twine upload dist/*" diff --git a/lint.sh b/lint.sh deleted file mode 100755 index b3c41cd4..00000000 --- a/lint.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -# TODO: Run under Python 2.7 and 3.7 -flake8 . --count --exit-zero --select=E901,E999,F821,F822,F823 --show-source --statistics || true -flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics || true diff --git a/setup.sh b/setup.sh deleted file mode 100755 index fa89d431..00000000 --- a/setup.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -set -ex - -version=$1 -pytag=$2 - -if [ "$pytag" = 'py33' ]; then - pip3 install virtualenv==16.2.0 -fi - -. /root/"$pytag"/bin/activate - -if [ "$pytag" = 'py26' ]; then - pip install importlib -fi -pip install pytest unittest2 -python setup.py bdist_wheel --python-tag="$pytag" -pip install "dist/future-$version-$pytag-none-any.whl" -# Ignore test failures for now -pytest tests/ || true diff --git a/src/future/moves/_dummy_thread.py b/src/future/moves/_dummy_thread.py index 96cf99e1..6633f42e 100644 --- a/src/future/moves/_dummy_thread.py +++ b/src/future/moves/_dummy_thread.py @@ -1,13 +1,13 @@ from __future__ import absolute_import -from future.utils import PY3 +from future.utils import PY3, PY39_PLUS -if PY3: + +if PY39_PLUS: # _dummy_thread and dummy_threading modules were both deprecated in # Python 3.7 and removed in Python 3.9 - try: + from _thread import * +elif PY3: from _dummy_thread import * - except ImportError: - from _thread import * else: __future_module__ = True from dummy_thread import * diff --git a/test.sh b/test.sh new file mode 100755 index 00000000..d45e98d3 --- /dev/null +++ b/test.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -exo pipefail + +python --version + +if [ -e "/root/pip" ] +then + pip install /root/pip/*.zip /root/pip/*.whl /root/pip/*tar.gz +else + pip install pytest unittest2 +fi + +pytag="py${PYTHON_VERSION//./}" + +python setup.py bdist_wheel --python-tag="${pytag}" +pip install dist/future-*-${pytag}-none-any.whl +pytest tests/