summaryrefslogtreecommitdiffstats
path: root/Python/Dependencies/future-0.18.2/tests/test_future
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2022-12-17 17:26:16 -0800
committeryum <yum.food.vr@gmail.com>2022-12-17 17:26:16 -0800
commit4d836989720523cd0363927e3e066f56b9dc445c (patch)
treef7a9ff7cb50eda1ff29e91c78067dcc5e0ce6233 /Python/Dependencies/future-0.18.2/tests/test_future
parentda754e9cf5b192239826aa1619e1ada3c98daa45 (diff)
Check in `future` package
I hit some issues installing Whisper and had to embed this package. I haven't taken the time to deeply understand what's going on. I think that embedded Python follows different rules about resolving module paths than regular system Python. Basically, `future`'s setup.py has a line like `import src`, where `src` is a module inside future (like `future/src/__init__.py`). This doesn't work unless we put that directory on the search path.
Diffstat (limited to 'Python/Dependencies/future-0.18.2/tests/test_future')
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/__init__.py0
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_backports.py665
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_buffer.py251
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_builtins.py1876
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_builtins_explicit_import.py18
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_bytes.py786
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_chainmap.py160
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_common_iterators.py39
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_decorators.py57
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_dict.py142
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_email_multipart.py31
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_explicit_imports.py49
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_futurize.py1432
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_html.py27
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_htmlparser.py764
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_http_cookiejar.py1755
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_httplib.py568
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_import_star.py61
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_imports_httplib.py25
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_imports_urllib.py44
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_int.py1096
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_int_old_division.py101
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_isinstance.py287
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_libfuturize_fixers.py4413
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_list.py192
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_magicsuper.py135
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_object.py289
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_pasteurize.py256
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_py2_str_literals_to_bytes.py1
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_range.py216
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_requests.py107
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_standard_library.py624
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_str.py591
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_super.py347
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_surrogateescape.py142
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_urllib.py1386
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_urllib2.py1569
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_urllib_response.py45
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_urllib_toplevel.py1401
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_urllibnet.py231
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_urlparse.py860
-rw-r--r--Python/Dependencies/future-0.18.2/tests/test_future/test_utils.py406
42 files changed, 23445 insertions, 0 deletions
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/__init__.py b/Python/Dependencies/future-0.18.2/tests/test_future/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/__init__.py
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_backports.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_backports.py
new file mode 100644
index 0000000..9eeb741
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_backports.py
@@ -0,0 +1,665 @@
+# -*- coding: utf-8 -*-
+"""
+Tests for various backported functions and classes in ``future.backports``
+"""
+
+from __future__ import absolute_import, print_function
+
+import sys
+import copy
+import inspect
+import pickle
+from random import randrange, shuffle
+
+from future.backports.misc import (count,
+ _count,
+ OrderedDict,
+ Counter,
+ ChainMap,
+ _count_elements)
+from future.utils import PY2, PY26
+from future.tests.base import unittest, skip26, expectedFailurePY27
+
+if PY2:
+ from collections import Mapping, MutableMapping
+else:
+ from collections.abc import Mapping, MutableMapping
+
+
+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)
+
+ def test_own_count(self):
+ """Test own count implementation."""
+ if PY26:
+ self.assertIs(count, _count)
+ else:
+ self.assertNotEqual(count, _count)
+ self._test_count_func(_count)
+
+
+################################################################################
+### ChainMap (helper class for configparser and the string module)
+################################################################################
+
+class TestChainMap(unittest.TestCase):
+
+ def test_basics(self):
+ c = ChainMap()
+ c['a'] = 1
+ c['b'] = 2
+ d = c.new_child()
+ d['b'] = 20
+ d['c'] = 30
+ self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
+ self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem
+ self.assertEqual(len(d), 3) # check len
+ for key in 'abc': # check contains
+ self.assertIn(key, d)
+ for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get
+ self.assertEqual(d.get(k, 100), v)
+
+ del d['b'] # unmask a value
+ self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state
+ self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem
+ self.assertEqual(len(d), 3) # check len
+ for key in 'abc': # check contains
+ self.assertIn(key, d)
+ for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get
+ self.assertEqual(d.get(k, 100), v)
+ self.assertIn(repr(d), [ # check repr
+ type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
+ type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
+ ])
+
+ for e in d.copy(), copy.copy(d): # check shallow copies
+ self.assertEqual(d, e)
+ self.assertEqual(d.maps, e.maps)
+ self.assertIsNot(d, e)
+ self.assertIsNot(d.maps[0], e.maps[0])
+ for m1, m2 in zip(d.maps[1:], e.maps[1:]):
+ self.assertIs(m1, m2)
+
+ _ChainMap = ChainMap
+
+ for e in [pickle.loads(pickle.dumps(d)),
+ copy.deepcopy(d),
+ eval(repr(d))
+ ]: # check deep copies
+ self.assertEqual(d, e)
+ self.assertEqual(d.maps, e.maps)
+ self.assertIsNot(d, e)
+ for m1, m2 in zip(d.maps, e.maps):
+ self.assertIsNot(m1, m2, e)
+
+ f = d.new_child()
+ f['b'] = 5
+ self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
+ self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents
+ self.assertEqual(f['b'], 5) # find first in chain
+ self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
+
+ def test_contructor(self):
+ self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
+ self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
+
+ def test_bool(self):
+ self.assertFalse(ChainMap())
+ self.assertFalse(ChainMap({}, {}))
+ self.assertTrue(ChainMap({1:2}, {}))
+ self.assertTrue(ChainMap({}, {1:2}))
+
+ def test_missing(self):
+ class DefaultChainMap(ChainMap):
+ def __missing__(self, key):
+ return 999
+ d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
+ for k, v in dict(a=1, b=2, c=30, d=999).items():
+ self.assertEqual(d[k], v) # check __getitem__ w/missing
+ for k, v in dict(a=1, b=2, c=30, d=77).items():
+ self.assertEqual(d.get(k, 77), v) # check get() w/ missing
+ for k, v in dict(a=True, b=True, c=True, d=False).items():
+ self.assertEqual(k in d, v) # check __contains__ w/missing
+ self.assertEqual(d.pop('a', 1001), 1, d)
+ self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
+ self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
+ with self.assertRaises(KeyError):
+ d.popitem()
+
+ def test_dict_coercion(self):
+ d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
+ self.assertEqual(dict(d), dict(a=1, b=2, c=30))
+ self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
+
+
+################################################################################
+### Counter
+################################################################################
+
+class CounterSubclassWithSetItem(Counter):
+ # Test a counter subclass that overrides __setitem__
+ def __init__(self, *args, **kwds):
+ self.called = False
+ Counter.__init__(self, *args, **kwds)
+ def __setitem__(self, key, value):
+ self.called = True
+ Counter.__setitem__(self, key, value)
+
+class CounterSubclassWithGet(Counter):
+ # Test a counter subclass that overrides get()
+ def __init__(self, *args, **kwds):
+ self.called = False
+ Counter.__init__(self, *args, **kwds)
+ def get(self, key, default):
+ self.called = True
+ return Counter.get(self, key, default)
+
+class TestCounter(unittest.TestCase):
+
+ def test_basics(self):
+ c = Counter('abcaba')
+ self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
+ self.assertEqual(c, Counter(a=3, b=2, c=1))
+ self.assertIsInstance(c, dict)
+ self.assertIsInstance(c, Mapping)
+ self.assertTrue(issubclass(Counter, dict))
+ self.assertTrue(issubclass(Counter, Mapping))
+ self.assertEqual(len(c), 3)
+ self.assertEqual(sum(c.values()), 6)
+ self.assertEqual(sorted(c.values()), [1, 2, 3])
+ self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
+ self.assertEqual(sorted(c), ['a', 'b', 'c'])
+ self.assertEqual(sorted(c.items()),
+ [('a', 3), ('b', 2), ('c', 1)])
+ self.assertEqual(c['b'], 2)
+ self.assertEqual(c['z'], 0)
+ self.assertEqual(c.__contains__('c'), True)
+ self.assertEqual(c.__contains__('z'), False)
+ self.assertEqual(c.get('b', 10), 2)
+ self.assertEqual(c.get('z', 10), 10)
+ self.assertEqual(c, dict(a=3, b=2, c=1))
+ self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
+ self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
+ for i in range(5):
+ self.assertEqual(c.most_common(i),
+ [('a', 3), ('b', 2), ('c', 1)][:i])
+ self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
+ c['a'] += 1 # increment an existing value
+ c['b'] -= 2 # sub existing value to zero
+ del c['c'] # remove an entry
+ del c['c'] # make sure that del doesn't raise KeyError
+ c['d'] -= 2 # sub from a missing value
+ c['e'] = -5 # directly assign a missing value
+ c['f'] += 4 # add to a missing value
+ self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
+ self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
+ self.assertEqual(c.pop('f'), 4)
+ self.assertNotIn('f', c)
+ for i in range(3):
+ elem, cnt = c.popitem()
+ self.assertNotIn(elem, c)
+ c.clear()
+ self.assertEqual(c, {})
+ self.assertEqual(repr(c), 'Counter()')
+ self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
+ self.assertRaises(TypeError, hash, c)
+ c.update(dict(a=5, b=3))
+ c.update(c=1)
+ c.update(Counter('a' * 50 + 'b' * 30))
+ c.update() # test case with no args
+ c.__init__('a' * 500 + 'b' * 300)
+ c.__init__('cdc')
+ c.__init__()
+ self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
+ self.assertEqual(c.setdefault('d', 5), 1)
+ self.assertEqual(c['d'], 1)
+ self.assertEqual(c.setdefault('e', 5), 5)
+ self.assertEqual(c['e'], 5)
+
+ def test_copying(self):
+ # Check that counters are copyable, deepcopyable, picklable, and
+ #have a repr/eval round-trip
+ words = Counter('which witch had which witches wrist watch'.split())
+ update_test = Counter()
+ update_test.update(words)
+ for i, dup in enumerate([
+ words.copy(),
+ copy.copy(words),
+ copy.deepcopy(words),
+ pickle.loads(pickle.dumps(words, 0)),
+ pickle.loads(pickle.dumps(words, 1)),
+ pickle.loads(pickle.dumps(words, 2)),
+ pickle.loads(pickle.dumps(words, -1)),
+ eval(repr(words)),
+ update_test,
+ Counter(words),
+ ]):
+ msg = (i, dup, words)
+ self.assertTrue(dup is not words)
+ self.assertEqual(dup, words)
+ self.assertEqual(len(dup), len(words))
+ self.assertEqual(type(dup), type(words))
+
+ def test_copy_subclass(self):
+ class MyCounter(Counter):
+ pass
+ c = MyCounter('slartibartfast')
+ d = c.copy()
+ self.assertEqual(d, c)
+ self.assertEqual(len(d), len(c))
+ self.assertEqual(type(d), type(c))
+
+ def test_conversions(self):
+ # Convert to: set, list, dict
+ s = 'she sells sea shells by the sea shore'
+ self.assertEqual(sorted(Counter(s).elements()), sorted(s))
+ self.assertEqual(sorted(Counter(s)), sorted(set(s)))
+ self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
+ self.assertEqual(set(Counter(s)), set(s))
+
+ def test_invariant_for_the_in_operator(self):
+ c = Counter(a=10, b=-2, c=0)
+ for elem in c:
+ self.assertTrue(elem in c)
+ self.assertIn(elem, c)
+
+ def test_multiset_operations(self):
+ # Verify that adding a zero counter will strip zeros and negatives
+ c = Counter(a=10, b=-2, c=0) + Counter()
+ self.assertEqual(dict(c), dict(a=10))
+
+ elements = 'abcd'
+ for i in range(1000):
+ # test random pairs of multisets
+ p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
+ p.update(e=1, f=-1, g=0)
+ q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
+ q.update(h=1, i=-1, j=0)
+ for counterop, numberop in [
+ (Counter.__add__, lambda x, y: max(0, x+y)),
+ (Counter.__sub__, lambda x, y: max(0, x-y)),
+ (Counter.__or__, lambda x, y: max(0,x,y)),
+ (Counter.__and__, lambda x, y: max(0, min(x,y))),
+ ]:
+ result = counterop(p, q)
+ for x in elements:
+ self.assertEqual(numberop(p[x], q[x]), result[x],
+ (counterop, x, p, q))
+ # verify that results exclude non-positive counts
+ self.assertTrue(x>0 for x in result.values())
+
+ elements = 'abcdef'
+ for i in range(100):
+ # verify that random multisets with no repeats are exactly like sets
+ p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
+ q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
+ for counterop, setop in [
+ (Counter.__sub__, set.__sub__),
+ (Counter.__or__, set.__or__),
+ (Counter.__and__, set.__and__),
+ ]:
+ counter_result = counterop(p, q)
+ set_result = setop(set(p.elements()), set(q.elements()))
+ self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
+
+ @expectedFailurePY27
+ def test_inplace_operations(self):
+ elements = 'abcd'
+ for i in range(1000):
+ # test random pairs of multisets
+ p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
+ p.update(e=1, f=-1, g=0)
+ q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
+ q.update(h=1, i=-1, j=0)
+ for inplace_op, regular_op in [
+ (Counter.__iadd__, Counter.__add__),
+ (Counter.__isub__, Counter.__sub__),
+ (Counter.__ior__, Counter.__or__),
+ (Counter.__iand__, Counter.__and__),
+ ]:
+ c = p.copy()
+ c_id = id(c)
+ regular_result = regular_op(c, q)
+ inplace_result = inplace_op(c, q)
+ self.assertEqual(inplace_result, regular_result)
+ self.assertEqual(id(inplace_result), c_id)
+
+ def test_subtract(self):
+ c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
+ c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
+ self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
+ c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
+ c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
+ self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
+ c = Counter('aaabbcd')
+ c.subtract('aaaabbcce')
+ self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
+
+ @expectedFailurePY27
+ def test_unary(self):
+ c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
+ self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
+ self.assertEqual(dict(-c), dict(a=5))
+
+ def test_repr_nonsortable(self):
+ c = Counter(a=2, b=None)
+ r = repr(c)
+ self.assertIn("'a': 2", r)
+ self.assertIn("'b': None", r)
+
+ def test_helper_function(self):
+ # two paths, one for real dicts and one for other mappings
+ elems = list('abracadabra')
+
+ d = dict()
+ _count_elements(d, elems)
+ self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
+
+ m = OrderedDict()
+ _count_elements(m, elems)
+ self.assertEqual(m,
+ OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
+
+ # test fidelity to the pure python version
+ c = CounterSubclassWithSetItem('abracadabra')
+ self.assertTrue(c.called)
+ c = CounterSubclassWithGet('abracadabra')
+ self.assertTrue(c.called)
+
+
+################################################################################
+### OrderedDict
+################################################################################
+
+class TestOrderedDict(unittest.TestCase):
+
+ def test_init(self):
+ with self.assertRaises(TypeError):
+ OrderedDict([('a', 1), ('b', 2)], None) # too many args
+ pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
+ self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input
+ self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input
+ self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input
+ self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)],
+ c=3, e=5).items()), pairs) # mixed input
+
+ # Make sure that direct calls to __init__ do not clear previous contents
+ d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
+ d.__init__([('e', 5), ('f', 6)], g=7, d=4)
+ self.assertEqual(list(d.items()),
+ [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
+
+ def test_update(self):
+ with self.assertRaises(TypeError):
+ OrderedDict().update([('a', 1), ('b', 2)], None) # too many args
+ pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
+ od = OrderedDict()
+ od.update(dict(pairs))
+ self.assertEqual(sorted(od.items()), pairs) # dict input
+ od = OrderedDict()
+ od.update(**dict(pairs))
+ self.assertEqual(sorted(od.items()), pairs) # kwds input
+ od = OrderedDict()
+ od.update(pairs)
+ self.assertEqual(list(od.items()), pairs) # pairs input
+ od = OrderedDict()
+ od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5)
+ self.assertEqual(list(od.items()), pairs) # mixed input
+
+ ### The tests below fail on Py2.6
+ if PY26:
+ return
+ # Issue 9137: Named argument called 'other' or 'self'
+ # shouldn't be treated specially.
+ od = OrderedDict()
+ od.update(self=23)
+ self.assertEqual(list(od.items()), [('self', 23)])
+ od = OrderedDict()
+ od.update(other={})
+ self.assertEqual(list(od.items()), [('other', {})])
+ od = OrderedDict()
+ od.update(red=5, blue=6, other=7, self=8)
+ self.assertEqual(sorted(list(od.items())),
+ [('blue', 6), ('other', 7), ('red', 5), ('self', 8)])
+
+ # Make sure that direct calls to update do not clear previous contents
+ # add that updates items are not moved to the end
+ d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
+ d.update([('e', 5), ('f', 6)], g=7, d=4)
+ self.assertEqual(list(d.items()),
+ [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
+
+ def test_abc(self):
+ self.assertIsInstance(OrderedDict(), MutableMapping)
+ self.assertTrue(issubclass(OrderedDict, MutableMapping))
+
+ def test_clear(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ shuffle(pairs)
+ od = OrderedDict(pairs)
+ self.assertEqual(len(od), len(pairs))
+ od.clear()
+ self.assertEqual(len(od), 0)
+
+ def test_delitem(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ od = OrderedDict(pairs)
+ del od['a']
+ self.assertNotIn('a', od)
+ with self.assertRaises(KeyError):
+ del od['a']
+ self.assertEqual(list(od.items()), pairs[:2] + pairs[3:])
+
+ def test_setitem(self):
+ od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)])
+ od['c'] = 10 # existing element
+ od['f'] = 20 # new element
+ self.assertEqual(list(od.items()),
+ [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)])
+
+ def test_iterators(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ shuffle(pairs)
+ od = OrderedDict(pairs)
+ self.assertEqual(list(od), [t[0] for t in pairs])
+ self.assertEqual(list(od.keys()), [t[0] for t in pairs])
+ self.assertEqual(list(od.values()), [t[1] for t in pairs])
+ self.assertEqual(list(od.items()), pairs)
+ self.assertEqual(list(reversed(od)),
+ [t[0] for t in reversed(pairs)])
+
+ def test_popitem(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ shuffle(pairs)
+ od = OrderedDict(pairs)
+ while pairs:
+ self.assertEqual(od.popitem(), pairs.pop())
+ with self.assertRaises(KeyError):
+ od.popitem()
+ self.assertEqual(len(od), 0)
+
+ def test_pop(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ shuffle(pairs)
+ od = OrderedDict(pairs)
+ shuffle(pairs)
+ while pairs:
+ k, v = pairs.pop()
+ self.assertEqual(od.pop(k), v)
+ with self.assertRaises(KeyError):
+ od.pop('xyz')
+ self.assertEqual(len(od), 0)
+ self.assertEqual(od.pop(k, 12345), 12345)
+
+ # make sure pop still works when __missing__ is defined
+ class Missing(OrderedDict):
+ def __missing__(self, key):
+ return 0
+ m = Missing(a=1)
+ self.assertEqual(m.pop('b', 5), 5)
+ self.assertEqual(m.pop('a', 6), 1)
+ self.assertEqual(m.pop('a', 6), 6)
+ with self.assertRaises(KeyError):
+ m.pop('a')
+
+ def test_equality(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ shuffle(pairs)
+ od1 = OrderedDict(pairs)
+ od2 = OrderedDict(pairs)
+ self.assertEqual(od1, od2) # same order implies equality
+ pairs = pairs[2:] + pairs[:2]
+ od2 = OrderedDict(pairs)
+ self.assertNotEqual(od1, od2) # different order implies inequality
+ # comparison to regular dict is not order sensitive
+ self.assertEqual(od1, dict(od2))
+ self.assertEqual(dict(od2), od1)
+ # different length implied inequality
+ self.assertNotEqual(od1, OrderedDict(pairs[:-1]))
+
+ def test_copying(self):
+ # Check that ordered dicts are copyable, deepcopyable, picklable,
+ # and have a repr/eval round-trip
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ od = OrderedDict(pairs)
+ update_test = OrderedDict()
+ update_test.update(od)
+ for i, dup in enumerate([
+ od.copy(),
+ copy.copy(od),
+ copy.deepcopy(od),
+ pickle.loads(pickle.dumps(od, 0)),
+ pickle.loads(pickle.dumps(od, 1)),
+ pickle.loads(pickle.dumps(od, 2)),
+ # pickle.loads(pickle.dumps(od, 3)),
+ pickle.loads(pickle.dumps(od, -1)),
+ eval(repr(od)),
+ update_test,
+ OrderedDict(od),
+ ]):
+ self.assertTrue(dup is not od)
+ self.assertEqual(dup, od)
+ self.assertEqual(list(dup.items()), list(od.items()))
+ self.assertEqual(len(dup), len(od))
+ self.assertEqual(type(dup), type(od))
+
+ def test_yaml_linkage(self):
+ # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
+ # In yaml, lists are native but tuples are not.
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ od = OrderedDict(pairs)
+ # yaml.dump(od) -->
+ # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n'
+ self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
+
+ # def test_reduce_not_too_fat(self):
+ # # do not save instance dictionary if not needed
+ # pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ # od = OrderedDict(pairs)
+ # self.assertEqual(len(od.__reduce__()), 2)
+ # od.x = 10
+ # self.assertEqual(len(od.__reduce__()), 3)
+
+ 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)])")
+ self.assertEqual(eval(repr(od)), od)
+ self.assertEqual(repr(OrderedDict()), "OrderedDict()")
+
+ 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', ...)])")
+
+ def test_setdefault(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ shuffle(pairs)
+ od = OrderedDict(pairs)
+ pair_order = list(od.items())
+ self.assertEqual(od.setdefault('a', 10), 3)
+ # make sure order didn't change
+ self.assertEqual(list(od.items()), pair_order)
+ self.assertEqual(od.setdefault('x', 10), 10)
+ # make sure 'x' is added to the end
+ self.assertEqual(list(od.items())[-1], ('x', 10))
+
+ # make sure setdefault still works when __missing__ is defined
+ class Missing(OrderedDict):
+ def __missing__(self, key):
+ return 0
+ self.assertEqual(Missing().setdefault(5, 9), 9)
+
+ def test_reinsert(self):
+ # Given insert a, insert b, delete a, re-insert a,
+ # verify that a is now later than b.
+ od = OrderedDict()
+ od['a'] = 1
+ od['b'] = 2
+ del od['a']
+ od['a'] = 1
+ self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
+
+ @expectedFailurePY27
+ def test_move_to_end(self):
+ od = OrderedDict.fromkeys('abcde')
+ self.assertEqual(list(od), list('abcde'))
+ od.move_to_end('c')
+ self.assertEqual(list(od), list('abdec'))
+ od.move_to_end('c', 0)
+ self.assertEqual(list(od), list('cabde'))
+ od.move_to_end('c', 0)
+ self.assertEqual(list(od), list('cabde'))
+ od.move_to_end('e')
+ self.assertEqual(list(od), list('cabde'))
+ with self.assertRaises(KeyError):
+ od.move_to_end('x')
+
+ def test_override_update(self):
+ # Verify that subclasses can override update() without breaking __init__()
+ class MyOD(OrderedDict):
+ def update(self, *args, **kwds):
+ raise Exception()
+ items = [('a', 1), ('c', 3), ('b', 2)]
+ self.assertEqual(list(MyOD(items).items()), items)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_buffer.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_buffer.py
new file mode 100644
index 0000000..74cfb74
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_buffer.py
@@ -0,0 +1,251 @@
+# Tests that work for both bytes and buffer objects.
+# See PEP 3137.
+
+from __future__ import (absolute_import, division,
+ print_function, unicode_literals)
+from future.builtins import *
+from future.tests.base import unittest, expectedFailurePY26
+
+import struct
+import sys
+
+
+class MixinBytesBufferCommonTests(object):
+ """Tests that work for both bytes and buffer objects.
+ See PEP 3137.
+ """
+
+ def marshal(self, x):
+ """Convert x into the appropriate type for these tests."""
+ raise RuntimeError('test class must provide a marshal method')
+
+ def test_islower(self):
+ self.assertFalse(self.marshal(b'').islower())
+ self.assertTrue(self.marshal(b'a').islower())
+ self.assertFalse(self.marshal(b'A').islower())
+ self.assertFalse(self.marshal(b'\n').islower())
+ self.assertTrue(self.marshal(b'abc').islower())
+ self.assertFalse(self.marshal(b'aBc').islower())
+ self.assertTrue(self.marshal(b'abc\n').islower())
+ self.assertRaises(TypeError, self.marshal(b'abc').islower, 42)
+
+ def test_isupper(self):
+ self.assertFalse(self.marshal(b'').isupper())
+ self.assertFalse(self.marshal(b'a').isupper())
+ self.assertTrue(self.marshal(b'A').isupper())
+ self.assertFalse(self.marshal(b'\n').isupper())
+ self.assertTrue(self.marshal(b'ABC').isupper())
+ self.assertFalse(self.marshal(b'AbC').isupper())
+ self.assertTrue(self.marshal(b'ABC\n').isupper())
+ self.assertRaises(TypeError, self.marshal(b'abc').isupper, 42)
+
+ def test_istitle(self):
+ self.assertFalse(self.marshal(b'').istitle())
+ self.assertFalse(self.marshal(b'a').istitle())
+ self.assertTrue(self.marshal(b'A').istitle())
+ self.assertFalse(self.marshal(b'\n').istitle())
+ self.assertTrue(self.marshal(b'A Titlecased Line').istitle())
+ self.assertTrue(self.marshal(b'A\nTitlecased Line').istitle())
+ self.assertTrue(self.marshal(b'A Titlecased, Line').istitle())
+ self.assertFalse(self.marshal(b'Not a capitalized String').istitle())
+ self.assertFalse(self.marshal(b'Not\ta Titlecase String').istitle())
+ self.assertFalse(self.marshal(b'Not--a Titlecase String').istitle())
+ self.assertFalse(self.marshal(b'NOT').istitle())
+ self.assertRaises(TypeError, self.marshal(b'abc').istitle, 42)
+
+ def test_isspace(self):
+ self.assertFalse(self.marshal(b'').isspace())
+ self.assertFalse(self.marshal(b'a').isspace())
+ self.assertTrue(self.marshal(b' ').isspace())
+ self.assertTrue(self.marshal(b'\t').isspace())
+ self.assertTrue(self.marshal(b'\r').isspace())
+ self.assertTrue(self.marshal(b'\n').isspace())
+ self.assertTrue(self.marshal(b' \t\r\n').isspace())
+ self.assertFalse(self.marshal(b' \t\r\na').isspace())
+ self.assertRaises(TypeError, self.marshal(b'abc').isspace, 42)
+
+ def test_isalpha(self):
+ self.assertFalse(self.marshal(b'').isalpha())
+ self.assertTrue(self.marshal(b'a').isalpha())
+ self.assertTrue(self.marshal(b'A').isalpha())
+ self.assertFalse(self.marshal(b'\n').isalpha())
+ self.assertTrue(self.marshal(b'abc').isalpha())
+ self.assertFalse(self.marshal(b'aBc123').isalpha())
+ self.assertFalse(self.marshal(b'abc\n').isalpha())
+ self.assertRaises(TypeError, self.marshal(b'abc').isalpha, 42)
+
+ def test_isalnum(self):
+ self.assertFalse(self.marshal(b'').isalnum())
+ self.assertTrue(self.marshal(b'a').isalnum())
+ self.assertTrue(self.marshal(b'A').isalnum())
+ self.assertFalse(self.marshal(b'\n').isalnum())
+ self.assertTrue(self.marshal(b'123abc456').isalnum())
+ self.assertTrue(self.marshal(b'a1b3c').isalnum())
+ self.assertFalse(self.marshal(b'aBc000 ').isalnum())
+ self.assertFalse(self.marshal(b'abc\n').isalnum())
+ self.assertRaises(TypeError, self.marshal(b'abc').isalnum, 42)
+
+ def test_isdigit(self):
+ self.assertFalse(self.marshal(b'').isdigit())
+ self.assertFalse(self.marshal(b'a').isdigit())
+ self.assertTrue(self.marshal(b'0').isdigit())
+ self.assertTrue(self.marshal(b'0123456789').isdigit())
+ self.assertFalse(self.marshal(b'0123456789a').isdigit())
+
+ self.assertRaises(TypeError, self.marshal(b'abc').isdigit, 42)
+
+ def test_lower(self):
+ self.assertEqual(bytes(b'hello'), self.marshal(b'HeLLo').lower())
+ self.assertEqual(bytes(b'hello'), self.marshal(b'hello').lower())
+ self.assertRaises(TypeError, self.marshal(b'hello').lower, 42)
+
+ def test_upper(self):
+ self.assertEqual(bytes(b'HELLO'), self.marshal(b'HeLLo').upper())
+ self.assertEqual(bytes(b'HELLO'), self.marshal(b'HELLO').upper())
+ self.assertRaises(TypeError, self.marshal(b'hello').upper, 42)
+
+ def test_capitalize(self):
+ self.assertEqual(bytes(b' hello '), self.marshal(b' hello ').capitalize())
+ self.assertEqual(bytes(b'Hello '), self.marshal(b'Hello ').capitalize())
+ self.assertEqual(bytes(b'Hello '), self.marshal(b'hello ').capitalize())
+ self.assertEqual(bytes(b'Aaaa'), self.marshal(b'aaaa').capitalize())
+ self.assertEqual(bytes(b'Aaaa'), self.marshal(b'AaAa').capitalize())
+
+ self.assertRaises(TypeError, self.marshal(b'hello').capitalize, 42)
+
+ def test_ljust(self):
+ self.assertEqual(bytes(b'abc '), self.marshal(b'abc').ljust(10))
+ self.assertEqual(bytes(b'abc '), self.marshal(b'abc').ljust(6))
+ self.assertEqual(bytes(b'abc'), self.marshal(b'abc').ljust(3))
+ self.assertEqual(bytes(b'abc'), self.marshal(b'abc').ljust(2))
+ self.assertEqual(bytes(b'abc*******'), self.marshal(b'abc').ljust(10, b'*'))
+ self.assertRaises(TypeError, self.marshal(b'abc').ljust)
+
+ def test_rjust(self):
+ self.assertEqual(bytes(b' abc'), self.marshal(b'abc').rjust(10))
+ self.assertEqual(bytes(b' abc'), self.marshal(b'abc').rjust(6))
+ self.assertEqual(bytes(b'abc'), self.marshal(b'abc').rjust(3))
+ self.assertEqual(bytes(b'abc'), self.marshal(b'abc').rjust(2))
+ self.assertEqual(bytes(b'*******abc'), self.marshal(b'abc').rjust(10, b'*'))
+ self.assertRaises(TypeError, self.marshal(b'abc').rjust)
+
+ def test_center(self):
+ self.assertEqual(bytes(b' abc '), self.marshal(b'abc').center(10))
+ self.assertEqual(bytes(b' abc '), self.marshal(b'abc').center(6))
+ self.assertEqual(bytes(b'abc'), self.marshal(b'abc').center(3))
+ self.assertEqual(bytes(b'abc'), self.marshal(b'abc').center(2))
+ self.assertEqual(bytes(b'***abc****'), self.marshal(b'abc').center(10, b'*'))
+ self.assertRaises(TypeError, self.marshal(b'abc').center)
+
+ def test_swapcase(self):
+ self.assertEqual(bytes(b'hEllO CoMPuTErS'),
+ self.marshal(bytes(b'HeLLo cOmpUteRs')).swapcase())
+
+ self.assertRaises(TypeError, self.marshal(b'hello').swapcase, 42)
+
+ def test_zfill(self):
+ self.assertEqual(bytes(b'123'), self.marshal(b'123').zfill(2))
+ self.assertEqual(bytes(b'123'), self.marshal(b'123').zfill(3))
+ self.assertEqual(bytes(b'0123'), self.marshal(b'123').zfill(4))
+ self.assertEqual(bytes(b'+123'), self.marshal(b'+123').zfill(3))
+ self.assertEqual(bytes(b'+123'), self.marshal(b'+123').zfill(4))
+ self.assertEqual(bytes(b'+0123'), self.marshal(b'+123').zfill(5))
+ self.assertEqual(bytes(b'-123'), self.marshal(b'-123').zfill(3))
+ self.assertEqual(bytes(b'-123'), self.marshal(b'-123').zfill(4))
+ self.assertEqual(bytes(b'-0123'), self.marshal(b'-123').zfill(5))
+ self.assertEqual(bytes(b'000'), self.marshal(b'').zfill(3))
+ self.assertEqual(bytes(b'34'), self.marshal(b'34').zfill(1))
+ self.assertEqual(bytes(b'0034'), self.marshal(b'34').zfill(4))
+
+ self.assertRaises(TypeError, self.marshal(b'123').zfill)
+
+ def test_expandtabs(self):
+ self.assertEqual(bytes(b'abc\rab def\ng hi'),
+ self.marshal(b'abc\rab\tdef\ng\thi').expandtabs())
+ self.assertEqual(bytes(b'abc\rab def\ng hi'),
+ self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(8))
+ self.assertEqual(bytes(b'abc\rab def\ng hi'),
+ self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(4))
+ self.assertEqual(bytes(b'abc\r\nab def\ng hi'),
+ self.marshal(b'abc\r\nab\tdef\ng\thi').expandtabs(4))
+ self.assertEqual(bytes(b'abc\rab def\ng hi'),
+ self.marshal(b'abc\rab\tdef\ng\thi').expandtabs())
+ self.assertEqual(bytes(b'abc\rab def\ng hi'),
+ self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(8))
+ self.assertEqual(bytes(b'abc\r\nab\r\ndef\ng\r\nhi'),
+ self.marshal(b'abc\r\nab\r\ndef\ng\r\nhi').expandtabs(4))
+ self.assertEqual(bytes(b' a\n b'), self.marshal(b' \ta\n\tb').expandtabs(1))
+
+ self.assertRaises(TypeError, self.marshal(b'hello').expandtabs, 42, 42)
+ # This test is only valid when sizeof(int) == sizeof(void*) == 4.
+ if sys.maxsize < (1 << 32) and struct.calcsize('P') == 4:
+ self.assertRaises(OverflowError,
+ self.marshal(b'\ta\n\tb').expandtabs, sys.maxsize)
+
+ def test_title(self):
+ self.assertEqual(bytes(b' Hello '), self.marshal(b' hello ').title())
+ self.assertEqual(bytes(b'Hello '), self.marshal(b'hello ').title())
+ self.assertEqual(bytes(b'Hello '), self.marshal(b'Hello ').title())
+ self.assertEqual(bytes(b'Format This As Title String'),
+ self.marshal(b'fOrMaT thIs aS titLe String').title())
+ self.assertEqual(bytes(b'Format,This-As*Title;String'),
+ self.marshal(b'fOrMaT,thIs-aS*titLe;String').title())
+ self.assertEqual(bytes(b'Getint'), self.marshal(b'getInt').title())
+ self.assertRaises(TypeError, self.marshal(b'hello').title, 42)
+
+ def test_splitlines(self):
+ self.assertEqual([bytes(b'abc'), bytes(b'def'), bytes(b''), bytes(b'ghi')],
+ self.marshal(b'abc\ndef\n\rghi').splitlines())
+ self.assertEqual([bytes(b'abc'), bytes(b'def'), bytes(b''), bytes(b'ghi')],
+ self.marshal(b'abc\ndef\n\r\nghi').splitlines())
+ self.assertEqual([bytes(b'abc'), bytes(b'def'), bytes(b'ghi')],
+ self.marshal(b'abc\ndef\r\nghi').splitlines())
+ # TODO: add bytes calls around these too ...
+ self.assertEqual([b'abc', b'def', b'ghi'],
+ self.marshal(b'abc\ndef\r\nghi\n').splitlines())
+ self.assertEqual([b'abc', b'def', b'ghi', b''],
+ self.marshal(b'abc\ndef\r\nghi\n\r').splitlines())
+ self.assertEqual([b'', b'abc', b'def', b'ghi', b''],
+ self.marshal(b'\nabc\ndef\r\nghi\n\r').splitlines())
+ self.assertEqual([b'', b'abc', b'def', b'ghi', b''],
+ self.marshal(b'\nabc\ndef\r\nghi\n\r').splitlines(False))
+ self.assertEqual([b'\n', b'abc\n', b'def\r\n', b'ghi\n', b'\r'],
+ self.marshal(b'\nabc\ndef\r\nghi\n\r').splitlines(True))
+ self.assertEqual([b'', b'abc', b'def', b'ghi', b''],
+ self.marshal(b'\nabc\ndef\r\nghi\n\r').splitlines(False))
+ self.assertEqual([b'\n', b'abc\n', b'def\r\n', b'ghi\n', b'\r'],
+ self.marshal(b'\nabc\ndef\r\nghi\n\r').splitlines(True))
+
+ self.assertRaises(TypeError, self.marshal(b'abc').splitlines, 42, 42)
+
+
+# From Python-3.3.5/Lib/test/test_bytes.py:
+
+class BytearrayPEP3137Test(unittest.TestCase,
+ MixinBytesBufferCommonTests):
+ def marshal(self, x):
+ return bytearray(bytes(x))
+
+ @expectedFailurePY26
+ def test_returns_new_copy(self):
+ val = self.marshal(b'1234')
+ # On immutable types these MAY return a reference to themselves
+ # but on mutable types like bytearray they MUST return a new copy.
+ for methname in ('zfill', 'rjust', 'ljust', 'center'):
+ method = getattr(val, methname)
+ newval = method(3)
+ self.assertEqual(val, newval)
+ self.assertTrue(val is not newval,
+ methname+' returned self on a mutable object')
+ for expr in ('val.split()[0]', 'val.rsplit()[0]',
+ 'val.partition(b".")[0]', 'val.rpartition(b".")[2]',
+ 'val.splitlines()[0]', 'val.replace(b"", b"")'):
+ newval = eval(expr)
+ self.assertEqual(val, newval)
+ self.assertTrue(val is not newval,
+ expr+' returned val on a mutable object')
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_builtins.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_builtins.py
new file mode 100644
index 0000000..ca07b9e
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_builtins.py
@@ -0,0 +1,1876 @@
+# -*- coding: utf-8 -*-
+"""
+Tests to make sure the behaviour of the builtins is sensible and correct.
+"""
+
+from __future__ import absolute_import, division, print_function, unicode_literals
+from future.builtins import (bytes, dict, int, range, round, str, super,
+ ascii, chr, hex, input, next, oct, open, pow,
+ filter, map, zip, min, max)
+
+from future.utils import PY3, exec_, native_str, implements_iterator
+from future.tests.base import (unittest, skip26, expectedFailurePY2,
+ expectedFailurePY26)
+
+import sys
+import textwrap
+import tempfile
+import os
+from subprocess import Popen, PIPE
+from numbers import Integral
+from decimal import Decimal
+
+
+class TestBuiltins(unittest.TestCase):
+ def setUp(self):
+ self.tempdir = tempfile.mkdtemp() + os.path.sep
+
+ def test_super(self):
+ class verbose_list(list):
+ '''
+ A class that uses the new simpler super() function
+ '''
+ def append(self, item):
+ print('Adding an item')
+ super().append(item)
+
+ l = verbose_list()
+ l.append('blah')
+ self.assertEqual(l[0], 'blah')
+ self.assertEqual(len(l), 1)
+ self.assertTrue(isinstance(l, list))
+
+ def test_super_2(self):
+ """
+ This occurs in the backported email/_header_value_parser.py
+ module and seems to fail.
+ """
+ class Terminal(str):
+ def __new__(cls, value, token_type):
+ self = super().__new__(cls, value)
+ self.token_type = token_type
+ self.defects = []
+ return self
+
+ DOT = Terminal('.', 'dot')
+
+ self.assertTrue(True)
+
+ def test_isinstance_int(self):
+ """
+ Redefining ``int`` to a ``long`` subclass on Py2 makes this
+ test fail unless __instancecheck__() is defined appropriately (or
+ isinstance is redefined, as we used to do ...)
+ """
+ self.assertTrue(isinstance(0, int))
+ self.assertTrue(isinstance(int(1), int))
+ self.assertFalse(isinstance(1.0, int))
+
+ def test_isinstance_Integral(self):
+ """
+ Tests the preferred alternative to the above
+ """
+ self.assertTrue(isinstance(0, Integral))
+
+ def test_isinstance_long(self):
+ """
+ Py2's long doesn't inherit from int!
+ """
+ self.assertTrue(isinstance(10**100, int))
+ self.assertTrue(isinstance(int(2**64), int))
+ if not PY3:
+ self.assertTrue(isinstance(long(1), int))
+ # Note: the following is a SyntaxError on Py3:
+ # self.assertTrue(isinstance(1L, int))
+
+ def test_isinstance_bytes(self):
+ self.assertTrue(isinstance(b'byte-string', bytes))
+ self.assertFalse(isinstance(b'byte-string', str))
+
+ def test_isinstance_str(self):
+ self.assertTrue(isinstance('string', str))
+ self.assertTrue(isinstance(u'string', str))
+ self.assertFalse(isinstance(u'string', bytes))
+
+ @expectedFailurePY2
+ def test_type(self):
+ """
+ The following fails when passed a unicode string on Python
+ (including when unicode_literals is in effect) and fails when
+ passed a byte-string on Python 3. So type() always wants a native
+ string as the first argument.
+
+ TODO: maybe provide a replacement that works identically on Py2/3?
+ """
+ mytype = type('blah', (dict,), {"old": 1, "new": 2})
+ d = mytype()
+ self.assertTrue(isinstance(d, mytype))
+ self.assertTrue(isinstance(d, dict))
+
+ def test_isinstance_tuple_of_types(self):
+ # These two should be equivalent, even if ``int`` is a special
+ # backported type.
+ label = 1
+ self.assertTrue(isinstance(label, (float, Decimal)) or
+ isinstance(label, int))
+ self.assertTrue(isinstance(label, (float, Decimal, int)))
+ self.assertTrue(isinstance(10**100, (float, Decimal, int)))
+
+ self.assertTrue(isinstance(b'blah', (str, bytes)))
+ self.assertTrue(isinstance(b'blah', (bytes, float, int)))
+
+ self.assertFalse(isinstance(b'blah', (str, Decimal, float, int)))
+
+ self.assertTrue(isinstance('blah', (str, Decimal, float, int)))
+ self.assertTrue(isinstance(u'blah', (Decimal, float, int, str)))
+
+ self.assertFalse(isinstance('blah', (bytes, Decimal, float, int)))
+
+ def test_round(self):
+ """
+ Note that the Python 2.x round() function fails these tests. The
+ Python 3.x round() function passes them, as should our custom
+ round() function.
+ """
+ self.assertEqual(round(0.1250, 2), 0.12)
+ self.assertEqual(round(0.1350, 2), 0.14)
+ self.assertEqual(round(0.1251, 2), 0.13)
+ self.assertEqual(round(0.125000001, 2), 0.13)
+ self.assertEqual(round(123.5, 0), 124.0)
+ self.assertEqual(round(123.5), 124)
+ self.assertEqual(round(12.35, 2), 12.35)
+ self.assertEqual(round(12.35, 1), 12.3)
+ self.assertEqual(round(12.35, 0), 12.0)
+ self.assertEqual(round(123.5, 1), 123.5)
+
+ self.assertTrue(isinstance(round(123.5, 0), float))
+ self.assertTrue(isinstance(round(123.5), Integral))
+
+ @unittest.skip('negative ndigits not implemented yet')
+ def test_round_negative_ndigits(self):
+ self.assertEqual(round(10.1350, 0), 10.0)
+ self.assertEqual(round(10.1350, -1), 10.0)
+ self.assertEqual(round(10.1350, -2), 0.0)
+ self.assertEqual(round(10.1350, -3), 0.0)
+
+ self.assertEqual(round(12.35, -1), 10.0)
+ self.assertEqual(round(12.35, -2), 0.0)
+ self.assertEqual(round(123.5, -1), 120.0)
+ self.assertEqual(round(123.5, -2), 100.0)
+ self.assertEqual(round(123.551, -2), 100.0)
+ self.assertEqual(round(123.551, -3), 0.0)
+
+ def test_newnext_doc_example(self):
+ # Python 3-style iterator:
+ class Upper(object):
+ def __init__(self, iterable):
+ self._iter = iter(iterable)
+ def __next__(self): # note the Py3 interface
+ return next(self._iter).upper()
+ def __iter__(self):
+ return self
+
+ # from future.builtins import next
+ itr = Upper('hello')
+ self.assertEqual(next(itr), 'H')
+ self.assertEqual(next(itr), 'E')
+ # This doesn't work on Py2 because next() isn't defined:
+ # self.assertEqual(list(itr), 'LLO')
+
+ # Check that regular Py2 iterators with just a .next method also work:
+ itr2 = iter(['one', 'three', 'five'])
+ self.assertEqual(next(itr2), 'one')
+
+
+##############################################################
+# Below here are the tests from Py3.3'2 test_builtin.py module
+##############################################################
+
+from future.backports.test.support import TESTFN, unlink, run_unittest, check_warnings
+import ast
+import collections
+
+import io
+import locale
+import os
+import pickle
+import platform
+import random
+import sys
+import traceback
+import types
+# Imported above more portably (using unittest2 on Py2.6):
+import warnings
+from operator import neg
+try:
+ import pty, signal
+except ImportError:
+ pty = signal = None
+
+
+class Squares:
+
+ def __init__(self, max):
+ self.max = max
+ self.sofar = []
+
+ def __len__(self): return len(self.sofar)
+
+ def __getitem__(self, i):
+ if not 0 <= i < self.max: raise IndexError
+ n = len(self.sofar)
+ while n <= i:
+ self.sofar.append(n*n)
+ n += 1
+ return self.sofar[i]
+
+class StrSquares:
+
+ def __init__(self, max):
+ self.max = max
+ self.sofar = []
+
+ def __len__(self):
+ return len(self.sofar)
+
+ def __getitem__(self, i):
+ if not 0 <= i < self.max:
+ raise IndexError
+ n = len(self.sofar)
+ while n <= i:
+ self.sofar.append(str(n*n))
+ n += 1
+ return self.sofar[i]
+
+class BitBucket:
+ def write(self, line):
+ pass
+
+test_conv_no_sign = [
+ ('0', 0),
+ ('1', 1),
+ ('9', 9),
+ ('10', 10),
+ ('99', 99),
+ ('100', 100),
+ ('314', 314),
+ (' 314', 314),
+ ('314 ', 314),
+ (' \t\t 314 \t\t ', 314),
+ (repr(sys.maxsize), sys.maxsize),
+ (' 1x', ValueError),
+ (' 1 ', 1),
+ (' 1\02 ', ValueError),
+ ('', ValueError),
+ (' ', ValueError),
+ (' \t\t ', ValueError),
+ (str(b'\u0663\u0661\u0664 ','raw-unicode-escape'), 314),
+ (chr(0x200), ValueError),
+]
+
+test_conv_sign = [
+ ('0', 0),
+ ('1', 1),
+ ('9', 9),
+ ('10', 10),
+ ('99', 99),
+ ('100', 100),
+ ('314', 314),
+ (' 314', ValueError),
+ ('314 ', 314),
+ (' \t\t 314 \t\t ', ValueError),
+ (repr(sys.maxsize), sys.maxsize),
+ (' 1x', ValueError),
+ (' 1 ', ValueError),
+ (' 1\02 ', ValueError),
+ ('', ValueError),
+ (' ', ValueError),
+ (' \t\t ', ValueError),
+ (str(b'\u0663\u0661\u0664 ','raw-unicode-escape'), 314),
+ (chr(0x200), ValueError),
+]
+
+class TestFailingBool:
+ def __bool__(self):
+ raise RuntimeError
+ # On Py2:
+ def __nonzero__(self):
+ raise RuntimeError
+
+class TestFailingIter:
+ def __iter__(self):
+ raise RuntimeError
+
+def filter_char(arg):
+ return ord(arg) > ord("d")
+
+def map_char(arg):
+ return chr(ord(arg)+1)
+
+class BuiltinTest(unittest.TestCase):
+ # Helper to check picklability
+ def check_iter_pickle(self, it, seq):
+ itorg = it
+ d = pickle.dumps(it)
+ it = pickle.loads(d)
+ self.assertEqual(type(itorg), type(it))
+ self.assertEqual(list(it), seq)
+
+ #test the iterator after dropping one from it
+ it = pickle.loads(d)
+ try:
+ next(it)
+ except StopIteration:
+ return
+ d = pickle.dumps(it)
+ it = pickle.loads(d)
+ self.assertEqual(list(it), seq[1:])
+
+ def test_import(self):
+ __import__('sys')
+ __import__('time')
+ __import__('string')
+ __import__(name='sys')
+ __import__(name='time', level=0)
+ self.assertRaises(ImportError, __import__, 'spamspam')
+ self.assertRaises(TypeError, __import__, 1, 2, 3, 4)
+ self.assertRaises(ValueError, __import__, '')
+ self.assertRaises(TypeError, __import__, 'sys', name='sys')
+
+ def test_abs(self):
+ # int
+ self.assertEqual(abs(0), 0)
+ self.assertEqual(abs(1234), 1234)
+ self.assertEqual(abs(-1234), 1234)
+ self.assertTrue(abs(-sys.maxsize-1) > 0)
+ # float
+ self.assertEqual(abs(0.0), 0.0)
+ self.assertEqual(abs(3.14), 3.14)
+ self.assertEqual(abs(-3.14), 3.14)
+ # str
+ self.assertRaises(TypeError, abs, 'a')
+ # bool
+ self.assertEqual(abs(True), 1)
+ self.assertEqual(abs(False), 0)
+ # other
+ self.assertRaises(TypeError, abs)
+ self.assertRaises(TypeError, abs, None)
+ class AbsClass(object):
+ def __abs__(self):
+ return -5
+ self.assertEqual(abs(AbsClass()), -5)
+
+ def test_all(self):
+ self.assertEqual(all([2, 4, 6]), True)
+ self.assertEqual(all([2, None, 6]), False)
+ self.assertRaises(RuntimeError, all, [2, TestFailingBool(), 6])
+ self.assertRaises(RuntimeError, all, TestFailingIter())
+ self.assertRaises(TypeError, all, 10) # Non-iterable
+ self.assertRaises(TypeError, all) # No args
+ self.assertRaises(TypeError, all, [2, 4, 6], []) # Too many args
+ self.assertEqual(all([]), True) # Empty iterator
+ self.assertEqual(all([0, TestFailingBool()]), False)# Short-circuit
+ S = [50, 60]
+ self.assertEqual(all(x > 42 for x in S), True)
+ S = [50, 40, 60]
+ self.assertEqual(all(x > 42 for x in S), False)
+
+ def test_any(self):
+ self.assertEqual(any([None, None, None]), False)
+ self.assertEqual(any([None, 4, None]), True)
+ self.assertRaises(RuntimeError, any, [None, TestFailingBool(), 6])
+ self.assertRaises(RuntimeError, any, TestFailingIter())
+ self.assertRaises(TypeError, any, 10) # Non-iterable
+ self.assertRaises(TypeError, any) # No args
+ self.assertRaises(TypeError, any, [2, 4, 6], []) # Too many args
+ self.assertEqual(any([]), False) # Empty iterator
+ self.assertEqual(any([1, TestFailingBool()]), True) # Short-circuit
+ S = [40, 60, 30]
+ self.assertEqual(any(x > 42 for x in S), True)
+ S = [10, 20, 30]
+ self.assertEqual(any(x > 42 for x in S), False)
+
+ def test_ascii(self):
+ # Was: self.assertEqual(ascii(''), "''") # '\'\'')
+ # Heisenbug on Py2.7?!
+ self.assertEqual(ascii(0), '0')
+ self.assertEqual(ascii(()), '()')
+ self.assertEqual(ascii([]), '[]')
+ self.assertEqual(ascii({}), '{}')
+ a = []
+ a.append(a)
+ self.assertEqual(ascii(a), '[[...]]')
+ a = {}
+ a[0] = a
+ self.assertEqual(ascii(a), '{0: {...}}')
+ # Advanced checks for unicode strings
+ def _check_uni(s):
+ self.assertEqual(ascii(s), repr(s))
+ _check_uni("'")
+ _check_uni('"')
+ _check_uni('"\'')
+ _check_uni('\0')
+ _check_uni('\r\n\t .')
+ # Unprintable non-ASCII characters
+ _check_uni('\x85')
+ _check_uni('\u1fff')
+ _check_uni('\U00012fff')
+ # Lone surrogates
+ _check_uni('\ud800')
+ _check_uni('\udfff')
+
+ # Issue #9804: surrogates should be joined even for printable
+ # wide characters (UCS-2 builds).
+
+ # Fails on Py2.7. Was:
+ # self.assertEqual(ascii('\U0001d121'), "'\\U0001d121'")
+ # # All together
+ # s = "'\0\"\n\r\t abcd\x85é\U00012fff\uD800\U0001D121xxx."
+ # self.assertEqual(ascii(s),
+ # r"""'\'\x00"\n\r\t abcd\x85\xe9\U00012fff\ud800\U0001d121xxx.'""")
+
+ def test_neg(self):
+ x = -sys.maxsize-1
+ self.assertTrue(isinstance(x, int))
+ self.assertEqual(-x, sys.maxsize+1)
+
+ def test_callable(self):
+ self.assertTrue(callable(len))
+ self.assertFalse(callable("a"))
+ self.assertTrue(callable(callable))
+ self.assertTrue(callable(lambda x, y: x + y))
+ self.assertFalse(callable(__builtins__))
+ def f(): pass
+ self.assertTrue(callable(f))
+
+ class C1(object): # Was: class C1: (old-style class on Py2)
+ def meth(self): pass
+ self.assertTrue(callable(C1))
+ c = C1()
+ self.assertTrue(callable(c.meth))
+ self.assertFalse(callable(c))
+
+ # __call__ is looked up on the class, not the instance
+ c.__call__ = None
+ self.assertFalse(callable(c))
+ c.__call__ = lambda self: 0
+ self.assertFalse(callable(c))
+ del c.__call__
+ self.assertFalse(callable(c))
+
+ class C2(object):
+ def __call__(self): pass
+ c2 = C2()
+ self.assertTrue(callable(c2))
+ c2.__call__ = None
+ self.assertTrue(callable(c2))
+ class C3(C2): pass
+ c3 = C3()
+ self.assertTrue(callable(c3))
+
+ def test_chr(self):
+ self.assertEqual(chr(32), ' ')
+ self.assertEqual(chr(65), 'A')
+ self.assertEqual(chr(97), 'a')
+ self.assertEqual(chr(0xff), '\xff')
+ self.assertRaises(ValueError, chr, 1<<24)
+ self.assertRaises(TypeError, chr)
+ self.assertEqual(chr(0x0000FFFF), "\U0000FFFF")
+ self.assertRaises(ValueError, chr, -1)
+ self.assertRaises(ValueError, chr, 0x00110000)
+ self.assertRaises((OverflowError, ValueError), chr, 2**32)
+
+ @unittest.skip('FIXME: skip on narrow builds?')
+ def test_ord_big(self):
+ """
+ These tests seem to fail on OS X (narrow Python build?)
+ """
+ self.assertEqual(chr(sys.maxunicode),
+ str('\\U0010ffff'.encode("ascii"), 'unicode-escape'))
+ self.assertEqual(ord("\U0000FFFF"), 0x0000FFFF)
+ self.assertEqual(ord("\U00010000"), 0x00010000)
+ self.assertEqual(ord("\U00010001"), 0x00010001)
+ self.assertEqual(ord("\U000FFFFE"), 0x000FFFFE)
+ self.assertEqual(ord("\U000FFFFF"), 0x000FFFFF)
+ self.assertEqual(ord("\U00100000"), 0x00100000)
+ self.assertEqual(ord("\U00100001"), 0x00100001)
+ self.assertEqual(ord("\U0010FFFE"), 0x0010FFFE)
+ self.assertEqual(ord("\U0010FFFF"), 0x0010FFFF)
+
+ @unittest.skip('FIXME: skip on narrow builds?')
+ def test_chr_big(self):
+ """
+ These tests seem to fail on OS X (narrow Python build?)
+ """
+ self.assertEqual(ord(chr(0x10FFFF)), 0x10FFFF)
+ self.assertEqual(chr(0x00010000), "\U00010000")
+ self.assertEqual(chr(0x00010001), "\U00010001")
+ self.assertEqual(chr(0x000FFFFE), "\U000FFFFE")
+ self.assertEqual(chr(0x000FFFFF), "\U000FFFFF")
+ self.assertEqual(chr(0x00100000), "\U00100000")
+ self.assertEqual(chr(0x00100001), "\U00100001")
+ self.assertEqual(chr(0x0010FFFE), "\U0010FFFE")
+ self.assertEqual(chr(0x0010FFFF), "\U0010FFFF")
+
+ def test_compile(self):
+ compile('print(1)\n', '', 'exec')
+ bom = b'\xef\xbb\xbf'
+ compile(bom + b'print(1)\n', '', 'exec')
+ compile(source='pass', filename='?', mode='exec')
+ compile(dont_inherit=0, filename='tmp', source='0', mode='eval')
+ compile('pass', '?', dont_inherit=1, mode='exec')
+ # Fails on Py2.7:
+ # Was: compile(memoryview(b"text"), "name", "exec")
+ self.assertRaises(TypeError, compile)
+ self.assertRaises(ValueError, compile, 'print(42)\n', '<string>', 'badmode')
+ self.assertRaises(ValueError, compile, 'print(42)\n', '<string>', 'single', 0xff)
+ # Raises TypeError in Python < v3.5, ValueError in v3.5:
+ self.assertRaises((TypeError, ValueError), compile, chr(0), 'f', 'exec')
+ self.assertRaises(TypeError, compile, 'pass', '?', 'exec',
+ mode='eval', source='0', filename='tmp')
+ compile('print("\xe5")\n', '', 'exec')
+ self.assertRaises(ValueError, compile, str('a = 1'), 'f', 'bad')
+
+ # test the optimize argument
+ # These tests fail on Py2.7 ...
+
+ # codestr = '''def f():
+ # """doc"""
+ # try:
+ # assert False
+ # except AssertionError:
+ # return (True, f.__doc__)
+ # else:
+ # return (False, f.__doc__)
+ # '''
+ # def f(): """doc"""
+ # values = [(-1, __debug__, f.__doc__),
+ # (0, True, 'doc'),
+ # (1, False, 'doc'),
+ # (2, False, None)]
+ # for optval, debugval, docstring in values:
+ # # test both direct compilation and compilation via AST
+ # codeobjs = []
+ # codeobjs.append(compile(codestr, "<test>", "exec", optimize=optval))
+ # tree = ast.parse(codestr)
+ # codeobjs.append(compile(tree, "<test>", "exec", optimize=optval))
+ # for code in codeobjs:
+ # ns = {}
+ # exec_(code, ns)
+ # rv = ns['f']()
+ # self.assertEqual(rv, (debugval, docstring))
+
+ def test_delattr(self):
+ sys.spam = 1
+ delattr(sys, 'spam')
+ self.assertRaises(TypeError, delattr)
+
+ def test_dir(self):
+ # dir(wrong number of arguments)
+ self.assertRaises(TypeError, dir, 42, 42)
+
+ # dir() - local scope
+ local_var = 1
+ self.assertIn('local_var', dir())
+
+ # dir(module)
+ self.assertIn('exit', dir(sys))
+
+ # dir(module_with_invalid__dict__)
+ class Foo(types.ModuleType):
+ __dict__ = 8
+ f = Foo(native_str("foo"))
+ self.assertRaises(TypeError, dir, f)
+
+ # dir(type)
+ self.assertIn("strip", dir(str))
+ self.assertNotIn("__mro__", dir(str))
+
+ # dir(obj)
+ class Foo(object):
+ def __init__(self):
+ self.x = 7
+ self.y = 8
+ self.z = 9
+ f = Foo()
+ self.assertIn("y", dir(f))
+
+ # dir(obj_no__dict__)
+ class Foo(object):
+ __slots__ = []
+ f = Foo()
+ self.assertIn("__repr__", dir(f))
+
+ # dir(obj_no__class__with__dict__)
+ # (an ugly trick to cause getattr(f, "__class__") to fail)
+ class Foo(object):
+ __slots__ = ["__class__", "__dict__"]
+ def __init__(self):
+ self.bar = "wow"
+ f = Foo()
+ self.assertNotIn("__repr__", dir(f))
+ self.assertIn("bar", dir(f))
+
+ # dir(obj_using __dir__)
+ class Foo(object):
+ def __dir__(self):
+ return ["kan", "ga", "roo"]
+ f = Foo()
+ self.assertTrue(dir(f) == ["ga", "kan", "roo"])
+
+ # dir(obj__dir__tuple)
+ # Was:
+ # class Foo(object):
+ # def __dir__(self):
+ # return ("b", "c", "a")
+ # res = dir(Foo())
+ # self.assertIsInstance(res, list)
+ # self.assertTrue(res == ["a", "b", "c"])
+
+ # dir(obj__dir__not_sequence)
+ class Foo(object):
+ def __dir__(self):
+ return 7
+ f = Foo()
+ self.assertRaises(TypeError, dir, f)
+
+ # These tests fail on Py2:
+ # # dir(traceback)
+ # try:
+ # raise IndexError
+ # except:
+ # self.assertEqual(len(dir(sys.exc_info()[2])), 4)
+ #
+ # # test that object has a __dir__()
+ # self.assertEqual(sorted([].__dir__()), dir([]))
+
+ def test_divmod(self):
+ self.assertEqual(divmod(12, 7), (1, 5))
+ self.assertEqual(divmod(-12, 7), (-2, 2))
+ self.assertEqual(divmod(12, -7), (-2, -2))
+ self.assertEqual(divmod(-12, -7), (1, -5))
+
+ self.assertEqual(divmod(-sys.maxsize-1, -1), (sys.maxsize+1, 0))
+
+ for num, denom, exp_result in [ (3.25, 1.0, (3.0, 0.25)),
+ (-3.25, 1.0, (-4.0, 0.75)),
+ (3.25, -1.0, (-4.0, -0.75)),
+ (-3.25, -1.0, (3.0, -0.25))]:
+ result = divmod(num, denom)
+ self.assertAlmostEqual(result[0], exp_result[0])
+ self.assertAlmostEqual(result[1], exp_result[1])
+
+ self.assertRaises(TypeError, divmod)
+
+ def test_eval(self):
+ self.assertEqual(eval('1+1'), 2)
+ self.assertEqual(eval(' 1+1\n'), 2)
+ globals = {'a': 1, 'b': 2}
+ locals = {'b': 200, 'c': 300}
+ self.assertEqual(eval('a', globals) , 1)
+ self.assertEqual(eval('a', globals, locals), 1)
+ self.assertEqual(eval('b', globals, locals), 200)
+ self.assertEqual(eval('c', globals, locals), 300)
+ globals = {'a': 1, 'b': 2}
+ locals = {'b': 200, 'c': 300}
+ bom = b'\xef\xbb\xbf'
+ self.assertEqual(eval(bom + b'a', globals, locals), 1)
+ self.assertEqual(eval('"\xe5"', globals), "\xe5")
+ self.assertRaises(TypeError, eval)
+ self.assertRaises(TypeError, eval, ())
+ self.assertRaises(SyntaxError, eval, bom[:2] + b'a')
+
+ def test_general_eval(self):
+ # Tests that general mappings can be used for the locals argument
+
+ class M:
+ "Test mapping interface versus possible calls from eval()."
+ def __getitem__(self, key):
+ if key == 'a':
+ return 12
+ raise KeyError
+ def keys(self):
+ return list('xyz')
+
+ m = M()
+ g = globals()
+ self.assertEqual(eval('a', g, m), 12)
+ self.assertRaises(NameError, eval, 'b', g, m)
+ self.assertEqual(eval('dir()', g, m), list('xyz'))
+ self.assertEqual(eval('globals()', g, m), g)
+ self.assertEqual(eval('locals()', g, m), m)
+ self.assertRaises(TypeError, eval, 'a', m)
+ class A:
+ "Non-mapping"
+ pass
+ m = A()
+ self.assertRaises(TypeError, eval, 'a', g, m)
+
+ # Verify that dict subclasses work as well
+ class D(dict):
+ def __getitem__(self, key):
+ if key == 'a':
+ return 12
+ return dict.__getitem__(self, key)
+ def keys(self):
+ return list('xyz')
+
+ d = D()
+ self.assertEqual(eval('a', g, d), 12)
+ self.assertRaises(NameError, eval, 'b', g, d)
+ self.assertEqual(eval('dir()', g, d), list('xyz'))
+ self.assertEqual(eval('globals()', g, d), g)
+ self.assertEqual(eval('locals()', g, d), d)
+
+ # Verify locals stores (used by list comps)
+ eval('[locals() for i in (2,3)]', g, d)
+ if PY3:
+ from collections import UserDict
+ else:
+ from UserDict import UserDict
+ eval('[locals() for i in (2,3)]', g, UserDict())
+
+ class SpreadSheet:
+ "Sample application showing nested, calculated lookups."
+ _cells = {}
+ def __setitem__(self, key, formula):
+ self._cells[key] = formula
+ def __getitem__(self, key):
+ return eval(self._cells[key], globals(), self)
+
+ ss = SpreadSheet()
+ ss['a1'] = '5'
+ ss['a2'] = 'a1*6'
+ ss['a3'] = 'a2*7'
+ self.assertEqual(ss['a3'], 210)
+
+ # Verify that dir() catches a non-list returned by eval
+ # SF bug #1004669
+ class C:
+ def __getitem__(self, item):
+ raise KeyError(item)
+ def keys(self):
+ return 1 # used to be 'a' but that's no longer an error
+ self.assertRaises(TypeError, eval, 'dir()', globals(), C())
+
+ def test_exec_(self):
+ g = {}
+ exec_('z = 1', g)
+ if '__builtins__' in g:
+ del g['__builtins__']
+ self.assertEqual(g, {'z': 1})
+
+ exec_('z = 1+1', g)
+ if '__builtins__' in g:
+ del g['__builtins__']
+ self.assertEqual(g, {'z': 2})
+ g = {}
+ l = {}
+
+ with check_warnings():
+ warnings.filterwarnings("ignore", "global statement",
+ module="<string>")
+ exec_('global a; a = 1; b = 2', g, l)
+ if '__builtins__' in g:
+ del g['__builtins__']
+ if '__builtins__' in l:
+ del l['__builtins__']
+ self.assertEqual((g, l), ({'a': 1}, {'b': 2}))
+
+ def test_exec_globals(self):
+ code = compile("print('Hello World!')", "", "exec")
+ # no builtin function
+ # Was:
+ # self.assertRaisesRegex(NameError, "name 'print' is not defined",
+ # exec_, code, {'__builtins__': {}})
+ # Now:
+ self.assertRaises(NameError,
+ exec_, code, {'__builtins__': {}})
+ # __builtins__ must be a mapping type
+ # Was:
+ # self.assertRaises(TypeError,
+ # exec_, code, {'__builtins__': 123})
+ # Raises a NameError again on Py2
+
+ # no __build_class__ function
+ code = compile("class A: pass", "", "exec")
+ # Was:
+ # self.assertRaisesRegex(NameError, "__build_class__ not found",
+ # exec_, code, {'__builtins__': {}})
+ self.assertRaises(NameError,
+ exec_, code, {'__builtins__': {}})
+
+ class frozendict_error(Exception):
+ pass
+
+ class frozendict(dict):
+ def __setitem__(self, key, value):
+ raise frozendict_error("frozendict is readonly")
+
+ # This test seems to fail with "TypeError: 'module' object is not iterable":
+ # # read-only builtins
+ # frozen_builtins = frozendict(__builtins__)
+ # code = compile("__builtins__['superglobal']=2; print(superglobal)", "test", "exec")
+ # self.assertRaises(frozendict_error,
+ # exec_, code, {'__builtins__': frozen_builtins})
+
+ # read-only globals
+ namespace = frozendict({})
+ code = compile("x=1", "test", "exec")
+ self.assertRaises(frozendict_error,
+ exec_, code, namespace)
+
+ def test_exec_redirected(self):
+ savestdout = sys.stdout
+ sys.stdout = None # Whatever that cannot flush()
+ try:
+ # Used to raise SystemError('error return without exception set')
+ exec_('a')
+ except NameError:
+ pass
+ finally:
+ sys.stdout = savestdout
+
+ def test_filter(self):
+ self.assertEqual(list(filter(lambda c: 'a' <= c <= 'z', 'Hello World')), list('elloorld'))
+ self.assertEqual(list(filter(None, [1, 'hello', [], [3], '', None, 9, 0])), [1, 'hello', [3], 9])
+ self.assertEqual(list(filter(lambda x: x > 0, [1, -3, 9, 0, 2])), [1, 9, 2])
+ self.assertEqual(list(filter(None, Squares(10))), [1, 4, 9, 16, 25, 36, 49, 64, 81])
+ self.assertEqual(list(filter(lambda x: x%2, Squares(10))), [1, 9, 25, 49, 81])
+ def identity(item):
+ return 1
+ filter(identity, Squares(5))
+ self.assertRaises(TypeError, filter)
+ class BadSeq(object):
+ def __getitem__(self, index):
+ if index<4:
+ return 42
+ raise ValueError
+ self.assertRaises(ValueError, list, filter(lambda x: x, BadSeq()))
+ def badfunc():
+ pass
+ self.assertRaises(TypeError, list, filter(badfunc, range(5)))
+
+ # test bltinmodule.c::filtertuple()
+ self.assertEqual(list(filter(None, (1, 2))), [1, 2])
+ self.assertEqual(list(filter(lambda x: x>=3, (1, 2, 3, 4))), [3, 4])
+ self.assertRaises(TypeError, list, filter(42, (1, 2)))
+
+ @expectedFailurePY2
+ def test_filter_pickle(self):
+ f1 = filter(filter_char, "abcdeabcde")
+ f2 = filter(filter_char, "abcdeabcde")
+ self.check_iter_pickle(f1, list(f2))
+
+ def test_getattr(self):
+ self.assertTrue(getattr(sys, 'stdout') is sys.stdout)
+ self.assertRaises(TypeError, getattr, sys, 1)
+ self.assertRaises(TypeError, getattr, sys, 1, "foo")
+ self.assertRaises(TypeError, getattr)
+ # These tests fail on Py2:
+ # self.assertRaises(AttributeError, getattr, sys, chr(sys.maxunicode))
+ # unicode surrogates are not encodable to the default encoding (utf8)
+ # self.assertRaises(AttributeError, getattr, 1, "\uDAD1\uD51E")
+ # This test fails on Py2
+
+ def test_hasattr(self):
+ self.assertTrue(hasattr(sys, 'stdout'))
+ self.assertRaises(TypeError, hasattr, sys, 1)
+ self.assertRaises(TypeError, hasattr)
+ # Fails on Py2:
+ # self.assertEqual(False, hasattr(sys, chr(sys.maxunicode)))
+
+ # Check that hasattr propagates all exceptions outside of
+ # AttributeError.
+ class A(object):
+ def __getattr__(self, what):
+ raise SystemExit
+ self.assertRaises(SystemExit, hasattr, A(), "b")
+ class B(object):
+ def __getattr__(self, what):
+ raise ValueError
+ # Was: self.assertRaises(ValueError, hasattr, B(), "b")
+ # Fails on Py2
+
+ def test_hash(self):
+ hash(None)
+ self.assertEqual(hash(1), hash(1))
+ self.assertEqual(hash(1), hash(1.0))
+ hash('spam')
+ self.assertEqual(hash('spam'), hash(b'spam'))
+ hash((0,1,2,3))
+ def f(): pass
+ self.assertRaises(TypeError, hash, [])
+ self.assertRaises(TypeError, hash, {})
+ # Bug 1536021: Allow hash to return long objects
+ class X:
+ def __hash__(self):
+ return 2**100
+ self.assertTrue(isinstance(hash(X()), int))
+ class Z(int):
+ def __hash__(self):
+ return self
+ self.assertEqual(hash(Z(42)), hash(42))
+
+ def test_hex(self):
+ self.assertEqual(hex(16), '0x10')
+ self.assertEqual(hex(-16), '-0x10')
+ self.assertRaises(TypeError, hex, {})
+
+ def test_id(self):
+ id(None)
+ id(1)
+ id(1.0)
+ id('spam')
+ id((0,1,2,3))
+ id([0,1,2,3])
+ id({'spam': 1, 'eggs': 2, 'ham': 3})
+
+ # Test input() later, alphabetized as if it were raw_input
+
+ def test_iter(self):
+ self.assertRaises(TypeError, iter)
+ self.assertRaises(TypeError, iter, 42, 42)
+ lists = [("1", "2"), ["1", "2"], "12"]
+ for l in lists:
+ i = iter(l)
+ self.assertEqual(next(i), '1')
+ self.assertEqual(next(i), '2')
+ self.assertRaises(StopIteration, next, i)
+
+ def test_isinstance(self):
+ class C:
+ pass
+ class D(C):
+ pass
+ class E:
+ pass
+ c = C()
+ d = D()
+ e = E()
+ self.assertTrue(isinstance(c, C))
+ self.assertTrue(isinstance(d, C))
+ self.assertTrue(not isinstance(e, C))
+ self.assertTrue(not isinstance(c, D))
+ self.assertTrue(not isinstance('foo', E))
+ self.assertRaises(TypeError, isinstance, E, 'foo')
+ self.assertRaises(TypeError, isinstance)
+
+ def test_issubclass(self):
+ class C:
+ pass
+ class D(C):
+ pass
+ class E:
+ pass
+ c = C()
+ d = D()
+ e = E()
+ self.assertTrue(issubclass(D, C))
+ self.assertTrue(issubclass(C, C))
+ self.assertTrue(not issubclass(C, D))
+ self.assertRaises(TypeError, issubclass, 'foo', E)
+ self.assertRaises(TypeError, issubclass, E, 'foo')
+ self.assertRaises(TypeError, issubclass)
+
+ def test_len(self):
+ self.assertEqual(len('123'), 3)
+ self.assertEqual(len(()), 0)
+ self.assertEqual(len((1, 2, 3, 4)), 4)
+ self.assertEqual(len([1, 2, 3, 4]), 4)
+ self.assertEqual(len({}), 0)
+ self.assertEqual(len({'a':1, 'b': 2}), 2)
+ class BadSeq:
+ def __len__(self):
+ raise ValueError
+ self.assertRaises(ValueError, len, BadSeq())
+ class InvalidLen:
+ def __len__(self):
+ return None
+ self.assertRaises(TypeError, len, InvalidLen())
+ class FloatLen:
+ def __len__(self):
+ return 4.5
+ self.assertRaises(TypeError, len, FloatLen())
+ class HugeLen:
+ def __len__(self):
+ return sys.maxsize + 1
+ # Was: self.assertRaises(OverflowError, len, HugeLen())
+ class NoLenMethod(object): pass
+ self.assertRaises(TypeError, len, NoLenMethod())
+
+ def test_map(self):
+ self.assertEqual(
+ list(map(lambda x: x*x, range(1,4))),
+ [1, 4, 9]
+ )
+ try:
+ from math import sqrt
+ except ImportError:
+ def sqrt(x):
+ return pow(x, 0.5)
+ self.assertEqual(
+ list(map(lambda x: list(map(sqrt, x)), [[16, 4], [81, 9]])),
+ [[4.0, 2.0], [9.0, 3.0]]
+ )
+ self.assertEqual(
+ list(map(lambda x, y: x+y, [1,3,2], [9,1,4])),
+ [10, 4, 6]
+ )
+
+ def plus(*v):
+ accu = 0
+ for i in v: accu = accu + i
+ return accu
+ self.assertEqual(
+ list(map(plus, [1, 3, 7])),
+ [1, 3, 7]
+ )
+ self.assertEqual(
+ list(map(plus, [1, 3, 7], [4, 9, 2])),
+ [1+4, 3+9, 7+2]
+ )
+ self.assertEqual(
+ list(map(plus, [1, 3, 7], [4, 9, 2], [1, 1, 0])),
+ [1+4+1, 3+9+1, 7+2+0]
+ )
+ self.assertEqual(
+ list(map(int, Squares(10))),
+ [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
+ )
+ def Max(a, b):
+ if a is None:
+ return b
+ if b is None:
+ return a
+ return max(a, b)
+ self.assertEqual(
+ list(map(Max, Squares(3), Squares(2))),
+ [0, 1]
+ )
+ self.assertRaises(TypeError, map)
+ self.assertRaises(TypeError, map, lambda x: x, 42)
+ class BadSeq:
+ def __iter__(self):
+ raise ValueError
+ yield None
+ self.assertRaises(ValueError, list, map(lambda x: x, BadSeq()))
+ def badfunc(x):
+ raise RuntimeError
+ self.assertRaises(RuntimeError, list, map(badfunc, range(5)))
+
+ @expectedFailurePY2
+ def test_map_pickle(self):
+ m1 = map(map_char, "Is this the real life?")
+ m2 = map(map_char, "Is this the real life?")
+ self.check_iter_pickle(m1, list(m2))
+
+ def test_max(self):
+ self.assertEqual(max('123123'), '3')
+ self.assertEqual(max(1, 2, 3), 3)
+ self.assertEqual(max((1, 2, 3, 1, 2, 3)), 3)
+ self.assertEqual(max([1, 2, 3, 1, 2, 3]), 3)
+
+ self.assertEqual(max(1, 2, 3.0), 3.0)
+ self.assertEqual(max(1, 2.0, 3), 3)
+ self.assertEqual(max(1.0, 2, 3), 3)
+
+ for stmt in (
+ "max(key=int)", # no args
+ "max(1, key=int)", # single arg not iterable
+ "max(1, 2, keystone=int)", # wrong keyword
+ "max(1, 2, key=int, abc=int)", # two many keywords
+ "max(1, 2, key=1)", # keyfunc is not callable
+ ):
+ try:
+ exec_(stmt, globals())
+ except TypeError:
+ pass
+ else:
+ self.fail(stmt)
+
+ self.assertEqual(max((1,), key=neg), 1) # one elem iterable
+ self.assertEqual(max((1,2), key=neg), 1) # two elem iterable
+ self.assertEqual(max(1, 2, key=neg), 1) # two elems
+
+ data = [random.randrange(200) for i in range(100)]
+ keys = dict((elem, random.randrange(50)) for elem in data)
+ f = keys.__getitem__
+ self.assertEqual(max(data, key=f),
+ sorted(reversed(data), key=f)[-1])
+
+ self.assertEqual(max([], default=5), 5)
+ with self.assertRaises(TypeError):
+ max(None, default=5)
+ with self.assertRaises(TypeError):
+ max(1, 2, default=0)
+ self.assertEqual(max([], default=0), 0)
+ self.assertIs(max([], default=None), None)
+
+ def test_min(self):
+ self.assertEqual(min('123123'), '1')
+ self.assertEqual(min(1, 2, 3), 1)
+ self.assertEqual(min((1, 2, 3, 1, 2, 3)), 1)
+ self.assertEqual(min([1, 2, 3, 1, 2, 3]), 1)
+
+ self.assertEqual(min(1, 2, 3.0), 1)
+ self.assertEqual(min(1, 2.0, 3), 1)
+ self.assertEqual(min(1.0, 2, 3), 1.0)
+
+ self.assertRaises(TypeError, min)
+ self.assertRaises(TypeError, min, 42)
+ self.assertRaises(ValueError, min, ())
+ class BadSeq:
+ def __getitem__(self, index):
+ raise ValueError
+ self.assertRaises(ValueError, min, BadSeq())
+ self.assertEqual(max(x for x in [5, 4, 3]), 5)
+
+ for stmt in (
+ "min(key=int)", # no args
+ "min(1, key=int)", # single arg not iterable
+ "min(1, 2, keystone=int)", # wrong keyword
+ "min(1, 2, key=int, abc=int)", # two many keywords
+ "min(1, 2, key=1)", # keyfunc is not callable
+ ):
+ try:
+ exec_(stmt, globals())
+ except TypeError:
+ pass
+ else:
+ self.fail(stmt)
+
+ self.assertEqual(min((1,), key=neg), 1) # one elem iterable
+ self.assertEqual(min((1,2), key=neg), 2) # two elem iterable
+ self.assertEqual(min(1, 2, key=neg), 2) # two elems
+
+ data = [random.randrange(200) for i in range(100)]
+ keys = dict((elem, random.randrange(50)) for elem in data)
+ f = keys.__getitem__
+ self.assertEqual(min(data, key=f),
+ sorted(data, key=f)[0])
+ self.assertEqual(min([], default=5), 5)
+ self.assertEqual(min([], default=0), 0)
+ self.assertIs(min([], default=None), None)
+ with self.assertRaises(TypeError):
+ max(None, default=5)
+ with self.assertRaises(TypeError):
+ max(1, 2, default=0)
+
+ # Test iterables that can only be looped once #510
+ self.assertEqual(min(x for x in [5]), 5)
+
+ def test_next(self):
+ it = iter(range(2))
+ self.assertEqual(next(it), 0)
+ self.assertEqual(next(it), 1)
+ self.assertRaises(StopIteration, next, it)
+ self.assertRaises(StopIteration, next, it)
+ self.assertEqual(next(it, 42), 42)
+
+ class Iter(object):
+ def __iter__(self):
+ return self
+ def __next__(self):
+ raise StopIteration
+
+ # Was: it = iter(Iter())
+ # Needs this on Py2:
+ Iter = implements_iterator(Iter)
+ it = iter(Iter())
+ self.assertEqual(next(it, 42), 42)
+ self.assertRaises(StopIteration, next, it)
+
+ def gen():
+ yield 1
+ return
+
+ it = gen()
+ self.assertEqual(next(it), 1)
+ self.assertRaises(StopIteration, next, it)
+ self.assertEqual(next(it, 42), 42)
+
+ def test_oct(self):
+ self.assertEqual(oct(100), '0o144')
+ self.assertEqual(oct(-100), '-0o144')
+ self.assertRaises(TypeError, oct, ())
+
+ def write_testfile(self):
+ # NB the first 4 lines are also used to test input, below
+ fp = open(TESTFN, 'w')
+ try:
+ fp.write('1+1\n')
+ fp.write('The quick brown fox jumps over the lazy dog')
+ fp.write('.\n')
+ fp.write('Dear John\n')
+ fp.write('XXX'*100)
+ fp.write('YYY'*100)
+ finally:
+ fp.close()
+
+ def test_open(self):
+ self.write_testfile()
+ fp = open(TESTFN, 'r')
+ try:
+ self.assertEqual(fp.readline(4), '1+1\n')
+ self.assertEqual(fp.readline(), 'The quick brown fox jumps over the lazy dog.\n')
+ self.assertEqual(fp.readline(4), 'Dear')
+ self.assertEqual(fp.readline(100), ' John\n')
+ self.assertEqual(fp.read(300), 'XXX'*100)
+ self.assertEqual(fp.read(1000), 'YYY'*100)
+ finally:
+ fp.close()
+ unlink(TESTFN)
+
+ def test_open_default_encoding(self):
+ old_environ = dict(os.environ)
+ try:
+ # try to get a user preferred encoding different than the current
+ # locale encoding to check that open() uses the current locale
+ # encoding and not the user preferred encoding
+ for key in ('LC_ALL', 'LANG', 'LC_CTYPE'):
+ if key in os.environ:
+ del os.environ[key]
+
+ self.write_testfile()
+ current_locale_encoding = locale.getpreferredencoding(False)
+ fp = open(TESTFN, 'w')
+ try:
+ self.assertEqual(fp.encoding, current_locale_encoding)
+ finally:
+ fp.close()
+ unlink(TESTFN)
+ finally:
+ os.environ.clear()
+ os.environ.update(old_environ)
+
+ def test_ord(self):
+ self.assertEqual(ord(' '), 32)
+ self.assertEqual(ord('A'), 65)
+ self.assertEqual(ord('a'), 97)
+ self.assertEqual(ord('\x80'), 128)
+ self.assertEqual(ord('\xff'), 255)
+
+ self.assertEqual(ord(b' '), 32)
+ self.assertEqual(ord(b'A'), 65)
+ self.assertEqual(ord(b'a'), 97)
+ self.assertEqual(ord(b'\x80'), 128)
+ self.assertEqual(ord(b'\xff'), 255)
+
+ self.assertEqual(ord(chr(sys.maxunicode)), sys.maxunicode)
+ self.assertRaises(TypeError, ord, 42)
+
+ def test_pow(self):
+ self.assertEqual(pow(0,0), 1)
+ self.assertEqual(pow(0,1), 0)
+ self.assertEqual(pow(1,0), 1)
+ self.assertEqual(pow(1,1), 1)
+
+ self.assertEqual(pow(2,0), 1)
+ self.assertEqual(pow(2,10), 1024)
+ self.assertEqual(pow(2,20), 1024*1024)
+ self.assertEqual(pow(2,30), 1024*1024*1024)
+
+ self.assertEqual(pow(-2,0), 1)
+ self.assertEqual(pow(-2,1), -2)
+ self.assertEqual(pow(-2,2), 4)
+ self.assertEqual(pow(-2,3), -8)
+
+ self.assertAlmostEqual(pow(0.,0), 1.)
+ self.assertAlmostEqual(pow(0.,1), 0.)
+ self.assertAlmostEqual(pow(1.,0), 1.)
+ self.assertAlmostEqual(pow(1.,1), 1.)
+
+ self.assertAlmostEqual(pow(2.,0), 1.)
+ self.assertAlmostEqual(pow(2.,10), 1024.)
+ self.assertAlmostEqual(pow(2.,20), 1024.*1024.)
+ self.assertAlmostEqual(pow(2.,30), 1024.*1024.*1024.)
+
+ self.assertAlmostEqual(pow(-2.,0), 1.)
+ self.assertAlmostEqual(pow(-2.,1), -2.)
+ self.assertAlmostEqual(pow(-2.,2), 4.)
+ self.assertAlmostEqual(pow(-2.,3), -8.)
+
+ for x in 2, int(2), 2.0:
+ for y in 10, int(10), 10.0:
+ for z in 1000, int(1000), 1000.0:
+ if isinstance(x, float) or \
+ isinstance(y, float) or \
+ isinstance(z, float):
+ self.assertRaises(TypeError, pow, x, y, z)
+ else:
+ self.assertAlmostEqual(pow(x, y, z), 24.0)
+
+ 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)
+ self.assertRaises(ValueError, pow, 1, 2, 0)
+
+ self.assertRaises(TypeError, pow)
+
+ def test_input(self):
+ self.write_testfile()
+ fp = open(TESTFN, 'r')
+ savestdin = sys.stdin
+ savestdout = sys.stdout # Eats the echo
+ try:
+ sys.stdin = fp
+ sys.stdout = BitBucket()
+ self.assertEqual(input(), "1+1")
+ self.assertEqual(input(), 'The quick brown fox jumps over the lazy dog.')
+ self.assertEqual(input('testing\n'), 'Dear John')
+
+ # SF 1535165: don't segfault on closed stdin
+ # sys.stdout must be a regular file for triggering
+ sys.stdout = savestdout
+ sys.stdin.close()
+ self.assertRaises(ValueError, input)
+
+ sys.stdout = BitBucket()
+ sys.stdin = io.StringIO("NULL\0")
+ self.assertRaises(TypeError, input, 42, 42)
+ sys.stdin = io.StringIO(" 'whitespace'")
+ self.assertEqual(input(), " 'whitespace'")
+ sys.stdin = io.StringIO()
+ self.assertRaises(EOFError, input)
+
+ del sys.stdout
+ self.assertRaises(RuntimeError, input, 'prompt')
+ del sys.stdin
+ self.assertRaises(RuntimeError, input, 'prompt')
+ finally:
+ sys.stdin = savestdin
+ sys.stdout = savestdout
+ fp.close()
+ unlink(TESTFN)
+
+ @expectedFailurePY2
+ @unittest.skipUnless(pty, "the pty and signal modules must be available")
+ def check_input_tty(self, prompt, terminal_input, stdio_encoding=None):
+ if not sys.stdin.isatty() or not sys.stdout.isatty():
+ self.skipTest("stdin and stdout must be ttys")
+ r, w = os.pipe()
+ try:
+ pid, fd = pty.fork()
+ except (OSError, AttributeError) as e:
+ os.close(r)
+ os.close(w)
+ self.skipTest("pty.fork() raised {0}".format(e))
+ if pid == 0:
+ # Child
+ try:
+ # Make sure we don't get stuck if there's a problem
+ signal.alarm(2)
+ os.close(r)
+ # Check the error handlers are accounted for
+ if stdio_encoding:
+ sys.stdin = io.TextIOWrapper(sys.stdin.detach(),
+ encoding=stdio_encoding,
+ errors='surrogateescape')
+ sys.stdout = io.TextIOWrapper(sys.stdout.detach(),
+ encoding=stdio_encoding,
+ errors='replace')
+ with open(w, "w") as wpipe:
+ print("tty =", sys.stdin.isatty() and sys.stdout.isatty(), file=wpipe)
+ print(ascii(input(prompt)), file=wpipe)
+ except:
+ traceback.print_exc()
+ finally:
+ # We don't want to return to unittest...
+ os._exit(0)
+ # Parent
+ os.close(w)
+ os.write(fd, terminal_input + b"\r\n")
+ # Get results from the pipe
+ with open(r, "r") as rpipe:
+ lines = []
+ while True:
+ line = rpipe.readline().strip()
+ if line == "":
+ # The other end was closed => the child exited
+ break
+ lines.append(line)
+ # Check the result was got and corresponds to the user's terminal input
+ if len(lines) != 2:
+ # Something went wrong, try to get at stderr
+ with open(fd, "r", encoding="ascii", errors="ignore") as child_output:
+ self.fail("got %d lines in pipe but expected 2, child output was:\n%s"
+ % (len(lines), child_output.read()))
+ os.close(fd)
+ # Check we did exercise the GNU readline path
+ self.assertIn(lines[0], set(['tty = True', 'tty = False']))
+ if lines[0] != 'tty = True':
+ self.skipTest("standard IO in should have been a tty")
+ input_result = eval(lines[1]) # ascii() -> eval() roundtrip
+ if stdio_encoding:
+ expected = terminal_input.decode(stdio_encoding, 'surrogateescape')
+ else:
+ expected = terminal_input.decode(sys.stdin.encoding) # what else?
+ self.assertEqual(input_result, expected)
+
+ @expectedFailurePY26
+ def test_input_tty(self):
+ # Test input() functionality when wired to a tty (the code path
+ # is different and invokes GNU readline if available).
+ self.check_input_tty("prompt", b"quux")
+
+ @expectedFailurePY26
+ def test_input_tty_non_ascii(self):
+ # Check stdin/stdout encoding is used when invoking GNU readline
+ self.check_input_tty("prompté", b"quux\xe9", "utf-8")
+
+ @expectedFailurePY26
+ def test_input_tty_non_ascii_unicode_errors(self):
+ # Check stdin/stdout error handler is used when invoking GNU readline
+ self.check_input_tty("prompté", b"quux\xe9", "ascii")
+
+ # test_int(): see test_int.py for tests of built-in function int().
+
+ def test_repr(self):
+ # Was: self.assertEqual(repr(''), "\'\'")
+ # Why is this failing on Py2.7? A Heisenbug ...
+ self.assertEqual(repr(0), '0')
+ self.assertEqual(repr(()), '()')
+ self.assertEqual(repr([]), '[]')
+ self.assertEqual(repr({}), '{}')
+
+ # Future versions of the above:
+ self.assertEqual(repr(str('')), '\'\'')
+ self.assertEqual(repr(int(0)), '0')
+ self.assertEqual(repr(dict({})), '{}')
+ self.assertEqual(repr(dict()), '{}')
+
+ a = []
+ a.append(a)
+ self.assertEqual(repr(a), '[[...]]')
+ a = {}
+ a[0] = a
+ self.assertEqual(repr(a), '{0: {...}}')
+
+ @expectedFailurePY2
+ def test_round(self):
+ self.assertEqual(round(0.0), 0.0)
+ # Was: self.assertEqual(type(round(0.0)), int)
+ # Now:
+ self.assertTrue(isinstance(round(0.0), int))
+ self.assertEqual(round(1.0), 1.0)
+ self.assertEqual(round(10.0), 10.0)
+ self.assertEqual(round(1000000000.0), 1000000000.0)
+ self.assertEqual(round(1e20), 1e20)
+
+ self.assertEqual(round(-1.0), -1.0)
+ self.assertEqual(round(-10.0), -10.0)
+ self.assertEqual(round(-1000000000.0), -1000000000.0)
+ self.assertEqual(round(-1e20), -1e20)
+
+ self.assertEqual(round(0.1), 0.0)
+ self.assertEqual(round(1.1), 1.0)
+ self.assertEqual(round(10.1), 10.0)
+ self.assertEqual(round(1000000000.1), 1000000000.0)
+
+ self.assertEqual(round(-1.1), -1.0)
+ self.assertEqual(round(-10.1), -10.0)
+ self.assertEqual(round(-1000000000.1), -1000000000.0)
+
+ self.assertEqual(round(0.9), 1.0)
+ self.assertEqual(round(9.9), 10.0)
+ self.assertEqual(round(999999999.9), 1000000000.0)
+
+ self.assertEqual(round(-0.9), -1.0)
+ self.assertEqual(round(-9.9), -10.0)
+ self.assertEqual(round(-999999999.9), -1000000000.0)
+
+ self.assertEqual(round(-8.0, -1), -10.0)
+ self.assertEqual(type(round(-8.0, -1)), float)
+
+ self.assertEqual(type(round(-8.0, 0)), float)
+ self.assertEqual(type(round(-8.0, 1)), float)
+
+ # Check even / odd rounding behaviour
+ self.assertEqual(round(5.5), 6)
+ self.assertEqual(round(6.5), 6)
+ self.assertEqual(round(-5.5), -6)
+ self.assertEqual(round(-6.5), -6)
+
+ # Check behavior on ints
+ self.assertEqual(round(0), 0)
+ self.assertEqual(round(8), 8)
+ self.assertEqual(round(-8), -8)
+ # Was:
+ # self.assertEqual(type(round(0)), int)
+ # self.assertEqual(type(round(-8, -1)), int)
+ # self.assertEqual(type(round(-8, 0)), int)
+ # self.assertEqual(type(round(-8, 1)), int)
+ # Now:
+ self.assertTrue(isinstance(round(0), int))
+ self.assertTrue(isinstance(round(-8, -1), int))
+ self.assertTrue(isinstance(round(-8, 0), int))
+ self.assertTrue(isinstance(round(-8, 1), int))
+
+ # test new kwargs
+ self.assertEqual(round(number=-8.0, ndigits=-1), -10.0)
+
+ self.assertRaises(TypeError, round)
+
+ # test generic rounding delegation for reals
+ class TestRound:
+ def __round__(self):
+ return 23
+
+ class TestNoRound:
+ pass
+
+ self.assertEqual(round(TestRound()), 23)
+
+ self.assertRaises(TypeError, round, 1, 2, 3)
+ self.assertRaises(TypeError, round, TestNoRound())
+
+ t = TestNoRound()
+ t.__round__ = lambda *args: args
+ self.assertRaises(TypeError, round, t)
+ self.assertRaises(TypeError, round, t, 0)
+
+ # # Some versions of glibc for alpha have a bug that affects
+ # # float -> integer rounding (floor, ceil, rint, round) for
+ # # values in the range [2**52, 2**53). See:
+ # #
+ # # http://sources.redhat.com/bugzilla/show_bug.cgi?id=5350
+ # #
+ # # We skip this test on Linux/alpha if it would fail.
+ # linux_alpha = (platform.system().startswith('Linux') and
+ # platform.machine().startswith('alpha'))
+ # system_round_bug = round(5e15+1) != 5e15+1
+ # @unittest.skipIf(PY26)linux_alpha and system_round_bug,
+ # "test will fail; failure is probably due to a "
+ # "buggy system round function")
+ @skip26
+ def test_round_large(self):
+ # Issue #1869: integral floats should remain unchanged
+ self.assertEqual(round(5e15-1), 5e15-1)
+ self.assertEqual(round(5e15), 5e15)
+ self.assertEqual(round(5e15+1), 5e15+1)
+ self.assertEqual(round(5e15+2), 5e15+2)
+ self.assertEqual(round(5e15+3), 5e15+3)
+
+ def test_setattr(self):
+ setattr(sys, 'spam', 1)
+ self.assertEqual(sys.spam, 1)
+ self.assertRaises(TypeError, setattr, sys, 1, 'spam')
+ self.assertRaises(TypeError, setattr)
+
+ # test_str(): see test_unicode.py and test_bytes.py for str() tests.
+
+ def test_sum(self):
+ self.assertEqual(sum([]), 0)
+ self.assertEqual(sum(list(range(2,8))), 27)
+ self.assertEqual(sum(iter(list(range(2,8)))), 27)
+ self.assertEqual(sum(Squares(10)), 285)
+ self.assertEqual(sum(iter(Squares(10))), 285)
+ self.assertEqual(sum([[1], [2], [3]], []), [1, 2, 3])
+
+ self.assertRaises(TypeError, sum)
+ self.assertRaises(TypeError, sum, 42)
+ self.assertRaises(TypeError, sum, ['a', 'b', 'c'])
+ self.assertRaises(TypeError, sum, ['a', 'b', 'c'], '')
+ self.assertRaises(TypeError, sum, [b'a', b'c'], b'')
+ # Was:
+ # values = [bytearray(b'a'), bytearray(b'b')]
+ # self.assertRaises(TypeError, sum, values, bytearray(b''))
+ # Currently fails on Py2 -- i.e. sum(values, bytearray(b'')) is allowed
+ self.assertRaises(TypeError, sum, [[1], [2], [3]])
+ self.assertRaises(TypeError, sum, [{2:3}])
+ self.assertRaises(TypeError, sum, [{2:3}]*2, {2:3})
+
+ class BadSeq:
+ def __getitem__(self, index):
+ raise ValueError
+ self.assertRaises(ValueError, sum, BadSeq())
+
+ empty = []
+ sum(([x] for x in range(10)), empty)
+ self.assertEqual(empty, [])
+
+ def test_type(self):
+ self.assertEqual(type(''), type('123'))
+ self.assertNotEqual(type(''), type(()))
+
+ # We don't want self in vars(), so these are static methods
+
+ @staticmethod
+ def get_vars_f0():
+ return vars()
+
+ @staticmethod
+ def get_vars_f2():
+ BuiltinTest.get_vars_f0()
+ a = 1
+ b = 2
+ return vars()
+
+ class C_get_vars(object):
+ def getDict(self):
+ return {'a':2}
+ __dict__ = property(fget=getDict)
+
+ def test_vars(self):
+ self.assertEqual(set(vars()), set(dir()))
+ self.assertEqual(set(vars(sys)), set(dir(sys)))
+ self.assertEqual(self.get_vars_f0(), {})
+ self.assertEqual(self.get_vars_f2(), {'a': 1, 'b': 2})
+ self.assertRaises(TypeError, vars, 42, 42)
+ self.assertRaises(TypeError, vars, 42)
+ self.assertEqual(vars(self.C_get_vars()), {'a':2})
+
+ def test_zip(self):
+ a = (1, 2, 3)
+ b = (4, 5, 6)
+ t = [(1, 4), (2, 5), (3, 6)]
+ self.assertEqual(list(zip(a, b)), t)
+ b = [4, 5, 6]
+ self.assertEqual(list(zip(a, b)), t)
+ b = (4, 5, 6, 7)
+ self.assertEqual(list(zip(a, b)), t)
+ class I:
+ def __getitem__(self, i):
+ if i < 0 or i > 2: raise IndexError
+ return i + 4
+ self.assertEqual(list(zip(a, I())), t)
+ self.assertEqual(list(zip()), [])
+ self.assertEqual(list(zip(*[])), [])
+ self.assertRaises(TypeError, zip, None)
+ class G:
+ pass
+ self.assertRaises(TypeError, zip, a, G())
+ self.assertRaises(RuntimeError, zip, a, TestFailingIter())
+
+ # Make sure zip doesn't try to allocate a billion elements for the
+ # result list when one of its arguments doesn't say how long it is.
+ # A MemoryError is the most likely failure mode.
+ class SequenceWithoutALength:
+ def __getitem__(self, i):
+ if i == 5:
+ raise IndexError
+ else:
+ return i
+ self.assertEqual(
+ list(zip(SequenceWithoutALength(), range(2**30))),
+ list(enumerate(range(5)))
+ )
+
+ class BadSeq:
+ def __getitem__(self, i):
+ if i == 5:
+ raise ValueError
+ else:
+ return i
+ self.assertRaises(ValueError, list, zip(BadSeq(), BadSeq()))
+
+ @expectedFailurePY2
+ def test_zip_pickle(self):
+ a = (1, 2, 3)
+ b = (4, 5, 6)
+ t = [(1, 4), (2, 5), (3, 6)]
+ z1 = zip(a, b)
+ self.check_iter_pickle(z1, t)
+
+ def test_format(self):
+ # Test the basic machinery of the format() builtin. Don't test
+ # the specifics of the various formatters
+ self.assertEqual(format(3, ''), '3')
+
+ # Returns some classes to use for various tests. There's
+ # an old-style version, and a new-style version
+ def classes_new():
+ class A(object):
+ def __init__(self, x):
+ self.x = x
+ def __format__(self, format_spec):
+ return str(self.x) + format_spec
+ class DerivedFromA(A):
+ pass
+
+ class Simple(object): pass
+ class DerivedFromSimple(Simple):
+ def __init__(self, x):
+ self.x = x
+ def __format__(self, format_spec):
+ return str(self.x) + format_spec
+ class DerivedFromSimple2(DerivedFromSimple): pass
+ return A, DerivedFromA, DerivedFromSimple, DerivedFromSimple2
+
+ def class_test(A, DerivedFromA, DerivedFromSimple, DerivedFromSimple2):
+ self.assertEqual(format(A(3), 'spec'), '3spec')
+ self.assertEqual(format(DerivedFromA(4), 'spec'), '4spec')
+ self.assertEqual(format(DerivedFromSimple(5), 'abc'), '5abc')
+ self.assertEqual(format(DerivedFromSimple2(10), 'abcdef'),
+ '10abcdef')
+
+ class_test(*classes_new())
+
+ def empty_format_spec(value):
+ # test that:
+ # format(x, '') == str(x)
+ # format(x) == str(x)
+ self.assertEqual(format(value, ""), str(value))
+ self.assertEqual(format(value), str(value))
+
+ # for builtin types, format(x, "") == str(x)
+ empty_format_spec(17**13)
+ empty_format_spec(1.0)
+ empty_format_spec(3.1415e104)
+ empty_format_spec(-3.1415e104)
+ empty_format_spec(3.1415e-104)
+ empty_format_spec(-3.1415e-104)
+ empty_format_spec(object)
+ empty_format_spec(None)
+
+ # TypeError because self.__format__ returns the wrong type
+ class BadFormatResult:
+ def __format__(self, format_spec):
+ return 1.0
+ self.assertRaises(TypeError, format, BadFormatResult(), "")
+
+ # TypeError because format_spec is not unicode or str
+ self.assertRaises(TypeError, format, object(), 4)
+ self.assertRaises(TypeError, format, object(), object())
+
+ # tests for object.__format__ really belong elsewhere, but
+ # there's no good place to put them
+ x = object().__format__('')
+ self.assertTrue(x.startswith('<object object at'))
+
+ # first argument to object.__format__ must be string
+ self.assertRaises(TypeError, object().__format__, 3)
+ self.assertRaises(TypeError, object().__format__, object())
+ self.assertRaises(TypeError, object().__format__, None)
+
+ # --------------------------------------------------------------------
+ # Issue #7994: object.__format__ with a non-empty format string is
+ # deprecated
+ def test_deprecated_format_string(obj, fmt_str, should_raise_warning):
+ if sys.version_info[0] == 3 and sys.version_info[1] >= 4:
+ if should_raise_warning:
+ self.assertRaises(TypeError, format, obj, fmt_str)
+ else:
+ try:
+ format(obj, fmt_str)
+ except TypeError:
+ self.fail('object.__format__ raised TypeError unexpectedly')
+ else:
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter("always", DeprecationWarning)
+ format(obj, fmt_str)
+ # Was:
+ # if should_raise_warning:
+ # self.assertEqual(len(w), 1)
+ # self.assertIsInstance(w[0].message, DeprecationWarning)
+ # self.assertIn('object.__format__ with a non-empty format '
+ # 'string', str(w[0].message))
+ # else:
+ # self.assertEqual(len(w), 0)
+ # Py2.7 fails these tests
+
+ fmt_strs = ['', 's']
+
+ class A:
+ def __format__(self, fmt_str):
+ return format('', fmt_str)
+
+ for fmt_str in fmt_strs:
+ test_deprecated_format_string(A(), fmt_str, False)
+
+ class B:
+ pass
+
+ class C(object):
+ pass
+
+ for cls in [object, B, C]:
+ for fmt_str in fmt_strs:
+ test_deprecated_format_string(cls(), fmt_str, len(fmt_str) != 0)
+ # --------------------------------------------------------------------
+
+ # make sure we can take a subclass of str as a format spec
+ class DerivedFromStr(str): pass
+ self.assertEqual(format(0, DerivedFromStr('10')), ' 0')
+
+ def test_bin(self):
+ self.assertEqual(bin(0), '0b0')
+ self.assertEqual(bin(1), '0b1')
+ self.assertEqual(bin(-1), '-0b1')
+ self.assertEqual(bin(2**65), '0b1' + '0' * 65)
+ self.assertEqual(bin(2**65-1), '0b' + '1' * 65)
+ self.assertEqual(bin(-(2**65)), '-0b1' + '0' * 65)
+ self.assertEqual(bin(-(2**65-1)), '-0b' + '1' * 65)
+
+ def test_bytearray_translate(self):
+ x = bytearray(b"abc")
+ self.assertRaises(ValueError, x.translate, b"1", 1)
+ self.assertRaises(TypeError, x.translate, b"1"*256, 1)
+
+ def test_construct_singletons(self):
+ for const in None, Ellipsis, NotImplemented:
+ tp = type(const)
+ # Was: self.assertIs(tp(), const)
+ # Fails for Py2
+ self.assertRaises(TypeError, tp, 1, 2)
+ self.assertRaises(TypeError, tp, a=1, b=2)
+
+class TestSorted(unittest.TestCase):
+
+ def test_basic(self):
+ data = list(range(100))
+ copy = data[:]
+ random.shuffle(copy)
+ self.assertEqual(data, sorted(copy))
+ self.assertNotEqual(data, copy)
+
+ data.reverse()
+ random.shuffle(copy)
+ self.assertEqual(data, sorted(copy, key=lambda x: -x))
+ self.assertNotEqual(data, copy)
+ random.shuffle(copy)
+ self.assertEqual(data, sorted(copy, reverse=1))
+ self.assertNotEqual(data, copy)
+
+ def test_inputtypes(self):
+ s = 'abracadabra'
+ types = [list, tuple, str]
+ for T in types:
+ self.assertEqual(sorted(s), sorted(T(s)))
+
+ s = ''.join(set(s)) # unique letters only
+ types = [str, set, frozenset, list, tuple, dict.fromkeys]
+ for T in types:
+ self.assertEqual(sorted(s), sorted(T(s)))
+
+ def test_baddecorator(self):
+ data = 'The quick Brown fox Jumped over The lazy Dog'.split()
+ self.assertRaises(TypeError, sorted, data, None, lambda x,y: 0)
+
+
+ # def test_input(self, interpreter='python2'):
+ # """
+ # Passes in a string to the waiting input()
+ # """
+ # code = '''
+ # from future.builtins import input
+ # def greet(name):
+ # print "Hello, {0}!".format(name)
+ # print "What's your name?"
+ # name = input()
+ # greet(name)
+ # '''
+ # with open(self.tempdir + 'input_test_script.py', 'w') as f:
+ # f.write(textwrap.dedent(code))
+ # p1 = Popen([interpreter, 'input_test_script.py'], stdout=PIPE, stdin=PIPE, stderr=None)
+ # (stdout, stderr) = p1.communicate(b'Ed')
+ # # print(stdout)
+ # # print(stderr)
+ # self.assertEqual(stdout, b"What's your name?\nHello, Ed!\n")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_builtins_explicit_import.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_builtins_explicit_import.py
new file mode 100644
index 0000000..24800c4
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_builtins_explicit_import.py
@@ -0,0 +1,18 @@
+"""
+Tests to make sure that all builtins can be imported explicitly from the
+future.builtins namespace.
+"""
+
+from __future__ import absolute_import, division, unicode_literals
+from future.builtins import (filter, map, zip)
+from future.builtins import (ascii, chr, hex, input, isinstance, next, oct, open)
+from future.builtins import (bytes, dict, int, range, round, str, super)
+from future.tests.base import unittest
+
+
+class TestBuiltinsExplicitImport(unittest.TestCase):
+ pass
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_bytes.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_bytes.py
new file mode 100644
index 0000000..b9b157d
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_bytes.py
@@ -0,0 +1,786 @@
+# -*- coding: utf-8 -*-
+"""
+Tests for the backported bytes object
+"""
+
+from __future__ import absolute_import, unicode_literals, print_function
+from future.builtins import *
+from future import utils
+
+from numbers import Integral
+from future.tests.base import unittest, expectedFailurePY2
+
+
+TEST_UNICODE_STR = u'ℝεα∂@ßʟ℮ ☂ℯṧт υηḯ¢☺ḓ℮'
+# Tk icon as a .gif:
+TEST_BYTE_STR = b'GIF89a\x0e\x00\x0b\x00\x80\xff\x00\xff\x00\x00\xc0\xc0\xc0!\xf9\x04\x01\x00\x00\x01\x00,\x00\x00\x00\x00\x0e\x00\x0b\x00@\x02\x1f\x0c\x8e\x10\xbb\xcan\x90\x99\xaf&\xd8\x1a\xce\x9ar\x06F\xd7\xf1\x90\xa1c\x9e\xe8\x84\x99\x89\x97\xa2J\x01\x00;\x1a\x14\x00;;\xba\nD\x14\x00\x00;;'
+
+
+class TestBytes(unittest.TestCase):
+ def test_bytes_encoding_arg(self):
+ """
+ The bytes class has changed in Python 3 to accept an
+ additional argument in the constructor: encoding.
+
+ It would be nice to support this without breaking the
+ isinstance(..., bytes) test below.
+ """
+ u = u'Unicode string: \u5b54\u5b50'
+ b = bytes(u, encoding='utf-8')
+ self.assertEqual(b, u.encode('utf-8'))
+
+ nu = str(u)
+ b = bytes(nu, encoding='utf-8')
+ self.assertEqual(b, u.encode('utf-8'))
+
+ def test_bytes_encoding_arg_issue_193(self):
+ """
+ This used to be True: bytes(str(u'abc'), 'utf8') == b"b'abc'"
+ """
+ u = u'abc'
+ b = bytes(str(u), 'utf8')
+ self.assertNotEqual(b, b"b'abc'")
+ self.assertEqual(b, b'abc')
+ self.assertEqual(b, bytes(b'abc'))
+
+ def test_bytes_encoding_arg_non_kwarg(self):
+ """
+ As above, but with a positional argument
+ """
+ u = u'Unicode string: \u5b54\u5b50'
+ b = bytes(u, 'utf-8')
+ self.assertEqual(b, u.encode('utf-8'))
+
+ nu = str(u)
+ b = bytes(nu, 'utf-8')
+ self.assertEqual(b, u.encode('utf-8'))
+
+ def test_bytes_string_no_encoding(self):
+ with self.assertRaises(TypeError):
+ bytes(u'ABC')
+
+ def test_bytes_int(self):
+ """
+ In Py3, bytes(int) -> bytes object of size given by the parameter initialized with null
+ """
+ self.assertEqual(bytes(5), b'\x00\x00\x00\x00\x00')
+ # Test using newint:
+ self.assertEqual(bytes(int(5)), b'\x00\x00\x00\x00\x00')
+ self.assertTrue(isinstance(bytes(int(5)), bytes))
+
+ # Negative counts are not allowed in Py3:
+ with self.assertRaises(ValueError):
+ bytes(-1)
+ with self.assertRaises(ValueError):
+ bytes(int(-1))
+
+ @unittest.skipIf(utils.PY3, 'test not needed on Py3: all ints are long')
+ def test_bytes_long(self):
+ """
+ As above, but explicitly feeding in a long on Py2. Note that
+ checks like:
+ isinstance(n, int)
+ are fragile on Py2, because isinstance(10L, int) is False.
+ """
+ m = long(5)
+ n = long(-1)
+ self.assertEqual(bytes(m), b'\x00\x00\x00\x00\x00')
+ # Negative counts are not allowed in Py3:
+ with self.assertRaises(ValueError):
+ bytes(n)
+
+ def test_bytes_empty(self):
+ """
+ bytes() -> b''
+ """
+ self.assertEqual(bytes(), b'')
+
+ def test_bytes_iterable_of_ints(self):
+ self.assertEqual(bytes([65, 66, 67]), b'ABC')
+ self.assertEqual(bytes([int(120), int(121), int(122)]), b'xyz')
+
+ def test_bytes_bytes(self):
+ self.assertEqual(bytes(b'ABC'), b'ABC')
+
+ def test_bytes_is_bytes(self):
+ b = bytes(b'ABC')
+ self.assertTrue(bytes(b) is b)
+ self.assertEqual(repr(bytes(b)), "b'ABC'")
+
+ def test_bytes_fromhex(self):
+ self.assertEqual(bytes.fromhex('bb 0f'), b'\xbb\x0f')
+ self.assertEqual(bytes.fromhex('1234'), b'\x124')
+ self.assertEqual(bytes.fromhex('12ffa0'), b'\x12\xff\xa0')
+ b = b'My bytestring'
+ self.assertEqual(bytes(b).fromhex('bb 0f'), b'\xbb\x0f')
+
+ def test_isinstance_bytes(self):
+ self.assertTrue(isinstance(bytes(b'blah'), bytes))
+
+ def test_isinstance_bytes_subclass(self):
+ """
+ Issue #89
+ """
+ value = bytes(b'abc')
+ class Magic(bytes):
+ pass
+ self.assertTrue(isinstance(value, bytes))
+ self.assertFalse(isinstance(value, Magic))
+
+ def test_isinstance_oldbytestrings_bytes(self):
+ """
+ Watch out for this. Byte-strings produced in various places in Py2
+ are of type 'str'. With 'from future.builtins import bytes', 'bytes'
+ is redefined to be a subclass of 'str', not just an alias for 'str'.
+ """
+ self.assertTrue(isinstance(b'blah', bytes)) # not with the redefined bytes obj
+ self.assertTrue(isinstance(u'blah'.encode('utf-8'), bytes)) # not with the redefined bytes obj
+
+ def test_bytes_getitem(self):
+ b = bytes(b'ABCD')
+ self.assertEqual(b[0], 65)
+ self.assertEqual(b[-1], 68)
+ self.assertEqual(b[0:1], b'A')
+ self.assertEqual(b[:], b'ABCD')
+
+ @expectedFailurePY2
+ def test_b_literal_creates_newbytes_object(self):
+ """
+ It would nice if the b'' literal syntax could be coaxed into producing
+ bytes objects somehow ... ;)
+ """
+ b = b'ABCD'
+ self.assertTrue(isinstance(b, bytes))
+ self.assertEqual(b[0], 65)
+ self.assertTrue(repr(b).startswith('b'))
+
+ def test_repr(self):
+ b = bytes(b'ABCD')
+ self.assertTrue(repr(b).startswith('b'))
+
+ def test_str(self):
+ b = bytes(b'ABCD')
+ self.assertEqual(str(b), "b'ABCD'")
+
+ def test_bytes_setitem(self):
+ b = b'ABCD'
+ with self.assertRaises(TypeError):
+ b[0] = b'B'
+
+ def test_bytes_iteration(self):
+ b = bytes(b'ABCD')
+ for item in b:
+ self.assertTrue(isinstance(item, Integral))
+ self.assertEqual(list(b), [65, 66, 67, 68])
+
+ def test_bytes_plus_unicode_string(self):
+ b = bytes(b'ABCD')
+ u = u'EFGH'
+ with self.assertRaises(TypeError):
+ b + u
+
+ with self.assertRaises(TypeError):
+ u + b
+
+ def test_bytes_plus_bytes(self):
+ b1 = bytes(b'ABCD')
+ b2 = b1 + b1
+ self.assertEqual(b2, b'ABCDABCD')
+ self.assertTrue(isinstance(b2, bytes))
+
+ b3 = b1 + b'ZYXW'
+ self.assertEqual(b3, b'ABCDZYXW')
+ self.assertTrue(isinstance(b3, bytes))
+
+ b4 = b'ZYXW' + b1
+ self.assertEqual(b4, b'ZYXWABCD')
+ self.assertTrue(isinstance(b4, bytes))
+
+ def test_find_not_found(self):
+ self.assertEqual(-1, bytes(b'ABCDE').find(b':'))
+
+ def test_find_found(self):
+ self.assertEqual(2, bytes(b'AB:CD:E').find(b':'))
+
+ def test_rfind_not_found(self):
+ self.assertEqual(-1, bytes(b'ABCDE').rfind(b':'))
+
+ def test_rfind_found(self):
+ self.assertEqual(5, bytes(b'AB:CD:E').rfind(b':'))
+
+ def test_bytes_join_bytes(self):
+ b = bytes(b' * ')
+ strings = [b'AB', b'EFGH', b'IJKL']
+ result = b.join(strings)
+ self.assertEqual(result, b'AB * EFGH * IJKL')
+ self.assertTrue(isinstance(result, bytes))
+
+ def test_bytes_join_others(self):
+ b = bytes(b' ')
+ with self.assertRaises(TypeError):
+ b.join([42])
+ with self.assertRaises(TypeError):
+ b.join(b'blah')
+ with self.assertRaises(TypeError):
+ b.join(bytes(b'blah'))
+
+ def test_bytes_join_unicode_strings(self):
+ b = bytes(b'ABCD')
+ strings = [u'EFGH', u'IJKL']
+ with self.assertRaises(TypeError):
+ b.join(strings)
+
+ def test_bytes_replace(self):
+ b = bytes(b'ABCD')
+ c = b.replace(b'A', b'F')
+ self.assertEqual(c, b'FBCD')
+ self.assertTrue(isinstance(c, bytes))
+
+ with self.assertRaises(TypeError):
+ b.replace(b'A', u'F')
+ with self.assertRaises(TypeError):
+ b.replace(u'A', b'F')
+
+ def test_bytes_partition(self):
+ b1 = bytes(b'ABCD')
+ parts = b1.partition(b'B')
+ self.assertEqual(parts, (b'A', b'B', b'CD'))
+ self.assertTrue(all([isinstance(p, bytes) for p in parts]))
+
+ b2 = bytes(b'ABCDABCD')
+ parts = b2.partition(b'B')
+ self.assertEqual(parts, (b'A', b'B', b'CDABCD'))
+
+ def test_bytes_rpartition(self):
+ b2 = bytes(b'ABCDABCD')
+ parts = b2.rpartition(b'B')
+ self.assertEqual(parts, (b'ABCDA', b'B', b'CD'))
+ self.assertTrue(all([isinstance(p, bytes) for p in parts]))
+
+ def test_bytes_contains_something(self):
+ b = bytes(b'ABCD')
+ self.assertTrue(b'A' in b)
+ self.assertTrue(65 in b)
+
+ self.assertTrue(b'AB' in b)
+ self.assertTrue(bytes([65, 66]) in b)
+
+ self.assertFalse(b'AC' in b)
+ self.assertFalse(bytes([65, 67]) in b)
+
+ self.assertFalse(b'Z' in b)
+ self.assertFalse(99 in b)
+
+ with self.assertRaises(TypeError):
+ u'A' in b
+
+ def test_bytes_index(self):
+ b = bytes(b'ABCD')
+ self.assertEqual(b.index(b'B'), 1)
+ self.assertEqual(b.index(67), 2)
+
+ def test_startswith(self):
+ b = bytes(b'abcd')
+ self.assertTrue(b.startswith(b'a'))
+ self.assertTrue(b.startswith((b'a', b'b')))
+ self.assertTrue(b.startswith(bytes(b'ab')))
+ self.assertFalse(b.startswith((b'A', b'B')))
+
+ with self.assertRaises(TypeError) as cm:
+ b.startswith(65)
+ with self.assertRaises(TypeError) as cm:
+ b.startswith([b'A'])
+ exc = str(cm.exception)
+ # self.assertIn('bytes', exc)
+ # self.assertIn('tuple', exc)
+
+ def test_endswith(self):
+ b = bytes(b'abcd')
+ self.assertTrue(b.endswith(b'd'))
+ self.assertTrue(b.endswith((b'c', b'd')))
+ self.assertTrue(b.endswith(bytes(b'cd')))
+ self.assertFalse(b.endswith((b'A', b'B')))
+
+ with self.assertRaises(TypeError) as cm:
+ b.endswith(65)
+ with self.assertRaises(TypeError) as cm:
+ b.endswith([b'D'])
+ exc = str(cm.exception)
+ # self.assertIn('bytes', exc)
+ # self.assertIn('tuple', exc)
+
+ def test_decode(self):
+ b = bytes(b'abcd')
+ s = b.decode('utf-8')
+ self.assertEqual(s, 'abcd')
+ self.assertTrue(isinstance(s, str))
+
+ def test_encode(self):
+ b = bytes(b'abcd')
+ with self.assertRaises(AttributeError) as cm:
+ b.encode('utf-8')
+
+ def test_eq(self):
+ """
+ Equals: ==
+ """
+ b = bytes(b'ABCD')
+ self.assertEqual(b, b'ABCD')
+ self.assertTrue(b == b'ABCD')
+ self.assertEqual(b'ABCD', b)
+ self.assertEqual(b, b)
+ self.assertFalse(b == b'ABC')
+ self.assertFalse(b == bytes(b'ABC'))
+ self.assertFalse(b == u'ABCD')
+ self.assertFalse(b == str('ABCD'))
+ # Fails:
+ # self.assertFalse(u'ABCD' == b)
+ self.assertFalse(str('ABCD') == b)
+
+ self.assertFalse(b == list(b))
+ self.assertFalse(b == str(b))
+ self.assertFalse(b == u'ABC')
+ self.assertFalse(bytes(b'Z') == 90)
+
+ def test_ne(self):
+ b = bytes(b'ABCD')
+ self.assertFalse(b != b)
+ self.assertFalse(b != b'ABCD')
+ self.assertTrue(b != b'ABCDEFG')
+ self.assertTrue(b != bytes(b'ABCDEFG'))
+ self.assertTrue(b'ABCDEFG' != b)
+
+ # self.assertTrue(b'ABCD' != u'ABCD')
+ self.assertTrue(b != u'ABCD')
+ self.assertTrue(b != u'ABCDE')
+ self.assertTrue(bytes(b'') != str(u''))
+ self.assertTrue(str(u'') != bytes(b''))
+
+ self.assertTrue(b != list(b))
+ self.assertTrue(b != str(b))
+
+ def test_hash(self):
+ d = {}
+ b = bytes(b'ABCD')
+ native_b = b'ABCD'
+ s = str('ABCD')
+ native_s = u'ABCD'
+ d[b] = b
+ d[s] = s
+ self.assertEqual(len(d), 2)
+ # This should overwrite d[s] but not d[b]:
+ d[native_s] = native_s
+ self.assertEqual(len(d), 2)
+ # This should overwrite d[native_s] again:
+ d[s] = s
+ self.assertEqual(len(d), 2)
+ self.assertEqual(set(d.keys()), set([s, b]))
+
+ @unittest.expectedFailure
+ def test_hash_with_native_types(self):
+ # Warning: initializing the dict with native Py2 types throws the
+ # hashing out:
+ d = {u'ABCD': u'ABCD', b'ABCD': b'ABCD'}
+ # On Py2: len(d) == 1
+ b = bytes(b'ABCD')
+ s = str('ABCD')
+ d[s] = s
+ d[b] = b
+ # Fails:
+ self.assertEqual(len(d) > 1)
+
+ def test_add(self):
+ b = bytes(b'ABC')
+ c = bytes(b'XYZ')
+ d = b + c
+ self.assertTrue(isinstance(d, bytes))
+ self.assertEqual(d, b'ABCXYZ')
+ f = b + b'abc'
+ self.assertTrue(isinstance(f, bytes))
+ self.assertEqual(f, b'ABCabc')
+ g = b'abc' + b
+ self.assertTrue(isinstance(g, bytes))
+ self.assertEqual(g, b'abcABC')
+
+ def test_cmp(self):
+ b = bytes(b'ABC')
+ with self.assertRaises(TypeError):
+ b > 3
+ with self.assertRaises(TypeError):
+ b > u'XYZ'
+ with self.assertRaises(TypeError):
+ b <= 3
+ with self.assertRaises(TypeError):
+ b >= int(3)
+ with self.assertRaises(TypeError):
+ b < 3.3
+ with self.assertRaises(TypeError):
+ b > (3.3 + 3j)
+ with self.assertRaises(TypeError):
+ b >= (1, 2)
+ with self.assertRaises(TypeError):
+ b <= [1, 2]
+
+ def test_mul(self):
+ b = bytes(b'ABC')
+ c = b * 4
+ self.assertTrue(isinstance(c, bytes))
+ self.assertEqual(c, b'ABCABCABCABC')
+ d = b * int(4)
+ self.assertTrue(isinstance(d, bytes))
+ self.assertEqual(d, b'ABCABCABCABC')
+ if utils.PY2:
+ e = b * long(4)
+ self.assertTrue(isinstance(e, bytes))
+ self.assertEqual(e, b'ABCABCABCABC')
+
+ def test_rmul(self):
+ b = bytes(b'XYZ')
+ c = 3 * b
+ self.assertTrue(isinstance(c, bytes))
+ self.assertEqual(c, b'XYZXYZXYZ')
+ d = b * int(3)
+ self.assertTrue(isinstance(d, bytes))
+ self.assertEqual(d, b'XYZXYZXYZ')
+ if utils.PY2:
+ e = long(3) * b
+ self.assertTrue(isinstance(e, bytes))
+ self.assertEqual(e, b'XYZXYZXYZ')
+
+ def test_slice(self):
+ b = bytes(b'ABCD')
+ c1 = b[:]
+ self.assertTrue(isinstance(c1, bytes))
+ self.assertTrue(c1 == b)
+ # The following is not true, whereas it is true normally on Py2 and
+ # Py3. Does this matter?:
+ # self.assertTrue(c1 is b)
+
+ c2 = b[10:]
+ self.assertTrue(isinstance(c2, bytes))
+ self.assertTrue(c2 == bytes(b''))
+ self.assertTrue(c2 == b'')
+
+ c3 = b[:0]
+ self.assertTrue(isinstance(c3, bytes))
+ self.assertTrue(c3 == bytes(b''))
+ self.assertTrue(c3 == b'')
+
+ c4 = b[:1]
+ self.assertTrue(isinstance(c4, bytes))
+ self.assertTrue(c4 == bytes(b'A'))
+ self.assertTrue(c4 == b'A')
+
+ c5 = b[:-1]
+ self.assertTrue(isinstance(c5, bytes))
+ self.assertTrue(c5 == bytes(b'ABC'))
+ self.assertTrue(c5 == b'ABC')
+
+ def test_bytes_frozenset(self):
+ _ALWAYS_SAFE = bytes(b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ b'abcdefghijklmnopqrstuvwxyz'
+ b'0123456789'
+ b'_.-') # from Py3.3's urllib.parse
+ s = frozenset(_ALWAYS_SAFE)
+ self.assertTrue(65 in s)
+ self.assertFalse(64 in s)
+ # Convert back to bytes
+ b1 = bytes(s)
+ self.assertTrue(65 in b1)
+ self.assertEqual(set(b1), set(_ALWAYS_SAFE))
+
+ def test_bytes_within_range(self):
+ """
+ Python 3 does this:
+ >>> bytes([255, 254, 256])
+ ValueError
+ ...
+ ValueError: bytes must be in range(0, 256)
+
+ Ensure our bytes() constructor has the same behaviour
+ """
+ b1 = bytes([254, 255])
+ self.assertEqual(b1, b'\xfe\xff')
+ with self.assertRaises(ValueError):
+ b2 = bytes([254, 255, 256])
+
+ def test_bytes_hasattr_encode(self):
+ """
+ This test tests whether hasattr(b, 'encode') is False, like it is on Py3.
+ """
+ b = bytes(b'abcd')
+ self.assertFalse(hasattr(b, 'encode'))
+ self.assertTrue(hasattr(b, 'decode'))
+
+ def test_quote_from_bytes(self):
+ """
+ This test was failing in the backported urllib.parse module in quote_from_bytes
+ """
+ empty = bytes([])
+ self.assertEqual(empty, b'')
+ self.assertTrue(type(empty), bytes)
+
+ empty2 = bytes(())
+ self.assertEqual(empty2, b'')
+ self.assertTrue(type(empty2), bytes)
+
+ safe = bytes(u'Philosopher guy: 孔子. More text here.'.encode('utf-8'))
+ safe = bytes([c for c in safe if c < 128])
+ self.assertEqual(safe, b'Philosopher guy: . More text here.')
+ self.assertTrue(type(safe), bytes)
+
+ def test_rstrip(self):
+ b = bytes(b'abcd')
+ c = b.rstrip(b'd')
+ self.assertEqual(c, b'abc')
+ self.assertEqual(type(c), type(b))
+
+ def test_maketrans(self):
+ """
+ Issue #51.
+
+ Test is from Py3.3.5.
+ """
+ transtable = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff'
+ self.assertEqual(bytes.maketrans(b'', b''), transtable)
+
+ transtable = b'\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377'
+ self.assertEqual(bytes.maketrans(b'abc', b'xyz'), transtable)
+
+ transtable = b'\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374xyz'
+ self.assertEqual(bytes.maketrans(b'\375\376\377', b'xyz'), transtable)
+ self.assertRaises(ValueError, bytes.maketrans, b'abc', b'xyzq')
+ self.assertRaises(TypeError, bytes.maketrans, 'abc', 'def')
+
+ @unittest.skipUnless(utils.PY2, 'test requires Python 2')
+ def test_mod_custom_dict(self):
+ import UserDict
+
+ class MyDict(UserDict.UserDict):
+ pass
+
+ d = MyDict()
+ d['foo'] = bytes(b'bar')
+ self.assertFalse(isinstance(d, dict))
+ self.assertTrue(isinstance(d, UserDict.UserDict))
+
+ self.assertEqual(bytes(b'%(foo)s') % d, b'bar')
+
+ @unittest.skipUnless(utils.PY35_PLUS or utils.PY2,
+ 'test requires Python 2 or 3.5+')
+ def test_mod_more(self):
+ self.assertEqual(b'%s' % b'aaa', b'aaa')
+ self.assertEqual(bytes(b'%s') % b'aaa', b'aaa')
+ self.assertEqual(bytes(b'%s') % bytes(b'aaa'), b'aaa')
+
+ self.assertEqual(b'%s' % (b'aaa',), b'aaa')
+ self.assertEqual(bytes(b'%s') % (b'aaa',), b'aaa')
+ self.assertEqual(bytes(b'%s') % (bytes(b'aaa'),), b'aaa')
+
+ self.assertEqual(bytes(b'%(x)s') % {b'x': b'aaa'}, b'aaa')
+ self.assertEqual(bytes(b'%(x)s') % {b'x': bytes(b'aaa')}, b'aaa')
+
+ @unittest.skipUnless(utils.PY35_PLUS or utils.PY2,
+ 'test requires Python 2 or 3.5+')
+ def test_mod(self):
+ """
+ From Py3.5 test suite (post-PEP 461).
+
+ The bytes mod code is in _PyBytes_Format() in bytesobject.c in Py3.5.
+ """
+
+ # XXX Add support for %b!
+ #
+ # b = bytes(b'hello, %b!')
+ # orig = b
+ # b = b % b'world'
+ # self.assertEqual(b, b'hello, world!')
+ # self.assertEqual(orig, b'hello, %b!')
+ # self.assertFalse(b is orig)
+
+ b = bytes(b'%s / 100 = %d%%')
+ a = b % (b'seventy-nine', 79)
+ self.assertEqual(a, b'seventy-nine / 100 = 79%')
+
+ b = bytes(b'%s / 100 = %d%%')
+ a = b % (bytes(b'seventy-nine'), 79)
+ self.assertEqual(a, b'seventy-nine / 100 = 79%')
+
+ @unittest.skipUnless(utils.PY35_PLUS or utils.PY2,
+ 'test requires Python 2 or 3.5+')
+ def test_imod(self):
+ """
+ From Py3.5 test suite (post-PEP 461)
+ """
+ # if (3, 0) <= sys.version_info[:2] < (3, 5):
+ # raise unittest.SkipTest('bytes % not yet implemented on Py3.0-3.4')
+
+ # b = bytes(b'hello, %b!')
+ # orig = b
+ # b %= b'world'
+ # self.assertEqual(b, b'hello, world!')
+ # self.assertEqual(orig, b'hello, %b!')
+ # self.assertFalse(b is orig)
+
+ b = bytes(b'%s / 100 = %d%%')
+ b %= (b'seventy-nine', 79)
+ self.assertEqual(b, b'seventy-nine / 100 = 79%')
+
+ b = bytes(b'%s / 100 = %d%%')
+ b %= (bytes(b'seventy-nine'), 79)
+ self.assertEqual(b, b'seventy-nine / 100 = 79%')
+
+ # def test_mod_pep_461(self):
+ # """
+ # Test for the PEP 461 functionality (resurrection of %s formatting for
+ # bytes).
+ # """
+ # b1 = bytes(b'abc%b')
+ # b2 = b1 % b'def'
+ # self.assertEqual(b2, b'abcdef')
+ # self.assertTrue(isinstance(b2, bytes))
+ # self.assertEqual(type(b2), bytes)
+ # b3 = b1 % bytes(b'def')
+ # self.assertEqual(b3, b'abcdef')
+ # self.assertTrue(isinstance(b3, bytes))
+ # self.assertEqual(type(b3), bytes)
+ #
+ # # %s is supported for backwards compatibility with Py2's str
+ # b4 = bytes(b'abc%s')
+ # b5 = b4 % b'def'
+ # self.assertEqual(b5, b'abcdef')
+ # self.assertTrue(isinstance(b5, bytes))
+ # self.assertEqual(type(b5), bytes)
+ # b6 = b4 % bytes(b'def')
+ # self.assertEqual(b6, b'abcdef')
+ # self.assertTrue(isinstance(b6, bytes))
+ # self.assertEqual(type(b6), bytes)
+ #
+ # self.assertEqual(bytes(b'%c') % 48, b'0')
+ # self.assertEqual(bytes(b'%c') % b'a', b'a')
+ #
+ # # For any numeric code %x, formatting of
+ # # b"%x" % val
+ # # is supposed to be equivalent to
+ # # ("%x" % val).encode("ascii")
+ # for code in b'xdiouxXeEfFgG':
+ # bytechar = bytes([code])
+ # pct_str = u"%" + bytechar.decode('ascii')
+ # for val in range(300):
+ # self.assertEqual(bytes(b"%" + bytechar) % val,
+ # (pct_str % val).encode("ascii"))
+ #
+ # with self.assertRaises(TypeError):
+ # bytes(b'%b') % 3.14
+ # # Traceback (most recent call last):
+ # # ...
+ # # TypeError: b'%b' does not accept 'float'
+ #
+ # with self.assertRaises(TypeError):
+ # bytes(b'%b') % 'hello world!'
+ # # Traceback (most recent call last):
+ # # ...
+ # # TypeError: b'%b' does not accept 'str'
+ #
+ # self.assertEqual(bytes(b'%a') % 3.14, b'3.14')
+ #
+ # self.assertEqual(bytes(b'%a') % b'abc', b"b'abc'")
+ # self.assertEqual(bytes(b'%a') % bytes(b'abc'), b"b'abc'")
+ #
+ # self.assertEqual(bytes(b'%a') % 'def', b"'def'")
+ #
+ # # PEP 461 was updated after an Py3.5 alpha release to specify that %r is now supported
+ # # for compatibility: http://legacy.python.org/dev/peps/pep-0461/#id16
+ # assert bytes(b'%r' % b'abc') == bytes(b'%a' % b'abc')
+ #
+ # # with self.assertRaises(TypeError):
+ # # bytes(b'%r' % 'abc')
+
+ @expectedFailurePY2
+ def test_multiple_inheritance(self):
+ """
+ Issue #96 (for newbytes instead of newobject)
+ """
+ if utils.PY2:
+ from collections import Container
+ else:
+ from collections.abc import Container
+
+ class Base(bytes):
+ pass
+
+ class Foo(Base, Container):
+ def __contains__(self, item):
+ return False
+
+ @expectedFailurePY2
+ def test_with_metaclass_and_bytes(self):
+ """
+ Issue #91 (for newdict instead of newobject)
+ """
+ from future.utils import with_metaclass
+
+ class MetaClass(type):
+ pass
+
+ class TestClass(with_metaclass(MetaClass, bytes)):
+ pass
+
+ def test_surrogateescape_decoding(self):
+ """
+ Tests whether surrogateescape decoding works correctly.
+ """
+ pairs = [(u'\udcc3', b'\xc3'),
+ (u'\udcff', b'\xff')]
+
+ for (s, b) in pairs:
+ decoded = bytes(b).decode('utf-8', 'surrogateescape')
+ self.assertEqual(s, decoded)
+ self.assertTrue(isinstance(decoded, str))
+ self.assertEqual(b, decoded.encode('utf-8', 'surrogateescape'))
+
+ def test_issue_171_part_a(self):
+ b1 = str(u'abc \u0123 do re mi').encode(u'utf_8')
+ b2 = bytes(u'abc \u0123 do re mi', u'utf_8')
+ b3 = bytes(str(u'abc \u0123 do re mi'), u'utf_8')
+
+ @expectedFailurePY2
+ def test_issue_171_part_b(self):
+ """
+ Tests whether:
+ >>> nativebytes = bytes ; nativestr = str ; from builtins import *
+ >>> nativebytes(bytes(b'asdf'))[0] == b'a' == b'asdf'
+ """
+ nativebytes = type(b'')
+ nativestr = type('')
+ b = nativebytes(bytes(b'asdf'))
+ self.assertEqual(b, b'asdf')
+
+ def test_cast_to_bytes(self):
+ """
+ Tests whether __bytes__ method is called
+ """
+
+ class TestObject:
+ def __bytes__(self):
+ return b'asdf'
+
+ self.assertEqual(bytes(TestObject()), b'asdf')
+
+ def test_cast_to_bytes_iter_precedence(self):
+ """
+ Tests that call to __bytes__ is preferred to iteration
+ """
+
+ class TestObject:
+ def __bytes__(self):
+ return b'asdf'
+
+ def __iter__(self):
+ return iter(b'hjkl')
+
+ self.assertEqual(bytes(TestObject()), b'asdf')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_chainmap.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_chainmap.py
new file mode 100644
index 0000000..2440401
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_chainmap.py
@@ -0,0 +1,160 @@
+"""
+Tests for the future.standard_library module
+"""
+
+from __future__ import absolute_import, print_function
+from future import standard_library
+from future import utils
+from future.tests.base import unittest, CodeHandler, expectedFailurePY2
+
+import sys
+import tempfile
+import os
+import copy
+import textwrap
+from subprocess import CalledProcessError
+
+
+class TestChainMap(CodeHandler):
+
+ def setUp(self):
+ self.interpreter = sys.executable
+ standard_library.install_aliases()
+ super(TestChainMap, self).setUp()
+
+ def tearDown(self):
+ # standard_library.remove_hooks()
+ pass
+
+ @staticmethod
+ def simple_cm():
+ from collections import ChainMap
+ c = ChainMap()
+ c['one'] = 1
+ c['two'] = 2
+
+ cc = c.new_child()
+ cc['one'] = 'one'
+
+ return c, cc
+
+
+ def test_repr(self):
+ c, cc = TestChainMap.simple_cm()
+
+ order1 = "ChainMap({'one': 'one'}, {'one': 1, 'two': 2})"
+ order2 = "ChainMap({'one': 'one'}, {'two': 2, 'one': 1})"
+ assert repr(cc) in [order1, order2]
+
+
+ def test_recursive_repr(self):
+ """
+ Test for degnerative recursive cases. Very unlikely in
+ ChainMaps. But all must bow before the god of testing coverage.
+ """
+ from collections import ChainMap
+ c = ChainMap()
+ c['one'] = c
+ assert repr(c) == "ChainMap({'one': ...})"
+
+
+ def test_get(self):
+ c, cc = TestChainMap.simple_cm()
+
+ assert cc.get('two') == 2
+ assert cc.get('three') == None
+ assert cc.get('three', 'notthree') == 'notthree'
+
+
+ def test_bool(self):
+ from collections import ChainMap
+ c = ChainMap()
+ assert not(bool(c))
+
+ c['one'] = 1
+ c['two'] = 2
+ assert bool(c)
+
+ cc = c.new_child()
+ cc['one'] = 'one'
+ assert cc
+
+
+ def test_fromkeys(self):
+ from collections import ChainMap
+ keys = 'a b c'.split()
+ c = ChainMap.fromkeys(keys)
+ assert len(c) == 3
+ assert c['a'] == None
+ assert c['b'] == None
+ assert c['c'] == None
+
+
+ def test_copy(self):
+ c, cc = TestChainMap.simple_cm()
+ new_cc = cc.copy()
+ assert new_cc is not cc
+ assert sorted(new_cc.items()) == sorted(cc.items())
+
+
+ def test_parents(self):
+ c, cc = TestChainMap.simple_cm()
+
+ new_c = cc.parents
+ assert c is not new_c
+ assert len(new_c) == 2
+ assert new_c['one'] == c['one']
+ assert new_c['two'] == c['two']
+
+
+ def test_delitem(self):
+ c, cc = TestChainMap.simple_cm()
+
+ with self.assertRaises(KeyError):
+ del cc['two']
+
+ del cc['one']
+ assert len(cc) == 2
+ assert cc['one'] == 1
+ assert cc['two'] == 2
+
+
+ def test_popitem(self):
+ c, cc = TestChainMap.simple_cm()
+
+ assert cc.popitem() == ('one', 'one')
+
+ with self.assertRaises(KeyError):
+ cc.popitem()
+
+
+ def test_pop(self):
+ c, cc = TestChainMap.simple_cm()
+
+ assert cc.pop('one') == 'one'
+
+ with self.assertRaises(KeyError):
+ cc.pop('two')
+
+ assert len(cc) == 2
+
+
+ def test_clear(self):
+ c, cc = TestChainMap.simple_cm()
+
+ cc.clear()
+ assert len(cc) == 2
+ assert cc['one'] == 1
+ assert cc['two'] == 2
+
+
+ def test_missing(self):
+
+ c, cc = TestChainMap.simple_cm()
+
+ with self.assertRaises(KeyError):
+ cc['clown']
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_common_iterators.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_common_iterators.py
new file mode 100644
index 0000000..d274c23
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_common_iterators.py
@@ -0,0 +1,39 @@
+from __future__ import absolute_import
+
+from future.builtins.iterators import *
+from future.tests.base import unittest
+
+
+class TestIterators(unittest.TestCase):
+ def test_range(self):
+ self.assertNotEqual(type(range(10)), list)
+ self.assertEqual(sum(range(10)), 45)
+ self.assertTrue(9 in range(10))
+ self.assertEqual(list(range(5)), [0, 1, 2, 3, 4])
+ self.assertEqual(repr(range(10)), 'range(0, 10)')
+ self.assertEqual(repr(range(1, 10)), 'range(1, 10)')
+ self.assertEqual(repr(range(1, 1)), 'range(1, 1)')
+ self.assertEqual(repr(range(-10, 10, 2)), 'range(-10, 10, 2)')
+
+ def test_map(self):
+ def square(x):
+ return x**2
+ self.assertNotEqual(type(map(square, range(10))), list)
+ self.assertEqual(sum(map(square, range(10))), 285)
+ self.assertEqual(list(map(square, range(3))), [0, 1, 4])
+
+ def test_zip(self):
+ a = range(10)
+ b = ['a', 'b', 'c']
+ self.assertNotEqual(type(zip(a, b)), list)
+ self.assertEqual(list(zip(a, b)), [(0, 'a'), (1, 'b'), (2, 'c')])
+
+ def test_filter(self):
+ a = range(10)
+ def is_odd(x):
+ return x % 2 == 1
+ self.assertNotEqual(type(filter(is_odd, a)), list)
+ self.assertEqual(list(filter(is_odd, a)), [1, 3, 5, 7, 9])
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_decorators.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_decorators.py
new file mode 100644
index 0000000..9ec2bb3
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_decorators.py
@@ -0,0 +1,57 @@
+"""
+Tests to make sure the decorators (implements_iterator and
+python2_unicode_compatible) are working.
+"""
+
+from __future__ import absolute_import, division
+from future import utils
+from future.builtins import *
+from future.utils import implements_iterator, python_2_unicode_compatible
+from future.tests.base import unittest
+
+
+class TestDecorators(unittest.TestCase):
+ def test_python_2_unicode_compatible_decorator(self):
+ my_unicode_str = u'Unicode string: \u5b54\u5b50'
+ # With the decorator:
+ @python_2_unicode_compatible
+ class A(object):
+ def __str__(self):
+ return my_unicode_str
+ a = A()
+ assert len(str(a)) == 18
+ if not utils.PY3:
+ assert hasattr(a, '__unicode__')
+ self.assertEqual(str(a), my_unicode_str)
+ self.assertTrue(isinstance(str(a).encode('utf-8'), bytes))
+
+ # Manual equivalent on Py2 without the decorator:
+ if not utils.PY3:
+ class B(object):
+ def __unicode__(self):
+ return u'Unicode string: \u5b54\u5b50'
+ def __str__(self):
+ return unicode(self).encode('utf-8')
+ b = B()
+ assert str(a) == str(b)
+
+ def test_implements_iterator(self):
+
+ @implements_iterator
+ class MyIter(object):
+ def __next__(self):
+ return 'Next!'
+ def __iter__(self):
+ return self
+
+ itr = MyIter()
+ self.assertEqual(next(itr), 'Next!')
+
+ itr2 = MyIter()
+ for i, item in enumerate(itr2):
+ if i >= 3:
+ break
+ self.assertEqual(item, 'Next!')
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_dict.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_dict.py
new file mode 100644
index 0000000..ff9dd4a
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_dict.py
@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*-
+"""
+Tests for the backported class:`dict` class.
+"""
+
+from __future__ import absolute_import, unicode_literals, print_function
+from future.builtins import *
+from future import utils
+from future.tests.base import unittest, expectedFailurePY2
+
+import os
+import sys
+
+class TestDict(unittest.TestCase):
+ def setUp(self):
+ self.d1 = {'C': 1, 'B': 2, 'A': 3}
+ self.d2 = dict(key1='value1', key2='value2')
+
+ def test_dict_empty(self):
+ """
+ dict() -> {}
+ """
+ self.assertEqual(dict(), {})
+
+ def test_dict_dict(self):
+ """
+ Exrapolated from issue #50 -- newlist(newlist([...]))
+ """
+ d = dict({1: 2, 2: 4, 3: 9})
+ d2 = dict(d)
+ self.assertEqual(len(d2), 3)
+ self.assertEqual(d2, d)
+ self.assertTrue(isinstance(d2, dict))
+ self.assertTrue(type(d2) == dict)
+
+ def test_dict_eq(self):
+ d = self.d1
+ self.assertEqual(dict(d), d)
+
+ def test_dict_keys(self):
+ """
+ The keys, values and items methods should now return iterators on
+ Python 2.x (with set-like behaviour on Python 2.7).
+ """
+ d = self.d1
+ self.assertEqual(set(dict(d)), set(d))
+ self.assertEqual(set(dict(d).keys()), set(d.keys()))
+ with self.assertRaises(TypeError):
+ dict(d).keys()[0]
+
+ def test_dict_values(self):
+ d = self.d1
+ self.assertEqual(set(dict(d).values()), set(d.values()))
+ with self.assertRaises(TypeError):
+ dict(d).values()[0]
+
+ def test_dict_items(self):
+ d = self.d1
+ self.assertEqual(set(dict(d).items()), set(d.items()))
+ with self.assertRaises(TypeError):
+ dict(d).items()[0]
+
+ def test_isinstance_dict(self):
+ d = self.d1
+ self.assertTrue(isinstance(d, dict))
+
+ def test_isinstance_dict_subclass(self):
+ """
+ Issue #89
+ """
+ value = dict()
+ class Magic(dict):
+ pass
+ self.assertTrue(isinstance(value, dict))
+ self.assertFalse(isinstance(value, Magic))
+
+ def test_dict_getitem(self):
+ d = dict({'C': 1, 'B': 2, 'A': 3})
+ self.assertEqual(d['C'], 1)
+ self.assertEqual(d['B'], 2)
+ self.assertEqual(d['A'], 3)
+ with self.assertRaises(KeyError):
+ self.assertEqual(d['D'])
+
+ def test_methods_do_not_produce_lists(self):
+ for d in (dict(self.d1), self.d2):
+ assert not isinstance(d.keys(), list)
+ assert not isinstance(d.values(), list)
+ assert not isinstance(d.items(), list)
+
+ @unittest.skipIf(sys.version_info[:2] == (2, 6),
+ 'set-like behaviour of dict methods is only available in Py2.7+')
+ def test_set_like_behaviour(self):
+ d1, d2 = self.d1, self.d2
+ assert d1.keys() & d2.keys() == set()
+ assert isinstance(d1.keys() & d2.keys(), set)
+ assert isinstance(d1.values() | d2.keys(), set)
+ assert isinstance(d1.items() | d2.items(), set)
+
+ @expectedFailurePY2
+ def test_braces_create_newdict_object(self):
+ """
+ It would nice if the {} dict syntax could be coaxed
+ into producing our new dict objects somehow ...
+ """
+ d = self.d1
+ self.assertTrue(type(d) == dict)
+
+ @expectedFailurePY2
+ def test_multiple_inheritance(self):
+ """
+ Issue #96 (for newdict instead of newobject)
+ """
+ if utils.PY2:
+ from collections import Container
+ else:
+ from collections.abc import Container
+
+ class Base(dict):
+ pass
+
+ class Foo(Base, Container):
+ def __contains__(self, item):
+ return False
+
+ @expectedFailurePY2
+ def test_with_metaclass_and_dict(self):
+ """
+ Issue #91 (for newdict instead of newobject)
+ """
+ from future.utils import with_metaclass
+
+ class MetaClass(type):
+ pass
+
+ class TestClass(with_metaclass(MetaClass, dict)):
+ pass
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_email_multipart.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_email_multipart.py
new file mode 100644
index 0000000..cbd93b8
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_email_multipart.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+"""Tests for multipart emails."""
+
+from future.tests.base import unittest
+import future.backports.email as email
+import future.backports.email.mime.multipart
+from future.builtins import list
+
+class EmailMultiPartTests(unittest.TestCase):
+ """Tests for handling multipart email Messages."""
+
+ def test_multipart_serialize_without_boundary(self):
+ """Tests that serializing an empty multipart email does not fail."""
+ multipart_message = email.mime.multipart.MIMEMultipart()
+ self.assertIsNot(multipart_message.as_string(), None)
+
+ def test_multipart_set_boundary_does_not_change_header_type(self):
+ """
+ Tests that Message.set_boundary() does not cause Python2 errors.
+
+ In particular, tests that set_boundary does not cause the type of the
+ message headers list to be changed from the future built-in list.
+ """
+ multipart_message = email.mime.multipart.MIMEMultipart()
+ headers_type = type(multipart_message._headers)
+ self.assertEqual(headers_type, type(list()))
+
+ boundary = '===============6387699881409002085=='
+ multipart_message.set_boundary(boundary)
+ headers_type = type(multipart_message._headers)
+ self.assertEqual(headers_type, type(list()))
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_explicit_imports.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_explicit_imports.py
new file mode 100644
index 0000000..7a23c3e
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_explicit_imports.py
@@ -0,0 +1,49 @@
+"""
+This tests whether explicit imports like
+
+ from future.builtins import str, range
+
+etc. all work as expected on both Python 2 and Python 3.
+
+"""
+
+from __future__ import absolute_import, print_function, unicode_literals
+
+import copy
+
+from future import utils
+from future.tests.base import unittest
+
+
+class TestExplicitImports(unittest.TestCase):
+ def test_py3_builtin_imports(self):
+ from future.builtins import (input,
+ filter,
+ map,
+ range,
+ round,
+ super,
+ str,
+ zip)
+
+ def test_py2k_disabled_builtins(self):
+ """
+ On Py2 these should import.
+ """
+ if not utils.PY3:
+ from future.builtins.disabled import (apply,
+ cmp,
+ coerce,
+ execfile,
+ file,
+ long,
+ raw_input,
+ reduce,
+ reload,
+ unicode,
+ xrange,
+ StandardError)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_futurize.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_futurize.py
new file mode 100644
index 0000000..0d7c42d
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_futurize.py
@@ -0,0 +1,1432 @@
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import, division, print_function
+
+import pprint
+import tempfile
+from subprocess import Popen, PIPE
+import os
+
+from libfuturize.fixer_util import is_shebang_comment, is_encoding_comment
+from lib2to3.fixer_util import FromImport
+from lib2to3.pytree import Leaf, Node
+from lib2to3.pygram import token
+
+from future.tests.base import (CodeHandler, unittest, skip26, reformat_code,
+ order_future_lines, expectedFailurePY26)
+from future.utils import PY2
+
+
+class TestLibFuturize(unittest.TestCase):
+
+ def setUp(self):
+ # For tests that need a text file:
+ _, self.textfilename = tempfile.mkstemp(text=True)
+ super(TestLibFuturize, self).setUp()
+
+ def tearDown(self):
+ os.unlink(self.textfilename)
+
+ def test_correct_exit_status(self):
+ """
+ Issue #119: futurize and pasteurize were not exiting with the correct
+ status code. This is because the status code returned from
+ libfuturize.main.main() etc. was a ``newint``, which sys.exit() always
+ translates into 1!
+ """
+ from libfuturize.main import main
+ retcode = main([self.textfilename])
+ self.assertTrue(isinstance(retcode, int)) # i.e. Py2 builtin int
+
+ def test_is_shebang_comment(self):
+ """
+ Tests whether the fixer_util.is_encoding_comment() function is working.
+ """
+ shebang_comments = [u'#!/usr/bin/env python\n'
+ u"#!/usr/bin/python2\n",
+ u"#! /usr/bin/python3\n",
+ ]
+ not_shebang_comments = [u"# I saw a giant python\n",
+ u"# I have never seen a python2\n",
+ ]
+ for comment in shebang_comments:
+ node = FromImport(u'math', [Leaf(token.NAME, u'cos', prefix=" ")])
+ node.prefix = comment
+ self.assertTrue(is_shebang_comment(node))
+
+ for comment in not_shebang_comments:
+ node = FromImport(u'math', [Leaf(token.NAME, u'cos', prefix=" ")])
+ node.prefix = comment
+ self.assertFalse(is_shebang_comment(node))
+
+
+ def test_is_encoding_comment(self):
+ """
+ Tests whether the fixer_util.is_encoding_comment() function is working.
+ """
+ encoding_comments = [u"# coding: utf-8",
+ u"# encoding: utf-8",
+ u"# -*- coding: latin-1 -*-",
+ u"# vim: set fileencoding=iso-8859-15 :",
+ ]
+ not_encoding_comments = [u"# We use the file encoding utf-8",
+ u"coding = 'utf-8'",
+ u"encoding = 'utf-8'",
+ ]
+ for comment in encoding_comments:
+ node = FromImport(u'math', [Leaf(token.NAME, u'cos', prefix=" ")])
+ node.prefix = comment
+ self.assertTrue(is_encoding_comment(node))
+
+ for comment in not_encoding_comments:
+ node = FromImport(u'math', [Leaf(token.NAME, u'cos', prefix=" ")])
+ node.prefix = comment
+ self.assertFalse(is_encoding_comment(node))
+
+
+class TestFuturizeSimple(CodeHandler):
+ """
+ This class contains snippets of Python 2 code (invalid Python 3) and
+ tests for whether they can be passed to ``futurize`` and immediately
+ run under both Python 2 again and Python 3.
+ """
+
+ def test_encoding_comments_kept_at_top(self):
+ """
+ Issues #10 and #97: If there is a source encoding comment line
+ (PEP 263), is it kept at the top of a module by ``futurize``?
+ """
+ before = """
+ # coding=utf-8
+
+ print 'Hello'
+ """
+ after = """
+ # coding=utf-8
+
+ from __future__ import print_function
+ print('Hello')
+ """
+ self.convert_check(before, after)
+
+ before = """
+ #!/usr/bin/env python
+ # -*- coding: latin-1 -*-"
+
+ print 'Hello'
+ """
+ after = """
+ #!/usr/bin/env python
+ # -*- coding: latin-1 -*-"
+
+ from __future__ import print_function
+ print('Hello')
+ """
+ self.convert_check(before, after)
+
+ def test_multiline_future_import(self):
+ """
+ Issue #113: don't crash if a future import has multiple lines
+ """
+ text = """
+ from __future__ import (
+ division
+ )
+ """
+ self.convert(text)
+
+ def test_shebang_blank_with_future_division_import(self):
+ """
+ Issue #43: Is shebang line preserved as the first
+ line by futurize when followed by a blank line?
+ """
+ before = """
+ #!/usr/bin/env python
+
+ import math
+ 1 / 5
+ """
+ after = """
+ #!/usr/bin/env python
+
+ from __future__ import division
+ from past.utils import old_div
+ import math
+ old_div(1, 5)
+ """
+ self.convert_check(before, after)
+
+ def test_shebang_blank_with_print_import(self):
+ before = """
+ #!/usr/bin/env python
+
+ import math
+ print 'Hello'
+ """
+ after = """
+ #!/usr/bin/env python
+ from __future__ import print_function
+
+ import math
+ print('Hello')
+ """
+ self.convert_check(before, after)
+
+ def test_shebang_comment(self):
+ """
+ Issue #43: Is shebang line preserved as the first
+ line by futurize when followed by a comment?
+ """
+ before = """
+ #!/usr/bin/env python
+ # some comments
+ # and more comments
+
+ import math
+ print 'Hello!'
+ """
+ after = """
+ #!/usr/bin/env python
+ # some comments
+ # and more comments
+ from __future__ import print_function
+
+ import math
+ print('Hello!')
+ """
+ self.convert_check(before, after)
+
+ def test_shebang_docstring(self):
+ """
+ Issue #43: Is shebang line preserved as the first
+ line by futurize when followed by a docstring?
+ """
+ before = '''
+ #!/usr/bin/env python
+ """
+ a doc string
+ """
+ import math
+ print 'Hello!'
+ '''
+ after = '''
+ #!/usr/bin/env python
+ """
+ a doc string
+ """
+ from __future__ import print_function
+ import math
+ print('Hello!')
+ '''
+ self.convert_check(before, after)
+
+ def test_oldstyle_classes(self):
+ """
+ Stage 2 should convert old-style to new-style classes. This makes
+ the new-style class explicit and reduces the gap between the
+ behaviour (e.g. method resolution order) on Py2 and Py3. It also
+ allows us to provide ``newobject`` (see
+ test_oldstyle_classes_iterator).
+ """
+ before = """
+ class Blah:
+ pass
+ """
+ after = """
+ from builtins import object
+ class Blah(object):
+ pass
+ """
+ self.convert_check(before, after, ignore_imports=False)
+
+ def test_oldstyle_classes_iterator(self):
+ """
+ An old-style class used as an iterator should be converted
+ properly. This requires ``futurize`` to do both steps (adding
+ inheritance from object and adding the newobject import) in the
+ right order. Any next() method should also be renamed to __next__.
+ """
+ before = """
+ class Upper:
+ def __init__(self, iterable):
+ self._iter = iter(iterable)
+ def next(self):
+ return next(self._iter).upper()
+ def __iter__(self):
+ return self
+
+ assert list(Upper('hello')) == list('HELLO')
+ """
+ after = """
+ from builtins import next
+ from builtins import object
+ class Upper(object):
+ def __init__(self, iterable):
+ self._iter = iter(iterable)
+ def __next__(self):
+ return next(self._iter).upper()
+ def __iter__(self):
+ return self
+
+ assert list(Upper('hello')) == list('HELLO')
+ """
+ self.convert_check(before, after, ignore_imports=False)
+
+ # Try it again with this convention: class Upper():
+ before2 = """
+ class Upper():
+ def __init__(self, iterable):
+ self._iter = iter(iterable)
+ def next(self):
+ return next(self._iter).upper()
+ def __iter__(self):
+ return self
+
+ assert list(Upper('hello')) == list('HELLO')
+ """
+ self.convert_check(before2, after)
+
+ @unittest.expectedFailure
+ def test_problematic_string(self):
+ """ This string generates a SyntaxError on Python 3 unless it has
+ an r prefix.
+ """
+ before = r"""
+ s = 'The folder is "C:\Users"'.
+ """
+ after = r"""
+ s = r'The folder is "C:\Users"'.
+ """
+ self.convert_check(before, after)
+
+ @unittest.skip('--tobytes feature removed for now ...')
+ def test_tobytes(self):
+ """
+ The --tobytes option converts all UNADORNED string literals 'abcd' to b'abcd'.
+ It does apply to multi-line strings but doesn't apply if it's a raw
+ string, because ur'abcd' is a SyntaxError on Python 2 and br'abcd' is a
+ SyntaxError on Python 3.
+ """
+ before = r"""
+ s0 = '1234'
+ s1 = '''5678
+ '''
+ s2 = "9abc"
+ # Unchanged:
+ s3 = r'1234'
+ s4 = R"defg"
+ s5 = u'hijk'
+ s6 = u"lmno"
+ s7 = b'lmno'
+ s8 = b"pqrs"
+ """
+ after = r"""
+ s0 = b'1234'
+ s1 = b'''5678
+ '''
+ s2 = b"9abc"
+ # Unchanged:
+ s3 = r'1234'
+ s4 = R"defg"
+ s5 = u'hijk'
+ s6 = u"lmno"
+ s7 = b'lmno'
+ s8 = b"pqrs"
+ """
+ self.convert_check(before, after, tobytes=True)
+
+ def test_cmp(self):
+ before = """
+ assert cmp(1, 2) == -1
+ assert cmp(2, 1) == 1
+ """
+ after = """
+ from past.builtins import cmp
+ assert cmp(1, 2) == -1
+ assert cmp(2, 1) == 1
+ """
+ self.convert_check(before, after, stages=(1, 2), ignore_imports=False)
+
+ def test_execfile(self):
+ before = """
+ with open('mytempfile.py', 'w') as f:
+ f.write('x = 1')
+ execfile('mytempfile.py')
+ x += 1
+ assert x == 2
+ """
+ after = """
+ from past.builtins import execfile
+ with open('mytempfile.py', 'w') as f:
+ f.write('x = 1')
+ execfile('mytempfile.py')
+ x += 1
+ assert x == 2
+ """
+ self.convert_check(before, after, stages=(1, 2), ignore_imports=False)
+
+ @unittest.expectedFailure
+ def test_izip(self):
+ before = """
+ from itertools import izip
+ for (a, b) in izip([1, 3, 5], [2, 4, 6]):
+ pass
+ """
+ after = """
+ from builtins import zip
+ for (a, b) in zip([1, 3, 5], [2, 4, 6]):
+ pass
+ """
+ self.convert_check(before, after, stages=(1, 2), ignore_imports=False)
+
+ def test_UserList(self):
+ before = """
+ from UserList import UserList
+ a = UserList([1, 3, 5])
+ assert len(a) == 3
+ """
+ after = """
+ from collections import UserList
+ a = UserList([1, 3, 5])
+ assert len(a) == 3
+ """
+ self.convert_check(before, after, stages=(1, 2), ignore_imports=True)
+
+ @unittest.expectedFailure
+ def test_no_unneeded_list_calls(self):
+ """
+ TODO: get this working
+ """
+ code = """
+ for (a, b) in zip(range(3), range(3, 6)):
+ pass
+ """
+ self.unchanged(code)
+
+ @expectedFailurePY26
+ def test_import_builtins(self):
+ before = """
+ a = raw_input()
+ b = open(a, b, c)
+ c = filter(a, b)
+ d = map(a, b)
+ e = isinstance(a, str)
+ f = bytes(a, encoding='utf-8')
+ for g in xrange(10**10):
+ pass
+ h = reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
+ super(MyClass, self)
+ """
+ after = """
+ from builtins import bytes
+ from builtins import filter
+ from builtins import input
+ from builtins import map
+ from builtins import range
+ from functools import reduce
+ a = input()
+ b = open(a, b, c)
+ c = list(filter(a, b))
+ d = list(map(a, b))
+ e = isinstance(a, str)
+ f = bytes(a, encoding='utf-8')
+ for g in range(10**10):
+ pass
+ h = reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
+ super(MyClass, self)
+ """
+ self.convert_check(before, after, ignore_imports=False, run=False)
+
+ def test_input_without_import(self):
+ before = """
+ a = input()
+ """
+ after = """
+ from builtins import input
+ a = eval(input())
+ """
+ self.convert_check(before, after, ignore_imports=False, run=False)
+
+ def test_input_with_import(self):
+ before = """
+ from builtins import input
+ a = input()
+ """
+ after = """
+ from builtins import input
+ a = input()
+ """
+ self.convert_check(before, after, ignore_imports=False, run=False)
+
+ def test_xrange(self):
+ """
+ The ``from builtins import range`` line was being added to the
+ bottom of the file as of v0.11.4, but only using Py2.7's lib2to3.
+ (Py3.3's lib2to3 seems to work.)
+ """
+ before = """
+ for i in xrange(10):
+ pass
+ """
+ after = """
+ from builtins import range
+ for i in range(10):
+ pass
+ """
+ self.convert_check(before, after, ignore_imports=False)
+
+ def test_source_coding_utf8(self):
+ """
+ Tests to ensure that the source coding line is not corrupted or
+ removed. It must be left as the first line in the file (including
+ before any __future__ imports). Also tests whether the unicode
+ characters in this encoding are parsed correctly and left alone.
+ """
+ code = """
+ # -*- coding: utf-8 -*-
+ icons = [u"◐", u"◓", u"◑", u"◒"]
+ """
+
+ def test_exception_syntax(self):
+ """
+ Test of whether futurize handles the old-style exception syntax
+ """
+ before = """
+ try:
+ pass
+ except IOError, e:
+ val = e.errno
+ """
+ after = """
+ try:
+ pass
+ except IOError as e:
+ val = e.errno
+ """
+ self.convert_check(before, after)
+
+ def test_super(self):
+ """
+ This tests whether futurize keeps the old two-argument super() calls the
+ same as before. It should, because this still works in Py3.
+ """
+ code = '''
+ class VerboseList(list):
+ def append(self, item):
+ print('Adding an item')
+ super(VerboseList, self).append(item)
+ '''
+ self.unchanged(code)
+
+ @unittest.expectedFailure
+ def test_file(self):
+ """
+ file() as a synonym for open() is obsolete and invalid on Python 3.
+ """
+ before = '''
+ f = file(self.textfilename)
+ data = f.read()
+ f.close()
+ '''
+ after = '''
+ f = open(__file__)
+ data = f.read()
+ f.close()
+ '''
+ self.convert_check(before, after)
+
+ def test_apply(self):
+ before = '''
+ def addup(*x):
+ return sum(x)
+
+ assert apply(addup, (10,20)) == 30
+ '''
+ after = """
+ def addup(*x):
+ return sum(x)
+
+ assert addup(*(10,20)) == 30
+ """
+ self.convert_check(before, after)
+
+ @unittest.skip('not implemented yet')
+ def test_download_pypi_package_and_test(self):
+ URL = 'http://pypi.python.org/pypi/{0}/json'
+
+ import requests
+ package = 'future'
+ r = requests.get(URL.format(package))
+ pprint.pprint(r.json())
+
+ download_url = r.json()['urls'][0]['url']
+ filename = r.json()['urls'][0]['filename']
+ # r2 = requests.get(download_url)
+ # with open('/tmp/' + filename, 'w') as tarball:
+ # tarball.write(r2.content)
+
+ @expectedFailurePY26
+ def test_raw_input(self):
+ """
+ Passes in a string to the waiting input() after futurize
+ conversion.
+
+ The code is the first snippet from these docs:
+ http://docs.python.org/2/library/2to3.html
+ """
+ before = """
+ from io import BytesIO
+ def greet(name):
+ print "Hello, {0}!".format(name)
+ print "What's your name?"
+ import sys
+ oldstdin = sys.stdin
+
+ sys.stdin = BytesIO(b'Ed\\n')
+ name = raw_input()
+ greet(name.decode())
+
+ sys.stdin = oldstdin
+ assert name == b'Ed'
+ """
+ desired = """
+ from io import BytesIO
+ def greet(name):
+ print("Hello, {0}!".format(name))
+ print("What's your name?")
+ import sys
+ oldstdin = sys.stdin
+
+ sys.stdin = BytesIO(b'Ed\\n')
+ name = input()
+ greet(name.decode())
+
+ sys.stdin = oldstdin
+ assert name == b'Ed'
+ """
+ self.convert_check(before, desired, run=False)
+
+ for interpreter in self.interpreters:
+ p1 = Popen([interpreter, self.tempdir + 'mytestscript.py'],
+ stdout=PIPE, stdin=PIPE, stderr=PIPE)
+ (stdout, stderr) = p1.communicate(b'Ed')
+ self.assertEqual(stderr, b'')
+ self.assertEqual(stdout, b"What's your name?\nHello, Ed!\n")
+
+ def test_literal_prefixes_are_not_stripped(self):
+ """
+ Tests to ensure that the u'' and b'' prefixes on unicode strings and
+ byte strings are not removed by the futurize script. Removing the
+ prefixes on Py3.3+ is unnecessary and loses some information -- namely,
+ that the strings have explicitly been marked as unicode or bytes,
+ rather than just e.g. a guess by some automated tool about what they
+ are.
+ """
+ code = '''
+ s = u'unicode string'
+ b = b'byte string'
+ '''
+ self.unchanged(code)
+
+ def test_division(self):
+ before = """
+ x = 1 / 2
+ """
+ after = """
+ from past.utils import old_div
+ x = old_div(1, 2)
+ """
+ self.convert_check(before, after, stages=[1, 2])
+
+ def test_already_future_division(self):
+ code = """
+ from __future__ import division
+ x = 1 / 2
+ assert x == 0.5
+ y = 3. / 2.
+ assert y == 1.5
+ """
+ self.unchanged(code)
+
+
+class TestFuturizeRenamedStdlib(CodeHandler):
+ @unittest.skip('Infinite loop?')
+ def test_renamed_modules(self):
+ before = """
+ import ConfigParser
+ import copy_reg
+ import cPickle
+ import cStringIO
+ """
+ after = """
+ import configparser
+ import copyreg
+ import pickle
+ import io
+ """
+ # We can't run the converted code because configparser may
+ # not be there.
+ self.convert_check(before, after, run=False)
+
+ @unittest.skip('Not working yet ...')
+ def test_urllib_refactor(self):
+ # Code like this using urllib is refactored by futurize --stage2 to use
+ # the new Py3 module names, but ``future`` doesn't support urllib yet.
+ before = """
+ import urllib
+
+ URL = 'http://pypi.python.org/pypi/future/json'
+ package = 'future'
+ r = urllib.urlopen(URL.format(package))
+ data = r.read()
+ """
+ after = """
+ from future import standard_library
+ standard_library.install_aliases()
+ import urllib.request
+
+ URL = 'http://pypi.python.org/pypi/future/json'
+ package = 'future'
+ r = urllib.request.urlopen(URL.format(package))
+ data = r.read()
+ """
+ self.convert_check(before, after)
+
+ @unittest.skip('Infinite loop?')
+ def test_renamed_copy_reg_and_cPickle_modules(self):
+ """
+ Example from docs.python.org/2/library/copy_reg.html
+ """
+ before = """
+ import copy_reg
+ import copy
+ import cPickle
+ class C(object):
+ def __init__(self, a):
+ self.a = a
+
+ def pickle_c(c):
+ print('pickling a C instance...')
+ return C, (c.a,)
+
+ copy_reg.pickle(C, pickle_c)
+ c = C(1)
+ d = copy.copy(c)
+ p = cPickle.dumps(c)
+ """
+ after = """
+ import copyreg
+ import copy
+ import pickle
+ class C(object):
+ def __init__(self, a):
+ self.a = a
+
+ def pickle_c(c):
+ print('pickling a C instance...')
+ return C, (c.a,)
+
+ copyreg.pickle(C, pickle_c)
+ c = C(1)
+ d = copy.copy(c)
+ p = pickle.dumps(c)
+ """
+ self.convert_check(before, after)
+
+ @unittest.expectedFailure
+ def test_Py2_StringIO_module(self):
+ """
+ This requires that the argument to io.StringIO be made a
+ unicode string explicitly if we're not using unicode_literals:
+
+ Ideally, there would be a fixer for this. For now:
+
+ TODO: add the Py3 equivalent for this to the docs. Also add back
+ a test for the unicode_literals case.
+ """
+ before = """
+ import cStringIO
+ import StringIO
+ s1 = cStringIO.StringIO('my string')
+ s2 = StringIO.StringIO('my other string')
+ assert isinstance(s1, cStringIO.InputType)
+ """
+
+ # There is no io.InputType in Python 3. futurize should change this to
+ # something like this. But note that the input to io.StringIO
+ # must be a unicode string on both Py2 and Py3.
+ after = """
+ import io
+ import io
+ s1 = io.StringIO(u'my string')
+ s2 = io.StringIO(u'my other string')
+ assert isinstance(s1, io.StringIO)
+ """
+ self.convert_check(before, after)
+
+
+class TestFuturizeStage1(CodeHandler):
+ """
+ Tests "stage 1": safe optimizations: modernizing Python 2 code so that it
+ uses print functions, new-style exception syntax, etc.
+
+ The behaviour should not change and this should introduce no dependency on
+ the ``future`` package. It produces more modern Python 2-only code. The
+ goal is to reduce the size of the real porting patch-set by performing
+ the uncontroversial patches first.
+ """
+
+ def test_apply(self):
+ """
+ apply() should be changed by futurize --stage1
+ """
+ before = '''
+ def f(a, b):
+ return a + b
+
+ args = (1, 2)
+ assert apply(f, args) == 3
+ assert apply(f, ('a', 'b')) == 'ab'
+ '''
+ after = '''
+ def f(a, b):
+ return a + b
+
+ args = (1, 2)
+ assert f(*args) == 3
+ assert f(*('a', 'b')) == 'ab'
+ '''
+ self.convert_check(before, after, stages=[1])
+
+ def test_next_1(self):
+ """
+ Custom next methods should not be converted to __next__ in stage1, but
+ any obj.next() calls should be converted to next(obj).
+ """
+ before = """
+ class Upper:
+ def __init__(self, iterable):
+ self._iter = iter(iterable)
+ def next(self): # note the Py2 interface
+ return next(self._iter).upper()
+ def __iter__(self):
+ return self
+
+ itr = Upper('hello')
+ assert itr.next() == 'H'
+ assert next(itr) == 'E'
+ assert list(itr) == list('LLO')
+ """
+
+ after = """
+ class Upper:
+ def __init__(self, iterable):
+ self._iter = iter(iterable)
+ def next(self): # note the Py2 interface
+ return next(self._iter).upper()
+ def __iter__(self):
+ return self
+
+ itr = Upper('hello')
+ assert next(itr) == 'H'
+ assert next(itr) == 'E'
+ assert list(itr) == list('LLO')
+ """
+ self.convert_check(before, after, stages=[1], run=PY2)
+
+ @unittest.expectedFailure
+ def test_next_2(self):
+ """
+ This version of the above doesn't currently work: the self._iter.next() call in
+ line 5 isn't converted to next(self._iter).
+ """
+ before = """
+ class Upper:
+ def __init__(self, iterable):
+ self._iter = iter(iterable)
+ def next(self): # note the Py2 interface
+ return self._iter.next().upper()
+ def __iter__(self):
+ return self
+
+ itr = Upper('hello')
+ assert itr.next() == 'H'
+ assert next(itr) == 'E'
+ assert list(itr) == list('LLO')
+ """
+
+ after = """
+ class Upper(object):
+ def __init__(self, iterable):
+ self._iter = iter(iterable)
+ def next(self): # note the Py2 interface
+ return next(self._iter).upper()
+ def __iter__(self):
+ return self
+
+ itr = Upper('hello')
+ assert next(itr) == 'H'
+ assert next(itr) == 'E'
+ assert list(itr) == list('LLO')
+ """
+ self.convert_check(before, after, stages=[1], run=PY2)
+
+ def test_xrange(self):
+ """
+ xrange should not be changed by futurize --stage1
+ """
+ code = '''
+ for i in xrange(10):
+ pass
+ '''
+ self.unchanged(code, stages=[1], run=PY2)
+
+ @unittest.expectedFailure
+ def test_absolute_import_changes(self):
+ """
+ Implicit relative imports should be converted to absolute or explicit
+ relative imports correctly.
+
+ Issue #16 (with porting bokeh/bbmodel.py)
+ """
+ with open(self.tempdir + 'specialmodels.py', 'w') as f:
+ f.write('pass')
+
+ before = """
+ import specialmodels.pandasmodel
+ specialmodels.pandasmodel.blah()
+ """
+ after = """
+ from __future__ import absolute_import
+ from .specialmodels import pandasmodel
+ pandasmodel.blah()
+ """
+ self.convert_check(before, after, stages=[1])
+
+ def test_safe_futurize_imports(self):
+ """
+ The standard library module names should not be changed until stage 2
+ """
+ before = """
+ import ConfigParser
+ import HTMLParser
+ from itertools import ifilterfalse
+
+ ConfigParser.ConfigParser
+ HTMLParser.HTMLParser
+ assert list(ifilterfalse(lambda x: x % 2, [2, 4])) == [2, 4]
+ """
+ self.unchanged(before, stages=[1], run=PY2)
+
+ def test_print(self):
+ before = """
+ print 'Hello'
+ """
+ after = """
+ print('Hello')
+ """
+ self.convert_check(before, after, stages=[1])
+
+ before = """
+ import sys
+ print >> sys.stderr, 'Hello', 'world'
+ """
+ after = """
+ import sys
+ print('Hello', 'world', file=sys.stderr)
+ """
+ self.convert_check(before, after, stages=[1])
+
+ def test_print_already_function(self):
+ """
+ Running futurize --stage1 should not add a second set of parentheses
+ """
+ before = """
+ print('Hello')
+ """
+ self.unchanged(before, stages=[1])
+
+ @unittest.expectedFailure
+ def test_print_already_function_complex(self):
+ """
+ Running futurize --stage1 does add a second second set of parentheses
+ in this case. This is because the underlying lib2to3 has two distinct
+ grammars -- with a print statement and with a print function -- and,
+ when going forwards (2 to both), futurize assumes print is a statement,
+ which raises a ParseError.
+ """
+ before = """
+ import sys
+ print('Hello', 'world', file=sys.stderr)
+ """
+ self.unchanged(before, stages=[1])
+
+ def test_exceptions(self):
+ before = """
+ try:
+ raise AttributeError('blah')
+ except AttributeError, e:
+ pass
+ """
+ after = """
+ try:
+ raise AttributeError('blah')
+ except AttributeError as e:
+ pass
+ """
+ self.convert_check(before, after, stages=[1])
+
+ @unittest.expectedFailure
+ def test_string_exceptions(self):
+ """
+ 2to3 does not convert string exceptions: see
+ http://python3porting.com/differences.html.
+ """
+ before = """
+ try:
+ raise "old string exception"
+ except Exception, e:
+ pass
+ """
+ after = """
+ try:
+ raise Exception("old string exception")
+ except Exception as e:
+ pass
+ """
+ self.convert_check(before, after, stages=[1])
+
+ def test_oldstyle_classes(self):
+ """
+ We don't convert old-style classes to new-style automatically in
+ stage 1 (but we should in stage 2). So Blah should not inherit
+ explicitly from object yet.
+ """
+ before = """
+ class Blah:
+ pass
+ """
+ self.unchanged(before, stages=[1])
+
+ def test_stdlib_modules_not_changed(self):
+ """
+ Standard library module names should not be changed in stage 1
+ """
+ before = """
+ import ConfigParser
+ import HTMLParser
+ import collections
+
+ print 'Hello'
+ try:
+ raise AttributeError('blah')
+ except AttributeError, e:
+ pass
+ """
+ after = """
+ import ConfigParser
+ import HTMLParser
+ import collections
+
+ print('Hello')
+ try:
+ raise AttributeError('blah')
+ except AttributeError as e:
+ pass
+ """
+ self.convert_check(before, after, stages=[1], run=PY2)
+
+ def test_octal_literals(self):
+ before = """
+ mode = 0644
+ """
+ after = """
+ mode = 0o644
+ """
+ self.convert_check(before, after)
+
+ def test_long_int_literals(self):
+ before = """
+ bignumber = 12345678901234567890L
+ """
+ after = """
+ bignumber = 12345678901234567890
+ """
+ self.convert_check(before, after)
+
+ def test___future___import_position(self):
+ """
+ Issue #4: __future__ imports inserted too low in file: SyntaxError
+ """
+ code = """
+ # Comments here
+ # and here
+ __version__=''' $Id$ '''
+ __doc__="A Sequencer class counts things. It aids numbering and formatting lists."
+ __all__='Sequencer getSequencer setSequencer'.split()
+ #
+ # another comment
+ #
+
+ CONSTANTS = [ 0, 01, 011, 0111, 012, 02, 021, 0211, 02111, 013 ]
+ _RN_LETTERS = "IVXLCDM"
+
+ def my_func(value):
+ pass
+
+ ''' Docstring-like comment here '''
+ """
+ self.convert(code)
+
+ def test_issue_45(self):
+ """
+ Tests whether running futurize -f libfuturize.fixes.fix_future_standard_library_urllib
+ on the code below causes a ValueError (issue #45).
+ """
+ code = r"""
+ from __future__ import print_function
+ from urllib import urlopen, urlencode
+ oeis_url = 'http://oeis.org/'
+ def _fetch(url):
+ try:
+ f = urlopen(url)
+ result = f.read()
+ f.close()
+ return result
+ except IOError as msg:
+ raise IOError("%s\nError fetching %s." % (msg, url))
+ """
+ self.convert(code)
+
+ def test_order_future_lines(self):
+ """
+ Tests the internal order_future_lines() function.
+ """
+ before = '''
+ # comment here
+ from __future__ import print_function
+ from __future__ import absolute_import
+ # blank line or comment here
+ from future.utils import with_metaclass
+ from builtins import zzz
+ from builtins import aaa
+ from builtins import blah
+ # another comment
+
+ import something_else
+ code_here
+ more_code_here
+ '''
+ after = '''
+ # comment here
+ from __future__ import absolute_import
+ from __future__ import print_function
+ # blank line or comment here
+ from future.utils import with_metaclass
+ from builtins import aaa
+ from builtins import blah
+ from builtins import zzz
+ # another comment
+
+ import something_else
+ code_here
+ more_code_here
+ '''
+ self.assertEqual(order_future_lines(reformat_code(before)),
+ reformat_code(after))
+
+ @unittest.expectedFailure
+ def test_issue_12(self):
+ """
+ Issue #12: This code shouldn't be upset by additional imports.
+ __future__ imports must appear at the top of modules since about Python
+ 2.5.
+ """
+ code = """
+ from __future__ import with_statement
+ f = open('setup.py')
+ for i in xrange(100):
+ pass
+ """
+ self.unchanged(code)
+
+ @expectedFailurePY26
+ def test_range_necessary_list_calls(self):
+ """
+ On Py2.6 (only), the xrange_with_import fixer somehow seems to cause
+ l = range(10)
+ to be converted to:
+ l = list(list(range(10)))
+ with an extra list(...) call.
+ """
+ before = """
+ l = range(10)
+ assert isinstance(l, list)
+ for i in range(3):
+ print i
+ for i in xrange(3):
+ print i
+ """
+ after = """
+ from __future__ import print_function
+ from builtins import range
+ l = list(range(10))
+ assert isinstance(l, list)
+ for i in range(3):
+ print(i)
+ for i in range(3):
+ print(i)
+ """
+ self.convert_check(before, after)
+
+ def test_basestring(self):
+ """
+ The 2to3 basestring fixer breaks working Py2 code that uses basestring.
+ This tests whether something sensible is done instead.
+ """
+ before = """
+ assert isinstance('hello', basestring)
+ assert isinstance(u'hello', basestring)
+ assert isinstance(b'hello', basestring)
+ """
+ after = """
+ from past.builtins import basestring
+ assert isinstance('hello', basestring)
+ assert isinstance(u'hello', basestring)
+ assert isinstance(b'hello', basestring)
+ """
+ self.convert_check(before, after)
+
+ def test_safe_division(self):
+ """
+ Tests whether Py2 scripts using old-style division still work
+ after futurization.
+ """
+ before = """
+ import random
+ class fraction(object):
+ numer = 0
+ denom = 0
+ def __init__(self, numer, denom):
+ self.numer = numer
+ self.denom = denom
+
+ def total_count(self):
+ return self.numer * 50
+
+ x = 3 / 2
+ y = 3. / 2
+ foo = list(range(100))
+ assert x == 1 and isinstance(x, int)
+ assert y == 1.5 and isinstance(y, float)
+ a = 1 + foo[len(foo) / 2]
+ b = 1 + foo[len(foo) * 3 / 4]
+ assert a == 51
+ assert b == 76
+ r = random.randint(0, 1000) * 1.0 / 1000
+ output = { "SUCCESS": 5, "TOTAL": 10 }
+ output["SUCCESS"] * 100 / output["TOTAL"]
+ obj = fraction(1, 50)
+ val = float(obj.numer) / obj.denom * 1e-9
+ obj.numer * obj.denom / val
+ obj.total_count() * val / 100
+ obj.numer / obj.denom * 1e-9
+ obj.numer / (obj.denom * 1e-9)
+ obj.numer / obj.denom / 1e-9
+ obj.numer / (obj.denom / 1e-9)
+ original_numer = 1
+ original_denom = 50
+ 100 * abs(obj.numer - original_numer) / float(max(obj.denom, original_denom))
+ 100 * abs(obj.numer - original_numer) / max(obj.denom, original_denom)
+ float(original_numer) * float(original_denom) / float(obj.numer)
+ """
+ after = """
+ from __future__ import division
+ from past.utils import old_div
+ import random
+ class fraction(object):
+ numer = 0
+ denom = 0
+ def __init__(self, numer, denom):
+ self.numer = numer
+ self.denom = denom
+
+ def total_count(self):
+ return self.numer * 50
+
+ x = old_div(3, 2)
+ y = 3. / 2
+ foo = list(range(100))
+ assert x == 1 and isinstance(x, int)
+ assert y == 1.5 and isinstance(y, float)
+ a = 1 + foo[old_div(len(foo), 2)]
+ b = 1 + foo[old_div(len(foo) * 3, 4)]
+ assert a == 51
+ assert b == 76
+ r = random.randint(0, 1000) * 1.0 / 1000
+ output = { "SUCCESS": 5, "TOTAL": 10 }
+ old_div(output["SUCCESS"] * 100, output["TOTAL"])
+ obj = fraction(1, 50)
+ val = float(obj.numer) / obj.denom * 1e-9
+ old_div(obj.numer * obj.denom, val)
+ old_div(obj.total_count() * val, 100)
+ old_div(obj.numer, obj.denom) * 1e-9
+ old_div(obj.numer, (obj.denom * 1e-9))
+ old_div(old_div(obj.numer, obj.denom), 1e-9)
+ old_div(obj.numer, (old_div(obj.denom, 1e-9)))
+ original_numer = 1
+ original_denom = 50
+ 100 * abs(obj.numer - original_numer) / float(max(obj.denom, original_denom))
+ old_div(100 * abs(obj.numer - original_numer), max(obj.denom, original_denom))
+ float(original_numer) * float(original_denom) / float(obj.numer)
+ """
+ self.convert_check(before, after)
+
+ def test_safe_division_overloaded(self):
+ """
+ If division is overloaded, futurize may produce spurious old_div
+ calls. This test is for whether the code still works on Py2
+ despite these calls.
+ """
+ before = """
+ class Path(str):
+ def __div__(self, other):
+ return self.__truediv__(other)
+ def __truediv__(self, other):
+ return Path(str(self) + '/' + str(other))
+ path1 = Path('home')
+ path2 = Path('user')
+ z = path1 / path2
+ assert isinstance(z, Path)
+ assert str(z) == 'home/user'
+ """
+ after = """
+ from __future__ import division
+ from past.utils import old_div
+ class Path(str):
+ def __div__(self, other):
+ return self.__truediv__(other)
+ def __truediv__(self, other):
+ return Path(str(self) + '/' + str(other))
+ path1 = Path('home')
+ path2 = Path('user')
+ z = old_div(path1, path2)
+ assert isinstance(z, Path)
+ assert str(z) == 'home/user'
+ """
+ self.convert_check(before, after)
+
+ def test_basestring_issue_156(self):
+ before = """
+ x = str(3)
+ allowed_types = basestring, int
+ assert isinstance('', allowed_types)
+ assert isinstance(u'', allowed_types)
+ assert isinstance(u'foo', basestring)
+ """
+ after = """
+ from builtins import str
+ from past.builtins import basestring
+ x = str(3)
+ allowed_types = basestring, int
+ assert isinstance('', allowed_types)
+ assert isinstance(u'', allowed_types)
+ assert isinstance(u'foo', basestring)
+ """
+ self.convert_check(before, after)
+
+
+class TestConservativeFuturize(CodeHandler):
+ @unittest.expectedFailure
+ def test_basestring(self):
+ """
+ In conservative mode, futurize would not modify "basestring"
+ but merely import it from ``past``, and the following code would still
+ run on both Py2 and Py3.
+ """
+ before = """
+ assert isinstance('hello', basestring)
+ assert isinstance(u'hello', basestring)
+ assert isinstance(b'hello', basestring)
+ """
+ after = """
+ from past.builtins import basestring
+ assert isinstance('hello', basestring)
+ assert isinstance(u'hello', basestring)
+ assert isinstance(b'hello', basestring)
+ """
+ self.convert_check(before, after, conservative=True)
+
+ @unittest.expectedFailure
+ def test_open(self):
+ """
+ In conservative mode, futurize would not import io.open because
+ this changes the default return type from bytes to text.
+ """
+ before = """
+ filename = 'temp_file_open.test'
+ contents = 'Temporary file contents. Delete me.'
+ with open(filename, 'w') as f:
+ f.write(contents)
+
+ with open(filename, 'r') as f:
+ data = f.read()
+ assert isinstance(data, str)
+ assert data == contents
+ """
+ after = """
+ from past.builtins import open, str as oldbytes, unicode
+ filename = oldbytes(b'temp_file_open.test')
+ contents = oldbytes(b'Temporary file contents. Delete me.')
+ with open(filename, oldbytes(b'w')) as f:
+ f.write(contents)
+
+ with open(filename, oldbytes(b'r')) as f:
+ data = f.read()
+ assert isinstance(data, oldbytes)
+ assert data == contents
+ assert isinstance(oldbytes(b'hello'), basestring)
+ assert isinstance(unicode(u'hello'), basestring)
+ assert isinstance(oldbytes(b'hello'), basestring)
+ """
+ self.convert_check(before, after, conservative=True)
+
+
+class TestFuturizeAllImports(CodeHandler):
+ """
+ Tests "futurize --all-imports".
+ """
+ @expectedFailurePY26
+ def test_all_imports(self):
+ before = """
+ import math
+ import os
+ l = range(10)
+ assert isinstance(l, list)
+ print 'Hello'
+ for i in xrange(100):
+ pass
+ print('Hello')
+ """
+ after = """
+ from __future__ import absolute_import
+ from __future__ import division
+ from __future__ import print_function
+ from __future__ import unicode_literals
+ from future import standard_library
+ standard_library.install_aliases()
+ from builtins import *
+ from builtins import range
+ import math
+ import os
+ l = list(range(10))
+ assert isinstance(l, list)
+ print('Hello')
+ for i in range(100):
+ pass
+ print('Hello')
+ """
+ self.convert_check(before, after, all_imports=True, ignore_imports=False)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_html.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_html.py
new file mode 100644
index 0000000..251a530
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_html.py
@@ -0,0 +1,27 @@
+"""
+Tests for the html module functions.
+
+Adapted for the python-future module from the Python 3.3 standard library tests.
+"""
+
+from __future__ import unicode_literals
+from future import standard_library
+
+with standard_library.hooks():
+ import html
+
+from future.tests.base import unittest
+
+
+class HtmlTests(unittest.TestCase):
+ def test_escape(self):
+ self.assertEqual(
+ html.escape('\'<script>"&foo;"</script>\''),
+ '&#x27;&lt;script&gt;&quot;&amp;foo;&quot;&lt;/script&gt;&#x27;')
+ self.assertEqual(
+ html.escape('\'<script>"&foo;"</script>\'', False),
+ '\'&lt;script&gt;"&amp;foo;"&lt;/script&gt;\'')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_htmlparser.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_htmlparser.py
new file mode 100644
index 0000000..7a745ac
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_htmlparser.py
@@ -0,0 +1,764 @@
+# -*- coding: utf-8 -*-
+"""
+Tests for the html.parser functions.
+
+Adapted for the python-future module from the Python 3.3 standard library
+tests.
+"""
+
+from __future__ import (absolute_import, print_function, unicode_literals)
+from future import standard_library, utils
+from future.builtins import *
+
+from future.backports.test import support
+import future.backports.html.parser as html_parser
+
+import pprint
+from future.tests.base import unittest
+import sys
+
+# print(html_parser.__doc__, file=sys.stderr)
+
+
+class EventCollector(html_parser.HTMLParser):
+
+ def __init__(self, *args, **kw):
+ self.events = []
+ self.append = self.events.append
+ html_parser.HTMLParser.__init__(self, *args, **kw)
+
+ def get_events(self):
+ # Normalize the list of events so that buffer artefacts don't
+ # separate runs of contiguous characters.
+ L = []
+ prevtype = None
+ for event in self.events:
+ type = event[0]
+ if type == prevtype == "data":
+ L[-1] = ("data", L[-1][1] + event[1])
+ else:
+ L.append(event)
+ prevtype = type
+ self.events = L
+ return L
+
+ # structure markup
+
+ def handle_starttag(self, tag, attrs):
+ self.append(("starttag", tag, attrs))
+
+ def handle_startendtag(self, tag, attrs):
+ self.append(("startendtag", tag, attrs))
+
+ def handle_endtag(self, tag):
+ self.append(("endtag", tag))
+
+ # all other markup
+
+ def handle_comment(self, data):
+ self.append(("comment", data))
+
+ def handle_charref(self, data):
+ self.append(("charref", data))
+
+ def handle_data(self, data):
+ self.append(("data", data))
+
+ def handle_decl(self, data):
+ self.append(("decl", data))
+
+ def handle_entityref(self, data):
+ self.append(("entityref", data))
+
+ def handle_pi(self, data):
+ self.append(("pi", data))
+
+ def unknown_decl(self, decl):
+ self.append(("unknown decl", decl))
+
+
+class EventCollectorExtra(EventCollector):
+
+ def handle_starttag(self, tag, attrs):
+ EventCollector.handle_starttag(self, tag, attrs)
+ self.append(("starttag_text", self.get_starttag_text()))
+
+
+class TestCaseBase(unittest.TestCase):
+
+ def get_collector(self):
+ raise NotImplementedError
+
+ def _run_check(self, source, expected_events, collector=None):
+ if collector is None:
+ collector = self.get_collector()
+ parser = collector
+ for s in source:
+ parser.feed(s)
+ parser.close()
+ events = parser.get_events()
+ if events != expected_events:
+ self.fail("received events did not match expected events\n"
+ "Expected:\n" + pprint.pformat(expected_events) +
+ "\nReceived:\n" + pprint.pformat(events))
+
+ def _run_check_extra(self, source, events):
+ self._run_check(source, events, EventCollectorExtra())
+
+ def _parse_error(self, source):
+ def parse(source=source):
+ parser = self.get_collector()
+ parser.feed(source)
+ parser.close()
+ self.assertRaises(html_parser.HTMLParseError, parse)
+
+
+class HTMLParserStrictTestCase(TestCaseBase):
+
+ def get_collector(self):
+ with support.check_warnings(("", DeprecationWarning), quiet=False):
+ return EventCollector(strict=True)
+
+ def test_processing_instruction_only(self):
+ self._run_check("<?processing instruction>", [
+ ("pi", "processing instruction"),
+ ])
+ self._run_check("<?processing instruction ?>", [
+ ("pi", "processing instruction ?"),
+ ])
+
+ def test_simple_html(self):
+ self._run_check("""
+<!DOCTYPE html PUBLIC 'foo'>
+<HTML>&entity;&#32;
+<!--comment1a
+-></foo><bar>&lt;<?pi?></foo<bar
+comment1b-->
+<Img sRc='Bar' isMAP>sample
+text
+&#x201C;
+<!--comment2a-- --comment2b-->
+</Html>
+""", [
+ ("data", "\n"),
+ ("decl", "DOCTYPE html PUBLIC 'foo'"),
+ ("data", "\n"),
+ ("starttag", "html", []),
+ ("entityref", "entity"),
+ ("charref", "32"),
+ ("data", "\n"),
+ ("comment", "comment1a\n-></foo><bar>&lt;<?pi?></foo<bar\ncomment1b"),
+ ("data", "\n"),
+ ("starttag", "img", [("src", "Bar"), ("ismap", None)]),
+ ("data", "sample\ntext\n"),
+ ("charref", "x201C"),
+ ("data", "\n"),
+ ("comment", "comment2a-- --comment2b"),
+ ("data", "\n"),
+ ("endtag", "html"),
+ ("data", "\n"),
+ ])
+
+ def test_malformatted_charref(self):
+ self._run_check("<p>&#bad;</p>", [
+ ("starttag", "p", []),
+ ("data", "&#bad;"),
+ ("endtag", "p"),
+ ])
+
+ def test_unclosed_entityref(self):
+ self._run_check("&entityref foo", [
+ ("entityref", "entityref"),
+ ("data", " foo"),
+ ])
+
+ def test_bad_nesting(self):
+ # Strangely, this *is* supposed to test that overlapping
+ # elements are allowed. HTMLParser is more geared toward
+ # lexing the input that parsing the structure.
+ self._run_check("<a><b></a></b>", [
+ ("starttag", "a", []),
+ ("starttag", "b", []),
+ ("endtag", "a"),
+ ("endtag", "b"),
+ ])
+
+ def test_bare_ampersands(self):
+ self._run_check("this text & contains & ampersands &", [
+ ("data", "this text & contains & ampersands &"),
+ ])
+
+ def test_bare_pointy_brackets(self):
+ self._run_check("this < text > contains < bare>pointy< brackets", [
+ ("data", "this < text > contains < bare>pointy< brackets"),
+ ])
+
+ def test_illegal_declarations(self):
+ self._parse_error('<!spacer type="block" height="25">')
+
+ def test_starttag_end_boundary(self):
+ self._run_check("""<a b='<'>""", [("starttag", "a", [("b", "<")])])
+ self._run_check("""<a b='>'>""", [("starttag", "a", [("b", ">")])])
+
+ def test_buffer_artefacts(self):
+ output = [("starttag", "a", [("b", "<")])]
+ self._run_check(["<a b='<'>"], output)
+ self._run_check(["<a ", "b='<'>"], output)
+ self._run_check(["<a b", "='<'>"], output)
+ self._run_check(["<a b=", "'<'>"], output)
+ self._run_check(["<a b='<", "'>"], output)
+ self._run_check(["<a b='<'", ">"], output)
+
+ output = [("starttag", "a", [("b", ">")])]
+ self._run_check(["<a b='>'>"], output)
+ self._run_check(["<a ", "b='>'>"], output)
+ self._run_check(["<a b", "='>'>"], output)
+ self._run_check(["<a b=", "'>'>"], output)
+ self._run_check(["<a b='>", "'>"], output)
+ self._run_check(["<a b='>'", ">"], output)
+
+ output = [("comment", "abc")]
+ self._run_check(["", "<!--abc-->"], output)
+ self._run_check(["<", "!--abc-->"], output)
+ self._run_check(["<!", "--abc-->"], output)
+ self._run_check(["<!-", "-abc-->"], output)
+ self._run_check(["<!--", "abc-->"], output)
+ self._run_check(["<!--a", "bc-->"], output)
+ self._run_check(["<!--ab", "c-->"], output)
+ self._run_check(["<!--abc", "-->"], output)
+ self._run_check(["<!--abc-", "->"], output)
+ self._run_check(["<!--abc--", ">"], output)
+ self._run_check(["<!--abc-->", ""], output)
+
+ def test_starttag_junk_chars(self):
+ self._parse_error("</>")
+ self._parse_error("</$>")
+ self._parse_error("</")
+ self._parse_error("</a")
+ self._parse_error("<a<a>")
+ self._parse_error("</a<a>")
+ self._parse_error("<!")
+ self._parse_error("<a")
+ self._parse_error("<a foo='bar'")
+ self._parse_error("<a foo='bar")
+ self._parse_error("<a foo='>'")
+ self._parse_error("<a foo='>")
+
+ def test_valid_doctypes(self):
+ # from http://www.w3.org/QA/2002/04/valid-dtd-list.html
+ dtds = ['HTML', # HTML5 doctype
+ ('HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" '
+ '"http://www.w3.org/TR/html4/strict.dtd"'),
+ ('HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" '
+ '"http://www.w3.org/TR/html4/loose.dtd"'),
+ ('html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" '
+ '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"'),
+ ('html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" '
+ '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"'),
+ ('math PUBLIC "-//W3C//DTD MathML 2.0//EN" '
+ '"http://www.w3.org/Math/DTD/mathml2/mathml2.dtd"'),
+ ('html PUBLIC "-//W3C//DTD '
+ 'XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" '
+ '"http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd"'),
+ ('svg PUBLIC "-//W3C//DTD SVG 1.1//EN" '
+ '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"'),
+ 'html PUBLIC "-//IETF//DTD HTML 2.0//EN"',
+ 'html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"']
+ for dtd in dtds:
+ self._run_check("<!DOCTYPE %s>" % dtd,
+ [('decl', 'DOCTYPE ' + dtd)])
+
+ def test_declaration_junk_chars(self):
+ self._parse_error("<!DOCTYPE foo $ >")
+
+ def test_startendtag(self):
+ self._run_check("<p/>", [
+ ("startendtag", "p", []),
+ ])
+ self._run_check("<p></p>", [
+ ("starttag", "p", []),
+ ("endtag", "p"),
+ ])
+ self._run_check("<p><img src='foo' /></p>", [
+ ("starttag", "p", []),
+ ("startendtag", "img", [("src", "foo")]),
+ ("endtag", "p"),
+ ])
+
+ def test_get_starttag_text(self):
+ s = """<foo:bar \n one="1"\ttwo=2 >"""
+ self._run_check_extra(s, [
+ ("starttag", "foo:bar", [("one", "1"), ("two", "2")]),
+ ("starttag_text", s)])
+
+ def test_cdata_content(self):
+ contents = [
+ '<!-- not a comment --> &not-an-entity-ref;',
+ "<not a='start tag'>",
+ '<a href="" /> <p> <span></span>',
+ 'foo = "</scr" + "ipt>";',
+ 'foo = "</SCRIPT" + ">";',
+ 'foo = <\n/script> ',
+ '<!-- document.write("</scr" + "ipt>"); -->',
+ ('\n//<![CDATA[\n'
+ 'document.write(\'<s\'+\'cript type="text/javascript" '
+ 'src="http://www.example.org/r=\'+new '
+ 'Date().getTime()+\'"><\\/s\'+\'cript>\');\n//]]>'),
+ '\n<!-- //\nvar foo = 3.14;\n// -->\n',
+ 'foo = "</sty" + "le>";',
+ '<!-- \u2603 -->',
+ # these two should be invalid according to the HTML 5 spec,
+ # section 8.1.2.2
+ #'foo = </\nscript>',
+ #'foo = </ script>',
+ ]
+ elements = ['script', 'style', 'SCRIPT', 'STYLE', 'Script', 'Style']
+ for content in contents:
+ for element in elements:
+ element_lower = element.lower()
+ s = '<{element}>{content}</{element}>'.format(element=element,
+ content=content)
+ self._run_check(s, [("starttag", element_lower, []),
+ ("data", content),
+ ("endtag", element_lower)])
+
+ def test_cdata_with_closing_tags(self):
+ # see issue #13358
+ # make sure that HTMLParser calls handle_data only once for each CDATA.
+ # The normal event collector normalizes the events in get_events,
+ # so we override it to return the original list of events.
+ class Collector(EventCollector):
+ def get_events(self):
+ return self.events
+
+ content = """<!-- not a comment --> &not-an-entity-ref;
+ <a href="" /> </p><p> <span></span></style>
+ '</script' + '>'"""
+ for element in [' script', 'script ', ' script ',
+ '\nscript', 'script\n', '\nscript\n']:
+ element_lower = element.lower().strip()
+ s = '<script>{content}</{element}>'.format(element=element,
+ content=content)
+ self._run_check(s, [("starttag", element_lower, []),
+ ("data", content),
+ ("endtag", element_lower)],
+ collector=Collector())
+
+ def test_comments(self):
+ html = ("<!-- I'm a valid comment -->"
+ '<!--me too!-->'
+ '<!------>'
+ '<!---->'
+ '<!----I have many hyphens---->'
+ '<!-- I have a > in the middle -->'
+ '<!-- and I have -- in the middle! -->')
+ expected = [('comment', " I'm a valid comment "),
+ ('comment', 'me too!'),
+ ('comment', '--'),
+ ('comment', ''),
+ ('comment', '--I have many hyphens--'),
+ ('comment', ' I have a > in the middle '),
+ ('comment', ' and I have -- in the middle! ')]
+ self._run_check(html, expected)
+
+ def test_condcoms(self):
+ html = ('<!--[if IE & !(lte IE 8)]>aren\'t<![endif]-->'
+ '<!--[if IE 8]>condcoms<![endif]-->'
+ '<!--[if lte IE 7]>pretty?<![endif]-->')
+ expected = [('comment', "[if IE & !(lte IE 8)]>aren't<![endif]"),
+ ('comment', '[if IE 8]>condcoms<![endif]'),
+ ('comment', '[if lte IE 7]>pretty?<![endif]')]
+ self._run_check(html, expected)
+
+
+class HTMLParserTolerantTestCase(HTMLParserStrictTestCase):
+
+ def get_collector(self):
+ return EventCollector(strict=False)
+
+ @unittest.skipIf(utils.PY3, 'not working on Py3.3.4 for some reason ...')
+ def test_tolerant_parsing(self):
+ self._run_check('<html <html>te>>xt&a<<bc</a></html>\n'
+ '<img src="URL><//img></html</html>', [
+ ('starttag', 'html', [('<html', None)]),
+ ('data', 'te>>xt'),
+ ('entityref', 'a'),
+ ('data', '<<bc'),
+ ('endtag', 'a'),
+ ('endtag', 'html'),
+ ('data', '\n<img src="URL>'),
+ ('comment', '/img'),
+ ('endtag', 'html<')])
+
+ @unittest.skipIf(utils.PY3, 'not working on Py3.3.4 for some reason ...')
+ def test_starttag_junk_chars(self):
+ self._run_check("</>", [])
+ self._run_check("</$>", [('comment', '$')])
+ self._run_check("</", [('data', '</')])
+ self._run_check("</a", [('data', '</a')])
+ # XXX this might be wrong
+ self._run_check("<a<a>", [('data', '<a'), ('starttag', 'a', [])])
+ self._run_check("</a<a>", [('endtag', 'a<a')])
+ self._run_check("<!", [('data', '<!')])
+ self._run_check("<a", [('data', '<a')])
+ self._run_check("<a foo='bar'", [('data', "<a foo='bar'")])
+ self._run_check("<a foo='bar", [('data', "<a foo='bar")])
+ self._run_check("<a foo='>'", [('data', "<a foo='>'")])
+ self._run_check("<a foo='>", [('data', "<a foo='>")])
+
+ def test_slashes_in_starttag(self):
+ self._run_check('<a foo="var"/>', [('startendtag', 'a', [('foo', 'var')])])
+ html = ('<img width=902 height=250px '
+ 'src="/sites/default/files/images/homepage/foo.jpg" '
+ '/*what am I doing here*/ />')
+ expected = [(
+ 'startendtag', 'img',
+ [('width', '902'), ('height', '250px'),
+ ('src', '/sites/default/files/images/homepage/foo.jpg'),
+ ('*what', None), ('am', None), ('i', None),
+ ('doing', None), ('here*', None)]
+ )]
+ self._run_check(html, expected)
+ html = ('<a / /foo/ / /=/ / /bar/ / />'
+ '<a / /foo/ / /=/ / /bar/ / >')
+ expected = [
+ ('startendtag', 'a', [('foo', None), ('=', None), ('bar', None)]),
+ ('starttag', 'a', [('foo', None), ('=', None), ('bar', None)])
+ ]
+ self._run_check(html, expected)
+ #see issue #14538
+ html = ('<meta><meta / ><meta // ><meta / / >'
+ '<meta/><meta /><meta //><meta//>')
+ expected = [
+ ('starttag', 'meta', []), ('starttag', 'meta', []),
+ ('starttag', 'meta', []), ('starttag', 'meta', []),
+ ('startendtag', 'meta', []), ('startendtag', 'meta', []),
+ ('startendtag', 'meta', []), ('startendtag', 'meta', []),
+ ]
+ self._run_check(html, expected)
+
+ def test_declaration_junk_chars(self):
+ self._run_check("<!DOCTYPE foo $ >", [('decl', 'DOCTYPE foo $ ')])
+
+ def test_illegal_declarations(self):
+ self._run_check('<!spacer type="block" height="25">',
+ [('comment', 'spacer type="block" height="25"')])
+
+ def test_with_unquoted_attributes(self):
+ # see #12008
+ html = ("<html><body bgcolor=d0ca90 text='181008'>"
+ "<table cellspacing=0 cellpadding=1 width=100% ><tr>"
+ "<td align=left><font size=-1>"
+ "- <a href=/rabota/><span class=en> software-and-i</span></a>"
+ "- <a href='/1/'><span class=en> library</span></a></table>")
+ expected = [
+ ('starttag', 'html', []),
+ ('starttag', 'body', [('bgcolor', 'd0ca90'), ('text', '181008')]),
+ ('starttag', 'table',
+ [('cellspacing', '0'), ('cellpadding', '1'), ('width', '100%')]),
+ ('starttag', 'tr', []),
+ ('starttag', 'td', [('align', 'left')]),
+ ('starttag', 'font', [('size', '-1')]),
+ ('data', '- '), ('starttag', 'a', [('href', '/rabota/')]),
+ ('starttag', 'span', [('class', 'en')]), ('data', ' software-and-i'),
+ ('endtag', 'span'), ('endtag', 'a'),
+ ('data', '- '), ('starttag', 'a', [('href', '/1/')]),
+ ('starttag', 'span', [('class', 'en')]), ('data', ' library'),
+ ('endtag', 'span'), ('endtag', 'a'), ('endtag', 'table')
+ ]
+ self._run_check(html, expected)
+
+ def test_comma_between_attributes(self):
+ self._run_check('<form action="/xxx.php?a=1&amp;b=2&amp", '
+ 'method="post">', [
+ ('starttag', 'form',
+ [('action', '/xxx.php?a=1&b=2&'),
+ (',', None), ('method', 'post')])])
+
+ def test_weird_chars_in_unquoted_attribute_values(self):
+ self._run_check('<form action=bogus|&#()value>', [
+ ('starttag', 'form',
+ [('action', 'bogus|&#()value')])])
+
+ def test_invalid_end_tags(self):
+ # A collection of broken end tags. <br> is used as separator.
+ # see http://www.w3.org/TR/html5/tokenization.html#end-tag-open-state
+ # and #13993
+ html = ('<br></label</p><br></div end tmAd-leaderBoard><br></<h4><br>'
+ '</li class="unit"><br></li\r\n\t\t\t\t\t\t</ul><br></><br>')
+ expected = [('starttag', 'br', []),
+ # < is part of the name, / is discarded, p is an attribute
+ ('endtag', 'label<'),
+ ('starttag', 'br', []),
+ # text and attributes are discarded
+ ('endtag', 'div'),
+ ('starttag', 'br', []),
+ # comment because the first char after </ is not a-zA-Z
+ ('comment', '<h4'),
+ ('starttag', 'br', []),
+ # attributes are discarded
+ ('endtag', 'li'),
+ ('starttag', 'br', []),
+ # everything till ul (included) is discarded
+ ('endtag', 'li'),
+ ('starttag', 'br', []),
+ # </> is ignored
+ ('starttag', 'br', [])]
+ self._run_check(html, expected)
+
+ def test_broken_invalid_end_tag(self):
+ # This is technically wrong (the "> shouldn't be included in the 'data')
+ # but is probably not worth fixing it (in addition to all the cases of
+ # the previous test, it would require a full attribute parsing).
+ # see #13993
+ html = '<b>This</b attr=">"> confuses the parser'
+ expected = [('starttag', 'b', []),
+ ('data', 'This'),
+ ('endtag', 'b'),
+ ('data', '"> confuses the parser')]
+ self._run_check(html, expected)
+
+ def test_correct_detection_of_start_tags(self):
+ # see #13273
+ html = ('<div style="" ><b>The <a href="some_url">rain</a> '
+ '<br /> in <span>Spain</span></b></div>')
+ expected = [
+ ('starttag', 'div', [('style', '')]),
+ ('starttag', 'b', []),
+ ('data', 'The '),
+ ('starttag', 'a', [('href', 'some_url')]),
+ ('data', 'rain'),
+ ('endtag', 'a'),
+ ('data', ' '),
+ ('startendtag', 'br', []),
+ ('data', ' in '),
+ ('starttag', 'span', []),
+ ('data', 'Spain'),
+ ('endtag', 'span'),
+ ('endtag', 'b'),
+ ('endtag', 'div')
+ ]
+ self._run_check(html, expected)
+
+ html = '<div style="", foo = "bar" ><b>The <a href="some_url">rain</a>'
+ expected = [
+ ('starttag', 'div', [('style', ''), (',', None), ('foo', 'bar')]),
+ ('starttag', 'b', []),
+ ('data', 'The '),
+ ('starttag', 'a', [('href', 'some_url')]),
+ ('data', 'rain'),
+ ('endtag', 'a'),
+ ]
+ self._run_check(html, expected)
+
+ def test_unescape_function(self):
+ p = self.get_collector()
+ self.assertEqual(p.unescape('&#bad;'),'&#bad;')
+ self.assertEqual(p.unescape('&#0038;'),'&')
+ # see #12888
+ self.assertEqual(p.unescape('&#123; ' * 1050), '{ ' * 1050)
+ # see #15156
+ self.assertEqual(p.unescape('&Eacuteric&Eacute;ric'
+ '&alphacentauri&alpha;centauri'),
+ 'ÉricÉric&alphacentauriαcentauri')
+ self.assertEqual(p.unescape('&co;'), '&co;')
+
+ def test_broken_comments(self):
+ html = ('<! not really a comment >'
+ '<! not a comment either -->'
+ '<! -- close enough -->'
+ '<!><!<-- this was an empty comment>'
+ '<!!! another bogus comment !!!>')
+ expected = [
+ ('comment', ' not really a comment '),
+ ('comment', ' not a comment either --'),
+ ('comment', ' -- close enough --'),
+ ('comment', ''),
+ ('comment', '<-- this was an empty comment'),
+ ('comment', '!! another bogus comment !!!'),
+ ]
+ self._run_check(html, expected)
+
+ def test_broken_condcoms(self):
+ # these condcoms are missing the '--' after '<!' and before the '>'
+ html = ('<![if !(IE)]>broken condcom<![endif]>'
+ '<![if ! IE]><link href="favicon.tiff"/><![endif]>'
+ '<![if !IE 6]><img src="firefox.png" /><![endif]>'
+ '<![if !ie 6]><b>foo</b><![endif]>'
+ '<![if (!IE)|(lt IE 9)]><img src="mammoth.bmp" /><![endif]>')
+ # According to the HTML5 specs sections "8.2.4.44 Bogus comment state"
+ # and "8.2.4.45 Markup declaration open state", comment tokens should
+ # be emitted instead of 'unknown decl', but calling unknown_decl
+ # provides more flexibility.
+ # See also Lib/_markupbase.py:parse_declaration
+ expected = [
+ ('unknown decl', 'if !(IE)'),
+ ('data', 'broken condcom'),
+ ('unknown decl', 'endif'),
+ ('unknown decl', 'if ! IE'),
+ ('startendtag', 'link', [('href', 'favicon.tiff')]),
+ ('unknown decl', 'endif'),
+ ('unknown decl', 'if !IE 6'),
+ ('startendtag', 'img', [('src', 'firefox.png')]),
+ ('unknown decl', 'endif'),
+ ('unknown decl', 'if !ie 6'),
+ ('starttag', 'b', []),
+ ('data', 'foo'),
+ ('endtag', 'b'),
+ ('unknown decl', 'endif'),
+ ('unknown decl', 'if (!IE)|(lt IE 9)'),
+ ('startendtag', 'img', [('src', 'mammoth.bmp')]),
+ ('unknown decl', 'endif')
+ ]
+ self._run_check(html, expected)
+
+
+class AttributesStrictTestCase(TestCaseBase):
+
+ def get_collector(self):
+ with support.check_warnings(("", DeprecationWarning), quiet=False):
+ return EventCollector(strict=True)
+
+ def test_attr_syntax(self):
+ output = [
+ ("starttag", "a", [("b", "v"), ("c", "v"), ("d", "v"), ("e", None)])
+ ]
+ self._run_check("""<a b='v' c="v" d=v e>""", output)
+ self._run_check("""<a b = 'v' c = "v" d = v e>""", output)
+ self._run_check("""<a\nb\n=\n'v'\nc\n=\n"v"\nd\n=\nv\ne>""", output)
+ self._run_check("""<a\tb\t=\t'v'\tc\t=\t"v"\td\t=\tv\te>""", output)
+
+ def test_attr_values(self):
+ self._run_check("""<a b='xxx\n\txxx' c="yyy\t\nyyy" d='\txyz\n'>""",
+ [("starttag", "a", [("b", "xxx\n\txxx"),
+ ("c", "yyy\t\nyyy"),
+ ("d", "\txyz\n")])])
+ self._run_check("""<a b='' c="">""",
+ [("starttag", "a", [("b", ""), ("c", "")])])
+ # Regression test for SF patch #669683.
+ self._run_check("<e a=rgb(1,2,3)>",
+ [("starttag", "e", [("a", "rgb(1,2,3)")])])
+ # Regression test for SF bug #921657.
+ self._run_check(
+ "<a href=mailto:xyz@example.com>",
+ [("starttag", "a", [("href", "mailto:xyz@example.com")])])
+
+ def test_attr_nonascii(self):
+ # see issue 7311
+ self._run_check(
+ "<img src=/foo/bar.png alt=\u4e2d\u6587>",
+ [("starttag", "img", [("src", "/foo/bar.png"),
+ ("alt", "\u4e2d\u6587")])])
+ self._run_check(
+ "<a title='\u30c6\u30b9\u30c8' href='\u30c6\u30b9\u30c8.html'>",
+ [("starttag", "a", [("title", "\u30c6\u30b9\u30c8"),
+ ("href", "\u30c6\u30b9\u30c8.html")])])
+ self._run_check(
+ '<a title="\u30c6\u30b9\u30c8" href="\u30c6\u30b9\u30c8.html">',
+ [("starttag", "a", [("title", "\u30c6\u30b9\u30c8"),
+ ("href", "\u30c6\u30b9\u30c8.html")])])
+
+ def test_attr_entity_replacement(self):
+ self._run_check(
+ "<a b='&amp;&gt;&lt;&quot;&apos;'>",
+ [("starttag", "a", [("b", "&><\"'")])])
+
+ def test_attr_funky_names(self):
+ self._run_check(
+ "<a a.b='v' c:d=v e-f=v>",
+ [("starttag", "a", [("a.b", "v"), ("c:d", "v"), ("e-f", "v")])])
+
+ def test_entityrefs_in_attributes(self):
+ self._run_check(
+ "<html foo='&euro;&amp;&#97;&#x61;&unsupported;'>",
+ [("starttag", "html", [("foo", "\u20AC&aa&unsupported;")])])
+
+
+
+class AttributesTolerantTestCase(AttributesStrictTestCase):
+
+ def get_collector(self):
+ return EventCollector(strict=False)
+
+ def test_attr_funky_names2(self):
+ self._run_check(
+ "<a $><b $=%><c \=/>",
+ [("starttag", "a", [("$", None)]),
+ ("starttag", "b", [("$", "%")]),
+ ("starttag", "c", [("\\", "/")])])
+
+ def test_entities_in_attribute_value(self):
+ # see #1200313
+ for entity in ['&', '&amp;', '&#38;', '&#x26;']:
+ self._run_check('<a href="%s">' % entity,
+ [("starttag", "a", [("href", "&")])])
+ self._run_check("<a href='%s'>" % entity,
+ [("starttag", "a", [("href", "&")])])
+ self._run_check("<a href=%s>" % entity,
+ [("starttag", "a", [("href", "&")])])
+
+ def test_malformed_attributes(self):
+ # see #13357
+ html = (
+ "<a href=test'style='color:red;bad1'>test - bad1</a>"
+ "<a href=test'+style='color:red;ba2'>test - bad2</a>"
+ "<a href=test'&nbsp;style='color:red;bad3'>test - bad3</a>"
+ "<a href = test'&nbsp;style='color:red;bad4' >test - bad4</a>"
+ )
+ expected = [
+ ('starttag', 'a', [('href', "test'style='color:red;bad1'")]),
+ ('data', 'test - bad1'), ('endtag', 'a'),
+ ('starttag', 'a', [('href', "test'+style='color:red;ba2'")]),
+ ('data', 'test - bad2'), ('endtag', 'a'),
+ ('starttag', 'a', [('href', "test'\xa0style='color:red;bad3'")]),
+ ('data', 'test - bad3'), ('endtag', 'a'),
+ ('starttag', 'a', [('href', "test'\xa0style='color:red;bad4'")]),
+ ('data', 'test - bad4'), ('endtag', 'a')
+ ]
+ self._run_check(html, expected)
+
+ def test_malformed_adjacent_attributes(self):
+ # see #12629
+ self._run_check('<x><y z=""o"" /></x>',
+ [('starttag', 'x', []),
+ ('startendtag', 'y', [('z', ''), ('o""', None)]),
+ ('endtag', 'x')])
+ self._run_check('<x><y z="""" /></x>',
+ [('starttag', 'x', []),
+ ('startendtag', 'y', [('z', ''), ('""', None)]),
+ ('endtag', 'x')])
+
+ # see #755670 for the following 3 tests
+ def test_adjacent_attributes(self):
+ self._run_check('<a width="100%"cellspacing=0>',
+ [("starttag", "a",
+ [("width", "100%"), ("cellspacing","0")])])
+
+ self._run_check('<a id="foo"class="bar">',
+ [("starttag", "a",
+ [("id", "foo"), ("class","bar")])])
+
+ def test_missing_attribute_value(self):
+ self._run_check('<a v=>',
+ [("starttag", "a", [("v", "")])])
+
+ def test_javascript_attribute_value(self):
+ self._run_check("<a href=javascript:popup('/popup/help.html')>",
+ [("starttag", "a",
+ [("href", "javascript:popup('/popup/help.html')")])])
+
+ def test_end_tag_in_attribute_value(self):
+ # see #1745761
+ self._run_check("<a href='http://www.example.org/\">;'>spam</a>",
+ [("starttag", "a",
+ [("href", "http://www.example.org/\">;")]),
+ ("data", "spam"), ("endtag", "a")])
+
+def test_main():
+ support.run_unittest(HTMLParserStrictTestCase, HTMLParserTolerantTestCase,
+ AttributesStrictTestCase, AttributesTolerantTestCase)
+
+
+if __name__ == "__main__":
+ # unittest.main()
+ test_main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_http_cookiejar.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_http_cookiejar.py
new file mode 100644
index 0000000..079026b
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_http_cookiejar.py
@@ -0,0 +1,1755 @@
+"""Tests for http/cookiejar.py."""
+from __future__ import unicode_literals
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+from future.builtins import range
+from future.builtins import open
+
+import os
+import re
+import time
+from future.tests.base import unittest, skip26, expectedFailurePY26
+import future.backports.test.support as test_support
+import future.backports.urllib.request as urllib_request
+
+from future.backports.http.cookiejar import (time2isoz, http2time,
+ iso2time, time2netscape,
+ parse_ns_headers, join_header_words, split_header_words, Cookie,
+ CookieJar, DefaultCookiePolicy, LWPCookieJar, MozillaCookieJar,
+ LoadError, lwp_cookie_str, DEFAULT_HTTP_PORT, escape_path,
+ reach, is_HDN, domain_match, user_domain_match, request_path,
+ request_port, request_host)
+
+
+class DateTimeTests(unittest.TestCase):
+
+ def test_time2isoz(self):
+ base = 1019227000
+ day = 24*3600
+ self.assertEqual(time2isoz(base), "2002-04-19 14:36:40Z")
+ self.assertEqual(time2isoz(base+day), "2002-04-20 14:36:40Z")
+ self.assertEqual(time2isoz(base+2*day), "2002-04-21 14:36:40Z")
+ self.assertEqual(time2isoz(base+3*day), "2002-04-22 14:36:40Z")
+
+ az = time2isoz()
+ bz = time2isoz(500000)
+ for text in (az, bz):
+ self.assertRegex(text, r"^\d{4}-\d\d-\d\d \d\d:\d\d:\d\dZ$",
+ "bad time2isoz format: %s %s" % (az, bz))
+
+ def test_http2time(self):
+ def parse_date(text):
+ return time.gmtime(http2time(text))[:6]
+
+ self.assertEqual(parse_date("01 Jan 2001"), (2001, 1, 1, 0, 0, 0.0))
+
+ # this test will break around year 2070
+ self.assertEqual(parse_date("03-Feb-20"), (2020, 2, 3, 0, 0, 0.0))
+
+ # this test will break around year 2048
+ self.assertEqual(parse_date("03-Feb-98"), (1998, 2, 3, 0, 0, 0.0))
+
+ def test_http2time_formats(self):
+ # test http2time for supported dates. Test cases with 2 digit year
+ # will probably break in year 2044.
+ tests = [
+ 'Thu, 03 Feb 1994 00:00:00 GMT', # proposed new HTTP format
+ 'Thursday, 03-Feb-94 00:00:00 GMT', # old rfc850 HTTP format
+ 'Thursday, 03-Feb-1994 00:00:00 GMT', # broken rfc850 HTTP format
+
+ '03 Feb 1994 00:00:00 GMT', # HTTP format (no weekday)
+ '03-Feb-94 00:00:00 GMT', # old rfc850 (no weekday)
+ '03-Feb-1994 00:00:00 GMT', # broken rfc850 (no weekday)
+ '03-Feb-1994 00:00 GMT', # broken rfc850 (no weekday, no seconds)
+ '03-Feb-1994 00:00', # broken rfc850 (no weekday, no seconds, no tz)
+ '02-Feb-1994 24:00', # broken rfc850 (no weekday, no seconds,
+ # no tz) using hour 24 with yesterday date
+
+ '03-Feb-94', # old rfc850 HTTP format (no weekday, no time)
+ '03-Feb-1994', # broken rfc850 HTTP format (no weekday, no time)
+ '03 Feb 1994', # proposed new HTTP format (no weekday, no time)
+
+ # A few tests with extra space at various places
+ ' 03 Feb 1994 0:00 ',
+ ' 03-Feb-1994 ',
+ ]
+
+ test_t = 760233600 # assume broken POSIX counting of seconds
+ result = time2isoz(test_t)
+ expected = "1994-02-03 00:00:00Z"
+ self.assertEqual(result, expected,
+ "%s => '%s' (%s)" % (test_t, result, expected))
+
+ for s in tests:
+ self.assertEqual(http2time(s), test_t, s)
+ self.assertEqual(http2time(s.lower()), test_t, s.lower())
+ self.assertEqual(http2time(s.upper()), test_t, s.upper())
+
+ def test_http2time_garbage(self):
+ for test in [
+ '',
+ 'Garbage',
+ 'Mandag 16. September 1996',
+ '01-00-1980',
+ '01-13-1980',
+ '00-01-1980',
+ '32-01-1980',
+ '01-01-1980 25:00:00',
+ '01-01-1980 00:61:00',
+ '01-01-1980 00:00:62',
+ ]:
+ self.assertIsNone(http2time(test),
+ "http2time(%s) is not None\n"
+ "http2time(test) %s" % (test, http2time(test)))
+
+ def test_iso2time(self):
+ def parse_date(text):
+ return time.gmtime(iso2time(text))[:6]
+
+ # ISO 8601 compact format
+ self.assertEqual(parse_date("19940203T141529Z"),
+ (1994, 2, 3, 14, 15, 29))
+
+ # ISO 8601 with time behind UTC
+ self.assertEqual(parse_date("1994-02-03 07:15:29 -0700"),
+ (1994, 2, 3, 14, 15, 29))
+
+ # ISO 8601 with time ahead of UTC
+ self.assertEqual(parse_date("1994-02-03 19:45:29 +0530"),
+ (1994, 2, 3, 14, 15, 29))
+
+ def test_iso2time_formats(self):
+ # test iso2time for supported dates.
+ tests = [
+ '1994-02-03 00:00:00 -0000', # ISO 8601 format
+ '1994-02-03 00:00:00 +0000', # ISO 8601 format
+ '1994-02-03 00:00:00', # zone is optional
+ '1994-02-03', # only date
+ '1994-02-03T00:00:00', # Use T as separator
+ '19940203', # only date
+ '1994-02-02 24:00:00', # using hour-24 yesterday date
+ '19940203T000000Z', # ISO 8601 compact format
+
+ # A few tests with extra space at various places
+ ' 1994-02-03 ',
+ ' 1994-02-03T00:00:00 ',
+ ]
+
+ test_t = 760233600 # assume broken POSIX counting of seconds
+ for s in tests:
+ self.assertEqual(iso2time(s), test_t, s)
+ self.assertEqual(iso2time(s.lower()), test_t, s.lower())
+ self.assertEqual(iso2time(s.upper()), test_t, s.upper())
+
+ def test_iso2time_garbage(self):
+ for test in [
+ '',
+ 'Garbage',
+ 'Thursday, 03-Feb-94 00:00:00 GMT',
+ '1980-00-01',
+ '1980-13-01',
+ '1980-01-00',
+ '1980-01-32',
+ '1980-01-01 25:00:00',
+ '1980-01-01 00:61:00',
+ '01-01-1980 00:00:62',
+ '01-01-1980T00:00:62',
+ '19800101T250000Z'
+ '1980-01-01 00:00:00 -2500',
+ ]:
+ self.assertIsNone(iso2time(test),
+ "iso2time(%s) is not None\n"
+ "iso2time(test) %s" % (test, iso2time(test)))
+
+
+class HeaderTests(unittest.TestCase):
+
+ def test_parse_ns_headers(self):
+ # quotes should be stripped
+ expected = [[('foo', 'bar'), ('expires', 2209069412), ('version', '0')]]
+ for hdr in [
+ 'foo=bar; expires=01 Jan 2040 22:23:32 GMT',
+ 'foo=bar; expires="01 Jan 2040 22:23:32 GMT"',
+ ]:
+ self.assertEqual(parse_ns_headers([hdr]), expected)
+
+ def test_parse_ns_headers_version(self):
+
+ # quotes should be stripped
+ expected = [[('foo', 'bar'), ('version', '1')]]
+ for hdr in [
+ 'foo=bar; version="1"',
+ 'foo=bar; Version="1"',
+ ]:
+ self.assertEqual(parse_ns_headers([hdr]), expected)
+
+ def test_parse_ns_headers_special_names(self):
+ # names such as 'expires' are not special in first name=value pair
+ # of Set-Cookie: header
+ # Cookie with name 'expires'
+ hdr = 'expires=01 Jan 2040 22:23:32 GMT'
+ expected = [[("expires", "01 Jan 2040 22:23:32 GMT"), ("version", "0")]]
+ self.assertEqual(parse_ns_headers([hdr]), expected)
+
+ def test_join_header_words(self):
+ joined = join_header_words([[("foo", None), ("bar", "baz")]])
+ self.assertEqual(joined, "foo; bar=baz")
+
+ self.assertEqual(join_header_words([[]]), "")
+
+ def test_split_header_words(self):
+ tests = [
+ ("foo", [[("foo", None)]]),
+ ("foo=bar", [[("foo", "bar")]]),
+ (" foo ", [[("foo", None)]]),
+ (" foo= ", [[("foo", "")]]),
+ (" foo=", [[("foo", "")]]),
+ (" foo= ; ", [[("foo", "")]]),
+ (" foo= ; bar= baz ", [[("foo", ""), ("bar", "baz")]]),
+ ("foo=bar bar=baz", [[("foo", "bar"), ("bar", "baz")]]),
+ # doesn't really matter if this next fails, but it works ATM
+ ("foo= bar=baz", [[("foo", "bar=baz")]]),
+ ("foo=bar;bar=baz", [[("foo", "bar"), ("bar", "baz")]]),
+ ('foo bar baz', [[("foo", None), ("bar", None), ("baz", None)]]),
+ ("a, b, c", [[("a", None)], [("b", None)], [("c", None)]]),
+ (r'foo; bar=baz, spam=, foo="\,\;\"", bar= ',
+ [[("foo", None), ("bar", "baz")],
+ [("spam", "")], [("foo", ',;"')], [("bar", "")]]),
+ ]
+
+ for arg, expect in tests:
+ try:
+ result = split_header_words([arg])
+ except:
+ import traceback, io
+ f = io.StringIO()
+ traceback.print_exc(None, f)
+ result = "(error -- traceback follows)\n\n%s" % f.getvalue()
+ self.assertEqual(result, expect, """
+When parsing: '%s'
+Expected: '%s'
+Got: '%s'
+""" % (arg, expect, result))
+
+ def test_roundtrip(self):
+ tests = [
+ ("foo", "foo"),
+ ("foo=bar", "foo=bar"),
+ (" foo ", "foo"),
+ ("foo=", 'foo=""'),
+ ("foo=bar bar=baz", "foo=bar; bar=baz"),
+ ("foo=bar;bar=baz", "foo=bar; bar=baz"),
+ ('foo bar baz', "foo; bar; baz"),
+ (r'foo="\"" bar="\\"', r'foo="\""; bar="\\"'),
+ ('foo,,,bar', 'foo, bar'),
+ ('foo=bar,bar=baz', 'foo=bar, bar=baz'),
+
+ ('text/html; charset=iso-8859-1',
+ 'text/html; charset="iso-8859-1"'),
+
+ ('foo="bar"; port="80,81"; discard, bar=baz',
+ 'foo=bar; port="80,81"; discard, bar=baz'),
+
+ (r'Basic realm="\"foo\\\\bar\""',
+ r'Basic; realm="\"foo\\\\bar\""')
+ ]
+
+ for arg, expect in tests:
+ input = split_header_words([arg])
+ res = join_header_words(input)
+ self.assertEqual(res, expect, """
+When parsing: '%s'
+Expected: '%s'
+Got: '%s'
+Input was: '%s'
+""" % (arg, expect, res, input))
+
+
+class FakeResponse(object):
+ def __init__(self, headers=[], url=None):
+ """
+ headers: list of RFC822-style 'Key: value' strings
+ """
+ import email
+ # The email.message_from_string is available on both Py2.7 and Py3.3
+ self._headers = email.message_from_string("\n".join(headers))
+ self._url = url
+ def info(self): return self._headers
+
+def interact_2965(cookiejar, url, *set_cookie_hdrs):
+ return _interact(cookiejar, url, set_cookie_hdrs, "Set-Cookie2")
+
+def interact_netscape(cookiejar, url, *set_cookie_hdrs):
+ return _interact(cookiejar, url, set_cookie_hdrs, "Set-Cookie")
+
+def _interact(cookiejar, url, set_cookie_hdrs, hdr_name):
+ """Perform a single request / response cycle, returning Cookie: header."""
+ req = urllib_request.Request(url)
+ cookiejar.add_cookie_header(req)
+ cookie_hdr = req.get_header("Cookie", "")
+ headers = []
+ for hdr in set_cookie_hdrs:
+ headers.append("%s: %s" % (hdr_name, hdr))
+ res = FakeResponse(headers, url)
+ cookiejar.extract_cookies(res, req)
+ return cookie_hdr
+
+
+class FileCookieJarTests(unittest.TestCase):
+ @skip26
+ def test_lwp_valueless_cookie(self):
+ # cookies with no value should be saved and loaded consistently
+ filename = test_support.TESTFN
+ c = LWPCookieJar()
+ interact_netscape(c, "http://www.acme.com/", 'boo')
+ self.assertEqual(c._cookies["www.acme.com"]["/"]["boo"].value, None)
+ try:
+ c.save(filename, ignore_discard=True)
+ c = LWPCookieJar()
+ c.load(filename, ignore_discard=True)
+ finally:
+ try: os.unlink(filename)
+ except OSError: pass
+ self.assertEqual(c._cookies["www.acme.com"]["/"]["boo"].value, None)
+
+ def test_bad_magic(self):
+ # OSErrors (eg. file doesn't exist) are allowed to propagate
+ filename = test_support.TESTFN
+ for cookiejar_class in LWPCookieJar, MozillaCookieJar:
+ c = cookiejar_class()
+ try:
+ c.load(filename="for this test to work, a file with this "
+ "filename should not exist")
+ # Py2.7 raises IOError, which is an alias of OSError only on Py3:
+ except (OSError, IOError) as exc:
+ # an OSError subclass (likely FileNotFoundError), but not
+ # LoadError
+ self.assertIsNot(exc.__class__, LoadError)
+ else:
+ self.fail("expected OSError for invalid filename")
+ # Invalid contents of cookies file (eg. bad magic string)
+ # causes a LoadError.
+ try:
+ with open(filename, "w") as f:
+ f.write("oops\n")
+ for cookiejar_class in LWPCookieJar, MozillaCookieJar:
+ c = cookiejar_class()
+ self.assertRaises(LoadError, c.load, filename)
+ finally:
+ try: os.unlink(filename)
+ except OSError: pass
+
+class CookieTests(unittest.TestCase):
+ # XXX
+ # Get rid of string comparisons where not actually testing str / repr.
+ # .clear() etc.
+ # IP addresses like 50 (single number, no dot) and domain-matching
+ # functions (and is_HDN)? See draft RFC 2965 errata.
+ # Strictness switches
+ # is_third_party()
+ # unverifiability / third-party blocking
+ # Netscape cookies work the same as RFC 2965 with regard to port.
+ # Set-Cookie with negative max age.
+ # If turn RFC 2965 handling off, Set-Cookie2 cookies should not clobber
+ # Set-Cookie cookies.
+ # Cookie2 should be sent if *any* cookies are not V1 (ie. V0 OR V2 etc.).
+ # Cookies (V1 and V0) with no expiry date should be set to be discarded.
+ # RFC 2965 Quoting:
+ # Should accept unquoted cookie-attribute values? check errata draft.
+ # Which are required on the way in and out?
+ # Should always return quoted cookie-attribute values?
+ # Proper testing of when RFC 2965 clobbers Netscape (waiting for errata).
+ # Path-match on return (same for V0 and V1).
+ # RFC 2965 acceptance and returning rules
+ # Set-Cookie2 without version attribute is rejected.
+
+ # Netscape peculiarities list from Ronald Tschalar.
+ # The first two still need tests, the rest are covered.
+## - Quoting: only quotes around the expires value are recognized as such
+## (and yes, some folks quote the expires value); quotes around any other
+## value are treated as part of the value.
+## - White space: white space around names and values is ignored
+## - Default path: if no path parameter is given, the path defaults to the
+## path in the request-uri up to, but not including, the last '/'. Note
+## that this is entirely different from what the spec says.
+## - Commas and other delimiters: Netscape just parses until the next ';'.
+## This means it will allow commas etc inside values (and yes, both
+## commas and equals are commonly appear in the cookie value). This also
+## means that if you fold multiple Set-Cookie header fields into one,
+## 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
+## 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
+## just the 7 special TLD's listed in their spec. And folks rely on
+## that...
+
+ def test_domain_return_ok(self):
+ # test optimization: .domain_return_ok() should filter out most
+ # domains in the CookieJar before we try to access them (because that
+ # may require disk access -- in particular, with MSIECookieJar)
+ # This is only a rough check for performance reasons, so it's not too
+ # critical as long as it's sufficiently liberal.
+ pol = DefaultCookiePolicy()
+ for url, domain, ok in [
+ ("http://foo.bar.com/", "blah.com", False),
+ ("http://foo.bar.com/", "rhubarb.blah.com", False),
+ ("http://foo.bar.com/", "rhubarb.foo.bar.com", False),
+ ("http://foo.bar.com/", ".foo.bar.com", True),
+ ("http://foo.bar.com/", "foo.bar.com", True),
+ ("http://foo.bar.com/", ".bar.com", True),
+ ("http://foo.bar.com/", "com", True),
+ ("http://foo.com/", "rhubarb.foo.com", False),
+ ("http://foo.com/", ".foo.com", True),
+ ("http://foo.com/", "foo.com", True),
+ ("http://foo.com/", "com", True),
+ ("http://foo/", "rhubarb.foo", False),
+ ("http://foo/", ".foo", True),
+ ("http://foo/", "foo", True),
+ ("http://foo/", "foo.local", True),
+ ("http://foo/", ".local", True),
+ ]:
+ request = urllib_request.Request(url)
+ r = pol.domain_return_ok(domain, request)
+ if ok: self.assertTrue(r)
+ else: self.assertFalse(r)
+
+ @skip26
+ def test_missing_value(self):
+ # missing = sign in Cookie: header is regarded by Mozilla as a missing
+ # name, and by http.cookiejar as a missing value
+ filename = test_support.TESTFN
+ c = MozillaCookieJar(filename)
+ interact_netscape(c, "http://www.acme.com/", 'eggs')
+ interact_netscape(c, "http://www.acme.com/", '"spam"; path=/foo/')
+ cookie = c._cookies["www.acme.com"]["/"]["eggs"]
+ self.assertIsNone(cookie.value)
+ self.assertEqual(cookie.name, "eggs")
+ cookie = c._cookies["www.acme.com"]['/foo/']['"spam"']
+ self.assertIsNone(cookie.value)
+ self.assertEqual(cookie.name, '"spam"')
+ self.assertEqual(lwp_cookie_str(cookie), (
+ r'"spam"; path="/foo/"; domain="www.acme.com"; '
+ 'path_spec; discard; version=0'))
+ old_str = repr(c)
+ c.save(ignore_expires=True, ignore_discard=True)
+ try:
+ c = MozillaCookieJar(filename)
+ c.revert(ignore_expires=True, ignore_discard=True)
+ finally:
+ os.unlink(c.filename)
+ # cookies unchanged apart from lost info re. whether path was specified
+ self.assertEqual(
+ repr(c),
+ re.sub("path_specified=%s" % True, "path_specified=%s" % False,
+ old_str)
+ )
+ self.assertEqual(interact_netscape(c, "http://www.acme.com/foo/"),
+ '"spam"; eggs')
+
+ @expectedFailurePY26
+ def test_rfc2109_handling(self):
+ # RFC 2109 cookies are handled as RFC 2965 or Netscape cookies,
+ # dependent on policy settings
+ for rfc2109_as_netscape, rfc2965, version in [
+ # default according to rfc2965 if not explicitly specified
+ (None, False, 0),
+ (None, True, 1),
+ # explicit rfc2109_as_netscape
+ (False, False, None), # version None here means no cookie stored
+ (False, True, 1),
+ (True, False, 0),
+ (True, True, 0),
+ ]:
+ policy = DefaultCookiePolicy(
+ rfc2109_as_netscape=rfc2109_as_netscape,
+ rfc2965=rfc2965)
+ c = CookieJar(policy)
+ interact_netscape(c, "http://www.example.com/", "ni=ni; Version=1")
+ try:
+ cookie = c._cookies["www.example.com"]["/"]["ni"]
+ except KeyError:
+ self.assertIsNone(version) # didn't expect a stored cookie
+ else:
+ self.assertEqual(cookie.version, version)
+ # 2965 cookies are unaffected
+ interact_2965(c, "http://www.example.com/",
+ "foo=bar; Version=1")
+ if rfc2965:
+ cookie2965 = c._cookies["www.example.com"]["/"]["foo"]
+ self.assertEqual(cookie2965.version, 1)
+
+ @skip26
+ def test_ns_parser(self):
+ c = CookieJar()
+ interact_netscape(c, "http://www.acme.com/",
+ 'spam=eggs; DoMain=.acme.com; port; blArgh="feep"')
+ interact_netscape(c, "http://www.acme.com/", 'ni=ni; port=80,8080')
+ interact_netscape(c, "http://www.acme.com:80/", 'nini=ni')
+ interact_netscape(c, "http://www.acme.com:80/", 'foo=bar; expires=')
+ interact_netscape(c, "http://www.acme.com:80/", 'spam=eggs; '
+ 'expires="Foo Bar 25 33:22:11 3022"')
+
+ cookie = c._cookies[".acme.com"]["/"]["spam"]
+ self.assertEqual(cookie.domain, ".acme.com")
+ self.assertTrue(cookie.domain_specified)
+ self.assertEqual(cookie.port, DEFAULT_HTTP_PORT)
+ self.assertFalse(cookie.port_specified)
+ # case is preserved
+ self.assertTrue(cookie.has_nonstandard_attr("blArgh"))
+ self.assertFalse(cookie.has_nonstandard_attr("blargh"))
+
+ cookie = c._cookies["www.acme.com"]["/"]["ni"]
+ self.assertEqual(cookie.domain, "www.acme.com")
+ self.assertFalse(cookie.domain_specified)
+ self.assertEqual(cookie.port, "80,8080")
+ self.assertTrue(cookie.port_specified)
+
+ cookie = c._cookies["www.acme.com"]["/"]["nini"]
+ self.assertIsNone(cookie.port)
+ self.assertFalse(cookie.port_specified)
+
+ # invalid expires should not cause cookie to be dropped
+ foo = c._cookies["www.acme.com"]["/"]["foo"]
+ spam = c._cookies["www.acme.com"]["/"]["foo"]
+ self.assertIsNone(foo.expires)
+ self.assertIsNone(spam.expires)
+
+ @skip26
+ def test_ns_parser_special_names(self):
+ # names such as 'expires' are not special in first name=value pair
+ # of Set-Cookie: header
+ c = CookieJar()
+ interact_netscape(c, "http://www.acme.com/", 'expires=eggs')
+ interact_netscape(c, "http://www.acme.com/", 'version=eggs; spam=eggs')
+
+ cookies = c._cookies["www.acme.com"]["/"]
+ self.assertIn('expires', cookies)
+ self.assertIn('version', cookies)
+
+ @expectedFailurePY26
+ def test_expires(self):
+ # if expires is in future, keep cookie...
+ c = CookieJar()
+ future = time2netscape(time.time()+3600)
+ interact_netscape(c, "http://www.acme.com/", 'spam="bar"; expires=%s' %
+ future)
+ self.assertEqual(len(c), 1)
+ now = time2netscape(time.time()-1)
+ # ... and if in past or present, discard it
+ interact_netscape(c, "http://www.acme.com/", 'foo="eggs"; expires=%s' %
+ now)
+ h = interact_netscape(c, "http://www.acme.com/")
+ self.assertEqual(len(c), 1)
+ self.assertIn('spam="bar"', h)
+ self.assertNotIn("foo", h)
+
+ # max-age takes precedence over expires, and zero max-age is request to
+ # delete both new cookie and any old matching cookie
+ interact_netscape(c, "http://www.acme.com/", 'eggs="bar"; expires=%s' %
+ future)
+ interact_netscape(c, "http://www.acme.com/", 'bar="bar"; expires=%s' %
+ future)
+ self.assertEqual(len(c), 3)
+ interact_netscape(c, "http://www.acme.com/", 'eggs="bar"; '
+ 'expires=%s; max-age=0' % future)
+ interact_netscape(c, "http://www.acme.com/", 'bar="bar"; '
+ 'max-age=0; expires=%s' % future)
+ h = interact_netscape(c, "http://www.acme.com/")
+ self.assertEqual(len(c), 1)
+
+ # test expiry at end of session for cookies with no expires attribute
+ interact_netscape(c, "http://www.rhubarb.net/", 'whum="fizz"')
+ self.assertEqual(len(c), 2)
+ c.clear_session_cookies()
+ self.assertEqual(len(c), 1)
+ self.assertIn('spam="bar"', h)
+
+ # XXX RFC 2965 expiry rules (some apply to V0 too)
+
+ @skip26
+ def test_default_path(self):
+ # RFC 2965
+ pol = DefaultCookiePolicy(rfc2965=True)
+
+ c = CookieJar(pol)
+ interact_2965(c, "http://www.acme.com/", 'spam="bar"; Version="1"')
+ self.assertIn("/", c._cookies["www.acme.com"])
+
+ c = CookieJar(pol)
+ interact_2965(c, "http://www.acme.com/blah", 'eggs="bar"; Version="1"')
+ self.assertIn("/", c._cookies["www.acme.com"])
+
+ c = CookieJar(pol)
+ interact_2965(c, "http://www.acme.com/blah/rhubarb",
+ 'eggs="bar"; Version="1"')
+ self.assertIn("/blah/", c._cookies["www.acme.com"])
+
+ c = CookieJar(pol)
+ interact_2965(c, "http://www.acme.com/blah/rhubarb/",
+ 'eggs="bar"; Version="1"')
+ self.assertIn("/blah/rhubarb/", c._cookies["www.acme.com"])
+
+ # Netscape
+
+ c = CookieJar()
+ interact_netscape(c, "http://www.acme.com/", 'spam="bar"')
+ self.assertIn("/", c._cookies["www.acme.com"])
+
+ c = CookieJar()
+ interact_netscape(c, "http://www.acme.com/blah", 'eggs="bar"')
+ self.assertIn("/", c._cookies["www.acme.com"])
+
+ c = CookieJar()
+ interact_netscape(c, "http://www.acme.com/blah/rhubarb", 'eggs="bar"')
+ self.assertIn("/blah", c._cookies["www.acme.com"])
+
+ c = CookieJar()
+ interact_netscape(c, "http://www.acme.com/blah/rhubarb/", 'eggs="bar"')
+ self.assertIn("/blah/rhubarb", c._cookies["www.acme.com"])
+
+ @skip26
+ def test_default_path_with_query(self):
+ cj = CookieJar()
+ uri = "http://example.com/?spam/eggs"
+ value = 'eggs="bar"'
+ interact_netscape(cj, uri, value)
+ # Default path does not include query, so is "/", not "/?spam".
+ self.assertIn("/", cj._cookies["example.com"])
+ # Cookie is sent back to the same URI.
+ self.assertEqual(interact_netscape(cj, uri), value)
+
+ def test_escape_path(self):
+ cases = [
+ # quoted safe
+ ("/foo%2f/bar", "/foo%2F/bar"),
+ ("/foo%2F/bar", "/foo%2F/bar"),
+ # quoted %
+ ("/foo%%/bar", "/foo%%/bar"),
+ # quoted unsafe
+ ("/fo%19o/bar", "/fo%19o/bar"),
+ ("/fo%7do/bar", "/fo%7Do/bar"),
+ # unquoted safe
+ ("/foo/bar&", "/foo/bar&"),
+ ("/foo//bar", "/foo//bar"),
+ ("\176/foo/bar", "\176/foo/bar"),
+ # unquoted unsafe
+ ("/foo\031/bar", "/foo%19/bar"),
+ ("/\175foo/bar", "/%7Dfoo/bar"),
+ # unicode, latin-1 range
+ ("/foo/bar\u00fc", "/foo/bar%C3%BC"), # UTF-8 encoded
+ # unicode
+ ("/foo/bar\uabcd", "/foo/bar%EA%AF%8D"), # UTF-8 encoded
+ ]
+ for arg, result in cases:
+ self.assertEqual(escape_path(arg), result)
+
+ def test_request_path(self):
+ # with parameters
+ req = urllib_request.Request(
+ "http://www.example.com/rheum/rhaponticum;"
+ "foo=bar;sing=song?apples=pears&spam=eggs#ni")
+ self.assertEqual(request_path(req),
+ "/rheum/rhaponticum;foo=bar;sing=song")
+ # without parameters
+ req = urllib_request.Request(
+ "http://www.example.com/rheum/rhaponticum?"
+ "apples=pears&spam=eggs#ni")
+ self.assertEqual(request_path(req), "/rheum/rhaponticum")
+ # missing final slash
+ req = urllib_request.Request("http://www.example.com")
+ self.assertEqual(request_path(req), "/")
+
+ def test_request_port(self):
+ req = urllib_request.Request("http://www.acme.com:1234/",
+ headers={"Host": "www.acme.com:4321"})
+ self.assertEqual(request_port(req), "1234")
+ req = urllib_request.Request("http://www.acme.com/",
+ headers={"Host": "www.acme.com:4321"})
+ self.assertEqual(request_port(req), DEFAULT_HTTP_PORT)
+
+ def test_request_host(self):
+ # this request is illegal (RFC2616, 14.2.3)
+ req = urllib_request.Request("http://1.1.1.1/",
+ headers={"Host": "www.acme.com:80"})
+ # libwww-perl wants this response, but that seems wrong (RFC 2616,
+ # section 5.2, point 1., and RFC 2965 section 1, paragraph 3)
+ #self.assertEqual(request_host(req), "www.acme.com")
+ self.assertEqual(request_host(req), "1.1.1.1")
+ req = urllib_request.Request("http://www.acme.com/",
+ headers={"Host": "irrelevant.com"})
+ self.assertEqual(request_host(req), "www.acme.com")
+ # port shouldn't be in request-host
+ req = urllib_request.Request("http://www.acme.com:2345/resource.html",
+ headers={"Host": "www.acme.com:5432"})
+ self.assertEqual(request_host(req), "www.acme.com")
+
+ def test_is_HDN(self):
+ self.assertTrue(is_HDN("foo.bar.com"))
+ self.assertTrue(is_HDN("1foo2.3bar4.5com"))
+ self.assertFalse(is_HDN("192.168.1.1"))
+ self.assertFalse(is_HDN(""))
+ self.assertFalse(is_HDN("."))
+ self.assertFalse(is_HDN(".foo.bar.com"))
+ self.assertFalse(is_HDN("..foo"))
+ self.assertFalse(is_HDN("foo."))
+
+ def test_reach(self):
+ self.assertEqual(reach("www.acme.com"), ".acme.com")
+ self.assertEqual(reach("acme.com"), "acme.com")
+ self.assertEqual(reach("acme.local"), ".local")
+ self.assertEqual(reach(".local"), ".local")
+ self.assertEqual(reach(".com"), ".com")
+ self.assertEqual(reach("."), ".")
+ self.assertEqual(reach(""), "")
+ self.assertEqual(reach("192.168.0.1"), "192.168.0.1")
+
+ def test_domain_match(self):
+ self.assertTrue(domain_match("192.168.1.1", "192.168.1.1"))
+ self.assertFalse(domain_match("192.168.1.1", ".168.1.1"))
+ self.assertTrue(domain_match("x.y.com", "x.Y.com"))
+ self.assertTrue(domain_match("x.y.com", ".Y.com"))
+ self.assertFalse(domain_match("x.y.com", "Y.com"))
+ self.assertTrue(domain_match("a.b.c.com", ".c.com"))
+ self.assertFalse(domain_match(".c.com", "a.b.c.com"))
+ self.assertTrue(domain_match("example.local", ".local"))
+ self.assertFalse(domain_match("blah.blah", ""))
+ self.assertFalse(domain_match("", ".rhubarb.rhubarb"))
+ self.assertTrue(domain_match("", ""))
+
+ self.assertTrue(user_domain_match("acme.com", "acme.com"))
+ self.assertFalse(user_domain_match("acme.com", ".acme.com"))
+ self.assertTrue(user_domain_match("rhubarb.acme.com", ".acme.com"))
+ self.assertTrue(user_domain_match("www.rhubarb.acme.com", ".acme.com"))
+ self.assertTrue(user_domain_match("x.y.com", "x.Y.com"))
+ self.assertTrue(user_domain_match("x.y.com", ".Y.com"))
+ self.assertFalse(user_domain_match("x.y.com", "Y.com"))
+ self.assertTrue(user_domain_match("y.com", "Y.com"))
+ self.assertFalse(user_domain_match(".y.com", "Y.com"))
+ self.assertTrue(user_domain_match(".y.com", ".Y.com"))
+ self.assertTrue(user_domain_match("x.y.com", ".com"))
+ self.assertFalse(user_domain_match("x.y.com", "com"))
+ self.assertFalse(user_domain_match("x.y.com", "m"))
+ self.assertFalse(user_domain_match("x.y.com", ".m"))
+ self.assertFalse(user_domain_match("x.y.com", ""))
+ self.assertFalse(user_domain_match("x.y.com", "."))
+ self.assertTrue(user_domain_match("192.168.1.1", "192.168.1.1"))
+ # not both HDNs, so must string-compare equal to match
+ self.assertFalse(user_domain_match("192.168.1.1", ".168.1.1"))
+ self.assertFalse(user_domain_match("192.168.1.1", "."))
+ # empty string is a special case
+ self.assertFalse(user_domain_match("192.168.1.1", ""))
+
+ def test_wrong_domain(self):
+ # Cookies whose effective request-host name does not domain-match the
+ # domain are rejected.
+
+ # XXX far from complete
+ c = CookieJar()
+ interact_2965(c, "http://www.nasty.com/",
+ 'foo=bar; domain=friendly.org; Version="1"')
+ self.assertEqual(len(c), 0)
+
+ @expectedFailurePY26
+ def test_strict_domain(self):
+ # Cookies whose domain is a country-code tld like .co.uk should
+ # not be set if CookiePolicy.strict_domain is true.
+ cp = DefaultCookiePolicy(strict_domain=True)
+ cj = CookieJar(policy=cp)
+ interact_netscape(cj, "http://example.co.uk/", 'no=problemo')
+ interact_netscape(cj, "http://example.co.uk/",
+ 'okey=dokey; Domain=.example.co.uk')
+ self.assertEqual(len(cj), 2)
+ for pseudo_tld in [".co.uk", ".org.za", ".tx.us", ".name.us"]:
+ interact_netscape(cj, "http://example.%s/" % pseudo_tld,
+ 'spam=eggs; Domain=.co.uk')
+ self.assertEqual(len(cj), 2)
+
+ @expectedFailurePY26
+ def test_two_component_domain_ns(self):
+ # Netscape: .www.bar.com, www.bar.com, .bar.com, bar.com, no domain
+ # should all get accepted, as should .acme.com, acme.com and no domain
+ # for 2-component domains like acme.com.
+ c = CookieJar()
+
+ # two-component V0 domain is OK
+ interact_netscape(c, "http://foo.net/", 'ns=bar')
+ self.assertEqual(len(c), 1)
+ self.assertEqual(c._cookies["foo.net"]["/"]["ns"].value, "bar")
+ self.assertEqual(interact_netscape(c, "http://foo.net/"), "ns=bar")
+ # *will* be returned to any other domain (unlike RFC 2965)...
+ self.assertEqual(interact_netscape(c, "http://www.foo.net/"),
+ "ns=bar")
+ # ...unless requested otherwise
+ pol = DefaultCookiePolicy(
+ strict_ns_domain=DefaultCookiePolicy.DomainStrictNonDomain)
+ c.set_policy(pol)
+ self.assertEqual(interact_netscape(c, "http://www.foo.net/"), "")
+
+ # unlike RFC 2965, even explicit two-component domain is OK,
+ # because .foo.net matches foo.net
+ interact_netscape(c, "http://foo.net/foo/",
+ 'spam1=eggs; domain=foo.net')
+ # even if starts with a dot -- in NS rules, .foo.net matches foo.net!
+ interact_netscape(c, "http://foo.net/foo/bar/",
+ 'spam2=eggs; domain=.foo.net')
+ self.assertEqual(len(c), 3)
+ self.assertEqual(c._cookies[".foo.net"]["/foo"]["spam1"].value,
+ "eggs")
+ self.assertEqual(c._cookies[".foo.net"]["/foo/bar"]["spam2"].value,
+ "eggs")
+ self.assertEqual(interact_netscape(c, "http://foo.net/foo/bar/"),
+ "spam2=eggs; spam1=eggs; ns=bar")
+
+ # top-level domain is too general
+ interact_netscape(c, "http://foo.net/", 'nini="ni"; domain=.net')
+ self.assertEqual(len(c), 3)
+
+## # Netscape protocol doesn't allow non-special top level domains (such
+## # as co.uk) in the domain attribute unless there are at least three
+## # dots in it.
+ # Oh yes it does! Real implementations don't check this, and real
+ # cookies (of course) rely on that behaviour.
+ interact_netscape(c, "http://foo.co.uk", 'nasty=trick; domain=.co.uk')
+## self.assertEqual(len(c), 2)
+ self.assertEqual(len(c), 4)
+
+ @expectedFailurePY26
+ def test_two_component_domain_rfc2965(self):
+ pol = DefaultCookiePolicy(rfc2965=True)
+ c = CookieJar(pol)
+
+ # two-component V1 domain is OK
+ interact_2965(c, "http://foo.net/", 'foo=bar; Version="1"')
+ self.assertEqual(len(c), 1)
+ self.assertEqual(c._cookies["foo.net"]["/"]["foo"].value, "bar")
+ self.assertEqual(interact_2965(c, "http://foo.net/"),
+ "$Version=1; foo=bar")
+ # won't be returned to any other domain (because domain was implied)
+ self.assertEqual(interact_2965(c, "http://www.foo.net/"), "")
+
+ # unless domain is given explicitly, because then it must be
+ # rewritten to start with a dot: foo.net --> .foo.net, which does
+ # not domain-match foo.net
+ interact_2965(c, "http://foo.net/foo",
+ 'spam=eggs; domain=foo.net; path=/foo; Version="1"')
+ self.assertEqual(len(c), 1)
+ self.assertEqual(interact_2965(c, "http://foo.net/foo"),
+ "$Version=1; foo=bar")
+
+ # explicit foo.net from three-component domain www.foo.net *does* get
+ # set, because .foo.net domain-matches .foo.net
+ interact_2965(c, "http://www.foo.net/foo/",
+ 'spam=eggs; domain=foo.net; Version="1"')
+ self.assertEqual(c._cookies[".foo.net"]["/foo/"]["spam"].value,
+ "eggs")
+ self.assertEqual(len(c), 2)
+ self.assertEqual(interact_2965(c, "http://foo.net/foo/"),
+ "$Version=1; foo=bar")
+ self.assertEqual(interact_2965(c, "http://www.foo.net/foo/"),
+ '$Version=1; spam=eggs; $Domain="foo.net"')
+
+ # top-level domain is too general
+ interact_2965(c, "http://foo.net/",
+ 'ni="ni"; domain=".net"; Version="1"')
+ self.assertEqual(len(c), 2)
+
+ # RFC 2965 doesn't require blocking this
+ interact_2965(c, "http://foo.co.uk/",
+ 'nasty=trick; domain=.co.uk; Version="1"')
+ self.assertEqual(len(c), 3)
+
+ @expectedFailurePY26
+ def test_domain_allow(self):
+ c = CookieJar(policy=DefaultCookiePolicy(
+ blocked_domains=["acme.com"],
+ allowed_domains=["www.acme.com"]))
+
+ req = urllib_request.Request("http://acme.com/")
+ headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"]
+ res = FakeResponse(headers, "http://acme.com/")
+ c.extract_cookies(res, req)
+ self.assertEqual(len(c), 0)
+
+ req = urllib_request.Request("http://www.acme.com/")
+ res = FakeResponse(headers, "http://www.acme.com/")
+ c.extract_cookies(res, req)
+ self.assertEqual(len(c), 1)
+
+ req = urllib_request.Request("http://www.coyote.com/")
+ res = FakeResponse(headers, "http://www.coyote.com/")
+ c.extract_cookies(res, req)
+ self.assertEqual(len(c), 1)
+
+ # set a cookie with non-allowed domain...
+ req = urllib_request.Request("http://www.coyote.com/")
+ res = FakeResponse(headers, "http://www.coyote.com/")
+ cookies = c.make_cookies(res, req)
+ c.set_cookie(cookies[0])
+ self.assertEqual(len(c), 2)
+ # ... and check is doesn't get returned
+ c.add_cookie_header(req)
+ self.assertFalse(req.has_header("Cookie"))
+
+ @expectedFailurePY26
+ def test_domain_block(self):
+ pol = DefaultCookiePolicy(
+ rfc2965=True, blocked_domains=[".acme.com"])
+ c = CookieJar(policy=pol)
+ headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"]
+
+ req = urllib_request.Request("http://www.acme.com/")
+ res = FakeResponse(headers, "http://www.acme.com/")
+ c.extract_cookies(res, req)
+ self.assertEqual(len(c), 0)
+
+ p = pol.set_blocked_domains(["acme.com"])
+ c.extract_cookies(res, req)
+ self.assertEqual(len(c), 1)
+
+ c.clear()
+ req = urllib_request.Request("http://www.roadrunner.net/")
+ res = FakeResponse(headers, "http://www.roadrunner.net/")
+ c.extract_cookies(res, req)
+ self.assertEqual(len(c), 1)
+ req = urllib_request.Request("http://www.roadrunner.net/")
+ c.add_cookie_header(req)
+ self.assertTrue(req.has_header("Cookie"))
+ self.assertTrue(req.has_header("Cookie2"))
+
+ c.clear()
+ pol.set_blocked_domains([".acme.com"])
+ c.extract_cookies(res, req)
+ self.assertEqual(len(c), 1)
+
+ # set a cookie with blocked domain...
+ req = urllib_request.Request("http://www.acme.com/")
+ res = FakeResponse(headers, "http://www.acme.com/")
+ cookies = c.make_cookies(res, req)
+ c.set_cookie(cookies[0])
+ self.assertEqual(len(c), 2)
+ # ... and check is doesn't get returned
+ c.add_cookie_header(req)
+ self.assertFalse(req.has_header("Cookie"))
+
+ @skip26
+ def test_secure(self):
+ for ns in True, False:
+ for whitespace in " ", "":
+ c = CookieJar()
+ if ns:
+ pol = DefaultCookiePolicy(rfc2965=False)
+ int = interact_netscape
+ vs = ""
+ else:
+ pol = DefaultCookiePolicy(rfc2965=True)
+ int = interact_2965
+ vs = "; Version=1"
+ c.set_policy(pol)
+ url = "http://www.acme.com/"
+ int(c, url, "foo1=bar%s%s" % (vs, whitespace))
+ int(c, url, "foo2=bar%s; secure%s" % (vs, whitespace))
+ self.assertFalse(
+ c._cookies["www.acme.com"]["/"]["foo1"].secure,
+ "non-secure cookie registered secure")
+ self.assertTrue(
+ c._cookies["www.acme.com"]["/"]["foo2"].secure,
+ "secure cookie registered non-secure")
+
+ @expectedFailurePY26
+ def test_quote_cookie_value(self):
+ c = CookieJar(policy=DefaultCookiePolicy(rfc2965=True))
+ interact_2965(c, "http://www.acme.com/", r'foo=\b"a"r; Version=1')
+ h = interact_2965(c, "http://www.acme.com/")
+ self.assertEqual(h, r'$Version=1; foo=\\b\"a\"r')
+
+ @expectedFailurePY26
+ def test_missing_final_slash(self):
+ # Missing slash from request URL's abs_path should be assumed present.
+ url = "http://www.acme.com"
+ c = CookieJar(DefaultCookiePolicy(rfc2965=True))
+ interact_2965(c, url, "foo=bar; Version=1")
+ req = urllib_request.Request(url)
+ self.assertEqual(len(c), 1)
+ c.add_cookie_header(req)
+ self.assertTrue(req.has_header("Cookie"))
+
+ @expectedFailurePY26
+ def test_domain_mirror(self):
+ pol = DefaultCookiePolicy(rfc2965=True)
+
+ c = CookieJar(pol)
+ url = "http://foo.bar.com/"
+ interact_2965(c, url, "spam=eggs; Version=1")
+ h = interact_2965(c, url)
+ self.assertNotIn("Domain", h,
+ "absent domain returned with domain present")
+
+ c = CookieJar(pol)
+ url = "http://foo.bar.com/"
+ interact_2965(c, url, 'spam=eggs; Version=1; Domain=.bar.com')
+ h = interact_2965(c, url)
+ self.assertIn('$Domain=".bar.com"', h, "domain not returned")
+
+ c = CookieJar(pol)
+ url = "http://foo.bar.com/"
+ # note missing initial dot in Domain
+ interact_2965(c, url, 'spam=eggs; Version=1; Domain=bar.com')
+ h = interact_2965(c, url)
+ self.assertIn('$Domain="bar.com"', h, "domain not returned")
+
+ @expectedFailurePY26
+ def test_path_mirror(self):
+ pol = DefaultCookiePolicy(rfc2965=True)
+
+ c = CookieJar(pol)
+ url = "http://foo.bar.com/"
+ interact_2965(c, url, "spam=eggs; Version=1")
+ h = interact_2965(c, url)
+ self.assertNotIn("Path", h, "absent path returned with path present")
+
+ c = CookieJar(pol)
+ url = "http://foo.bar.com/"
+ interact_2965(c, url, 'spam=eggs; Version=1; Path=/')
+ h = interact_2965(c, url)
+ self.assertIn('$Path="/"', h, "path not returned")
+
+ @expectedFailurePY26
+ def test_port_mirror(self):
+ pol = DefaultCookiePolicy(rfc2965=True)
+
+ c = CookieJar(pol)
+ url = "http://foo.bar.com/"
+ interact_2965(c, url, "spam=eggs; Version=1")
+ h = interact_2965(c, url)
+ self.assertNotIn("Port", h, "absent port returned with port present")
+
+ c = CookieJar(pol)
+ url = "http://foo.bar.com/"
+ interact_2965(c, url, "spam=eggs; Version=1; Port")
+ h = interact_2965(c, url)
+ self.assertRegex(h, "\$Port([^=]|$)",
+ "port with no value not returned with no value")
+
+ c = CookieJar(pol)
+ url = "http://foo.bar.com/"
+ interact_2965(c, url, 'spam=eggs; Version=1; Port="80"')
+ h = interact_2965(c, url)
+ self.assertIn('$Port="80"', h,
+ "port with single value not returned with single value")
+
+ c = CookieJar(pol)
+ url = "http://foo.bar.com/"
+ interact_2965(c, url, 'spam=eggs; Version=1; Port="80,8080"')
+ h = interact_2965(c, url)
+ self.assertIn('$Port="80,8080"', h,
+ "port with multiple values not returned with multiple "
+ "values")
+
+ def test_no_return_comment(self):
+ c = CookieJar(DefaultCookiePolicy(rfc2965=True))
+ url = "http://foo.bar.com/"
+ interact_2965(c, url, 'spam=eggs; Version=1; '
+ 'Comment="does anybody read these?"; '
+ 'CommentURL="http://foo.bar.net/comment.html"')
+ h = interact_2965(c, url)
+ self.assertNotIn("Comment", h,
+ "Comment or CommentURL cookie-attributes returned to server")
+
+ def test_Cookie_iterator(self):
+ cs = CookieJar(DefaultCookiePolicy(rfc2965=True))
+ # add some random cookies
+ interact_2965(cs, "http://blah.spam.org/", 'foo=eggs; Version=1; '
+ 'Comment="does anybody read these?"; '
+ 'CommentURL="http://foo.bar.net/comment.html"')
+ interact_netscape(cs, "http://www.acme.com/blah/", "spam=bar; secure")
+ interact_2965(cs, "http://www.acme.com/blah/",
+ "foo=bar; secure; Version=1")
+ interact_2965(cs, "http://www.acme.com/blah/",
+ "foo=bar; path=/; Version=1")
+ interact_2965(cs, "http://www.sol.no",
+ r'bang=wallop; version=1; domain=".sol.no"; '
+ r'port="90,100, 80,8080"; '
+ r'max-age=100; Comment = "Just kidding! (\"|\\\\) "')
+
+ versions = [1, 1, 1, 0, 1]
+ names = ["bang", "foo", "foo", "spam", "foo"]
+ domains = [".sol.no", "blah.spam.org", "www.acme.com",
+ "www.acme.com", "www.acme.com"]
+ paths = ["/", "/", "/", "/blah", "/blah/"]
+
+ for i in range(4):
+ i = 0
+ for c in cs:
+ self.assertIsInstance(c, Cookie)
+ self.assertEqual(c.version, versions[i])
+ self.assertEqual(c.name, names[i])
+ self.assertEqual(c.domain, domains[i])
+ self.assertEqual(c.path, paths[i])
+ i = i + 1
+
+ def test_parse_ns_headers(self):
+ # missing domain value (invalid cookie)
+ self.assertEqual(
+ parse_ns_headers(["foo=bar; path=/; domain"]),
+ [[("foo", "bar"),
+ ("path", "/"), ("domain", None), ("version", "0")]]
+ )
+ # invalid expires value
+ self.assertEqual(
+ parse_ns_headers(["foo=bar; expires=Foo Bar 12 33:22:11 2000"]),
+ [[("foo", "bar"), ("expires", None), ("version", "0")]]
+ )
+ # missing cookie value (valid cookie)
+ self.assertEqual(
+ parse_ns_headers(["foo"]),
+ [[("foo", None), ("version", "0")]]
+ )
+ # shouldn't add version if header is empty
+ self.assertEqual(parse_ns_headers([""]), [])
+
+ @skip26
+ def test_bad_cookie_header(self):
+
+ def cookiejar_from_cookie_headers(headers):
+ c = CookieJar()
+ req = urllib_request.Request("http://www.example.com/")
+ r = FakeResponse(headers, "http://www.example.com/")
+ c.extract_cookies(r, req)
+ return c
+
+ # none of these bad headers should cause an exception to be raised
+ for headers in [
+ ["Set-Cookie: "], # actually, nothing wrong with this
+ ["Set-Cookie2: "], # ditto
+ # missing domain value
+ ["Set-Cookie2: a=foo; path=/; Version=1; domain"],
+ # bad max-age
+ ["Set-Cookie: b=foo; max-age=oops"],
+ # bad version
+ ["Set-Cookie: b=foo; version=spam"],
+ ]:
+ c = cookiejar_from_cookie_headers(headers)
+ # these bad cookies shouldn't be set
+ self.assertEqual(len(c), 0)
+
+ # cookie with invalid expires is treated as session cookie
+ headers = ["Set-Cookie: c=foo; expires=Foo Bar 12 33:22:11 2000"]
+ c = cookiejar_from_cookie_headers(headers)
+ cookie = c._cookies["www.example.com"]["/"]["c"]
+ self.assertIsNone(cookie.expires)
+
+
+class LWPCookieTests(unittest.TestCase):
+ # Tests taken from libwww-perl, with a few modifications and additions.
+
+ @expectedFailurePY26
+ def test_netscape_example_1(self):
+ #-------------------------------------------------------------------
+ # First we check that it works for the original example at
+ # http://www.netscape.com/newsref/std/cookie_spec.html
+
+ # Client requests a document, and receives in the response:
+ #
+ # Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT
+ #
+ # When client requests a URL in path "/" on this server, it sends:
+ #
+ # Cookie: CUSTOMER=WILE_E_COYOTE
+ #
+ # Client requests a document, and receives in the response:
+ #
+ # Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
+ #
+ # When client requests a URL in path "/" on this server, it sends:
+ #
+ # Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
+ #
+ # Client receives:
+ #
+ # Set-Cookie: SHIPPING=FEDEX; path=/fo
+ #
+ # When client requests a URL in path "/" on this server, it sends:
+ #
+ # Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
+ #
+ # When client requests a URL in path "/foo" on this server, it sends:
+ #
+ # Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX
+ #
+ # The last Cookie is buggy, because both specifications say that the
+ # most specific cookie must be sent first. SHIPPING=FEDEX is the
+ # most specific and should thus be first.
+
+ year_plus_one = time.localtime()[0] + 1
+
+ headers = []
+
+ c = CookieJar(DefaultCookiePolicy(rfc2965 = True))
+
+ #req = urllib_request.Request("http://1.1.1.1/",
+ # headers={"Host": "www.acme.com:80"})
+ req = urllib_request.Request("http://www.acme.com:80/",
+ headers={"Host": "www.acme.com:80"})
+
+ headers.append(
+ "Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/ ; "
+ "expires=Wednesday, 09-Nov-%d 23:12:40 GMT" % year_plus_one)
+ res = FakeResponse(headers, "http://www.acme.com/")
+ c.extract_cookies(res, req)
+
+ req = urllib_request.Request("http://www.acme.com/")
+ c.add_cookie_header(req)
+
+ self.assertEqual(req.get_header("Cookie"), "CUSTOMER=WILE_E_COYOTE")
+ self.assertEqual(req.get_header("Cookie2"), '$Version="1"')
+
+ headers.append("Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/")
+ res = FakeResponse(headers, "http://www.acme.com/")
+ c.extract_cookies(res, req)
+
+ req = urllib_request.Request("http://www.acme.com/foo/bar")
+ c.add_cookie_header(req)
+
+ h = req.get_header("Cookie")
+ self.assertIn("PART_NUMBER=ROCKET_LAUNCHER_0001", h)
+ self.assertIn("CUSTOMER=WILE_E_COYOTE", h)
+
+ headers.append('Set-Cookie: SHIPPING=FEDEX; path=/foo')
+ res = FakeResponse(headers, "http://www.acme.com")
+ c.extract_cookies(res, req)
+
+ req = urllib_request.Request("http://www.acme.com/")
+ c.add_cookie_header(req)
+
+ h = req.get_header("Cookie")
+ self.assertIn("PART_NUMBER=ROCKET_LAUNCHER_0001", h)
+ self.assertIn("CUSTOMER=WILE_E_COYOTE", h)
+ self.assertNotIn("SHIPPING=FEDEX", h)
+
+ req = urllib_request.Request("http://www.acme.com/foo/")
+ c.add_cookie_header(req)
+
+ h = req.get_header("Cookie")
+ self.assertIn("PART_NUMBER=ROCKET_LAUNCHER_0001", h)
+ self.assertIn("CUSTOMER=WILE_E_COYOTE", h)
+ self.assertTrue(h.startswith("SHIPPING=FEDEX;"))
+
+ @expectedFailurePY26
+ def test_netscape_example_2(self):
+ # Second Example transaction sequence:
+ #
+ # Assume all mappings from above have been cleared.
+ #
+ # Client receives:
+ #
+ # Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
+ #
+ # When client requests a URL in path "/" on this server, it sends:
+ #
+ # Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001
+ #
+ # Client receives:
+ #
+ # Set-Cookie: PART_NUMBER=RIDING_ROCKET_0023; path=/ammo
+ #
+ # When client requests a URL in path "/ammo" on this server, it sends:
+ #
+ # Cookie: PART_NUMBER=RIDING_ROCKET_0023; PART_NUMBER=ROCKET_LAUNCHER_0001
+ #
+ # NOTE: There are two name/value pairs named "PART_NUMBER" due to
+ # the inheritance of the "/" mapping in addition to the "/ammo" mapping.
+
+ c = CookieJar()
+ headers = []
+
+ req = urllib_request.Request("http://www.acme.com/")
+ headers.append("Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/")
+ res = FakeResponse(headers, "http://www.acme.com/")
+
+ c.extract_cookies(res, req)
+
+ req = urllib_request.Request("http://www.acme.com/")
+ c.add_cookie_header(req)
+
+ self.assertEqual(req.get_header("Cookie"),
+ "PART_NUMBER=ROCKET_LAUNCHER_0001")
+
+ headers.append(
+ "Set-Cookie: PART_NUMBER=RIDING_ROCKET_0023; path=/ammo")
+ res = FakeResponse(headers, "http://www.acme.com/")
+ c.extract_cookies(res, req)
+
+ req = urllib_request.Request("http://www.acme.com/ammo")
+ c.add_cookie_header(req)
+
+ self.assertRegex(req.get_header("Cookie"),
+ r"PART_NUMBER=RIDING_ROCKET_0023;\s*"
+ "PART_NUMBER=ROCKET_LAUNCHER_0001")
+
+ @expectedFailurePY26
+ def test_ietf_example_1(self):
+ #-------------------------------------------------------------------
+ # Then we test with the examples from draft-ietf-http-state-man-mec-03.txt
+ #
+ # 5. EXAMPLES
+
+ c = CookieJar(DefaultCookiePolicy(rfc2965=True))
+
+ #
+ # 5.1 Example 1
+ #
+ # Most detail of request and response headers has been omitted. Assume
+ # the user agent has no stored cookies.
+ #
+ # 1. User Agent -> Server
+ #
+ # POST /acme/login HTTP/1.1
+ # [form data]
+ #
+ # User identifies self via a form.
+ #
+ # 2. Server -> User Agent
+ #
+ # HTTP/1.1 200 OK
+ # Set-Cookie2: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
+ #
+ # Cookie reflects user's identity.
+
+ cookie = interact_2965(
+ c, 'http://www.acme.com/acme/login',
+ 'Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"')
+ self.assertFalse(cookie)
+
+ #
+ # 3. User Agent -> Server
+ #
+ # POST /acme/pickitem HTTP/1.1
+ # Cookie: $Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"
+ # [form data]
+ #
+ # User selects an item for ``shopping basket.''
+ #
+ # 4. Server -> User Agent
+ #
+ # HTTP/1.1 200 OK
+ # Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1";
+ # Path="/acme"
+ #
+ # Shopping basket contains an item.
+
+ cookie = interact_2965(c, 'http://www.acme.com/acme/pickitem',
+ 'Part_Number="Rocket_Launcher_0001"; '
+ 'Version="1"; Path="/acme"');
+ self.assertRegex(cookie,
+ r'^\$Version="?1"?; Customer="?WILE_E_COYOTE"?; \$Path="/acme"$')
+
+ #
+ # 5. User Agent -> Server
+ #
+ # POST /acme/shipping HTTP/1.1
+ # Cookie: $Version="1";
+ # Customer="WILE_E_COYOTE"; $Path="/acme";
+ # Part_Number="Rocket_Launcher_0001"; $Path="/acme"
+ # [form data]
+ #
+ # User selects shipping method from form.
+ #
+ # 6. Server -> User Agent
+ #
+ # HTTP/1.1 200 OK
+ # Set-Cookie2: Shipping="FedEx"; Version="1"; Path="/acme"
+ #
+ # New cookie reflects shipping method.
+
+ cookie = interact_2965(c, "http://www.acme.com/acme/shipping",
+ 'Shipping="FedEx"; Version="1"; Path="/acme"')
+
+ self.assertRegex(cookie, r'^\$Version="?1"?;')
+ self.assertRegex(cookie, r'Part_Number="?Rocket_Launcher_0001"?;'
+ '\s*\$Path="\/acme"')
+ self.assertRegex(cookie, r'Customer="?WILE_E_COYOTE"?;'
+ '\s*\$Path="\/acme"')
+
+ #
+ # 7. User Agent -> Server
+ #
+ # POST /acme/process HTTP/1.1
+ # Cookie: $Version="1";
+ # Customer="WILE_E_COYOTE"; $Path="/acme";
+ # Part_Number="Rocket_Launcher_0001"; $Path="/acme";
+ # Shipping="FedEx"; $Path="/acme"
+ # [form data]
+ #
+ # User chooses to process order.
+ #
+ # 8. Server -> User Agent
+ #
+ # HTTP/1.1 200 OK
+ #
+ # Transaction is complete.
+
+ cookie = interact_2965(c, "http://www.acme.com/acme/process")
+ self.assertRegex(cookie, r'Shipping="?FedEx"?;\s*\$Path="\/acme"')
+ self.assertIn("WILE_E_COYOTE", cookie)
+
+ #
+ # The user agent makes a series of requests on the origin server, after
+ # each of which it receives a new cookie. All the cookies have the same
+ # Path attribute and (default) domain. Because the request URLs all have
+ # /acme as a prefix, and that matches the Path attribute, each request
+ # contains all the cookies received so far.
+
+ @expectedFailurePY26
+ def test_ietf_example_2(self):
+ # 5.2 Example 2
+ #
+ # This example illustrates the effect of the Path attribute. All detail
+ # of request and response headers has been omitted. Assume the user agent
+ # has no stored cookies.
+
+ c = CookieJar(DefaultCookiePolicy(rfc2965=True))
+
+ # Imagine the user agent has received, in response to earlier requests,
+ # the response headers
+ #
+ # Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1";
+ # Path="/acme"
+ #
+ # and
+ #
+ # Set-Cookie2: Part_Number="Riding_Rocket_0023"; Version="1";
+ # Path="/acme/ammo"
+
+ interact_2965(
+ c, "http://www.acme.com/acme/ammo/specific",
+ 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"',
+ 'Part_Number="Riding_Rocket_0023"; Version="1"; Path="/acme/ammo"')
+
+ # A subsequent request by the user agent to the (same) server for URLs of
+ # the form /acme/ammo/... would include the following request header:
+ #
+ # Cookie: $Version="1";
+ # Part_Number="Riding_Rocket_0023"; $Path="/acme/ammo";
+ # Part_Number="Rocket_Launcher_0001"; $Path="/acme"
+ #
+ # Note that the NAME=VALUE pair for the cookie with the more specific Path
+ # attribute, /acme/ammo, comes before the one with the less specific Path
+ # attribute, /acme. Further note that the same cookie name appears more
+ # than once.
+
+ cookie = interact_2965(c, "http://www.acme.com/acme/ammo/...")
+ self.assertRegex(cookie, r"Riding_Rocket_0023.*Rocket_Launcher_0001")
+
+ # A subsequent request by the user agent to the (same) server for a URL of
+ # the form /acme/parts/ would include the following request header:
+ #
+ # Cookie: $Version="1"; Part_Number="Rocket_Launcher_0001"; $Path="/acme"
+ #
+ # Here, the second cookie's Path attribute /acme/ammo is not a prefix of
+ # the request URL, /acme/parts/, so the cookie does not get forwarded to
+ # the server.
+
+ cookie = interact_2965(c, "http://www.acme.com/acme/parts/")
+ self.assertIn("Rocket_Launcher_0001", cookie)
+ self.assertNotIn("Riding_Rocket_0023", cookie)
+
+ @expectedFailurePY26
+ def test_rejection(self):
+ # Test rejection of Set-Cookie2 responses based on domain, path, port.
+ pol = DefaultCookiePolicy(rfc2965=True)
+
+ c = LWPCookieJar(policy=pol)
+
+ max_age = "max-age=3600"
+
+ # illegal domain (no embedded dots)
+ cookie = interact_2965(c, "http://www.acme.com",
+ 'foo=bar; domain=".com"; version=1')
+ self.assertFalse(c)
+
+ # legal domain
+ cookie = interact_2965(c, "http://www.acme.com",
+ 'ping=pong; domain="acme.com"; version=1')
+ self.assertEqual(len(c), 1)
+
+ # illegal domain (host prefix "www.a" contains a dot)
+ cookie = interact_2965(c, "http://www.a.acme.com",
+ 'whiz=bang; domain="acme.com"; version=1')
+ self.assertEqual(len(c), 1)
+
+ # legal domain
+ cookie = interact_2965(c, "http://www.a.acme.com",
+ 'wow=flutter; domain=".a.acme.com"; version=1')
+ self.assertEqual(len(c), 2)
+
+ # can't partially match an IP-address
+ cookie = interact_2965(c, "http://125.125.125.125",
+ 'zzzz=ping; domain="125.125.125"; version=1')
+ self.assertEqual(len(c), 2)
+
+ # illegal path (must be prefix of request path)
+ cookie = interact_2965(c, "http://www.sol.no",
+ 'blah=rhubarb; domain=".sol.no"; path="/foo"; '
+ 'version=1')
+ self.assertEqual(len(c), 2)
+
+ # legal path
+ cookie = interact_2965(c, "http://www.sol.no/foo/bar",
+ 'bing=bong; domain=".sol.no"; path="/foo"; '
+ 'version=1')
+ self.assertEqual(len(c), 3)
+
+ # illegal port (request-port not in list)
+ cookie = interact_2965(c, "http://www.sol.no",
+ 'whiz=ffft; domain=".sol.no"; port="90,100"; '
+ 'version=1')
+ self.assertEqual(len(c), 3)
+
+ # legal port
+ cookie = interact_2965(
+ c, "http://www.sol.no",
+ r'bang=wallop; version=1; domain=".sol.no"; '
+ r'port="90,100, 80,8080"; '
+ r'max-age=100; Comment = "Just kidding! (\"|\\\\) "')
+ self.assertEqual(len(c), 4)
+
+ # port attribute without any value (current port)
+ cookie = interact_2965(c, "http://www.sol.no",
+ 'foo9=bar; version=1; domain=".sol.no"; port; '
+ 'max-age=100;')
+ self.assertEqual(len(c), 5)
+
+ # encoded path
+ # LWP has this test, but unescaping allowed path characters seems
+ # like a bad idea, so I think this should fail:
+## cookie = interact_2965(c, "http://www.sol.no/foo/",
+## r'foo8=bar; version=1; path="/%66oo"')
+ # but this is OK, because '<' is not an allowed HTTP URL path
+ # character:
+ cookie = interact_2965(c, "http://www.sol.no/<oo/",
+ r'foo8=bar; version=1; path="/%3coo"')
+ self.assertEqual(len(c), 6)
+
+ # save and restore
+ filename = test_support.TESTFN
+
+ try:
+ c.save(filename, ignore_discard=True)
+ old = repr(c)
+
+ c = LWPCookieJar(policy=pol)
+ c.load(filename, ignore_discard=True)
+ finally:
+ try: os.unlink(filename)
+ except OSError: pass
+
+ self.assertEqual(old, repr(c))
+
+ @expectedFailurePY26
+ def test_url_encoding(self):
+ # Try some URL encodings of the PATHs.
+ # (the behaviour here has changed from libwww-perl)
+ c = CookieJar(DefaultCookiePolicy(rfc2965=True))
+ interact_2965(c, "http://www.acme.com/foo%2f%25/"
+ "%3c%3c%0Anew%C3%A5/%C3%A5",
+ "foo = bar; version = 1")
+
+ cookie = interact_2965(
+ c, "http://www.acme.com/foo%2f%25/<<%0anew\345/\346\370\345",
+ 'bar=baz; path="/foo/"; version=1');
+ version_re = re.compile(r'^\$version=\"?1\"?', re.I)
+ self.assertIn("foo=bar", cookie)
+ self.assertRegex(cookie, version_re)
+
+ cookie = interact_2965(
+ c, "http://www.acme.com/foo/%25/<<%0anew\345/\346\370\345")
+ self.assertFalse(cookie)
+
+ # unicode URL doesn't raise exception
+ cookie = interact_2965(c, "http://www.acme.com/\xfc")
+
+ @expectedFailurePY26
+ def test_mozilla(self):
+ # Save / load Mozilla/Netscape cookie file format.
+ year_plus_one = time.localtime()[0] + 1
+
+ filename = test_support.TESTFN
+
+ c = MozillaCookieJar(filename,
+ policy=DefaultCookiePolicy(rfc2965=True))
+ interact_2965(c, "http://www.acme.com/",
+ "foo1=bar; max-age=100; Version=1")
+ interact_2965(c, "http://www.acme.com/",
+ 'foo2=bar; port="80"; max-age=100; Discard; Version=1')
+ interact_2965(c, "http://www.acme.com/", "foo3=bar; secure; Version=1")
+
+ expires = "expires=09-Nov-%d 23:12:40 GMT" % (year_plus_one,)
+ interact_netscape(c, "http://www.foo.com/",
+ "fooa=bar; %s" % expires)
+ interact_netscape(c, "http://www.foo.com/",
+ "foob=bar; Domain=.foo.com; %s" % expires)
+ interact_netscape(c, "http://www.foo.com/",
+ "fooc=bar; Domain=www.foo.com; %s" % expires)
+
+ def save_and_restore(cj, ignore_discard):
+ try:
+ cj.save(ignore_discard=ignore_discard)
+ new_c = MozillaCookieJar(filename,
+ DefaultCookiePolicy(rfc2965=True))
+ new_c.load(ignore_discard=ignore_discard)
+ finally:
+ try: os.unlink(filename)
+ except OSError: pass
+ return new_c
+
+ new_c = save_and_restore(c, True)
+ self.assertEqual(len(new_c), 6) # none discarded
+ self.assertIn("name='foo1', value='bar'", repr(new_c))
+
+ new_c = save_and_restore(c, False)
+ self.assertEqual(len(new_c), 4) # 2 of them discarded on save
+ self.assertIn("name='foo1', value='bar'", repr(new_c))
+
+ @skip26
+ def test_netscape_misc(self):
+ # Some additional Netscape cookies tests.
+ c = CookieJar()
+ headers = []
+ req = urllib_request.Request("http://foo.bar.acme.com/foo")
+
+ # Netscape allows a host part that contains dots
+ headers.append("Set-Cookie: Customer=WILE_E_COYOTE; domain=.acme.com")
+ res = FakeResponse(headers, "http://www.acme.com/foo")
+ c.extract_cookies(res, req)
+
+ # and that the domain is the same as the host without adding a leading
+ # dot to the domain. Should not quote even if strange chars are used
+ # in the cookie value.
+ headers.append("Set-Cookie: PART_NUMBER=3,4; domain=foo.bar.acme.com")
+ res = FakeResponse(headers, "http://www.acme.com/foo")
+ c.extract_cookies(res, req)
+
+ req = urllib_request.Request("http://foo.bar.acme.com/foo")
+ c.add_cookie_header(req)
+ self.assertIn("PART_NUMBER=3,4", req.get_header("Cookie"))
+ self.assertIn("Customer=WILE_E_COYOTE",req.get_header("Cookie"))
+
+ @expectedFailurePY26
+ def test_intranet_domains_2965(self):
+ # Test handling of local intranet hostnames without a dot.
+ c = CookieJar(DefaultCookiePolicy(rfc2965=True))
+ interact_2965(c, "http://example/",
+ "foo1=bar; PORT; Discard; Version=1;")
+ cookie = interact_2965(c, "http://example/",
+ 'foo2=bar; domain=".local"; Version=1')
+ self.assertIn("foo1=bar", cookie)
+
+ interact_2965(c, "http://example/", 'foo3=bar; Version=1')
+ cookie = interact_2965(c, "http://example/")
+ self.assertIn("foo2=bar", cookie)
+ self.assertEqual(len(c), 3)
+
+ @expectedFailurePY26
+ def test_intranet_domains_ns(self):
+ c = CookieJar(DefaultCookiePolicy(rfc2965 = False))
+ interact_netscape(c, "http://example/", "foo1=bar")
+ cookie = interact_netscape(c, "http://example/",
+ 'foo2=bar; domain=.local')
+ self.assertEqual(len(c), 2)
+ self.assertIn("foo1=bar", cookie)
+
+ cookie = interact_netscape(c, "http://example/")
+ self.assertIn("foo2=bar", cookie)
+ self.assertEqual(len(c), 2)
+
+ @expectedFailurePY26
+ def test_empty_path(self):
+ # Test for empty path
+ # Broken web-server ORION/1.3.38 returns to the client response like
+ #
+ # Set-Cookie: JSESSIONID=ABCDERANDOM123; Path=
+ #
+ # ie. with Path set to nothing.
+ # In this case, extract_cookies() must set cookie to / (root)
+ c = CookieJar(DefaultCookiePolicy(rfc2965 = True))
+ headers = []
+
+ req = urllib_request.Request("http://www.ants.com/")
+ headers.append("Set-Cookie: JSESSIONID=ABCDERANDOM123; Path=")
+ res = FakeResponse(headers, "http://www.ants.com/")
+ c.extract_cookies(res, req)
+
+ req = urllib_request.Request("http://www.ants.com/")
+ c.add_cookie_header(req)
+
+ self.assertEqual(req.get_header("Cookie"),
+ "JSESSIONID=ABCDERANDOM123")
+ self.assertEqual(req.get_header("Cookie2"), '$Version="1"')
+
+ # missing path in the request URI
+ req = urllib_request.Request("http://www.ants.com:8080")
+ c.add_cookie_header(req)
+
+ self.assertEqual(req.get_header("Cookie"),
+ "JSESSIONID=ABCDERANDOM123")
+ self.assertEqual(req.get_header("Cookie2"), '$Version="1"')
+
+ @expectedFailurePY26
+ def test_session_cookies(self):
+ year_plus_one = time.localtime()[0] + 1
+
+ # Check session cookies are deleted properly by
+ # CookieJar.clear_session_cookies method
+
+ req = urllib_request.Request('http://www.perlmeister.com/scripts')
+ headers = []
+ headers.append("Set-Cookie: s1=session;Path=/scripts")
+ headers.append("Set-Cookie: p1=perm; Domain=.perlmeister.com;"
+ "Path=/;expires=Fri, 02-Feb-%d 23:24:20 GMT" %
+ year_plus_one)
+ headers.append("Set-Cookie: p2=perm;Path=/;expires=Fri, "
+ "02-Feb-%d 23:24:20 GMT" % year_plus_one)
+ headers.append("Set-Cookie: s2=session;Path=/scripts;"
+ "Domain=.perlmeister.com")
+ headers.append('Set-Cookie2: s3=session;Version=1;Discard;Path="/"')
+ res = FakeResponse(headers, 'http://www.perlmeister.com/scripts')
+
+ c = CookieJar()
+ c.extract_cookies(res, req)
+ # How many session/permanent cookies do we have?
+ counter = {"session_after": 0,
+ "perm_after": 0,
+ "session_before": 0,
+ "perm_before": 0}
+ for cookie in c:
+ key = "%s_before" % cookie.value
+ counter[key] = counter[key] + 1
+ c.clear_session_cookies()
+ # How many now?
+ for cookie in c:
+ key = "%s_after" % cookie.value
+ counter[key] = counter[key] + 1
+
+ # a permanent cookie got lost accidently
+ self.assertEqual(counter["perm_after"], counter["perm_before"])
+ # a session cookie hasn't been cleared
+ self.assertEqual(counter["session_after"], 0)
+ # we didn't have session cookies in the first place
+ self.assertNotEqual(counter["session_before"], 0)
+
+
+def test_main(verbose=None):
+ test_support.run_unittest(
+ DateTimeTests,
+ HeaderTests,
+ CookieTests,
+ FileCookieJarTests,
+ LWPCookieTests,
+ )
+
+if __name__ == "__main__":
+ test_main(verbose=True)
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_httplib.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_httplib.py
new file mode 100644
index 0000000..a1e2b19
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_httplib.py
@@ -0,0 +1,568 @@
+"""
+Tests for the http.client module
+
+Adapted for the python-future module from the Python 2.7 standard
+library tests.
+"""
+
+from __future__ import (absolute_import, division,
+ print_function, unicode_literals)
+from future.builtins import *
+from future import utils
+from future.tests.base import unittest, skip26
+
+from future.backports.http import client
+from future.backports.test import support
+import array
+import io
+import socket
+import errno
+import sys
+
+TestCase = unittest.TestCase
+HOST = support.HOST
+
+
+class FakeSocket(object):
+ def __init__(self, text, fileclass=io.BytesIO):
+ if isinstance(text, str):
+ text = str(text).encode('ascii')
+ self.text = text
+ self.fileclass = fileclass
+ self.data = bytes(b'')
+
+ def sendall(self, data):
+ # self.data += bytes(data)
+ olddata = self.data
+ assert isinstance(olddata, bytes)
+ if utils.PY3:
+ self.data += data
+ else:
+ if isinstance(data, type(u'')): # i.e. unicode
+ newdata = data.encode('ascii')
+ elif isinstance(data, type(b'')): # native string type. FIXME!
+ newdata = bytes(data)
+ elif isinstance(data, bytes):
+ newdata = data
+ elif isinstance(data, array.array):
+ newdata = data.tostring()
+ else:
+ newdata = bytes(b'').join(chr(d) for d in bytes(data))
+ self.data += newdata
+
+ def makefile(self, mode, bufsize=None):
+ if mode != 'r' and mode != 'rb':
+ raise client.UnimplementedFileMode()
+ return self.fileclass(self.text)
+
+class EPipeSocket(FakeSocket):
+
+ def __init__(self, text, pipe_trigger):
+ # When sendall() is called with pipe_trigger, raise EPIPE.
+ FakeSocket.__init__(self, text)
+ self.pipe_trigger = pipe_trigger
+
+ def sendall(self, data):
+ if self.pipe_trigger in data:
+ raise socket.error(errno.EPIPE, "gotcha")
+ self.data += data
+
+ def close(self):
+ pass
+
+class NoEOFBytesIO(io.BytesIO):
+ """Like BytesIO, but raises AssertionError on EOF.
+
+ This is used below to test that http.client doesn't try to read
+ more from the underlying file than it should.
+ """
+ def read(self, n=-1):
+ data = io.BytesIO.read(self, n)
+ if data == b'':
+ raise AssertionError('caller tried to read past EOF')
+ return data
+
+ def readline(self, length=None):
+ data = io.BytesIO.readline(self, length)
+ if data == b'':
+ raise AssertionError('caller tried to read past EOF')
+ return data
+
+
+@skip26
+class HeaderTests(TestCase):
+ def test_auto_headers(self):
+ # Some headers are added automatically, but should not be added by
+ # .request() if they are explicitly set.
+
+ class HeaderCountingBuffer(list):
+ def __init__(self):
+ self.count = {}
+ def append(self, item):
+ kv = item.split(b':')
+ if len(kv) > 1:
+ # item is a 'Key: Value' header string
+ lcKey = kv[0].decode('ascii').lower()
+ self.count.setdefault(lcKey, 0)
+ self.count[lcKey] += 1
+ list.append(self, item)
+
+ for explicit_header in True, False:
+ for header in 'Content-length', 'Host', 'Accept-encoding':
+ conn = client.HTTPConnection('example.com')
+ conn.sock = FakeSocket('blahblahblah')
+ conn._buffer = HeaderCountingBuffer()
+
+ body = 'spamspamspam'
+ headers = {}
+ if explicit_header:
+ headers[header] = str(len(body))
+ conn.request('POST', '/', body, headers)
+ self.assertEqual(conn._buffer.count[header.lower()], 1)
+
+ def test_content_length_0(self):
+
+ class ContentLengthChecker(list):
+ def __init__(self):
+ list.__init__(self)
+ self.content_length = None
+ def append(self, item):
+ kv = item.split(b':', 1)
+ if len(kv) > 1 and kv[0].lower() == b'content-length':
+ self.content_length = kv[1].strip()
+ list.append(self, item)
+
+ # POST with empty body
+ conn = client.HTTPConnection('example.com')
+ conn.sock = FakeSocket(None)
+ conn._buffer = ContentLengthChecker()
+ conn.request('POST', '/', '')
+ self.assertEqual(conn._buffer.content_length, b'0',
+ 'Header Content-Length not set')
+
+ # PUT request with empty body
+ conn = client.HTTPConnection('example.com')
+ conn.sock = FakeSocket(None)
+ conn._buffer = ContentLengthChecker()
+ conn.request('PUT', '/', '')
+ self.assertEqual(conn._buffer.content_length, b'0',
+ 'Header Content-Length not set')
+
+ def test_putheader(self):
+ conn = client.HTTPConnection('example.com')
+ conn.sock = FakeSocket(None)
+ conn.putrequest('GET','/')
+ conn.putheader('Content-length', 42)
+ self.assertTrue(b'Content-length: 42' in conn._buffer)
+
+ def test_ipv6host_header(self):
+ # Default host header on IPv6 transaction should wrapped by [] if
+ # its actual IPv6 address
+ expected = bytes(b'GET /foo HTTP/1.1\r\nHost: [2001::]:81\r\n') + \
+ bytes(b'Accept-Encoding: identity\r\n\r\n')
+ conn = client.HTTPConnection('[2001::]:81')
+ sock = FakeSocket('')
+ conn.sock = sock
+ conn.request('GET', '/foo')
+ self.assertTrue(sock.data.startswith(expected))
+
+ expected = bytes(b'GET /foo HTTP/1.1\r\nHost: [2001:102A::]\r\n') + \
+ bytes(b'Accept-Encoding: identity\r\n\r\n')
+ conn = client.HTTPConnection('[2001:102A::]')
+ sock = FakeSocket('')
+ conn.sock = sock
+ conn.request('GET', '/foo')
+ self.assertTrue(sock.data.startswith(expected))
+
+
+@skip26
+class BasicTest(TestCase):
+ def test_status_lines(self):
+ # Test HTTP status lines
+
+ body = "HTTP/1.1 200 Ok\r\n\r\nText"
+ sock = FakeSocket(body)
+ resp = client.HTTPResponse(sock)
+ resp.begin()
+ self.assertEqual(resp.read(), b'Text')
+ self.assertTrue(resp.isclosed())
+
+ body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
+ sock = FakeSocket(body)
+ resp = client.HTTPResponse(sock)
+ self.assertRaises(client.BadStatusLine, resp.begin)
+
+ def test_bad_status_repr(self):
+ exc = client.BadStatusLine('')
+ if not utils.PY3:
+ self.assertEqual(repr(exc), '''BadStatusLine("u\'\'",)''')
+ else:
+ self.assertIn(repr(exc), ('''BadStatusLine("''",)''', '''BadStatusLine("''")'''))
+
+ def test_partial_reads(self):
+ # if we have a length, the system knows when to close itself
+ # same behaviour than when we read the whole thing with read()
+ body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText"
+ sock = FakeSocket(body)
+ resp = client.HTTPResponse(sock)
+ resp.begin()
+ self.assertEqual(resp.read(2), b'Te')
+ self.assertFalse(resp.isclosed())
+ self.assertEqual(resp.read(2), b'xt')
+ self.assertTrue(resp.isclosed())
+
+ def test_partial_reads_no_content_length(self):
+ # when no length is present, the socket should be gracefully closed when
+ # all data was read
+ body = "HTTP/1.1 200 Ok\r\n\r\nText"
+ sock = FakeSocket(body)
+ resp = client.HTTPResponse(sock)
+ resp.begin()
+ self.assertEqual(resp.read(2), b'Te')
+ self.assertFalse(resp.isclosed())
+ self.assertEqual(resp.read(2), b'xt')
+ self.assertEqual(resp.read(1), b'')
+ self.assertTrue(resp.isclosed())
+
+ def test_partial_reads_incomplete_body(self):
+ # if the server shuts down the connection before the whole
+ # content-length is delivered, the socket is gracefully closed
+ body = "HTTP/1.1 200 Ok\r\nContent-Length: 10\r\n\r\nText"
+ sock = FakeSocket(body)
+ resp = client.HTTPResponse(sock)
+ resp.begin()
+ self.assertEqual(resp.read(2), b'Te')
+ self.assertFalse(resp.isclosed())
+ self.assertEqual(resp.read(2), b'xt')
+ self.assertEqual(resp.read(1), b'')
+ self.assertTrue(resp.isclosed())
+
+ def test_host_port(self):
+ # Check invalid host_port
+
+ # Note that http.client does not accept user:password@ in the host-port.
+ for hp in ("www.python.org:abc", "user:password@www.python.org"):
+ self.assertRaises(client.InvalidURL, client.HTTPConnection, hp)
+
+ for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b",
+ 8000),
+ ("www.python.org:80", "www.python.org", 80),
+ ("www.python.org", "www.python.org", 80),
+ ("www.python.org:", "www.python.org", 80),
+ ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
+ c = client.HTTPConnection(hp)
+ self.assertEqual(h, c.host)
+ self.assertEqual(p, c.port)
+
+ def test_response_headers(self):
+ # test response with multiple message headers with the same field name.
+ text = ('HTTP/1.1 200 OK\r\n'
+ 'Set-Cookie: Customer="WILE_E_COYOTE";'
+ ' Version="1"; Path="/acme"\r\n'
+ 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
+ ' Path="/acme"\r\n'
+ '\r\n'
+ 'No body\r\n')
+ hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
+ ', '
+ 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
+ s = FakeSocket(text)
+ r = client.HTTPResponse(s)
+ r.begin()
+ cookies = r.getheader("Set-Cookie")
+ self.assertEqual(cookies, hdr)
+
+ def test_read_head(self):
+ # Test that the library doesn't attempt to read any data
+ # from a HEAD request. (Tickles SF bug #622042.)
+ sock = FakeSocket(
+ 'HTTP/1.1 200 OK\r\n'
+ 'Content-Length: 14432\r\n'
+ '\r\n',
+ NoEOFBytesIO)
+ resp = client.HTTPResponse(sock, method="HEAD")
+ resp.begin()
+ if resp.read():
+ self.fail("Did not expect response from HEAD request")
+
+ def test_send_file(self):
+ expected = (bytes(b'GET /foo HTTP/1.1\r\nHost: example.com\r\n') +
+ bytes(b'Accept-Encoding: identity\r\nContent-Length:'))
+
+ # __file__ will usually be the .pyc, i.e. binary data
+ with open(__file__, 'rb') as body:
+ conn = client.HTTPConnection('example.com')
+ sock = FakeSocket(body)
+ conn.sock = sock
+ conn.request('GET', '/foo', body)
+ self.assertTrue(sock.data.startswith(expected), '%r != %r' %
+ (sock.data[:len(expected)], expected))
+
+ def test_send(self):
+ expected = bytes(b'this is a test this is only a test')
+ conn = client.HTTPConnection('example.com')
+ sock = FakeSocket(None)
+ conn.sock = sock
+ conn.send(expected)
+ self.assertEqual(expected, sock.data)
+ sock.data = bytes(b'')
+ if utils.PY3:
+ mydata = array.array('b', expected)
+ else:
+ mydata = array.array(b'b', expected)
+ conn.send(mydata)
+ self.assertEqual(expected, sock.data)
+ sock.data = bytes(b'')
+ conn.send(io.BytesIO(expected))
+ self.assertEqual(expected, sock.data)
+
+ def test_chunked(self):
+ chunked_start = (
+ 'HTTP/1.1 200 OK\r\n'
+ 'Transfer-Encoding: chunked\r\n\r\n'
+ 'a\r\n'
+ 'hello worl\r\n'
+ '1\r\n'
+ 'd\r\n'
+ )
+ sock = FakeSocket(chunked_start + '0\r\n')
+ resp = client.HTTPResponse(sock, method="GET")
+ resp.begin()
+ self.assertEqual(resp.read(), b'hello world')
+ resp.close()
+
+ for x in ('', 'foo\r\n'):
+ sock = FakeSocket(chunked_start + x)
+ resp = client.HTTPResponse(sock, method="GET")
+ resp.begin()
+ try:
+ resp.read()
+ except client.IncompleteRead as i:
+ self.assertEqual(i.partial, b'hello world')
+ self.assertEqual(repr(i),'IncompleteRead(11 bytes read)')
+ self.assertEqual(str(i),'IncompleteRead(11 bytes read)')
+ else:
+ self.fail('IncompleteRead expected')
+ finally:
+ resp.close()
+
+ def test_chunked_head(self):
+ chunked_start = (
+ 'HTTP/1.1 200 OK\r\n'
+ 'Transfer-Encoding: chunked\r\n\r\n'
+ 'a\r\n'
+ 'hello world\r\n'
+ '1\r\n'
+ 'd\r\n'
+ )
+ sock = FakeSocket(chunked_start + '0\r\n')
+ resp = client.HTTPResponse(sock, method="HEAD")
+ resp.begin()
+ self.assertEqual(resp.read(), b'')
+ self.assertEqual(resp.status, 200)
+ self.assertEqual(resp.reason, 'OK')
+ self.assertTrue(resp.isclosed())
+
+ def test_negative_content_length(self):
+ sock = FakeSocket('HTTP/1.1 200 OK\r\n'
+ 'Content-Length: -1\r\n\r\nHello\r\n')
+ resp = client.HTTPResponse(sock, method="GET")
+ resp.begin()
+ self.assertEqual(resp.read(), b'Hello\r\n')
+ self.assertTrue(resp.isclosed())
+
+ def test_incomplete_read(self):
+ sock = FakeSocket('HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\nHello\r\n')
+ resp = client.HTTPResponse(sock, method="GET")
+ resp.begin()
+ try:
+ resp.read()
+ except client.IncompleteRead as i:
+ self.assertEqual(i.partial, b'Hello\r\n')
+ self.assertEqual(repr(i),
+ "IncompleteRead(7 bytes read, 3 more expected)")
+ self.assertEqual(str(i),
+ "IncompleteRead(7 bytes read, 3 more expected)")
+ self.assertTrue(resp.isclosed())
+ else:
+ self.fail('IncompleteRead expected')
+
+ def test_epipe(self):
+ sock = EPipeSocket(
+ "HTTP/1.0 401 Authorization Required\r\n"
+ "Content-type: text/html\r\n"
+ "WWW-Authenticate: Basic realm=\"example\"\r\n",
+ b"Content-Length")
+ conn = client.HTTPConnection("example.com")
+ conn.sock = sock
+ self.assertRaises(socket.error,
+ lambda: conn.request("PUT", "/url", "body"))
+ resp = conn.getresponse()
+ self.assertEqual(401, resp.status)
+ self.assertEqual("Basic realm=\"example\"",
+ resp.getheader("www-authenticate"))
+
+ def test_filenoattr(self):
+ # Just test the fileno attribute in the HTTPResponse Object.
+ body = "HTTP/1.1 200 Ok\r\n\r\nText"
+ sock = FakeSocket(body)
+ resp = client.HTTPResponse(sock)
+ self.assertTrue(hasattr(resp,'fileno'),
+ 'HTTPResponse should expose a fileno attribute')
+
+ # Test lines overflowing the max line size (_MAXLINE in http.client)
+
+ def test_overflowing_status_line(self):
+ self.skipTest("disabled for HTTP 0.9 support")
+ body = "HTTP/1.1 200 Ok" + "k" * 65536 + "\r\n"
+ resp = client.HTTPResponse(FakeSocket(body))
+ self.assertRaises((client.LineTooLong, client.BadStatusLine), resp.begin)
+
+ def test_overflowing_header_line(self):
+ body = (
+ 'HTTP/1.1 200 OK\r\n'
+ 'X-Foo: bar' + 'r' * 65536 + '\r\n\r\n'
+ )
+ resp = client.HTTPResponse(FakeSocket(body))
+ self.assertRaises(client.LineTooLong, resp.begin)
+
+ def test_overflowing_chunked_line(self):
+ body = (
+ 'HTTP/1.1 200 OK\r\n'
+ 'Transfer-Encoding: chunked\r\n\r\n'
+ + '0' * 65536 + 'a\r\n'
+ 'hello world\r\n'
+ '0\r\n'
+ )
+ resp = client.HTTPResponse(FakeSocket(body))
+ resp.begin()
+ self.assertRaises(client.LineTooLong, resp.read)
+
+ def test_early_eof(self):
+ # Test httpresponse with no \r\n termination,
+ body = "HTTP/1.1 200 Ok"
+ sock = FakeSocket(body)
+ resp = client.HTTPResponse(sock)
+ resp.begin()
+ self.assertEqual(resp.read(), b'')
+ self.assertTrue(resp.isclosed())
+
+@skip26
+class OfflineTest(TestCase):
+ def test_responses(self):
+ self.assertEqual(client.responses[client.NOT_FOUND], "Not Found")
+
+
+@skip26
+class SourceAddressTest(TestCase):
+ def setUp(self):
+ self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.port = support.bind_port(self.serv)
+ self.source_port = support.find_unused_port()
+ self.serv.listen(5)
+ self.conn = None
+
+ def tearDown(self):
+ if self.conn:
+ self.conn.close()
+ self.conn = None
+ self.serv.close()
+ self.serv = None
+
+ def testHTTPConnectionSourceAddress(self):
+ self.conn = client.HTTPConnection(HOST, self.port,
+ source_address=('', self.source_port))
+ self.conn.connect()
+ self.assertEqual(self.conn.sock.getsockname()[1], self.source_port)
+
+ @unittest.skipIf(not hasattr(client, 'HTTPSConnection'),
+ 'http.client.HTTPSConnection not defined')
+ def testHTTPSConnectionSourceAddress(self):
+ self.conn = client.HTTPSConnection(HOST, self.port,
+ source_address=('', self.source_port))
+ # We don't test anything here other the constructor not barfing as
+ # this code doesn't deal with setting up an active running SSL server
+ # for an ssl_wrapped connect() to actually return from.
+
+
+@skip26
+class TimeoutTest(TestCase):
+ PORT = None
+
+ def setUp(self):
+ self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ TimeoutTest.PORT = support.bind_port(self.serv)
+ self.serv.listen(5)
+
+ def tearDown(self):
+ self.serv.close()
+ self.serv = None
+
+ def testTimeoutAttribute(self):
+ '''This will prove that the timeout gets through
+ HTTPConnection and into the socket.
+ '''
+ # default -- use global socket timeout
+ self.assertTrue(socket.getdefaulttimeout() is None)
+ socket.setdefaulttimeout(30)
+ try:
+ httpConn = client.HTTPConnection(HOST, TimeoutTest.PORT)
+ httpConn.connect()
+ finally:
+ socket.setdefaulttimeout(None)
+ self.assertEqual(httpConn.sock.gettimeout(), 30)
+ httpConn.close()
+
+ # no timeout -- do not use global socket default
+ self.assertTrue(socket.getdefaulttimeout() is None)
+ socket.setdefaulttimeout(30)
+ try:
+ httpConn = client.HTTPConnection(HOST, TimeoutTest.PORT,
+ timeout=None)
+ httpConn.connect()
+ finally:
+ socket.setdefaulttimeout(None)
+ self.assertEqual(httpConn.sock.gettimeout(), None)
+ httpConn.close()
+
+ # a value
+ httpConn = client.HTTPConnection(HOST, TimeoutTest.PORT, timeout=30)
+ httpConn.connect()
+ self.assertEqual(httpConn.sock.gettimeout(), 30)
+ httpConn.close()
+
+
+@skip26
+class HTTPSTest(TestCase):
+
+ def test_attributes(self):
+ # simple test to check it's storing it
+ if hasattr(client, 'HTTPSConnection'):
+ h = client.HTTPSConnection(HOST, TimeoutTest.PORT, timeout=30)
+ self.assertEqual(h.timeout, 30)
+
+ @unittest.skipIf(not hasattr(client, 'HTTPSConnection'), 'http.client.HTTPSConnection not available')
+ def test_host_port(self):
+ # Check invalid host_port
+
+ # Note that httplib does not accept user:password@ in the host-port.
+ for hp in ("www.python.org:abc", "user:password@www.python.org"):
+ self.assertRaises(client.InvalidURL, client.HTTPSConnection, hp)
+
+ for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b",
+ 8000),
+ ("pypi.python.org:443", "pypi.python.org", 443),
+ ("pypi.python.org", "pypi.python.org", 443),
+ ("pypi.python.org:", "pypi.python.org", 443),
+ ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 443)):
+ c = client.HTTPSConnection(hp)
+ self.assertEqual(h, c.host)
+ self.assertEqual(p, c.port)
+
+
+# def test_main(verbose=None):
+# support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest,
+# HTTPSTest, SourceAddressTest)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_import_star.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_import_star.py
new file mode 100644
index 0000000..ffffe8b
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_import_star.py
@@ -0,0 +1,61 @@
+"""
+This tests whether
+
+ from future.builtins import *
+
+works as expected:
+- This should NOT introduce namespace pollution on Py3.
+- On Python 2, this should not introduce any symbols that aren't in
+ __builtin__.
+
+"""
+
+from __future__ import absolute_import, print_function, unicode_literals
+
+import copy
+
+from future import utils
+from future.tests.base import unittest, skip26
+
+
+original_locals = set(copy.copy(locals()))
+original_globals = set(copy.copy(globals()))
+new_names = set(['original_locals', 'original_globals', 'new_names'])
+from future.builtins import *
+new_locals = set(copy.copy(locals())) - new_names - original_locals
+new_globals = set(copy.copy(globals())) - new_names - original_globals - \
+ set(['new_locals'])
+
+
+class TestImportStar(unittest.TestCase):
+ def test_namespace_pollution_locals(self):
+ if utils.PY3:
+ self.assertEqual(len(new_locals), 0,
+ 'namespace pollution: {0}'.format(new_locals))
+ else:
+ pass # maybe check that no new symbols are introduced
+
+ def test_namespace_pollution_globals(self):
+ if utils.PY3:
+ self.assertEqual(len(new_globals), 0,
+ 'namespace pollution: {0}'.format(new_globals))
+ else:
+ pass # maybe check that no new symbols are introduced
+
+ def test_iterators(self):
+ self.assertNotEqual(type(range(10)), list)
+
+ def test_super(self):
+ pass
+
+ def test_str(self):
+ self.assertIsNot(str, bytes) # Py2: assertIsNot only in 2.7
+ self.assertEqual(str('blah'), u'blah') # Py3.3 and Py2 only
+
+ def test_python_2_unicode_compatible_decorator(self):
+ # This should not be in the namespace
+ assert 'python_2_unicode_compatible' not in locals()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_imports_httplib.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_imports_httplib.py
new file mode 100644
index 0000000..3e84287
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_imports_httplib.py
@@ -0,0 +1,25 @@
+from __future__ import absolute_import, print_function
+import sys
+
+from future.utils import PY2
+from future.tests.base import unittest
+
+
+class ImportHttplibTest(unittest.TestCase):
+ def test_issue_159(self):
+ """
+ The latest version of urllib3 (as of 2015-07-25)
+ uses http.client.HTTPMessage, which isn't normally
+ exported on Py2 through __all__ in httplib.py.
+ """
+ from http.client import HTTPMessage
+ if PY2:
+ import mimetools
+ assert issubclass(HTTPMessage, mimetools.Message)
+ else:
+ import email.message
+ assert issubclass(HTTPMessage, email.message.Message)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_imports_urllib.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_imports_urllib.py
new file mode 100644
index 0000000..cbc616f
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_imports_urllib.py
@@ -0,0 +1,44 @@
+from __future__ import absolute_import, print_function
+
+import sys
+from future.tests.base import unittest
+from future.standard_library import install_aliases
+
+
+class ImportUrllibTest(unittest.TestCase):
+ def test_urllib(self):
+ """
+ Tests that urllib isn't changed from under our feet. (This might not
+ even be a problem?)
+ """
+ from future import standard_library
+ import urllib
+ orig_file = urllib.__file__
+ with standard_library.hooks():
+ import urllib.response
+ self.assertEqual(orig_file, urllib.__file__)
+
+ def test_issue_158(self):
+ """
+ CherryPy conditional import in _cpcompat.py: issue 158
+ """
+ install_aliases()
+ try:
+ from urllib.parse import unquote as parse_unquote
+
+ def unquote_qs(atom, encoding, errors='strict'):
+ return parse_unquote(
+ atom.replace('+', ' '),
+ encoding=encoding,
+ errors=errors)
+ except ImportError:
+ from urllib import unquote as parse_unquote
+
+ def unquote_qs(atom, encoding, errors='strict'):
+ return parse_unquote(atom.replace('+', ' ')).decode(encoding, errors)
+ self.assertEqual(unquote_qs('/%7Econnolly/', 'utf-8'),
+ '/~connolly/')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_int.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_int.py
new file mode 100644
index 0000000..573a0d5
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_int.py
@@ -0,0 +1,1096 @@
+"""
+int tests from Py3.3
+"""
+
+from __future__ import (absolute_import, division,
+ print_function, unicode_literals)
+from future.builtins import *
+from future.tests.base import unittest, expectedFailurePY2
+from future.utils import PY26, PY2, raise_from
+
+import sys
+import random
+import array
+
+try:
+ import numpy as np
+except ImportError:
+ np = None
+
+try:
+ from future.standard_library.test import support
+except ImportError:
+ def cpython_only(f):
+ return f
+else:
+ cpython_only = support.cpython_only
+
+
+L = [
+ ('0', 0),
+ ('1', 1),
+ ('9', 9),
+ ('10', 10),
+ ('99', 99),
+ ('100', 100),
+ ('314', 314),
+ (' 314', 314),
+ ('314 ', 314),
+ (' \t\t 314 \t\t ', 314),
+ (repr(sys.maxsize), sys.maxsize),
+ (' 1x', ValueError),
+ (' 1 ', 1),
+ (' 1\02 ', ValueError),
+ ('', ValueError),
+ (' ', ValueError),
+ (' \t\t ', ValueError),
+ ("\u0200", ValueError)
+]
+
+class IntTestCases(unittest.TestCase):
+
+ def setUp(self):
+ self.longMessage = True
+
+ def test_isinstance_int_subclass(self):
+ """
+ Issue #89
+ """
+ value = int(10)
+ class Magic(int):
+ pass
+ self.assertTrue(isinstance(value, int))
+ self.assertFalse(isinstance(value, Magic))
+
+ def test_basic(self):
+ self.assertEqual(int(314), 314)
+ self.assertEqual(int(3.14), 3)
+ # Check that conversion from float truncates towards zero
+ self.assertEqual(int(-3.14), -3)
+ self.assertEqual(int(3.9), 3)
+ self.assertEqual(int(-3.9), -3)
+ self.assertEqual(int(3.5), 3)
+ self.assertEqual(int(-3.5), -3)
+ self.assertEqual(int("-3"), -3)
+ self.assertEqual(int(" -3 "), -3)
+ self.assertEqual(int("\N{EM SPACE}-3\N{EN SPACE}"), -3)
+ # Different base:
+ self.assertEqual(int("10",16), 16)
+ # Test conversion from strings and various anomalies
+ for s, v in L:
+ for sign in "", "+", "-":
+ for prefix in "", " ", "\t", " \t\t ":
+ ss = prefix + sign + s
+ vv = v
+ if sign == "-" and v is not ValueError:
+ vv = -v
+ try:
+ self.assertEqual(int(ss), vv)
+ except ValueError:
+ pass
+
+ s = repr(-1-sys.maxsize)
+ x = int(s)
+ self.assertEqual(x+1, -sys.maxsize)
+ self.assertIsInstance(x, int)
+ # should return int
+ self.assertEqual(int(s[1:]), sys.maxsize+1)
+
+ # should return int
+ x = int(1e100)
+ self.assertIsInstance(x, int)
+ x = int(-1e100)
+ self.assertIsInstance(x, int)
+
+
+ # SF bug 434186: 0x80000000/2 != 0x80000000>>1.
+ # Worked by accident in Windows release build, but failed in debug build.
+ # Failed in all Linux builds.
+ x = -1-sys.maxsize
+ self.assertEqual(x >> 1, x//2)
+
+ self.assertRaises(ValueError, int, '123\0')
+ self.assertRaises(ValueError, int, '53', 40)
+
+ # SF bug 1545497: embedded NULs were not detected with
+ # explicit base
+ self.assertRaises(ValueError, int, '123\0', 10)
+ self.assertRaises(ValueError, int, '123\x00 245', 20)
+
+ x = int('1' * 600)
+ self.assertIsInstance(x, int)
+
+
+ self.assertRaises(TypeError, int, 1, 12)
+
+ self.assertEqual(int('0o123', 0), 83)
+ self.assertEqual(int('0x123', 16), 291)
+
+ # Bug 1679: "0x" is not a valid hex literal
+ self.assertRaises(ValueError, int, "0x", 16)
+ self.assertRaises(ValueError, int, "0x", 0)
+
+ self.assertRaises(ValueError, int, "0o", 8)
+ self.assertRaises(ValueError, int, "0o", 0)
+
+ self.assertRaises(ValueError, int, "0b", 2)
+ self.assertRaises(ValueError, int, "0b", 0)
+
+ # SF bug 1334662: int(string, base) wrong answers
+ # Various representations of 2**32 evaluated to 0
+ # rather than 2**32 in previous versions
+
+ self.assertEqual(int('100000000000000000000000000000000', 2), 4294967296)
+ self.assertEqual(int('102002022201221111211', 3), 4294967296)
+ self.assertEqual(int('10000000000000000', 4), 4294967296)
+ self.assertEqual(int('32244002423141', 5), 4294967296)
+ self.assertEqual(int('1550104015504', 6), 4294967296)
+ self.assertEqual(int('211301422354', 7), 4294967296)
+ self.assertEqual(int('40000000000', 8), 4294967296)
+ self.assertEqual(int('12068657454', 9), 4294967296)
+ self.assertEqual(int('4294967296', 10), 4294967296)
+ self.assertEqual(int('1904440554', 11), 4294967296)
+ self.assertEqual(int('9ba461594', 12), 4294967296)
+ self.assertEqual(int('535a79889', 13), 4294967296)
+ self.assertEqual(int('2ca5b7464', 14), 4294967296)
+ self.assertEqual(int('1a20dcd81', 15), 4294967296)
+ self.assertEqual(int('100000000', 16), 4294967296)
+ self.assertEqual(int('a7ffda91', 17), 4294967296)
+ self.assertEqual(int('704he7g4', 18), 4294967296)
+ self.assertEqual(int('4f5aff66', 19), 4294967296)
+ self.assertEqual(int('3723ai4g', 20), 4294967296)
+ self.assertEqual(int('281d55i4', 21), 4294967296)
+ self.assertEqual(int('1fj8b184', 22), 4294967296)
+ self.assertEqual(int('1606k7ic', 23), 4294967296)
+ self.assertEqual(int('mb994ag', 24), 4294967296)
+ self.assertEqual(int('hek2mgl', 25), 4294967296)
+ self.assertEqual(int('dnchbnm', 26), 4294967296)
+ self.assertEqual(int('b28jpdm', 27), 4294967296)
+ self.assertEqual(int('8pfgih4', 28), 4294967296)
+ self.assertEqual(int('76beigg', 29), 4294967296)
+ self.assertEqual(int('5qmcpqg', 30), 4294967296)
+ self.assertEqual(int('4q0jto4', 31), 4294967296)
+ self.assertEqual(int('4000000', 32), 4294967296)
+ self.assertEqual(int('3aokq94', 33), 4294967296)
+ self.assertEqual(int('2qhxjli', 34), 4294967296)
+ self.assertEqual(int('2br45qb', 35), 4294967296)
+ self.assertEqual(int('1z141z4', 36), 4294967296)
+
+ # tests with base 0
+ # this fails on 3.0, but in 2.x the old octal syntax is allowed
+ self.assertEqual(int(' 0o123 ', 0), 83)
+ self.assertEqual(int(' 0o123 ', 0), 83)
+ self.assertEqual(int('000', 0), 0)
+ self.assertEqual(int('0o123', 0), 83)
+ self.assertEqual(int('0x123', 0), 291)
+ self.assertEqual(int('0b100', 0), 4)
+ self.assertEqual(int(' 0O123 ', 0), 83)
+ self.assertEqual(int(' 0X123 ', 0), 291)
+ self.assertEqual(int(' 0B100 ', 0), 4)
+
+ # without base still base 10
+ self.assertEqual(int('0123'), 123)
+ self.assertEqual(int('0123', 10), 123)
+
+ # tests with prefix and base != 0
+ self.assertEqual(int('0x123', 16), 291)
+ self.assertEqual(int('0o123', 8), 83)
+ self.assertEqual(int('0b100', 2), 4)
+ self.assertEqual(int('0X123', 16), 291)
+ self.assertEqual(int('0O123', 8), 83)
+ self.assertEqual(int('0B100', 2), 4)
+
+ # the code has special checks for the first character after the
+ # type prefix
+ self.assertRaises(ValueError, int, '0b2', 2)
+ self.assertRaises(ValueError, int, '0b02', 2)
+ self.assertRaises(ValueError, int, '0B2', 2)
+ self.assertRaises(ValueError, int, '0B02', 2)
+ self.assertRaises(ValueError, int, '0o8', 8)
+ self.assertRaises(ValueError, int, '0o08', 8)
+ self.assertRaises(ValueError, int, '0O8', 8)
+ self.assertRaises(ValueError, int, '0O08', 8)
+ self.assertRaises(ValueError, int, '0xg', 16)
+ self.assertRaises(ValueError, int, '0x0g', 16)
+ self.assertRaises(ValueError, int, '0Xg', 16)
+ self.assertRaises(ValueError, int, '0X0g', 16)
+
+ # SF bug 1334662: int(string, base) wrong answers
+ # Checks for proper evaluation of 2**32 + 1
+ self.assertEqual(int('100000000000000000000000000000001', 2), 4294967297)
+ self.assertEqual(int('102002022201221111212', 3), 4294967297)
+ self.assertEqual(int('10000000000000001', 4), 4294967297)
+ self.assertEqual(int('32244002423142', 5), 4294967297)
+ self.assertEqual(int('1550104015505', 6), 4294967297)
+ self.assertEqual(int('211301422355', 7), 4294967297)
+ self.assertEqual(int('40000000001', 8), 4294967297)
+ self.assertEqual(int('12068657455', 9), 4294967297)
+ self.assertEqual(int('4294967297', 10), 4294967297)
+ self.assertEqual(int('1904440555', 11), 4294967297)
+ self.assertEqual(int('9ba461595', 12), 4294967297)
+ self.assertEqual(int('535a7988a', 13), 4294967297)
+ self.assertEqual(int('2ca5b7465', 14), 4294967297)
+ self.assertEqual(int('1a20dcd82', 15), 4294967297)
+ self.assertEqual(int('100000001', 16), 4294967297)
+ self.assertEqual(int('a7ffda92', 17), 4294967297)
+ self.assertEqual(int('704he7g5', 18), 4294967297)
+ self.assertEqual(int('4f5aff67', 19), 4294967297)
+ self.assertEqual(int('3723ai4h', 20), 4294967297)
+ self.assertEqual(int('281d55i5', 21), 4294967297)
+ self.assertEqual(int('1fj8b185', 22), 4294967297)
+ self.assertEqual(int('1606k7id', 23), 4294967297)
+ self.assertEqual(int('mb994ah', 24), 4294967297)
+ self.assertEqual(int('hek2mgm', 25), 4294967297)
+ self.assertEqual(int('dnchbnn', 26), 4294967297)
+ self.assertEqual(int('b28jpdn', 27), 4294967297)
+ self.assertEqual(int('8pfgih5', 28), 4294967297)
+ self.assertEqual(int('76beigh', 29), 4294967297)
+ self.assertEqual(int('5qmcpqh', 30), 4294967297)
+ self.assertEqual(int('4q0jto5', 31), 4294967297)
+ self.assertEqual(int('4000001', 32), 4294967297)
+ self.assertEqual(int('3aokq95', 33), 4294967297)
+ self.assertEqual(int('2qhxjlj', 34), 4294967297)
+ self.assertEqual(int('2br45qc', 35), 4294967297)
+ self.assertEqual(int('1z141z5', 36), 4294967297)
+
+ @expectedFailurePY2 # fails on Py2
+ @cpython_only
+ def test_small_ints(self):
+ # Bug #3236: Return small longs from PyLong_FromString
+ self.assertIs(int('10'), 10)
+ self.assertIs(int('-1'), -1)
+ self.assertIs(int(b'10'), 10)
+ self.assertIs(int(b'-1'), -1)
+
+ def test_no_args(self):
+ self.assertEqual(int(), 0)
+
+ @unittest.skipIf(sys.version_info >= (3, 7),
+ "The first parameter must be positional with Python >= 3.7"
+ )
+ def test_x_keyword_arg(self):
+ # Test invoking int() using keyword arguments.
+ self.assertEqual(int(x=1.2), 1)
+ self.assertEqual(int(x='100', base=2), 4)
+
+ def text_base_keyword_arg(self):
+ self.assertEqual(int('100', base=2), 4)
+
+ def test_newint_plus_float(self):
+ minutes = int(100)
+ second = 0.0
+ seconds = minutes*60 + second
+ self.assertEqual(seconds, 6000)
+ self.assertTrue(isinstance(seconds, float))
+
+ @expectedFailurePY2
+ def test_keyword_args_2(self):
+ # newint causes these to fail:
+ self.assertRaises(TypeError, int, base=10)
+ self.assertRaises(TypeError, int, base=0)
+
+ def test_non_numeric_input_types(self):
+ # Test possible non-numeric types for the argument x, including
+ # subclasses of the explicitly documented accepted types.
+ class CustomStr(str): pass
+ class CustomBytes(bytes): pass
+ class CustomByteArray(bytearray): pass
+
+ values = [b'100',
+ bytearray(b'100'),
+ CustomStr('100'),
+ CustomBytes(b'100'),
+ CustomByteArray(b'100')]
+
+ for x in values:
+ msg = 'x has type %s' % type(x).__name__
+ self.assertEqual(int(x), 100, msg=msg)
+ self.assertEqual(int(x, 2), 4, msg=msg)
+
+ def test_newint_of_newstr(self):
+ a = str(u'123')
+ b = int(a)
+ self.assertEqual(b, 123)
+ self.assertTrue(isinstance(b, int))
+
+ def test_string_float(self):
+ self.assertRaises(ValueError, int, '1.2')
+
+ def test_intconversion(self):
+ # Test __int__()
+ class ClassicMissingMethods:
+ pass
+ # The following raises an AttributeError (for '__trunc__') on Py2
+ # but a TypeError on Py3 (which uses new-style classes).
+ # Perhaps nothing is to be done but avoiding old-style classes!
+ # ...
+ # self.assertRaises(TypeError, int, ClassicMissingMethods())
+
+ class MissingMethods(object):
+ pass
+ self.assertRaises(TypeError, int, MissingMethods())
+
+ class Foo0:
+ def __int__(self):
+ return 42
+
+ class Foo1(object):
+ def __int__(self):
+ return 42
+
+ class Foo2(int):
+ def __int__(self):
+ return 42
+
+ class Foo3(int):
+ def __int__(self):
+ return self.real
+
+ class Foo4(int):
+ def __int__(self):
+ return 42
+
+ class Foo5(int):
+ def __int__(self):
+ return 42.
+
+ self.assertEqual(int(Foo0()), 42)
+ self.assertEqual(int(Foo1()), 42)
+ self.assertEqual(int(Foo2()), 42)
+ self.assertEqual(int(Foo3()), 0)
+ self.assertEqual(int(Foo4()), 42)
+ self.assertRaises(TypeError, int, Foo5())
+
+ class Classic:
+ pass
+ for base in (object, Classic):
+ class IntOverridesTrunc(base):
+ def __int__(self):
+ return 42
+ def __trunc__(self):
+ return -12
+ self.assertEqual(int(IntOverridesTrunc()), 42)
+
+ class JustTrunc(base):
+ def __trunc__(self):
+ return 42
+ # This fails on Python 2.x:
+ # if not PY26:
+ # self.assertEqual(int(JustTrunc()), 42)
+
+ for trunc_result_base in (object, Classic):
+ class Integral(trunc_result_base):
+ def __int__(self):
+ return 42
+
+ class TruncReturnsNonInt(base):
+ def __trunc__(self):
+ return Integral()
+ # Fails on Python 2.6:
+ # self.assertEqual(int(TruncReturnsNonInt()), 42)
+
+ class NonIntegral(trunc_result_base):
+ def __trunc__(self):
+ # Check that we avoid infinite recursion.
+ return NonIntegral()
+
+ class TruncReturnsNonIntegral(base):
+ def __trunc__(self):
+ return NonIntegral()
+ try:
+ int(TruncReturnsNonIntegral())
+ except TypeError as e:
+ # self.assertEqual(str(e),
+ # "__trunc__ returned non-Integral"
+ # " (type NonIntegral)")
+ pass
+ else:
+ self.fail("Failed to raise TypeError with %s" %
+ ((base, trunc_result_base),))
+
+ # Regression test for bugs.python.org/issue16060.
+ class BadInt(trunc_result_base):
+ def __int__(self):
+ return 42.0
+
+ class TruncReturnsBadInt(base):
+ def __trunc__(self):
+ return BadInt()
+
+ with self.assertRaises(TypeError):
+ int(TruncReturnsBadInt())
+
+ ####################################################################
+ # future-specific tests are below:
+ ####################################################################
+
+ # Exception messages in Py2 are 8-bit strings. The following fails,
+ # even if the testlist strings are wrapped in str() calls...
+ @expectedFailurePY2
+ def test_error_message(self):
+ testlist = ('\xbd', '123\xbd', ' 123 456 ')
+ for s in testlist:
+ try:
+ int(s)
+ except ValueError as e:
+ self.assertIn(s.strip(), e.args[0])
+ else:
+ self.fail("Expected int(%r) to raise a ValueError", s)
+
+ def test_bytes_mul(self):
+ self.assertEqual(b'\x00' * int(5), b'\x00' * 5)
+ self.assertEqual(bytes(b'\x00') * int(5), bytes(b'\x00') * 5)
+
+ def test_str_mul(self):
+ self.assertEqual(u'\x00' * int(5), u'\x00' * 5)
+ self.assertEqual(str(u'\x00') * int(5), str(u'\x00') * 5)
+
+ def test_int_bytes(self):
+ self.assertEqual(int(b'a\r\n', 16), 10)
+ self.assertEqual(int(bytes(b'a\r\n'), 16), 10)
+
+ def test_divmod(self):
+ """
+ Test int.__divmod__
+ """
+ vals = [10**i for i in range(0, 20)]
+ for i in range(200):
+ x = random.choice(vals)
+ y = random.choice(vals)
+ assert divmod(int(x), int(y)) == divmod(x, y)
+ assert divmod(int(-x), int(y)) == divmod(-x, y)
+ assert divmod(int(x), int(-y)) == divmod(x, -y)
+ assert divmod(int(-x), int(-y)) == divmod(-x, -y)
+
+ assert divmod(int(x), float(y)) == divmod(x, float(y))
+ assert divmod(int(-x), float(y)) == divmod(-x, float(y))
+ assert divmod(int(x), float(-y)) == divmod(x, float(-y))
+ assert divmod(int(-x), float(-y)) == divmod(-x, float(-y))
+
+ def _frange(x, y, step):
+ _x = x ; i = 0
+ while _x < y:
+ yield _x
+ i += 1 ; _x = x + i * step
+
+ for i in range(20):
+ for d in _frange(0.005, 5.0, 0.005):
+ self.assertEqual(divmod(int(i), d), divmod(i, d), msg='i={0}; d={1}'.format(i, d))
+ self.assertEqual(divmod(int(-i), d), divmod(-i, d), msg='i={0}; d={1}'.format(i, d))
+ self.assertEqual(divmod(int(i), -d), divmod(i, -d), msg='i={0}; d={1}'.format(i, d))
+ self.assertEqual(divmod(int(-i), -d), divmod(-i, -d), msg='i={0}; d={1}'.format(i, d))
+
+ def test_div(self):
+ """
+ Issue #38
+ """
+ a = int(3)
+ self.assertEqual(a / 5., 0.6)
+ self.assertEqual(a / 5, 0.6) # the __future__.division import is in
+ # effect
+
+ def test_truediv(self):
+ """
+ Test int.__truediv__ and friends (rtruediv, itruediv)
+ """
+ a = int(3)
+ self.assertEqual(a / 2, 1.5) # since "from __future__ import division"
+ # is in effect
+ self.assertEqual(type(a / 2), float)
+
+ b = int(2)
+ self.assertEqual(a / b, 1.5) # since "from __future__ import division"
+ # is in effect
+ self.assertEqual(type(a / b), float)
+
+ c = int(3) / b
+ self.assertEqual(c, 1.5)
+ self.assertTrue(isinstance(c, float))
+
+ d = int(5)
+ d /= 5
+ self.assertEqual(d, 1.0)
+ self.assertTrue(isinstance(d, float))
+
+ e = int(10)
+ f = int(20)
+ e /= f
+ self.assertEqual(e, 0.5)
+ self.assertTrue(isinstance(e, float))
+
+
+ def test_idiv(self):
+ a = int(3)
+ a /= 2
+ self.assertEqual(a, 1.5)
+ self.assertTrue(isinstance(a, float))
+ b = int(10)
+ b /= 2
+ self.assertEqual(b, 5.0)
+ self.assertTrue(isinstance(b, float))
+ c = int(-3)
+ c /= 2.0
+ self.assertEqual(c, -1.5)
+ self.assertTrue(isinstance(c, float))
+
+ def test_floordiv(self):
+ a = int(3)
+ self.assertEqual(a // 2, 1)
+ self.assertEqual(type(a // 2), int) # i.e. another newint
+ self.assertTrue(isinstance(a // 2, int))
+
+ b = int(2)
+ self.assertEqual(a // b, 1)
+ self.assertEqual(type(a // b), int) # i.e. another newint
+ self.assertTrue(isinstance(a // b, int))
+
+ c = 3 // b
+ self.assertEqual(c, 1)
+ self.assertEqual(type(c), int) # i.e. another newint
+ self.assertTrue(isinstance(c, int))
+
+ d = int(5)
+ d //= 5
+ self.assertEqual(d, 1)
+ self.assertEqual(type(d), int) # i.e. another newint
+ self.assertTrue(isinstance(d, int))
+
+ e = int(10)
+ f = int(20)
+ e //= f
+ self.assertEqual(e, 0)
+ self.assertEqual(type(e), int) # i.e. another newint
+ self.assertTrue(isinstance(e, int))
+
+
+ def test_div(self):
+ """
+ Issue #38
+ """
+ a = int(3)
+ self.assertEqual(a / 5., 0.6)
+ self.assertEqual(a / 5, 0.6) # the __future__.division import is in
+ # effect
+
+ def test_truediv(self):
+ """
+ Test int.__truediv__ and friends (rtruediv, itruediv)
+ """
+ a = int(3)
+ self.assertEqual(a / 2, 1.5) # since "from __future__ import division"
+ # is in effect
+ self.assertEqual(type(a / 2), float)
+
+ b = int(2)
+ self.assertEqual(a / b, 1.5) # since "from __future__ import division"
+ # is in effect
+ self.assertEqual(type(a / b), float)
+
+ c = int(3) / b
+ self.assertEqual(c, 1.5)
+ self.assertTrue(isinstance(c, float))
+
+ d = int(5)
+ d /= 5
+ self.assertEqual(d, 1.0)
+ self.assertTrue(isinstance(d, float))
+
+ e = int(10)
+ f = int(20)
+ e /= f
+ self.assertEqual(e, 0.5)
+ self.assertTrue(isinstance(e, float))
+
+
+ def test_idiv(self):
+ a = int(3)
+ a /= 2
+ self.assertEqual(a, 1.5)
+ self.assertTrue(isinstance(a, float))
+ b = int(10)
+ b /= 2
+ self.assertEqual(b, 5.0)
+ self.assertTrue(isinstance(b, float))
+ c = int(-3)
+ c /= 2.0
+ self.assertEqual(c, -1.5)
+ self.assertTrue(isinstance(c, float))
+
+
+ def test_floordiv(self):
+ a = int(3)
+ self.assertEqual(a // 2, 1)
+ self.assertEqual(type(a // 2), int) # i.e. another newint
+ self.assertTrue(isinstance(a // 2, int))
+
+ b = int(2)
+ self.assertEqual(a // b, 1)
+ self.assertEqual(type(a // b), int) # i.e. another newint
+ self.assertTrue(isinstance(a // b, int))
+
+ c = 3 // b
+ self.assertEqual(c, 1)
+ self.assertEqual(type(c), int) # i.e. another newint
+ self.assertTrue(isinstance(c, int))
+
+ d = int(5)
+ d //= 5
+ self.assertEqual(d, 1)
+ self.assertEqual(type(d), int) # i.e. another newint
+ self.assertTrue(isinstance(d, int))
+
+ e = int(10)
+ f = int(20)
+ e //= f
+ self.assertEqual(e, 0)
+ self.assertEqual(type(e), int) # i.e. another newint
+ self.assertTrue(isinstance(e, int))
+
+ @unittest.skipIf(np is None, "test requires NumPy")
+ @unittest.expectedFailure
+ def test_numpy_cast_as_long_and_newint(self):
+ """
+ NumPy currently doesn't like subclasses of ``long``. This should be fixed.
+ """
+ class longsubclass(long):
+ pass
+
+ a = np.arange(10**3, dtype=np.float64).reshape(10, 100)
+ b = a.astype(longsubclass)
+ c = a.astype(int)
+ print(b.dtype)
+ assert b.dtype == np.int64 == c.dtype
+
+ def test_upcasting_to_floats(self):
+ """
+ Integers should automatically be upcasted to floats for arithmetic
+ operations.
+ """
+ a = int(3)
+
+ # Addition with floats.
+ self.assertEqual(a + 0.5, 3.5)
+ self.assertEqual(0.5 + a, 3.5)
+ self.assertTrue(isinstance(a + 0.5, float))
+ self.assertTrue(isinstance(0.5 + a, float))
+
+ # Subtraction with floats.
+ self.assertEqual(a - 0.5, 2.5)
+ self.assertEqual(0.5 - a, -2.5)
+ self.assertTrue(isinstance(a - 0.5, float))
+ self.assertTrue(isinstance(0.5 - a, float))
+
+ # Multiplication with floats.
+ self.assertEqual(a * 0.5, 1.5)
+ self.assertEqual(0.5 * a, 1.5)
+ self.assertTrue(isinstance(a * 0.5, float))
+ self.assertTrue(isinstance(0.5 * a, float))
+
+ # Division with floats.
+ self.assertEqual(a / 0.5, 6.0)
+ self.assertEqual(0.5 / a, 0.5 / 3.0)
+ self.assertTrue(isinstance(a / 0.5, float))
+ self.assertTrue(isinstance(0.5 / a, float))
+
+ # Modulo with floats.
+ self.assertEqual(a % 0.5, 0.0)
+ self.assertEqual(0.5 % a, 0.5)
+ self.assertTrue(isinstance(a % 0.5, float))
+ self.assertTrue(isinstance(0.5 % a, float))
+
+ # Power with floats.
+ self.assertEqual(1.0 ** a, 1.0)
+ self.assertTrue(isinstance(1.0 ** a, float))
+
+ self.assertEqual(a ** 1.0, a)
+ self.assertTrue(isinstance(a ** 1.0, float))
+
+ def test_upcasting_to_complex(self):
+ """
+ Integers should automatically be upcasted to complex numbers for
+ arithmetic operations.
+
+ Python 3 cannot mod complex numbers so this does not have to be
+ supported here.
+ """
+ a = int(3)
+
+ # Addition with complex.
+ self.assertEqual(a + 0.5j, 3.0 + 0.5j)
+ self.assertEqual(0.5j + a, 3.0 + 0.5j)
+ self.assertTrue(isinstance(a + 0.5j, complex))
+ self.assertTrue(isinstance(0.5j + a, complex))
+
+ # Subtraction with complex.
+ self.assertEqual(a - 0.5j, 3.0 - 0.5j)
+ self.assertEqual(0.5j - a, -3.0 + 0.5j)
+ self.assertTrue(isinstance(a - 0.5j, complex))
+ self.assertTrue(isinstance(0.5j - a, complex))
+
+ # Multiplication with complex.
+ self.assertEqual(a * 0.5j, 1.5j)
+ self.assertEqual(0.5j * a, 1.5j)
+ self.assertTrue(isinstance(a * 0.5j, complex))
+ self.assertTrue(isinstance(0.5j * a, complex))
+
+ # Division with complex.
+ self.assertEqual(a / 0.5j, -6.0j)
+ self.assertEqual(0.5j / a, (0.5 / 3.0) * 1j)
+ self.assertTrue(isinstance(a / 0.5j, complex))
+ self.assertTrue(isinstance(0.5j / a, complex))
+
+ # Power with floats.
+ self.assertEqual(5.0j ** int(1), 5.0j)
+ self.assertTrue(isinstance(5.0j ** int(1), complex))
+
+ self.assertEqual(a ** 1.0j, 3.0 ** 1.0j)
+ self.assertTrue(isinstance(a ** 1.0j, complex))
+
+ def test_more_arithmetics(self):
+ """
+ More arithmetic tests to improve test coverage.
+ """
+ a = int(3)
+ b = int(5)
+ c = int(-5)
+
+ self.assertEqual(b - a, 2)
+ self.assertTrue(isinstance(b - a, int))
+
+ self.assertEqual(a * b, 15)
+ self.assertTrue(isinstance(a * b, int))
+
+ self.assertEqual(b % a, 2)
+ self.assertTrue(isinstance(b % a, int))
+
+ self.assertEqual(a ** b, 243)
+ self.assertTrue(isinstance(a ** b, int))
+
+ self.assertEqual(abs(c), 5)
+ self.assertEqual(abs(c), b)
+ self.assertTrue(isinstance(abs(c), int))
+
+ def test_bitwise_operations(self):
+ """
+ Tests bitwise operations.
+ """
+ a = int(3)
+ b = int(1)
+
+ self.assertEqual(a >> b, 1)
+ self.assertEqual(a >> 1, 1)
+ self.assertTrue(isinstance(a >> b, int))
+ self.assertTrue(isinstance(a >> 1, int))
+
+ self.assertEqual(a << b, 6)
+ self.assertEqual(a << 1, 6)
+ self.assertTrue(isinstance(a << b, int))
+ self.assertTrue(isinstance(a << 1, int))
+
+ self.assertEqual(a & b, 1)
+ self.assertEqual(a & 1, 1)
+ self.assertTrue(isinstance(a & b, int))
+ self.assertTrue(isinstance(a & 1, int))
+
+ self.assertEqual(a | b, 3)
+ self.assertEqual(a | 1, 3)
+ self.assertTrue(isinstance(a | b, int))
+ self.assertTrue(isinstance(a | 1, int))
+
+ self.assertEqual(a ^ b, 2)
+ self.assertEqual(a ^ 1, 2)
+ self.assertTrue(isinstance(a ^ b, int))
+ self.assertTrue(isinstance(a ^ 1, int))
+
+ self.assertEqual(~a, -4)
+ self.assertTrue(isinstance(~a, int))
+
+ def test_unary_operators(self):
+ a = int(3)
+ b = int(-3)
+
+ self.assertEqual(+a, a)
+ self.assertEqual(+a, 3)
+ self.assertEqual(+b, b)
+ self.assertEqual(+b, -3)
+ self.assertTrue(isinstance(+a, int))
+
+ self.assertEqual(-a, b)
+ self.assertEqual(-a, -3)
+ self.assertEqual(-b, a)
+ self.assertEqual(-b, 3)
+ self.assertTrue(isinstance(-a, int))
+
+ def test_to_bytes(self):
+ def check(tests, byteorder, signed=False):
+ for test, expected in tests.items():
+ try:
+ self.assertEqual(
+ int(test).to_bytes(len(expected), byteorder, signed=signed),
+ expected)
+ except Exception as err:
+ raise_from(AssertionError(
+ "failed to convert {0} with byteorder={1} and signed={2}"
+ .format(test, byteorder, signed)), err)
+
+ # Convert integers to signed big-endian byte arrays.
+ tests1 = {
+ 0: bytes(b'\x00'),
+ 1: bytes(b'\x01'),
+ -1: bytes(b'\xff'),
+ -127: bytes(b'\x81'),
+ -128: bytes(b'\x80'),
+ -129: bytes(b'\xff\x7f'),
+ 127: bytes(b'\x7f'),
+ 129: bytes(b'\x00\x81'),
+ -255: bytes(b'\xff\x01'),
+ -256: bytes(b'\xff\x00'),
+ 255: bytes(b'\x00\xff'),
+ 256: bytes(b'\x01\x00'),
+ 32767: bytes(b'\x7f\xff'),
+ -32768: bytes(b'\xff\x80\x00'),
+ 65535: bytes(b'\x00\xff\xff'),
+ -65536: bytes(b'\xff\x00\x00'),
+ -8388608: bytes(b'\x80\x00\x00')
+ }
+ check(tests1, 'big', signed=True)
+
+ # Convert integers to signed little-endian byte arrays.
+ tests2 = {
+ 0: bytes(b'\x00'),
+ 1: bytes(b'\x01'),
+ -1: bytes(b'\xff'),
+ -127: bytes(b'\x81'),
+ -128: bytes(b'\x80'),
+ -129: bytes(b'\x7f\xff'),
+ 127: bytes(b'\x7f'),
+ 129: bytes(b'\x81\x00'),
+ -255: bytes(b'\x01\xff'),
+ -256: bytes(b'\x00\xff'),
+ 255: bytes(b'\xff\x00'),
+ 256: bytes(b'\x00\x01'),
+ 32767: bytes(b'\xff\x7f'),
+ -32768: bytes(b'\x00\x80'),
+ 65535: bytes(b'\xff\xff\x00'),
+ -65536: bytes(b'\x00\x00\xff'),
+ -8388608: bytes(b'\x00\x00\x80')
+ }
+ check(tests2, 'little', signed=True)
+
+ # Convert integers to unsigned big-endian byte arrays.
+ tests3 = {
+ 0: bytes(b'\x00'),
+ 1: bytes(b'\x01'),
+ 127: bytes(b'\x7f'),
+ 128: bytes(b'\x80'),
+ 255: bytes(b'\xff'),
+ 256: bytes(b'\x01\x00'),
+ 32767: bytes(b'\x7f\xff'),
+ 32768: bytes(b'\x80\x00'),
+ 65535: bytes(b'\xff\xff'),
+ 65536: bytes(b'\x01\x00\x00')
+ }
+ check(tests3, 'big', signed=False)
+
+ # Convert integers to unsigned little-endian byte arrays.
+ tests4 = {
+ 0: bytes(b'\x00'),
+ 1: bytes(b'\x01'),
+ 127: bytes(b'\x7f'),
+ 128: bytes(b'\x80'),
+ 255: bytes(b'\xff'),
+ 256: bytes(b'\x00\x01'),
+ 32767: bytes(b'\xff\x7f'),
+ 32768: bytes(b'\x00\x80'),
+ 65535: bytes(b'\xff\xff'),
+ 65536: bytes(b'\x00\x00\x01')
+ }
+ check(tests4, 'little', signed=False)
+
+ self.assertRaises(OverflowError, int(256).to_bytes, 1, 'big', signed=False)
+ self.assertRaises(OverflowError, int(256).to_bytes, 1, 'big', signed=True)
+ self.assertRaises(OverflowError, int(256).to_bytes, 1, 'little', signed=False)
+ self.assertRaises(OverflowError, int(256).to_bytes, 1, 'little', signed=True)
+ self.assertRaises(OverflowError, int(-1).to_bytes, 2, 'big', signed=False),
+ self.assertRaises(OverflowError, int(-1).to_bytes, 2, 'little', signed=False)
+ self.assertEqual(int(0).to_bytes(0, 'big'), b'')
+ self.assertEqual(int(1).to_bytes(5, 'big'), b'\x00\x00\x00\x00\x01')
+ self.assertEqual(int(0).to_bytes(5, 'big'), b'\x00\x00\x00\x00\x00')
+ self.assertEqual(int(-1).to_bytes(5, 'big', signed=True),
+ bytes(b'\xff\xff\xff\xff\xff'))
+ self.assertRaises(OverflowError, int(1).to_bytes, 0, 'big')
+
+ def test_from_bytes(self):
+ def check(tests, byteorder, signed=False):
+ for test, expected in tests.items():
+ try:
+ self.assertEqual(
+ int.from_bytes(test, byteorder, signed=signed),
+ int(expected))
+ except Exception as err:
+ raise_from(AssertionError(
+ "failed to convert {0} with byteorder={1!r} and signed={2}"
+ .format(test, byteorder, signed)), err)
+
+ # Convert signed big-endian byte arrays to integers.
+ tests1 = {
+ bytes(b''): 0,
+ bytes(b'\x00'): 0,
+ bytes(b'\x00\x00'): 0,
+ bytes(b'\x01'): 1,
+ bytes(b'\x00\x01'): 1,
+ bytes(b'\xff'): -1,
+ bytes(b'\xff\xff'): -1,
+ bytes(b'\x81'): -127,
+ bytes(b'\x80'): -128,
+ bytes(b'\xff\x7f'): -129,
+ bytes(b'\x7f'): 127,
+ bytes(b'\x00\x81'): 129,
+ bytes(b'\xff\x01'): -255,
+ bytes(b'\xff\x00'): -256,
+ bytes(b'\x00\xff'): 255,
+ bytes(b'\x01\x00'): 256,
+ bytes(b'\x7f\xff'): 32767,
+ bytes(b'\x80\x00'): -32768,
+ bytes(b'\x00\xff\xff'): 65535,
+ bytes(b'\xff\x00\x00'): -65536,
+ bytes(b'\x80\x00\x00'): -8388608
+ }
+ # check(tests1, 'big', signed=True)
+
+ # Convert signed little-endian byte arrays to integers.
+ tests2 = {
+ bytes(b''): 0,
+ bytes(b'\x00'): 0,
+ bytes(b'\x00\x00'): 0,
+ bytes(b'\x01'): 1,
+ bytes(b'\x00\x01'): 256,
+ bytes(b'\xff'): -1,
+ bytes(b'\xff\xff'): -1,
+ bytes(b'\x81'): -127,
+ bytes(b'\x80'): -128,
+ bytes(b'\x7f\xff'): -129,
+ bytes(b'\x7f'): 127,
+ bytes(b'\x81\x00'): 129,
+ bytes(b'\x01\xff'): -255,
+ bytes(b'\x00\xff'): -256,
+ bytes(b'\xff\x00'): 255,
+ bytes(b'\x00\x01'): 256,
+ bytes(b'\xff\x7f'): 32767,
+ bytes(b'\x00\x80'): -32768,
+ bytes(b'\xff\xff\x00'): 65535,
+ bytes(b'\x00\x00\xff'): -65536,
+ bytes(b'\x00\x00\x80'): -8388608
+ }
+ # check(tests2, 'little', signed=True)
+
+ # Convert unsigned big-endian byte arrays to integers.
+ tests3 = {
+ bytes(b''): 0,
+ bytes(b'\x00'): 0,
+ bytes(b'\x01'): 1,
+ bytes(b'\x7f'): 127,
+ bytes(b'\x80'): 128,
+ bytes(b'\xff'): 255,
+ bytes(b'\x01\x00'): 256,
+ bytes(b'\x7f\xff'): 32767,
+ bytes(b'\x80\x00'): 32768,
+ bytes(b'\xff\xff'): 65535,
+ bytes(b'\x01\x00\x00'): 65536,
+ }
+ check(tests3, 'big', signed=False)
+
+ # Convert integers to unsigned little-endian byte arrays.
+ tests4 = {
+ bytes(b''): 0,
+ bytes(b'\x00'): 0,
+ bytes(b'\x01'): 1,
+ bytes(b'\x7f'): 127,
+ bytes(b'\x80'): 128,
+ bytes(b'\xff'): 255,
+ bytes(b'\x00\x01'): 256,
+ bytes(b'\xff\x7f'): 32767,
+ bytes(b'\x00\x80'): 32768,
+ bytes(b'\xff\xff'): 65535,
+ bytes(b'\x00\x00\x01'): 65536,
+ }
+ check(tests4, 'little', signed=False)
+
+ class myint(int):
+ pass
+
+ if PY2:
+ import __builtin__
+ oldbytes = __builtin__.bytes
+ types = (bytes, oldbytes)
+ else:
+ types = (bytes,)
+ for mytype in types:
+ self.assertIs(type(myint.from_bytes(mytype(b'\x00'), 'big')), myint)
+ self.assertEqual(myint.from_bytes(mytype(b'\x01'), 'big'), 1)
+ self.assertIs(
+ type(myint.from_bytes(mytype(b'\x00'), 'big', signed=False)), myint)
+ self.assertEqual(myint.from_bytes(mytype(b'\x01'), 'big', signed=False), 1)
+ self.assertIs(type(myint.from_bytes(mytype(b'\x00'), 'little')), myint)
+ self.assertEqual(myint.from_bytes(mytype(b'\x01'), 'little'), 1)
+ self.assertIs(type(myint.from_bytes(
+ mytype(b'\x00'), 'little', signed=False)), myint)
+ self.assertEqual(myint.from_bytes(mytype(b'\x01'), 'little', signed=False), 1)
+ # self.assertEqual(
+ # int.from_bytes([255, 0, 0], 'big', signed=True), -65536)
+ # self.assertEqual(
+ # int.from_bytes((255, 0, 0), 'big', signed=True), -65536)
+ # self.assertEqual(int.from_bytes(
+ # bytearray(mytype(b'\xff\x00\x00')), 'big', signed=True), -65536)
+ # self.assertEqual(int.from_bytes(
+ # bytearray(mytype(b'\xff\x00\x00')), 'big', signed=True), -65536)
+ # self.assertEqual(int.from_bytes(
+ # array.array('B', mytype(b'\xff\x00\x00')), 'big', signed=True), -65536)
+ # self.assertEqual(int.from_bytes(
+ # memoryview(mytype(b'\xff\x00\x00')), 'big', signed=True), -65536)
+
+ self.assertRaises(TypeError, int.from_bytes, u"", 'big')
+ self.assertRaises(TypeError, int.from_bytes, u"\x00", 'big')
+ self.assertRaises(TypeError, myint.from_bytes, u"", 'big')
+ self.assertRaises(TypeError, myint.from_bytes, u"\x00", 'big')
+
+ types = (int, lambda x: x) if PY2 else (lambda x: x,)
+ for mytype in types:
+ self.assertRaises(ValueError, int.from_bytes, [mytype(256)], 'big')
+ self.assertRaises(ValueError, int.from_bytes, [mytype(0)], 'big\x00')
+ self.assertRaises(ValueError, int.from_bytes, [mytype(0)], 'little\x00')
+ self.assertRaises(TypeError, int.from_bytes, mytype(0), 'big')
+ # self.assertRaises(TypeError, int.from_bytes, mytype(0), 'big', True)
+ self.assertRaises(TypeError, myint.from_bytes, mytype(0), 'big')
+ # self.assertRaises(TypeError, int.from_bytes, mytype(0), 'big', True)
+
+ @expectedFailurePY2
+ def test_multiple_inheritance(self):
+ """
+ Issue #96 (for newint instead of newobject)
+ """
+ import collections.abc
+
+ class Base(int):
+ pass
+
+ class Foo(Base, collections.abc.Container):
+ def __add__(self, other):
+ return 0
+
+ @expectedFailurePY2
+ def test_with_metaclass_and_int(self):
+ """
+ Issue #91 (for newint instead of newobject)
+ """
+ from future.utils import with_metaclass
+
+ class MetaClass(type):
+ pass
+
+ class TestClass(with_metaclass(MetaClass, int)):
+ pass
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_int_old_division.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_int_old_division.py
new file mode 100644
index 0000000..be6fded
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_int_old_division.py
@@ -0,0 +1,101 @@
+"""
+Py2 only. int tests involving division for the case that:
+
+ >>> from __future__ import division
+
+is not in effect.
+"""
+
+from __future__ import (absolute_import,
+ print_function, unicode_literals)
+from future import standard_library
+from future.builtins import *
+from future.tests.base import unittest
+from future.utils import PY2
+
+import sys
+import random
+
+
+@unittest.skipIf(not PY2, 'old division tests only for Py2')
+class IntTestCasesOldDivision(unittest.TestCase):
+
+ def setUp(self):
+ self.longMessage = True
+
+
+ def test_div(self):
+ """
+ Issue #38
+ """
+ a = int(3)
+ self.assertEqual(a / 5., 0.6)
+ self.assertEqual(a / 5, 0)
+
+
+ def test_idiv(self):
+ a = int(3)
+ a /= 2
+ self.assertEqual(a, 1)
+ self.assertTrue(isinstance(a, int))
+ b = int(10)
+ b /= 2
+ self.assertEqual(b, 5)
+ self.assertTrue(isinstance(b, int))
+ c = int(-3)
+ c /= 2.0
+ self.assertEqual(c, -1.5)
+ self.assertTrue(isinstance(c, float))
+
+
+ def test_truediv(self):
+ """
+ Test int.__truediv__ and friends (rtruediv, itruediv)
+ """
+ a = int(3)
+ self.assertEqual(a / 2, 1) # since "from __future__ import division"
+ # is in effect
+ self.assertEqual(type(a / 2), int)
+
+ b = int(2)
+ self.assertEqual(a / b, 1) # since "from __future__ import division"
+ # is in effect
+ self.assertEqual(type(a / b), int)
+
+ c = int(3) / b
+ self.assertEqual(c, 1)
+ self.assertTrue(isinstance(c, int))
+
+ d = int(5)
+ d /= 5
+ self.assertEqual(d, 1)
+ self.assertTrue(isinstance(d, int))
+
+ e = int(10)
+ f = int(20)
+ e /= f
+ self.assertEqual(e, 0)
+ self.assertTrue(isinstance(e, int))
+
+
+ def test_divmod(self):
+ """
+ Test int.__divmod__
+ """
+ vals = [10**i for i in range(0, 20)]
+ for i in range(200):
+ x = random.choice(vals)
+ y = random.choice(vals)
+ self.assertEqual(int(y).__rdivmod__(int(x)), divmod(x, y), msg='x={0}; y={1}'.format(x, y))
+ self.assertEqual(int(-y).__rdivmod__(int(x)), divmod(x, -y), msg='x={0}; y={1}'.format(x, y))
+ self.assertEqual(int(y).__rdivmod__(int(-x)), divmod(-x, y), msg='x={0}; y={1}'.format(x, y))
+ self.assertEqual(int(-y).__rdivmod__(int(-x)), divmod(-x, -y), msg='x={0}; y={1}'.format(x, y))
+
+ self.assertEqual(int(x).__rdivmod__(int(y)), long(x).__rdivmod__(y), msg='x={0}; y={1}'.format(x, y))
+ self.assertEqual(int(-x).__rdivmod__(int(y)), long(-x).__rdivmod__(y), msg='x={0}; y={1}'.format(x, y))
+ self.assertEqual(int(x).__rdivmod__(int(-y)), long(x).__rdivmod__(-y), msg='x={0}; y={1}'.format(x, y))
+ self.assertEqual(int(-x).__rdivmod__(int(-y)), long(-x).__rdivmod__(-y), msg='x={0}; y={1}'.format(x, y))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_isinstance.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_isinstance.py
new file mode 100644
index 0000000..33c0a58
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_isinstance.py
@@ -0,0 +1,287 @@
+"""
+From the Python 3.3 test suite
+"""
+
+from __future__ import (absolute_import, division, unicode_literals)
+from future.builtins import *
+
+# Tests some corner cases with isinstance() and issubclass(). While these
+# tests use new style classes and properties, they actually do whitebox
+# testing of error conditions uncovered when using extension types.
+
+import sys
+from future.tests.base import unittest
+
+
+class TestIsInstanceExceptions(unittest.TestCase):
+ # Test to make sure that an AttributeError when accessing the instance's
+ # class's bases is masked. This was actually a bug in Python 2.2 and
+ # 2.2.1 where the exception wasn't caught but it also wasn't being cleared
+ # (leading to an "undetected error" in the debug build). Set up is,
+ # isinstance(inst, cls) where:
+ #
+ # - cls isn't a type, or a tuple
+ # - cls has a __bases__ attribute
+ # - inst has a __class__ attribute
+ # - inst.__class__ as no __bases__ attribute
+ #
+ # Sounds complicated, I know, but this mimics a situation where an
+ # extension type raises an AttributeError when its __bases__ attribute is
+ # gotten. In that case, isinstance() should return False.
+ def test_class_has_no_bases(self):
+ class I(object):
+ def getclass(self):
+ # This must return an object that has no __bases__ attribute
+ return None
+ __class__ = property(getclass)
+
+ class C(object):
+ def getbases(self):
+ return ()
+ __bases__ = property(getbases)
+
+ self.assertEqual(False, isinstance(I(), C()))
+
+ # Like above except that inst.__class__.__bases__ raises an exception
+ # other than AttributeError
+ def test_bases_raises_other_than_attribute_error(self):
+ class E(object):
+ def getbases(self):
+ raise RuntimeError
+ __bases__ = property(getbases)
+
+ class I(object):
+ def getclass(self):
+ return E()
+ __class__ = property(getclass)
+
+ class C(object):
+ def getbases(self):
+ return ()
+ __bases__ = property(getbases)
+
+ self.assertRaises(RuntimeError, isinstance, I(), C())
+
+ # Here's a situation where getattr(cls, '__bases__') raises an exception.
+ # If that exception is not AttributeError, it should not get masked
+ def test_dont_mask_non_attribute_error(self):
+ class I: pass
+
+ class C(object):
+ def getbases(self):
+ raise RuntimeError
+ __bases__ = property(getbases)
+
+ self.assertRaises(RuntimeError, isinstance, I(), C())
+
+ # Like above, except that getattr(cls, '__bases__') raises an
+ # AttributeError, which /should/ get masked as a TypeError
+ def test_mask_attribute_error(self):
+ class I: pass
+
+ class C(object):
+ def getbases(self):
+ raise AttributeError
+ __bases__ = property(getbases)
+
+ self.assertRaises(TypeError, isinstance, I(), C())
+
+ # check that we don't mask non AttributeErrors
+ # see: http://bugs.python.org/issue1574217
+ def test_isinstance_dont_mask_non_attribute_error(self):
+ class C(object):
+ def getclass(self):
+ raise RuntimeError
+ __class__ = property(getclass)
+
+ # This fails on Python 2.7:
+ # c = C()
+ # self.assertRaises(RuntimeError, isinstance, c, bool)
+
+ # # test another code path
+ # class D: pass
+ # self.assertRaises(RuntimeError, isinstance, c, D)
+
+
+# These tests are similar to above, but tickle certain code paths in
+# issubclass() instead of isinstance() -- really PyObject_IsSubclass()
+# vs. PyObject_IsInstance().
+class TestIsSubclassExceptions(unittest.TestCase):
+ def test_dont_mask_non_attribute_error(self):
+ class C(object):
+ def getbases(self):
+ raise RuntimeError
+ __bases__ = property(getbases)
+
+ class S(C): pass
+
+ self.assertRaises(RuntimeError, issubclass, C(), S())
+
+ def test_mask_attribute_error(self):
+ class C(object):
+ def getbases(self):
+ raise AttributeError
+ __bases__ = property(getbases)
+
+ class S(C): pass
+
+ self.assertRaises(TypeError, issubclass, C(), S())
+
+ # Like above, but test the second branch, where the __bases__ of the
+ # second arg (the cls arg) is tested. This means the first arg must
+ # return a valid __bases__, and it's okay for it to be a normal --
+ # unrelated by inheritance -- class.
+ def test_dont_mask_non_attribute_error_in_cls_arg(self):
+ class B: pass
+
+ class C(object):
+ def getbases(self):
+ raise RuntimeError
+ __bases__ = property(getbases)
+
+ self.assertRaises(RuntimeError, issubclass, B, C())
+
+ def test_mask_attribute_error_in_cls_arg(self):
+ class B: pass
+
+ class C(object):
+ def getbases(self):
+ raise AttributeError
+ __bases__ = property(getbases)
+
+ self.assertRaises(TypeError, issubclass, B, C())
+
+
+
+# meta classes for creating abstract classes and instances
+class AbstractClass(object):
+ def __init__(self, bases):
+ self.bases = bases
+
+ def getbases(self):
+ return self.bases
+ __bases__ = property(getbases)
+
+ def __call__(self):
+ return AbstractInstance(self)
+
+class AbstractInstance(object):
+ def __init__(self, klass):
+ self.klass = klass
+
+ def getclass(self):
+ return self.klass
+ __class__ = property(getclass)
+
+# abstract classes
+AbstractSuper = AbstractClass(bases=())
+
+AbstractChild = AbstractClass(bases=(AbstractSuper,))
+
+# normal classes
+class Super:
+ pass
+
+class Child(Super):
+ pass
+
+# new-style classes
+class NewSuper(object):
+ pass
+
+class NewChild(NewSuper):
+ pass
+
+
+
+class TestIsInstanceIsSubclass(unittest.TestCase):
+ # Tests to ensure that isinstance and issubclass work on abstract
+ # classes and instances. Before the 2.2 release, TypeErrors were
+ # raised when boolean values should have been returned. The bug was
+ # triggered by mixing 'normal' classes and instances were with
+ # 'abstract' classes and instances. This case tries to test all
+ # combinations.
+
+ def test_isinstance_normal(self):
+ # normal instances
+ self.assertEqual(True, isinstance(Super(), Super))
+ self.assertEqual(False, isinstance(Super(), Child))
+ self.assertEqual(False, isinstance(Super(), AbstractSuper))
+ self.assertEqual(False, isinstance(Super(), AbstractChild))
+
+ self.assertEqual(True, isinstance(Child(), Super))
+ self.assertEqual(False, isinstance(Child(), AbstractSuper))
+
+ def test_isinstance_abstract(self):
+ # abstract instances
+ self.assertEqual(True, isinstance(AbstractSuper(), AbstractSuper))
+ self.assertEqual(False, isinstance(AbstractSuper(), AbstractChild))
+ self.assertEqual(False, isinstance(AbstractSuper(), Super))
+ self.assertEqual(False, isinstance(AbstractSuper(), Child))
+
+ self.assertEqual(True, isinstance(AbstractChild(), AbstractChild))
+ self.assertEqual(True, isinstance(AbstractChild(), AbstractSuper))
+ self.assertEqual(False, isinstance(AbstractChild(), Super))
+ self.assertEqual(False, isinstance(AbstractChild(), Child))
+
+ def test_subclass_normal(self):
+ # normal classes
+ self.assertEqual(True, issubclass(Super, Super))
+ self.assertEqual(False, issubclass(Super, AbstractSuper))
+ self.assertEqual(False, issubclass(Super, Child))
+
+ self.assertEqual(True, issubclass(Child, Child))
+ self.assertEqual(True, issubclass(Child, Super))
+ self.assertEqual(False, issubclass(Child, AbstractSuper))
+
+ def test_subclass_abstract(self):
+ # abstract classes
+ self.assertEqual(True, issubclass(AbstractSuper, AbstractSuper))
+ self.assertEqual(False, issubclass(AbstractSuper, AbstractChild))
+ self.assertEqual(False, issubclass(AbstractSuper, Child))
+
+ self.assertEqual(True, issubclass(AbstractChild, AbstractChild))
+ self.assertEqual(True, issubclass(AbstractChild, AbstractSuper))
+ self.assertEqual(False, issubclass(AbstractChild, Super))
+ self.assertEqual(False, issubclass(AbstractChild, Child))
+
+ def test_subclass_tuple(self):
+ # test with a tuple as the second argument classes
+ self.assertEqual(True, issubclass(Child, (Child,)))
+ self.assertEqual(True, issubclass(Child, (Super,)))
+ self.assertEqual(False, issubclass(Super, (Child,)))
+ self.assertEqual(True, issubclass(Super, (Child, Super)))
+ self.assertEqual(False, issubclass(Child, ()))
+ self.assertEqual(True, issubclass(Super, (Child, (Super,))))
+
+ self.assertEqual(True, issubclass(NewChild, (NewChild,)))
+ self.assertEqual(True, issubclass(NewChild, (NewSuper,)))
+ self.assertEqual(False, issubclass(NewSuper, (NewChild,)))
+ self.assertEqual(True, issubclass(NewSuper, (NewChild, NewSuper)))
+ self.assertEqual(False, issubclass(NewChild, ()))
+ self.assertEqual(True, issubclass(NewSuper, (NewChild, (NewSuper,))))
+
+ self.assertEqual(True, issubclass(int, (int, (float, int))))
+ self.assertEqual(True, issubclass(str, (str, (Child, NewChild, str))))
+
+ def test_subclass_recursion_limit(self):
+ # make sure that issubclass raises RuntimeError before the C stack is
+ # blown
+ self.assertRaises(RuntimeError, blowstack, issubclass, str, str)
+
+ def test_isinstance_recursion_limit(self):
+ # make sure that issubclass raises RuntimeError before the C stack is
+ # blown
+ self.assertRaises(RuntimeError, blowstack, isinstance, '', str)
+
+def blowstack(fxn, arg, compare_to):
+ # Make sure that calling isinstance with a deeply nested tuple for its
+ # argument will raise RuntimeError eventually.
+ tuple_arg = (compare_to,)
+ for cnt in range(sys.getrecursionlimit()+5):
+ tuple_arg = (tuple_arg,)
+ fxn(arg, tuple_arg)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_libfuturize_fixers.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_libfuturize_fixers.py
new file mode 100644
index 0000000..4ac0b7e
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_libfuturize_fixers.py
@@ -0,0 +1,4413 @@
+""" Test suite for the fixer modules.
+
+Based on lib2to3/tests/test_fixers.py
+
+"""
+# Support code for test_*.py files, from lib2to3/tests/support.py by Collin Winter:
+
+# Python imports
+import sys
+import os
+import os.path
+from itertools import chain
+from textwrap import dedent
+from operator import itemgetter
+from lib2to3 import pygram, pytree, refactor, fixer_util
+from lib2to3.pgen2 import driver
+
+# Local imports
+from future.tests.base import unittest
+from future.builtins import str
+
+
+test_dir = os.path.dirname(__file__)
+proj_dir = os.path.normpath(os.path.join(test_dir, ".."))
+# grammar_path = os.path.join(test_dir, "..", "Grammar.txt")
+# grammar = driver.load_grammar(grammar_path)
+# driver = driver.Driver(grammar, convert=pytree.convert)
+#
+# def parse_string(string):
+# return driver.parse_string(reformat(string), debug=True)
+
+def run_all_tests(test_mod=None, tests=None):
+ if tests is None:
+ tests = unittest.TestLoader().loadTestsFromModule(test_mod)
+ unittest.TextTestRunner(verbosity=2).run(tests)
+
+def reformat(string):
+ return dedent(string) + u"\n\n"
+
+def get_refactorer(fixer_pkg="lib2to3", fixers=None, options=None):
+ """
+ A convenience function for creating a RefactoringTool for tests.
+
+ fixers is a list of fixers for the RefactoringTool to use. By default
+ "lib2to3.fixes.*" is used. options is an optional dictionary of options to
+ be passed to the RefactoringTool.
+ """
+ if fixers is not None:
+ fixers = [fixer_pkg + ".fixes.fix_" + fix for fix in fixers]
+ else:
+ fixers = refactor.get_fixers_from_package(fixer_pkg + ".fixes")
+ options = options or {}
+ return refactor.RefactoringTool(fixers, options, explicit=True)
+
+def all_project_files():
+ for dirpath, dirnames, filenames in os.walk(proj_dir):
+ for filename in filenames:
+ if filename.endswith(".py"):
+ yield os.path.join(dirpath, filename)
+
+
+class FixerTestCase(unittest.TestCase):
+
+ # Other test cases can subclass this class and replace "fixer_pkg" with
+ # their own.
+ def setUp(self, fix_list=None, fixer_pkg="libfuturize", options=None):
+ if fix_list is None:
+ fix_list = [self.fixer]
+ self.refactor = get_refactorer(fixer_pkg, fix_list, options)
+ self.fixer_log = []
+ self.filename = u"<string>"
+
+ for fixer in chain(self.refactor.pre_order,
+ self.refactor.post_order):
+ fixer.log = self.fixer_log
+
+ def _check(self, before, after):
+ before = reformat(before)
+ after = reformat(after)
+ tree = self.refactor.refactor_string(before, self.filename)
+ self.assertEqual(after, str(tree))
+ return tree
+
+ def check(self, before, after, ignore_warnings=False):
+ tree = self._check(before, after)
+ self.assertTrue(tree.was_changed)
+ if not ignore_warnings:
+ self.assertEqual(self.fixer_log, [])
+
+ def warns(self, before, after, message, unchanged=False):
+ tree = self._check(before, after)
+ self.assertTrue(message in "".join(self.fixer_log))
+ if not unchanged:
+ self.assertTrue(tree.was_changed)
+
+ def warns_unchanged(self, before, message):
+ self.warns(before, before, message, unchanged=True)
+
+ def unchanged(self, before, ignore_warnings=False):
+ self._check(before, before)
+ if not ignore_warnings:
+ self.assertEqual(self.fixer_log, [])
+
+ def assert_runs_after(self, *names):
+ fixes = [self.fixer]
+ fixes.extend(names)
+ r = get_refactorer("lib2to3", fixes)
+ (pre, post) = r.get_fixers()
+ n = "fix_" + self.fixer
+ if post and post[-1].__class__.__module__.endswith(n):
+ # We're the last fixer to run
+ return
+ if pre and pre[-1].__class__.__module__.endswith(n) and not post:
+ # We're the last in pre and post is empty
+ return
+ self.fail("Fixer run order (%s) is incorrect; %s should be last."\
+ %(", ".join([x.__class__.__module__ for x in (pre+post)]), n))
+
+
+############### EDIT the tests below ...
+#
+# class Test_ne(FixerTestCase):
+# fixer = "ne"
+#
+# def test_basic(self):
+# b = """if x <> y:
+# pass"""
+#
+# a = """if x != y:
+# pass"""
+# self.check(b, a)
+#
+#
+# class Test_print(FixerTestCase):
+# fixer = "print_"
+#
+# def test_print(self):
+# b = """print 'Hello world'"""
+# a = """from __future__ import print_function\nprint('Hello world')"""
+# self.check(b, a)
+#
+#
+# class Test_apply(FixerTestCase):
+# fixer = "apply"
+#
+# def test_1(self):
+# b = """x = apply(f, g + h)"""
+# a = """x = f(*g + h)"""
+# self.check(b, a)
+#
+#
+# class Test_intern(FixerTestCase):
+# fixer = "intern"
+#
+# def test_prefix_preservation(self):
+# b = """x = intern( a )"""
+# a = """import sys\nx = sys.intern( a )"""
+# self.check(b, a)
+#
+# b = """y = intern("b" # test
+# )"""
+# a = """import sys\ny = sys.intern("b" # test
+# )"""
+# self.check(b, a)
+#
+# b = """z = intern(a+b+c.d, )"""
+# a = """import sys\nz = sys.intern(a+b+c.d, )"""
+# self.check(b, a)
+#
+# def test(self):
+# b = """x = intern(a)"""
+# a = """import sys\nx = sys.intern(a)"""
+# self.check(b, a)
+#
+# b = """z = intern(a+b+c.d,)"""
+# a = """import sys\nz = sys.intern(a+b+c.d,)"""
+# self.check(b, a)
+#
+# b = """intern("y%s" % 5).replace("y", "")"""
+# a = """import sys\nsys.intern("y%s" % 5).replace("y", "")"""
+# self.check(b, a)
+#
+# # These should not be refactored
+#
+# def test_unchanged(self):
+# s = """intern(a=1)"""
+# self.unchanged(s)
+#
+# s = """intern(f, g)"""
+# self.unchanged(s)
+#
+# s = """intern(*h)"""
+# self.unchanged(s)
+#
+# s = """intern(**i)"""
+# self.unchanged(s)
+#
+# s = """intern()"""
+# self.unchanged(s)
+#
+# class Test_reduce(FixerTestCase):
+# fixer = "reduce"
+#
+# def test_simple_call(self):
+# b = "reduce(a, b, c)"
+# a = "from functools import reduce\nreduce(a, b, c)"
+# self.check(b, a)
+#
+# def test_bug_7253(self):
+# # fix_tuple_params was being bad and orphaning nodes in the tree.
+# b = "def x(arg): reduce(sum, [])"
+# a = "from functools import reduce\ndef x(arg): reduce(sum, [])"
+# self.check(b, a)
+#
+# def test_call_with_lambda(self):
+# b = "reduce(lambda x, y: x + y, seq)"
+# a = "from functools import reduce\nreduce(lambda x, y: x + y, seq)"
+# self.check(b, a)
+#
+# def test_unchanged(self):
+# s = "reduce(a)"
+# self.unchanged(s)
+#
+# s = "reduce(a, b=42)"
+# self.unchanged(s)
+#
+# s = "reduce(a, b, c, d)"
+# self.unchanged(s)
+#
+# s = "reduce(**c)"
+# self.unchanged(s)
+#
+# s = "reduce()"
+# self.unchanged(s)
+
+class Test_print(FixerTestCase):
+ fixer = "print"
+
+ def test_prefix_preservation(self):
+ b = """print 1, 1+1, 1+1+1"""
+ a = """print(1, 1+1, 1+1+1)"""
+ self.check(b, a)
+
+ def test_idempotency(self):
+ s = """print()"""
+ self.unchanged(s)
+
+ s = """print('')"""
+ self.unchanged(s)
+
+ def test_idempotency_print_as_function(self):
+ self.refactor.driver.grammar = pygram.python_grammar_no_print_statement
+ s = """print(1, 1+1, 1+1+1)"""
+ self.unchanged(s)
+
+ s = """print()"""
+ self.unchanged(s)
+
+ s = """print('')"""
+ self.unchanged(s)
+
+ def test_1(self):
+ b = """print 1, 1+1, 1+1+1"""
+ a = """print(1, 1+1, 1+1+1)"""
+ self.check(b, a)
+
+ def test_2(self):
+ b = """print 1, 2"""
+ a = """print(1, 2)"""
+ self.check(b, a)
+
+ def test_3(self):
+ b = """print"""
+ a = """print()"""
+ self.check(b, a)
+
+ def test_4(self):
+ # from bug 3000
+ b = """print whatever; print"""
+ a = """print(whatever); print()"""
+ self.check(b, a)
+
+ def test_5(self):
+ b = """print; print whatever;"""
+ a = """print(); print(whatever);"""
+ self.check(b, a)
+
+ def test_tuple(self):
+ b = """print (a, b, c)"""
+ a = """print((a, b, c))"""
+ self.check(b, a)
+
+ # trailing commas
+
+ def test_trailing_comma_1(self):
+ b = """print 1, 2, 3,"""
+ a = """print(1, 2, 3, end=' ')"""
+ self.check(b, a)
+
+ def test_trailing_comma_2(self):
+ b = """print 1, 2,"""
+ a = """print(1, 2, end=' ')"""
+ self.check(b, a)
+
+ def test_trailing_comma_3(self):
+ b = """print 1,"""
+ a = """print(1, end=' ')"""
+ self.check(b, a)
+
+ # >> stuff
+
+ def test_vargs_without_trailing_comma(self):
+ b = """print >>sys.stderr, 1, 2, 3"""
+ a = """print(1, 2, 3, file=sys.stderr)"""
+ self.check(b, a)
+
+ def test_with_trailing_comma(self):
+ b = """print >>sys.stderr, 1, 2,"""
+ a = """print(1, 2, end=' ', file=sys.stderr)"""
+ self.check(b, a)
+
+ def test_no_trailing_comma(self):
+ b = """print >>sys.stderr, 1+1"""
+ a = """print(1+1, file=sys.stderr)"""
+ self.check(b, a)
+
+ def test_spaces_before_file(self):
+ b = """print >> sys.stderr"""
+ a = """print(file=sys.stderr)"""
+ self.check(b, a)
+
+ def test_with_future_print_function(self):
+ s = "from __future__ import print_function\n" \
+ "print('Hai!', end=' ')"
+ self.unchanged(s)
+
+ b = "print 'Hello, world!'"
+ a = "print('Hello, world!')"
+ self.check(b, a)
+
+
+# class Test_exec(FixerTestCase):
+# fixer = "exec"
+#
+# def test_prefix_preservation(self):
+# b = """ exec code in ns1, ns2"""
+# a = """ exec(code, ns1, ns2)"""
+# self.check(b, a)
+#
+# def test_basic(self):
+# b = """exec code"""
+# a = """exec(code)"""
+# self.check(b, a)
+#
+# def test_with_globals(self):
+# b = """exec code in ns"""
+# a = """exec(code, ns)"""
+# self.check(b, a)
+#
+# def test_with_globals_locals(self):
+# b = """exec code in ns1, ns2"""
+# a = """exec(code, ns1, ns2)"""
+# self.check(b, a)
+#
+# def test_complex_1(self):
+# b = """exec (a.b()) in ns"""
+# a = """exec((a.b()), ns)"""
+# self.check(b, a)
+#
+# def test_complex_2(self):
+# b = """exec a.b() + c in ns"""
+# a = """exec(a.b() + c, ns)"""
+# self.check(b, a)
+#
+# # These should not be touched
+#
+# def test_unchanged_1(self):
+# s = """exec(code)"""
+# self.unchanged(s)
+#
+# def test_unchanged_2(self):
+# s = """exec (code)"""
+# self.unchanged(s)
+#
+# def test_unchanged_3(self):
+# s = """exec(code, ns)"""
+# self.unchanged(s)
+#
+# def test_unchanged_4(self):
+# s = """exec(code, ns1, ns2)"""
+# self.unchanged(s)
+#
+# class Test_repr(FixerTestCase):
+# fixer = "repr"
+#
+# def test_prefix_preservation(self):
+# b = """x = `1 + 2`"""
+# a = """x = repr(1 + 2)"""
+# self.check(b, a)
+#
+# def test_simple_1(self):
+# b = """x = `1 + 2`"""
+# a = """x = repr(1 + 2)"""
+# self.check(b, a)
+#
+# def test_simple_2(self):
+# b = """y = `x`"""
+# a = """y = repr(x)"""
+# self.check(b, a)
+#
+# def test_complex(self):
+# b = """z = `y`.__repr__()"""
+# a = """z = repr(y).__repr__()"""
+# self.check(b, a)
+#
+# def test_tuple(self):
+# b = """x = `1, 2, 3`"""
+# a = """x = repr((1, 2, 3))"""
+# self.check(b, a)
+#
+# def test_nested(self):
+# b = """x = `1 + `2``"""
+# a = """x = repr(1 + repr(2))"""
+# self.check(b, a)
+#
+# def test_nested_tuples(self):
+# b = """x = `1, 2 + `3, 4``"""
+# a = """x = repr((1, 2 + repr((3, 4))))"""
+# self.check(b, a)
+#
+# class Test_except(FixerTestCase):
+# fixer = "except"
+#
+# def test_prefix_preservation(self):
+# b = """
+# try:
+# pass
+# except (RuntimeError, ImportError), e:
+# pass"""
+# a = """
+# try:
+# pass
+# except (RuntimeError, ImportError) as e:
+# pass"""
+# self.check(b, a)
+#
+# def test_simple(self):
+# b = """
+# try:
+# pass
+# except Foo, e:
+# pass"""
+# a = """
+# try:
+# pass
+# except Foo as e:
+# pass"""
+# self.check(b, a)
+#
+# def test_simple_no_space_before_target(self):
+# b = """
+# try:
+# pass
+# except Foo,e:
+# pass"""
+# a = """
+# try:
+# pass
+# except Foo as e:
+# pass"""
+# self.check(b, a)
+#
+# def test_tuple_unpack(self):
+# b = """
+# def foo():
+# try:
+# pass
+# except Exception, (f, e):
+# pass
+# except ImportError, e:
+# pass"""
+#
+# a = """
+# def foo():
+# try:
+# pass
+# except Exception as xxx_todo_changeme:
+# (f, e) = xxx_todo_changeme.args
+# pass
+# except ImportError as e:
+# pass"""
+# self.check(b, a)
+#
+# def test_multi_class(self):
+# b = """
+# try:
+# pass
+# except (RuntimeError, ImportError), e:
+# pass"""
+#
+# a = """
+# try:
+# pass
+# except (RuntimeError, ImportError) as e:
+# pass"""
+# self.check(b, a)
+#
+# def test_list_unpack(self):
+# b = """
+# try:
+# pass
+# except Exception, [a, b]:
+# pass"""
+#
+# a = """
+# try:
+# pass
+# except Exception as xxx_todo_changeme:
+# [a, b] = xxx_todo_changeme.args
+# pass"""
+# self.check(b, a)
+#
+# def test_weird_target_1(self):
+# b = """
+# try:
+# pass
+# except Exception, d[5]:
+# pass"""
+#
+# a = """
+# try:
+# pass
+# except Exception as xxx_todo_changeme:
+# d[5] = xxx_todo_changeme
+# pass"""
+# self.check(b, a)
+#
+# def test_weird_target_2(self):
+# b = """
+# try:
+# pass
+# except Exception, a.foo:
+# pass"""
+#
+# a = """
+# try:
+# pass
+# except Exception as xxx_todo_changeme:
+# a.foo = xxx_todo_changeme
+# pass"""
+# self.check(b, a)
+#
+# def test_weird_target_3(self):
+# b = """
+# try:
+# pass
+# except Exception, a().foo:
+# pass"""
+#
+# a = """
+# try:
+# pass
+# except Exception as xxx_todo_changeme:
+# a().foo = xxx_todo_changeme
+# pass"""
+# self.check(b, a)
+#
+# def test_bare_except(self):
+# b = """
+# try:
+# pass
+# except Exception, a:
+# pass
+# except:
+# pass"""
+#
+# a = """
+# try:
+# pass
+# except Exception as a:
+# pass
+# except:
+# pass"""
+# self.check(b, a)
+#
+# def test_bare_except_and_else_finally(self):
+# b = """
+# try:
+# pass
+# except Exception, a:
+# pass
+# except:
+# pass
+# else:
+# pass
+# finally:
+# pass"""
+#
+# a = """
+# try:
+# pass
+# except Exception as a:
+# pass
+# except:
+# pass
+# else:
+# pass
+# finally:
+# pass"""
+# self.check(b, a)
+#
+# def test_multi_fixed_excepts_before_bare_except(self):
+# b = """
+# try:
+# pass
+# except TypeError, b:
+# pass
+# except Exception, a:
+# pass
+# except:
+# pass"""
+#
+# a = """
+# try:
+# pass
+# except TypeError as b:
+# pass
+# except Exception as a:
+# pass
+# except:
+# pass"""
+# self.check(b, a)
+#
+# def test_one_line_suites(self):
+# b = """
+# try: raise TypeError
+# except TypeError, e:
+# pass
+# """
+# a = """
+# try: raise TypeError
+# except TypeError as e:
+# pass
+# """
+# self.check(b, a)
+# b = """
+# try:
+# raise TypeError
+# except TypeError, e: pass
+# """
+# a = """
+# try:
+# raise TypeError
+# except TypeError as e: pass
+# """
+# self.check(b, a)
+# b = """
+# try: raise TypeError
+# except TypeError, e: pass
+# """
+# a = """
+# try: raise TypeError
+# except TypeError as e: pass
+# """
+# self.check(b, a)
+# b = """
+# try: raise TypeError
+# except TypeError, e: pass
+# else: function()
+# finally: done()
+# """
+# a = """
+# try: raise TypeError
+# except TypeError as e: pass
+# else: function()
+# finally: done()
+# """
+# self.check(b, a)
+#
+# # These should not be touched:
+#
+# def test_unchanged_1(self):
+# s = """
+# try:
+# pass
+# except:
+# pass"""
+# self.unchanged(s)
+#
+# def test_unchanged_2(self):
+# s = """
+# try:
+# pass
+# except Exception:
+# pass"""
+# self.unchanged(s)
+#
+# def test_unchanged_3(self):
+# s = """
+# try:
+# pass
+# except (Exception, SystemExit):
+# pass"""
+# self.unchanged(s)
+
+class Test_raise(FixerTestCase):
+ fixer = "raise"
+
+ def test_basic(self):
+ b = """raise Exception, 5"""
+ a = """raise Exception(5)"""
+ self.check(b, a)
+
+ def test_prefix_preservation(self):
+ b = """raise Exception,5"""
+ a = """raise Exception(5)"""
+ self.check(b, a)
+
+ b = """raise Exception, 5"""
+ a = """raise Exception(5)"""
+ self.check(b, a)
+
+ def test_with_comments(self):
+ b = """raise Exception, 5 # foo"""
+ a = """raise Exception(5) # foo"""
+ self.check(b, a)
+
+ b = """def foo():
+ raise Exception, 5, 6 # foo"""
+ a = """def foo():
+ raise Exception(5).with_traceback(6) # foo"""
+ self.check(b, a)
+
+ def test_None_value(self):
+ b = """raise Exception(5), None, tb"""
+ a = """raise Exception(5).with_traceback(tb)"""
+ self.check(b, a)
+
+ def test_tuple_value(self):
+ b = """raise Exception, (5, 6, 7)"""
+ a = """raise Exception(5, 6, 7)"""
+ self.check(b, a)
+
+ def test_tuple_exc_1(self):
+ b = """raise (((E1, E2), E3), E4), 5"""
+ a = """raise E1(5)"""
+ self.check(b, a)
+
+ def test_tuple_exc_2(self):
+ b = """raise (E1, (E2, E3), E4), 5"""
+ a = """raise E1(5)"""
+ self.check(b, a)
+
+ def test_unknown_value(self):
+ b = """
+ raise E, V"""
+ a = """
+ from future.utils import raise_
+ raise_(E, V)"""
+ self.check(b, a)
+
+ def test_unknown_value_with_traceback_with_comments(self):
+ b = """
+ raise E, Func(arg1, arg2, arg3), tb # foo"""
+ a = """
+ from future.utils import raise_
+ raise_(E, Func(arg1, arg2, arg3), tb) # foo"""
+ self.check(b, a)
+
+ # These should produce a warning
+
+ def test_string_exc(self):
+ s = """raise 'foo'"""
+ self.warns_unchanged(s, "Python 3 does not support string exceptions")
+
+ def test_string_exc_val(self):
+ s = """raise "foo", 5"""
+ self.warns_unchanged(s, "Python 3 does not support string exceptions")
+
+ def test_string_exc_val_tb(self):
+ s = """raise "foo", 5, 6"""
+ self.warns_unchanged(s, "Python 3 does not support string exceptions")
+
+ # These should result in traceback-assignment
+
+ def test_tb_1(self):
+ b = """def foo():
+ raise Exception, 5, 6"""
+ a = """def foo():
+ raise Exception(5).with_traceback(6)"""
+ self.check(b, a)
+
+ def test_tb_2(self):
+ b = """def foo():
+ a = 5
+ raise Exception, 5, 6
+ b = 6"""
+ a = """def foo():
+ a = 5
+ raise Exception(5).with_traceback(6)
+ b = 6"""
+ self.check(b, a)
+
+ def test_tb_3(self):
+ b = """def foo():
+ raise Exception,5,6"""
+ a = """def foo():
+ raise Exception(5).with_traceback(6)"""
+ self.check(b, a)
+
+ def test_tb_4(self):
+ b = """def foo():
+ a = 5
+ raise Exception,5,6
+ b = 6"""
+ a = """def foo():
+ a = 5
+ raise Exception(5).with_traceback(6)
+ b = 6"""
+ self.check(b, a)
+
+ def test_tb_5(self):
+ b = """def foo():
+ raise Exception, (5, 6, 7), 6"""
+ a = """def foo():
+ raise Exception(5, 6, 7).with_traceback(6)"""
+ self.check(b, a)
+
+ def test_tb_6(self):
+ b = """def foo():
+ a = 5
+ raise Exception, (5, 6, 7), 6
+ b = 6"""
+ a = """def foo():
+ a = 5
+ raise Exception(5, 6, 7).with_traceback(6)
+ b = 6"""
+ self.check(b, a)
+#
+# class Test_throw(FixerTestCase):
+# fixer = "throw"
+#
+# def test_1(self):
+# b = """g.throw(Exception, 5)"""
+# a = """g.throw(Exception(5))"""
+# self.check(b, a)
+#
+# def test_2(self):
+# b = """g.throw(Exception,5)"""
+# a = """g.throw(Exception(5))"""
+# self.check(b, a)
+#
+# def test_3(self):
+# b = """g.throw(Exception, (5, 6, 7))"""
+# a = """g.throw(Exception(5, 6, 7))"""
+# self.check(b, a)
+#
+# def test_4(self):
+# b = """5 + g.throw(Exception, 5)"""
+# a = """5 + g.throw(Exception(5))"""
+# self.check(b, a)
+#
+# # These should produce warnings
+#
+# def test_warn_1(self):
+# s = """g.throw("foo")"""
+# self.warns_unchanged(s, "Python 3 does not support string exceptions")
+#
+# def test_warn_2(self):
+# s = """g.throw("foo", 5)"""
+# self.warns_unchanged(s, "Python 3 does not support string exceptions")
+#
+# def test_warn_3(self):
+# s = """g.throw("foo", 5, 6)"""
+# self.warns_unchanged(s, "Python 3 does not support string exceptions")
+#
+# # These should not be touched
+#
+# def test_untouched_1(self):
+# s = """g.throw(Exception)"""
+# self.unchanged(s)
+#
+# def test_untouched_2(self):
+# s = """g.throw(Exception(5, 6))"""
+# self.unchanged(s)
+#
+# def test_untouched_3(self):
+# s = """5 + g.throw(Exception(5, 6))"""
+# self.unchanged(s)
+#
+# # These should result in traceback-assignment
+#
+# def test_tb_1(self):
+# b = """def foo():
+# g.throw(Exception, 5, 6)"""
+# a = """def foo():
+# g.throw(Exception(5).with_traceback(6))"""
+# self.check(b, a)
+#
+# def test_tb_2(self):
+# b = """def foo():
+# a = 5
+# g.throw(Exception, 5, 6)
+# b = 6"""
+# a = """def foo():
+# a = 5
+# g.throw(Exception(5).with_traceback(6))
+# b = 6"""
+# self.check(b, a)
+#
+# def test_tb_3(self):
+# b = """def foo():
+# g.throw(Exception,5,6)"""
+# a = """def foo():
+# g.throw(Exception(5).with_traceback(6))"""
+# self.check(b, a)
+#
+# def test_tb_4(self):
+# b = """def foo():
+# a = 5
+# g.throw(Exception,5,6)
+# b = 6"""
+# a = """def foo():
+# a = 5
+# g.throw(Exception(5).with_traceback(6))
+# b = 6"""
+# self.check(b, a)
+#
+# def test_tb_5(self):
+# b = """def foo():
+# g.throw(Exception, (5, 6, 7), 6)"""
+# a = """def foo():
+# g.throw(Exception(5, 6, 7).with_traceback(6))"""
+# self.check(b, a)
+#
+# def test_tb_6(self):
+# b = """def foo():
+# a = 5
+# g.throw(Exception, (5, 6, 7), 6)
+# b = 6"""
+# a = """def foo():
+# a = 5
+# g.throw(Exception(5, 6, 7).with_traceback(6))
+# b = 6"""
+# self.check(b, a)
+#
+# def test_tb_7(self):
+# b = """def foo():
+# a + g.throw(Exception, 5, 6)"""
+# a = """def foo():
+# a + g.throw(Exception(5).with_traceback(6))"""
+# self.check(b, a)
+#
+# def test_tb_8(self):
+# b = """def foo():
+# a = 5
+# a + g.throw(Exception, 5, 6)
+# b = 6"""
+# a = """def foo():
+# a = 5
+# a + g.throw(Exception(5).with_traceback(6))
+# b = 6"""
+# self.check(b, a)
+#
+# class Test_long(FixerTestCase):
+# fixer = "long"
+#
+# def test_1(self):
+# b = """x = long(x)"""
+# a = """x = int(x)"""
+# self.check(b, a)
+#
+# def test_2(self):
+# b = """y = isinstance(x, long)"""
+# a = """y = isinstance(x, int)"""
+# self.check(b, a)
+#
+# def test_3(self):
+# b = """z = type(x) in (int, long)"""
+# a = """z = type(x) in (int, int)"""
+# self.check(b, a)
+#
+# def test_unchanged(self):
+# s = """long = True"""
+# self.unchanged(s)
+#
+# s = """s.long = True"""
+# self.unchanged(s)
+#
+# s = """def long(): pass"""
+# self.unchanged(s)
+#
+# s = """class long(): pass"""
+# self.unchanged(s)
+#
+# s = """def f(long): pass"""
+# self.unchanged(s)
+#
+# s = """def f(g, long): pass"""
+# self.unchanged(s)
+#
+# s = """def f(x, long=True): pass"""
+# self.unchanged(s)
+#
+# def test_prefix_preservation(self):
+# b = """x = long( x )"""
+# a = """x = int( x )"""
+# self.check(b, a)
+#
+#
+# class Test_execfile(FixerTestCase):
+# fixer = "execfile"
+#
+# def test_conversion(self):
+# b = """execfile("fn")"""
+# a = """exec(compile(open("fn").read(), "fn", 'exec'))"""
+# self.check(b, a)
+#
+# b = """execfile("fn", glob)"""
+# a = """exec(compile(open("fn").read(), "fn", 'exec'), glob)"""
+# self.check(b, a)
+#
+# b = """execfile("fn", glob, loc)"""
+# a = """exec(compile(open("fn").read(), "fn", 'exec'), glob, loc)"""
+# self.check(b, a)
+#
+# b = """execfile("fn", globals=glob)"""
+# a = """exec(compile(open("fn").read(), "fn", 'exec'), globals=glob)"""
+# self.check(b, a)
+#
+# b = """execfile("fn", locals=loc)"""
+# a = """exec(compile(open("fn").read(), "fn", 'exec'), locals=loc)"""
+# self.check(b, a)
+#
+# b = """execfile("fn", globals=glob, locals=loc)"""
+# a = """exec(compile(open("fn").read(), "fn", 'exec'), globals=glob, locals=loc)"""
+# self.check(b, a)
+#
+# def test_spacing(self):
+# b = """execfile( "fn" )"""
+# a = """exec(compile(open( "fn" ).read(), "fn", 'exec'))"""
+# self.check(b, a)
+#
+# b = """execfile("fn", globals = glob)"""
+# a = """exec(compile(open("fn").read(), "fn", 'exec'), globals = glob)"""
+# self.check(b, a)
+#
+#
+# class Test_isinstance(FixerTestCase):
+# fixer = "isinstance"
+#
+# def test_remove_multiple_items(self):
+# b = """isinstance(x, (int, int, int))"""
+# a = """isinstance(x, int)"""
+# self.check(b, a)
+#
+# b = """isinstance(x, (int, float, int, int, float))"""
+# a = """isinstance(x, (int, float))"""
+# self.check(b, a)
+#
+# b = """isinstance(x, (int, float, int, int, float, str))"""
+# a = """isinstance(x, (int, float, str))"""
+# self.check(b, a)
+#
+# b = """isinstance(foo() + bar(), (x(), y(), x(), int, int))"""
+# a = """isinstance(foo() + bar(), (x(), y(), x(), int))"""
+# self.check(b, a)
+#
+# def test_prefix_preservation(self):
+# b = """if isinstance( foo(), ( bar, bar, baz )) : pass"""
+# a = """if isinstance( foo(), ( bar, baz )) : pass"""
+# self.check(b, a)
+#
+# def test_unchanged(self):
+# self.unchanged("isinstance(x, (str, int))")
+#
+# class Test_dict(FixerTestCase):
+# fixer = "dict"
+#
+# def test_prefix_preservation(self):
+# b = "if d. keys ( ) : pass"
+# a = "if list(d. keys ( )) : pass"
+# self.check(b, a)
+#
+# b = "if d. items ( ) : pass"
+# a = "if list(d. items ( )) : pass"
+# self.check(b, a)
+#
+# b = "if d. iterkeys ( ) : pass"
+# a = "if iter(d. keys ( )) : pass"
+# self.check(b, a)
+#
+# b = "[i for i in d. iterkeys( ) ]"
+# a = "[i for i in d. keys( ) ]"
+# self.check(b, a)
+#
+# b = "if d. viewkeys ( ) : pass"
+# a = "if d. keys ( ) : pass"
+# self.check(b, a)
+#
+# b = "[i for i in d. viewkeys( ) ]"
+# a = "[i for i in d. keys( ) ]"
+# self.check(b, a)
+#
+# def test_trailing_comment(self):
+# b = "d.keys() # foo"
+# a = "list(d.keys()) # foo"
+# self.check(b, a)
+#
+# b = "d.items() # foo"
+# a = "list(d.items()) # foo"
+# self.check(b, a)
+#
+# b = "d.iterkeys() # foo"
+# a = "iter(d.keys()) # foo"
+# self.check(b, a)
+#
+# b = """[i for i in d.iterkeys() # foo
+# ]"""
+# a = """[i for i in d.keys() # foo
+# ]"""
+# self.check(b, a)
+#
+# b = """[i for i in d.iterkeys() # foo
+# ]"""
+# a = """[i for i in d.keys() # foo
+# ]"""
+# self.check(b, a)
+#
+# b = "d.viewitems() # foo"
+# a = "d.items() # foo"
+# self.check(b, a)
+#
+# def test_unchanged(self):
+# for wrapper in fixer_util.consuming_calls:
+# s = "s = %s(d.keys())" % wrapper
+# self.unchanged(s)
+#
+# s = "s = %s(d.values())" % wrapper
+# self.unchanged(s)
+#
+# s = "s = %s(d.items())" % wrapper
+# self.unchanged(s)
+#
+# def test_01(self):
+# b = "d.keys()"
+# a = "list(d.keys())"
+# self.check(b, a)
+#
+# b = "a[0].foo().keys()"
+# a = "list(a[0].foo().keys())"
+# self.check(b, a)
+#
+# def test_02(self):
+# b = "d.items()"
+# a = "list(d.items())"
+# self.check(b, a)
+#
+# def test_03(self):
+# b = "d.values()"
+# a = "list(d.values())"
+# self.check(b, a)
+#
+# def test_04(self):
+# b = "d.iterkeys()"
+# a = "iter(d.keys())"
+# self.check(b, a)
+#
+# def test_05(self):
+# b = "d.iteritems()"
+# a = "iter(d.items())"
+# self.check(b, a)
+#
+# def test_06(self):
+# b = "d.itervalues()"
+# a = "iter(d.values())"
+# self.check(b, a)
+#
+# def test_07(self):
+# s = "list(d.keys())"
+# self.unchanged(s)
+#
+# def test_08(self):
+# s = "sorted(d.keys())"
+# self.unchanged(s)
+#
+# def test_09(self):
+# b = "iter(d.keys())"
+# a = "iter(list(d.keys()))"
+# self.check(b, a)
+#
+# def test_10(self):
+# b = "foo(d.keys())"
+# a = "foo(list(d.keys()))"
+# self.check(b, a)
+#
+# def test_11(self):
+# b = "for i in d.keys(): print i"
+# a = "for i in list(d.keys()): print i"
+# self.check(b, a)
+#
+# def test_12(self):
+# b = "for i in d.iterkeys(): print i"
+# a = "for i in d.keys(): print i"
+# self.check(b, a)
+#
+# def test_13(self):
+# b = "[i for i in d.keys()]"
+# a = "[i for i in list(d.keys())]"
+# self.check(b, a)
+#
+# def test_14(self):
+# b = "[i for i in d.iterkeys()]"
+# a = "[i for i in d.keys()]"
+# self.check(b, a)
+#
+# def test_15(self):
+# b = "(i for i in d.keys())"
+# a = "(i for i in list(d.keys()))"
+# self.check(b, a)
+#
+# def test_16(self):
+# b = "(i for i in d.iterkeys())"
+# a = "(i for i in d.keys())"
+# self.check(b, a)
+#
+# def test_17(self):
+# b = "iter(d.iterkeys())"
+# a = "iter(d.keys())"
+# self.check(b, a)
+#
+# def test_18(self):
+# b = "list(d.iterkeys())"
+# a = "list(d.keys())"
+# self.check(b, a)
+#
+# def test_19(self):
+# b = "sorted(d.iterkeys())"
+# a = "sorted(d.keys())"
+# self.check(b, a)
+#
+# def test_20(self):
+# b = "foo(d.iterkeys())"
+# a = "foo(iter(d.keys()))"
+# self.check(b, a)
+#
+# def test_21(self):
+# b = "print h.iterkeys().next()"
+# a = "print iter(h.keys()).next()"
+# self.check(b, a)
+#
+# def test_22(self):
+# b = "print h.keys()[0]"
+# a = "print list(h.keys())[0]"
+# self.check(b, a)
+#
+# def test_23(self):
+# b = "print list(h.iterkeys().next())"
+# a = "print list(iter(h.keys()).next())"
+# self.check(b, a)
+#
+# def test_24(self):
+# b = "for x in h.keys()[0]: print x"
+# a = "for x in list(h.keys())[0]: print x"
+# self.check(b, a)
+#
+# def test_25(self):
+# b = "d.viewkeys()"
+# a = "d.keys()"
+# self.check(b, a)
+#
+# def test_26(self):
+# b = "d.viewitems()"
+# a = "d.items()"
+# self.check(b, a)
+#
+# def test_27(self):
+# b = "d.viewvalues()"
+# a = "d.values()"
+# self.check(b, a)
+#
+# def test_14(self):
+# b = "[i for i in d.viewkeys()]"
+# a = "[i for i in d.keys()]"
+# self.check(b, a)
+#
+# def test_15(self):
+# b = "(i for i in d.viewkeys())"
+# a = "(i for i in d.keys())"
+# self.check(b, a)
+#
+# def test_17(self):
+# b = "iter(d.viewkeys())"
+# a = "iter(d.keys())"
+# self.check(b, a)
+#
+# def test_18(self):
+# b = "list(d.viewkeys())"
+# a = "list(d.keys())"
+# self.check(b, a)
+#
+# def test_19(self):
+# b = "sorted(d.viewkeys())"
+# a = "sorted(d.keys())"
+# self.check(b, a)
+#
+# class Test_xrange(FixerTestCase):
+# fixer = "xrange"
+#
+# def test_prefix_preservation(self):
+# b = """x = xrange( 10 )"""
+# a = """x = range( 10 )"""
+# self.check(b, a)
+#
+# b = """x = xrange( 1 , 10 )"""
+# a = """x = range( 1 , 10 )"""
+# self.check(b, a)
+#
+# b = """x = xrange( 0 , 10 , 2 )"""
+# a = """x = range( 0 , 10 , 2 )"""
+# self.check(b, a)
+#
+# def test_single_arg(self):
+# b = """x = xrange(10)"""
+# a = """x = range(10)"""
+# self.check(b, a)
+#
+# def test_two_args(self):
+# b = """x = xrange(1, 10)"""
+# a = """x = range(1, 10)"""
+# self.check(b, a)
+#
+# def test_three_args(self):
+# b = """x = xrange(0, 10, 2)"""
+# a = """x = range(0, 10, 2)"""
+# self.check(b, a)
+#
+# def test_wrap_in_list(self):
+# b = """x = range(10, 3, 9)"""
+# a = """x = list(range(10, 3, 9))"""
+# self.check(b, a)
+#
+# b = """x = foo(range(10, 3, 9))"""
+# a = """x = foo(list(range(10, 3, 9)))"""
+# self.check(b, a)
+#
+# b = """x = range(10, 3, 9) + [4]"""
+# a = """x = list(range(10, 3, 9)) + [4]"""
+# self.check(b, a)
+#
+# b = """x = range(10)[::-1]"""
+# a = """x = list(range(10))[::-1]"""
+# self.check(b, a)
+#
+# b = """x = range(10) [3]"""
+# a = """x = list(range(10)) [3]"""
+# self.check(b, a)
+#
+# def test_xrange_in_for(self):
+# b = """for i in xrange(10):\n j=i"""
+# a = """for i in range(10):\n j=i"""
+# self.check(b, a)
+#
+# b = """[i for i in xrange(10)]"""
+# a = """[i for i in range(10)]"""
+# self.check(b, a)
+#
+# def test_range_in_for(self):
+# self.unchanged("for i in range(10): pass")
+# self.unchanged("[i for i in range(10)]")
+#
+# def test_in_contains_test(self):
+# self.unchanged("x in range(10, 3, 9)")
+#
+# def test_in_consuming_context(self):
+# for call in fixer_util.consuming_calls:
+# self.unchanged("a = %s(range(10))" % call)
+#
+# class Test_xrange_with_reduce(FixerTestCase):
+#
+# def setUp(self):
+# super(Test_xrange_with_reduce, self).setUp(["xrange", "reduce"])
+#
+# def test_double_transform(self):
+# b = """reduce(x, xrange(5))"""
+# a = """from functools import reduce
+# reduce(x, range(5))"""
+# self.check(b, a)
+#
+# class Test_raw_input(FixerTestCase):
+# fixer = "raw_input"
+#
+# def test_prefix_preservation(self):
+# b = """x = raw_input( )"""
+# a = """x = input( )"""
+# self.check(b, a)
+#
+# b = """x = raw_input( '' )"""
+# a = """x = input( '' )"""
+# self.check(b, a)
+#
+# def test_1(self):
+# b = """x = raw_input()"""
+# a = """x = input()"""
+# self.check(b, a)
+#
+# def test_2(self):
+# b = """x = raw_input('')"""
+# a = """x = input('')"""
+# self.check(b, a)
+#
+# def test_3(self):
+# b = """x = raw_input('prompt')"""
+# a = """x = input('prompt')"""
+# self.check(b, a)
+#
+# def test_4(self):
+# b = """x = raw_input(foo(a) + 6)"""
+# a = """x = input(foo(a) + 6)"""
+# self.check(b, a)
+#
+# def test_5(self):
+# b = """x = raw_input(invite).split()"""
+# a = """x = input(invite).split()"""
+# self.check(b, a)
+#
+# def test_6(self):
+# b = """x = raw_input(invite) . split ()"""
+# a = """x = input(invite) . split ()"""
+# self.check(b, a)
+#
+# def test_8(self):
+# b = "x = int(raw_input())"
+# a = "x = int(input())"
+# self.check(b, a)
+#
+# class Test_funcattrs(FixerTestCase):
+# fixer = "funcattrs"
+#
+# attrs = ["closure", "doc", "name", "defaults", "code", "globals", "dict"]
+#
+# def test(self):
+# for attr in self.attrs:
+# b = "a.func_%s" % attr
+# a = "a.__%s__" % attr
+# self.check(b, a)
+#
+# b = "self.foo.func_%s.foo_bar" % attr
+# a = "self.foo.__%s__.foo_bar" % attr
+# self.check(b, a)
+#
+# def test_unchanged(self):
+# for attr in self.attrs:
+# s = "foo(func_%s + 5)" % attr
+# self.unchanged(s)
+#
+# s = "f(foo.__%s__)" % attr
+# self.unchanged(s)
+#
+# s = "f(foo.__%s__.foo)" % attr
+# self.unchanged(s)
+#
+# class Test_xreadlines(FixerTestCase):
+# fixer = "xreadlines"
+#
+# def test_call(self):
+# b = "for x in f.xreadlines(): pass"
+# a = "for x in f: pass"
+# self.check(b, a)
+#
+# b = "for x in foo().xreadlines(): pass"
+# a = "for x in foo(): pass"
+# self.check(b, a)
+#
+# b = "for x in (5 + foo()).xreadlines(): pass"
+# a = "for x in (5 + foo()): pass"
+# self.check(b, a)
+#
+# def test_attr_ref(self):
+# b = "foo(f.xreadlines + 5)"
+# a = "foo(f.__iter__ + 5)"
+# self.check(b, a)
+#
+# b = "foo(f().xreadlines + 5)"
+# a = "foo(f().__iter__ + 5)"
+# self.check(b, a)
+#
+# b = "foo((5 + f()).xreadlines + 5)"
+# a = "foo((5 + f()).__iter__ + 5)"
+# self.check(b, a)
+#
+# def test_unchanged(self):
+# s = "for x in f.xreadlines(5): pass"
+# self.unchanged(s)
+#
+# s = "for x in f.xreadlines(k=5): pass"
+# self.unchanged(s)
+#
+# s = "for x in f.xreadlines(*k, **v): pass"
+# self.unchanged(s)
+#
+# s = "foo(xreadlines)"
+# self.unchanged(s)
+#
+#
+# class ImportsFixerTests:
+#
+# def test_import_module(self):
+# for old, new in self.modules.items():
+# b = "import %s" % old
+# a = "import %s" % new
+# self.check(b, a)
+#
+# b = "import foo, %s, bar" % old
+# a = "import foo, %s, bar" % new
+# self.check(b, a)
+#
+# def test_import_from(self):
+# for old, new in self.modules.items():
+# b = "from %s import foo" % old
+# a = "from %s import foo" % new
+# self.check(b, a)
+#
+# b = "from %s import foo, bar" % old
+# a = "from %s import foo, bar" % new
+# self.check(b, a)
+#
+# b = "from %s import (yes, no)" % old
+# a = "from %s import (yes, no)" % new
+# self.check(b, a)
+#
+# def test_import_module_as(self):
+# for old, new in self.modules.items():
+# b = "import %s as foo_bar" % old
+# a = "import %s as foo_bar" % new
+# self.check(b, a)
+#
+# b = "import %s as foo_bar" % old
+# a = "import %s as foo_bar" % new
+# self.check(b, a)
+#
+# def test_import_from_as(self):
+# for old, new in self.modules.items():
+# b = "from %s import foo as bar" % old
+# a = "from %s import foo as bar" % new
+# self.check(b, a)
+#
+# def test_star(self):
+# for old, new in self.modules.items():
+# b = "from %s import *" % old
+# a = "from %s import *" % new
+# self.check(b, a)
+#
+# def test_import_module_usage(self):
+# for old, new in self.modules.items():
+# b = """
+# import %s
+# foo(%s.bar)
+# """ % (old, old)
+# a = """
+# import %s
+# foo(%s.bar)
+# """ % (new, new)
+# self.check(b, a)
+#
+# b = """
+# from %s import x
+# %s = 23
+# """ % (old, old)
+# a = """
+# from %s import x
+# %s = 23
+# """ % (new, old)
+# self.check(b, a)
+#
+# s = """
+# def f():
+# %s.method()
+# """ % (old,)
+# self.unchanged(s)
+#
+# # test nested usage
+# b = """
+# import %s
+# %s.bar(%s.foo)
+# """ % (old, old, old)
+# a = """
+# import %s
+# %s.bar(%s.foo)
+# """ % (new, new, new)
+# self.check(b, a)
+#
+# b = """
+# import %s
+# x.%s
+# """ % (old, old)
+# a = """
+# import %s
+# x.%s
+# """ % (new, old)
+# self.check(b, a)
+#
+#
+# class Test_imports(FixerTestCase, ImportsFixerTests):
+# fixer = "imports"
+#
+# def test_multiple_imports(self):
+# b = """import urlparse, cStringIO"""
+# a = """import urllib.parse, io"""
+# self.check(b, a)
+#
+# def test_multiple_imports_as(self):
+# b = """
+# import copy_reg as bar, HTMLParser as foo, urlparse
+# s = urlparse.spam(bar.foo())
+# """
+# a = """
+# import copyreg as bar, html.parser as foo, urllib.parse
+# s = urllib.parse.spam(bar.foo())
+# """
+# self.check(b, a)
+#
+#
+# class Test_imports2(FixerTestCase, ImportsFixerTests):
+# fixer = "imports2"
+#
+#
+# class Test_imports_fixer_order(FixerTestCase, ImportsFixerTests):
+#
+# def setUp(self):
+# super(Test_imports_fixer_order, self).setUp(['imports', 'imports2'])
+# from ..fixes.fix_imports2 import MAPPING as mapping2
+# self.modules = mapping2.copy()
+# from ..fixes.fix_imports import MAPPING as mapping1
+# for key in ('dbhash', 'dumbdbm', 'dbm', 'gdbm'):
+# self.modules[key] = mapping1[key]
+#
+# def test_after_local_imports_refactoring(self):
+# for fix in ("imports", "imports2"):
+# self.fixer = fix
+# self.assert_runs_after("import")
+#
+#
+# class Test_urllib(FixerTestCase):
+# fixer = "urllib"
+# from ..fixes.fix_urllib import MAPPING as modules
+#
+# def test_import_module(self):
+# for old, changes in self.modules.items():
+# b = "import %s" % old
+# a = "import %s" % ", ".join(map(itemgetter(0), changes))
+# self.check(b, a)
+#
+# def test_import_from(self):
+# for old, changes in self.modules.items():
+# all_members = []
+# for new, members in changes:
+# for member in members:
+# all_members.append(member)
+# b = "from %s import %s" % (old, member)
+# a = "from %s import %s" % (new, member)
+# self.check(b, a)
+#
+# s = "from foo import %s" % member
+# self.unchanged(s)
+#
+# b = "from %s import %s" % (old, ", ".join(members))
+# a = "from %s import %s" % (new, ", ".join(members))
+# self.check(b, a)
+#
+# s = "from foo import %s" % ", ".join(members)
+# self.unchanged(s)
+#
+# # test the breaking of a module into multiple replacements
+# b = "from %s import %s" % (old, ", ".join(all_members))
+# a = "\n".join(["from %s import %s" % (new, ", ".join(members))
+# for (new, members) in changes])
+# self.check(b, a)
+#
+# def test_import_module_as(self):
+# for old in self.modules:
+# s = "import %s as foo" % old
+# self.warns_unchanged(s, "This module is now multiple modules")
+#
+# def test_import_from_as(self):
+# for old, changes in self.modules.items():
+# for new, members in changes:
+# for member in members:
+# b = "from %s import %s as foo_bar" % (old, member)
+# a = "from %s import %s as foo_bar" % (new, member)
+# self.check(b, a)
+# b = "from %s import %s as blah, %s" % (old, member, member)
+# a = "from %s import %s as blah, %s" % (new, member, member)
+# self.check(b, a)
+#
+# def test_star(self):
+# for old in self.modules:
+# s = "from %s import *" % old
+# self.warns_unchanged(s, "Cannot handle star imports")
+#
+# def test_indented(self):
+# b = """
+# def foo():
+# from urllib import urlencode, urlopen
+# """
+# a = """
+# def foo():
+# from urllib.parse import urlencode
+# from urllib.request import urlopen
+# """
+# self.check(b, a)
+#
+# b = """
+# def foo():
+# other()
+# from urllib import urlencode, urlopen
+# """
+# a = """
+# def foo():
+# other()
+# from urllib.parse import urlencode
+# from urllib.request import urlopen
+# """
+# self.check(b, a)
+#
+#
+#
+# def test_import_module_usage(self):
+# for old, changes in self.modules.items():
+# for new, members in changes:
+# for member in members:
+# new_import = ", ".join([n for (n, mems)
+# in self.modules[old]])
+# b = """
+# import %s
+# foo(%s.%s)
+# """ % (old, old, member)
+# a = """
+# import %s
+# foo(%s.%s)
+# """ % (new_import, new, member)
+# self.check(b, a)
+# b = """
+# import %s
+# %s.%s(%s.%s)
+# """ % (old, old, member, old, member)
+# a = """
+# import %s
+# %s.%s(%s.%s)
+# """ % (new_import, new, member, new, member)
+# self.check(b, a)
+#
+#
+# class Test_input(FixerTestCase):
+# fixer = "input"
+#
+# def test_prefix_preservation(self):
+# b = """x = input( )"""
+# a = """x = eval(input( ))"""
+# self.check(b, a)
+#
+# b = """x = input( '' )"""
+# a = """x = eval(input( '' ))"""
+# self.check(b, a)
+#
+# def test_trailing_comment(self):
+# b = """x = input() # foo"""
+# a = """x = eval(input()) # foo"""
+# self.check(b, a)
+#
+# def test_idempotency(self):
+# s = """x = eval(input())"""
+# self.unchanged(s)
+#
+# s = """x = eval(input(''))"""
+# self.unchanged(s)
+#
+# s = """x = eval(input(foo(5) + 9))"""
+# self.unchanged(s)
+#
+# def test_1(self):
+# b = """x = input()"""
+# a = """x = eval(input())"""
+# self.check(b, a)
+#
+# def test_2(self):
+# b = """x = input('')"""
+# a = """x = eval(input(''))"""
+# self.check(b, a)
+#
+# def test_3(self):
+# b = """x = input('prompt')"""
+# a = """x = eval(input('prompt'))"""
+# self.check(b, a)
+#
+# def test_4(self):
+# b = """x = input(foo(5) + 9)"""
+# a = """x = eval(input(foo(5) + 9))"""
+# self.check(b, a)
+#
+# class Test_tuple_params(FixerTestCase):
+# fixer = "tuple_params"
+#
+# def test_unchanged_1(self):
+# s = """def foo(): pass"""
+# self.unchanged(s)
+#
+# def test_unchanged_2(self):
+# s = """def foo(a, b, c): pass"""
+# self.unchanged(s)
+#
+# def test_unchanged_3(self):
+# s = """def foo(a=3, b=4, c=5): pass"""
+# self.unchanged(s)
+#
+# def test_1(self):
+# b = """
+# def foo(((a, b), c)):
+# x = 5"""
+#
+# a = """
+# def foo(xxx_todo_changeme):
+# ((a, b), c) = xxx_todo_changeme
+# x = 5"""
+# self.check(b, a)
+#
+# def test_2(self):
+# b = """
+# def foo(((a, b), c), d):
+# x = 5"""
+#
+# a = """
+# def foo(xxx_todo_changeme, d):
+# ((a, b), c) = xxx_todo_changeme
+# x = 5"""
+# self.check(b, a)
+#
+# def test_3(self):
+# b = """
+# def foo(((a, b), c), d) -> e:
+# x = 5"""
+#
+# a = """
+# def foo(xxx_todo_changeme, d) -> e:
+# ((a, b), c) = xxx_todo_changeme
+# x = 5"""
+# self.check(b, a)
+#
+# def test_semicolon(self):
+# b = """
+# def foo(((a, b), c)): x = 5; y = 7"""
+#
+# a = """
+# def foo(xxx_todo_changeme): ((a, b), c) = xxx_todo_changeme; x = 5; y = 7"""
+# self.check(b, a)
+#
+# def test_keywords(self):
+# b = """
+# def foo(((a, b), c), d, e=5) -> z:
+# x = 5"""
+#
+# a = """
+# def foo(xxx_todo_changeme, d, e=5) -> z:
+# ((a, b), c) = xxx_todo_changeme
+# x = 5"""
+# self.check(b, a)
+#
+# def test_varargs(self):
+# b = """
+# def foo(((a, b), c), d, *vargs, **kwargs) -> z:
+# x = 5"""
+#
+# a = """
+# def foo(xxx_todo_changeme, d, *vargs, **kwargs) -> z:
+# ((a, b), c) = xxx_todo_changeme
+# x = 5"""
+# self.check(b, a)
+#
+# def test_multi_1(self):
+# b = """
+# def foo(((a, b), c), (d, e, f)) -> z:
+# x = 5"""
+#
+# a = """
+# def foo(xxx_todo_changeme, xxx_todo_changeme1) -> z:
+# ((a, b), c) = xxx_todo_changeme
+# (d, e, f) = xxx_todo_changeme1
+# x = 5"""
+# self.check(b, a)
+#
+# def test_multi_2(self):
+# b = """
+# def foo(x, ((a, b), c), d, (e, f, g), y) -> z:
+# x = 5"""
+#
+# a = """
+# def foo(x, xxx_todo_changeme, d, xxx_todo_changeme1, y) -> z:
+# ((a, b), c) = xxx_todo_changeme
+# (e, f, g) = xxx_todo_changeme1
+# x = 5"""
+# self.check(b, a)
+#
+# def test_docstring(self):
+# b = """
+# def foo(((a, b), c), (d, e, f)) -> z:
+# "foo foo foo foo"
+# x = 5"""
+#
+# a = """
+# def foo(xxx_todo_changeme, xxx_todo_changeme1) -> z:
+# "foo foo foo foo"
+# ((a, b), c) = xxx_todo_changeme
+# (d, e, f) = xxx_todo_changeme1
+# x = 5"""
+# self.check(b, a)
+#
+# def test_lambda_no_change(self):
+# s = """lambda x: x + 5"""
+# self.unchanged(s)
+#
+# def test_lambda_parens_single_arg(self):
+# b = """lambda (x): x + 5"""
+# a = """lambda x: x + 5"""
+# self.check(b, a)
+#
+# b = """lambda(x): x + 5"""
+# a = """lambda x: x + 5"""
+# self.check(b, a)
+#
+# b = """lambda ((((x)))): x + 5"""
+# a = """lambda x: x + 5"""
+# self.check(b, a)
+#
+# b = """lambda((((x)))): x + 5"""
+# a = """lambda x: x + 5"""
+# self.check(b, a)
+#
+# def test_lambda_simple(self):
+# b = """lambda (x, y): x + f(y)"""
+# a = """lambda x_y: x_y[0] + f(x_y[1])"""
+# self.check(b, a)
+#
+# b = """lambda(x, y): x + f(y)"""
+# a = """lambda x_y: x_y[0] + f(x_y[1])"""
+# self.check(b, a)
+#
+# b = """lambda (((x, y))): x + f(y)"""
+# a = """lambda x_y: x_y[0] + f(x_y[1])"""
+# self.check(b, a)
+#
+# b = """lambda(((x, y))): x + f(y)"""
+# a = """lambda x_y: x_y[0] + f(x_y[1])"""
+# self.check(b, a)
+#
+# def test_lambda_one_tuple(self):
+# b = """lambda (x,): x + f(x)"""
+# a = """lambda x1: x1[0] + f(x1[0])"""
+# self.check(b, a)
+#
+# b = """lambda (((x,))): x + f(x)"""
+# a = """lambda x1: x1[0] + f(x1[0])"""
+# self.check(b, a)
+#
+# def test_lambda_simple_multi_use(self):
+# b = """lambda (x, y): x + x + f(x) + x"""
+# a = """lambda x_y: x_y[0] + x_y[0] + f(x_y[0]) + x_y[0]"""
+# self.check(b, a)
+#
+# def test_lambda_simple_reverse(self):
+# b = """lambda (x, y): y + x"""
+# a = """lambda x_y: x_y[1] + x_y[0]"""
+# self.check(b, a)
+#
+# def test_lambda_nested(self):
+# b = """lambda (x, (y, z)): x + y + z"""
+# a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + x_y_z[1][1]"""
+# self.check(b, a)
+#
+# b = """lambda (((x, (y, z)))): x + y + z"""
+# a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + x_y_z[1][1]"""
+# self.check(b, a)
+#
+# def test_lambda_nested_multi_use(self):
+# b = """lambda (x, (y, z)): x + y + f(y)"""
+# a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + f(x_y_z[1][0])"""
+# self.check(b, a)
+#
+# class Test_methodattrs(FixerTestCase):
+# fixer = "methodattrs"
+#
+# attrs = ["func", "self", "class"]
+#
+# def test(self):
+# for attr in self.attrs:
+# b = "a.im_%s" % attr
+# if attr == "class":
+# a = "a.__self__.__class__"
+# else:
+# a = "a.__%s__" % attr
+# self.check(b, a)
+#
+# b = "self.foo.im_%s.foo_bar" % attr
+# if attr == "class":
+# a = "self.foo.__self__.__class__.foo_bar"
+# else:
+# a = "self.foo.__%s__.foo_bar" % attr
+# self.check(b, a)
+#
+# def test_unchanged(self):
+# for attr in self.attrs:
+# s = "foo(im_%s + 5)" % attr
+# self.unchanged(s)
+#
+# s = "f(foo.__%s__)" % attr
+# self.unchanged(s)
+#
+# s = "f(foo.__%s__.foo)" % attr
+# self.unchanged(s)
+#
+# class Test_next(FixerTestCase):
+# fixer = "next"
+#
+# def test_1(self):
+# b = """it.next()"""
+# a = """next(it)"""
+# self.check(b, a)
+#
+# def test_2(self):
+# b = """a.b.c.d.next()"""
+# a = """next(a.b.c.d)"""
+# self.check(b, a)
+#
+# def test_3(self):
+# b = """(a + b).next()"""
+# a = """next((a + b))"""
+# self.check(b, a)
+#
+# def test_4(self):
+# b = """a().next()"""
+# a = """next(a())"""
+# self.check(b, a)
+#
+# def test_5(self):
+# b = """a().next() + b"""
+# a = """next(a()) + b"""
+# self.check(b, a)
+#
+# def test_6(self):
+# b = """c( a().next() + b)"""
+# a = """c( next(a()) + b)"""
+# self.check(b, a)
+#
+# def test_prefix_preservation_1(self):
+# b = """
+# for a in b:
+# foo(a)
+# a.next()
+# """
+# a = """
+# for a in b:
+# foo(a)
+# next(a)
+# """
+# self.check(b, a)
+#
+# def test_prefix_preservation_2(self):
+# b = """
+# for a in b:
+# foo(a) # abc
+# # def
+# a.next()
+# """
+# a = """
+# for a in b:
+# foo(a) # abc
+# # def
+# next(a)
+# """
+# self.check(b, a)
+#
+# def test_prefix_preservation_3(self):
+# b = """
+# next = 5
+# for a in b:
+# foo(a)
+# a.next()
+# """
+# a = """
+# next = 5
+# for a in b:
+# foo(a)
+# a.__next__()
+# """
+# self.check(b, a, ignore_warnings=True)
+#
+# def test_prefix_preservation_4(self):
+# b = """
+# next = 5
+# for a in b:
+# foo(a) # abc
+# # def
+# a.next()
+# """
+# a = """
+# next = 5
+# for a in b:
+# foo(a) # abc
+# # def
+# a.__next__()
+# """
+# self.check(b, a, ignore_warnings=True)
+#
+# def test_prefix_preservation_5(self):
+# b = """
+# next = 5
+# for a in b:
+# foo(foo(a), # abc
+# a.next())
+# """
+# a = """
+# next = 5
+# for a in b:
+# foo(foo(a), # abc
+# a.__next__())
+# """
+# self.check(b, a, ignore_warnings=True)
+#
+# def test_prefix_preservation_6(self):
+# b = """
+# for a in b:
+# foo(foo(a), # abc
+# a.next())
+# """
+# a = """
+# for a in b:
+# foo(foo(a), # abc
+# next(a))
+# """
+# self.check(b, a)
+#
+# def test_method_1(self):
+# b = """
+# class A:
+# def next(self):
+# pass
+# """
+# a = """
+# class A:
+# def __next__(self):
+# pass
+# """
+# self.check(b, a)
+#
+# def test_method_2(self):
+# b = """
+# class A(object):
+# def next(self):
+# pass
+# """
+# a = """
+# class A(object):
+# def __next__(self):
+# pass
+# """
+# self.check(b, a)
+#
+# def test_method_3(self):
+# b = """
+# class A:
+# def next(x):
+# pass
+# """
+# a = """
+# class A:
+# def __next__(x):
+# pass
+# """
+# self.check(b, a)
+#
+# def test_method_4(self):
+# b = """
+# class A:
+# def __init__(self, foo):
+# self.foo = foo
+#
+# def next(self):
+# pass
+#
+# def __iter__(self):
+# return self
+# """
+# a = """
+# class A:
+# def __init__(self, foo):
+# self.foo = foo
+#
+# def __next__(self):
+# pass
+#
+# def __iter__(self):
+# return self
+# """
+# self.check(b, a)
+#
+# def test_method_unchanged(self):
+# s = """
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.unchanged(s)
+#
+# def test_shadowing_assign_simple(self):
+# s = """
+# next = foo
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_assign_tuple_1(self):
+# s = """
+# (next, a) = foo
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_assign_tuple_2(self):
+# s = """
+# (a, (b, (next, c)), a) = foo
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_assign_list_1(self):
+# s = """
+# [next, a] = foo
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_assign_list_2(self):
+# s = """
+# [a, [b, [next, c]], a] = foo
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_builtin_assign(self):
+# s = """
+# def foo():
+# __builtin__.next = foo
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_builtin_assign_in_tuple(self):
+# s = """
+# def foo():
+# (a, __builtin__.next) = foo
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_builtin_assign_in_list(self):
+# s = """
+# def foo():
+# [a, __builtin__.next] = foo
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_assign_to_next(self):
+# s = """
+# def foo():
+# A.next = foo
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.unchanged(s)
+#
+# def test_assign_to_next_in_tuple(self):
+# s = """
+# def foo():
+# (a, A.next) = foo
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.unchanged(s)
+#
+# def test_assign_to_next_in_list(self):
+# s = """
+# def foo():
+# [a, A.next] = foo
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.unchanged(s)
+#
+# def test_shadowing_import_1(self):
+# s = """
+# import foo.bar as next
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_import_2(self):
+# s = """
+# import bar, bar.foo as next
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_import_3(self):
+# s = """
+# import bar, bar.foo as next, baz
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_import_from_1(self):
+# s = """
+# from x import next
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_import_from_2(self):
+# s = """
+# from x.a import next
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_import_from_3(self):
+# s = """
+# from x import a, next, b
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_import_from_4(self):
+# s = """
+# from x.a import a, next, b
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_funcdef_1(self):
+# s = """
+# def next(a):
+# pass
+#
+# class A:
+# def next(self, a, b):
+# pass
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_funcdef_2(self):
+# b = """
+# def next(a):
+# pass
+#
+# class A:
+# def next(self):
+# pass
+#
+# it.next()
+# """
+# a = """
+# def next(a):
+# pass
+#
+# class A:
+# def __next__(self):
+# pass
+#
+# it.__next__()
+# """
+# self.warns(b, a, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_global_1(self):
+# s = """
+# def f():
+# global next
+# next = 5
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_global_2(self):
+# s = """
+# def f():
+# global a, next, b
+# next = 5
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_for_simple(self):
+# s = """
+# for next in it():
+# pass
+#
+# b = 5
+# c = 6
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_for_tuple_1(self):
+# s = """
+# for next, b in it():
+# pass
+#
+# b = 5
+# c = 6
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_shadowing_for_tuple_2(self):
+# s = """
+# for a, (next, c), b in it():
+# pass
+#
+# b = 5
+# c = 6
+# """
+# self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+#
+# def test_noncall_access_1(self):
+# b = """gnext = g.next"""
+# a = """gnext = g.__next__"""
+# self.check(b, a)
+#
+# def test_noncall_access_2(self):
+# b = """f(g.next + 5)"""
+# a = """f(g.__next__ + 5)"""
+# self.check(b, a)
+#
+# def test_noncall_access_3(self):
+# b = """f(g().next + 5)"""
+# a = """f(g().__next__ + 5)"""
+# self.check(b, a)
+#
+# class Test_nonzero(FixerTestCase):
+# fixer = "nonzero"
+#
+# def test_1(self):
+# b = """
+# class A:
+# def __nonzero__(self):
+# pass
+# """
+# a = """
+# class A:
+# def __bool__(self):
+# pass
+# """
+# self.check(b, a)
+#
+# def test_2(self):
+# b = """
+# class A(object):
+# def __nonzero__(self):
+# pass
+# """
+# a = """
+# class A(object):
+# def __bool__(self):
+# pass
+# """
+# self.check(b, a)
+#
+# def test_unchanged_1(self):
+# s = """
+# class A(object):
+# def __bool__(self):
+# pass
+# """
+# self.unchanged(s)
+#
+# def test_unchanged_2(self):
+# s = """
+# class A(object):
+# def __nonzero__(self, a):
+# pass
+# """
+# self.unchanged(s)
+#
+# def test_unchanged_func(self):
+# s = """
+# def __nonzero__(self):
+# pass
+# """
+# self.unchanged(s)
+#
+# class Test_numliterals(FixerTestCase):
+# fixer = "numliterals"
+#
+# def test_octal_1(self):
+# b = """0755"""
+# a = """0o755"""
+# self.check(b, a)
+#
+# def test_long_int_1(self):
+# b = """a = 12L"""
+# a = """a = 12"""
+# self.check(b, a)
+#
+# def test_long_int_2(self):
+# b = """a = 12l"""
+# a = """a = 12"""
+# self.check(b, a)
+#
+# def test_long_hex(self):
+# b = """b = 0x12l"""
+# a = """b = 0x12"""
+# self.check(b, a)
+#
+# def test_comments_and_spacing(self):
+# b = """b = 0x12L"""
+# a = """b = 0x12"""
+# self.check(b, a)
+#
+# b = """b = 0755 # spam"""
+# a = """b = 0o755 # spam"""
+# self.check(b, a)
+#
+# def test_unchanged_int(self):
+# s = """5"""
+# self.unchanged(s)
+#
+# def test_unchanged_float(self):
+# s = """5.0"""
+# self.unchanged(s)
+#
+# def test_unchanged_octal(self):
+# s = """0o755"""
+# self.unchanged(s)
+#
+# def test_unchanged_hex(self):
+# s = """0xABC"""
+# self.unchanged(s)
+#
+# def test_unchanged_exp(self):
+# s = """5.0e10"""
+# self.unchanged(s)
+#
+# def test_unchanged_complex_int(self):
+# s = """5 + 4j"""
+# self.unchanged(s)
+#
+# def test_unchanged_complex_float(self):
+# s = """5.4 + 4.9j"""
+# self.unchanged(s)
+#
+# def test_unchanged_complex_bare(self):
+# s = """4j"""
+# self.unchanged(s)
+# s = """4.4j"""
+# self.unchanged(s)
+#
+# class Test_renames(FixerTestCase):
+# fixer = "renames"
+#
+# modules = {"sys": ("maxint", "maxsize"),
+# }
+#
+# def test_import_from(self):
+# for mod, (old, new) in self.modules.items():
+# b = "from %s import %s" % (mod, old)
+# a = "from %s import %s" % (mod, new)
+# self.check(b, a)
+#
+# s = "from foo import %s" % old
+# self.unchanged(s)
+#
+# def test_import_from_as(self):
+# for mod, (old, new) in self.modules.items():
+# b = "from %s import %s as foo_bar" % (mod, old)
+# a = "from %s import %s as foo_bar" % (mod, new)
+# self.check(b, a)
+#
+# def test_import_module_usage(self):
+# for mod, (old, new) in self.modules.items():
+# b = """
+# import %s
+# foo(%s, %s.%s)
+# """ % (mod, mod, mod, old)
+# a = """
+# import %s
+# foo(%s, %s.%s)
+# """ % (mod, mod, mod, new)
+# self.check(b, a)
+#
+# def XXX_test_from_import_usage(self):
+# # not implemented yet
+# for mod, (old, new) in self.modules.items():
+# b = """
+# from %s import %s
+# foo(%s, %s)
+# """ % (mod, old, mod, old)
+# a = """
+# from %s import %s
+# foo(%s, %s)
+# """ % (mod, new, mod, new)
+# self.check(b, a)
+#
+# class Test_unicode(FixerTestCase):
+# fixer = "unicode"
+#
+# def test_whitespace(self):
+# b = """unicode( x)"""
+# a = """str( x)"""
+# self.check(b, a)
+#
+# b = """ unicode(x )"""
+# a = """ str(x )"""
+# self.check(b, a)
+#
+# b = """ u'h'"""
+# a = """ 'h'"""
+# self.check(b, a)
+#
+# def test_unicode_call(self):
+# b = """unicode(x, y, z)"""
+# a = """str(x, y, z)"""
+# self.check(b, a)
+#
+# def test_unichr(self):
+# b = """unichr(u'h')"""
+# a = """chr('h')"""
+# self.check(b, a)
+#
+# def test_unicode_literal_1(self):
+# b = '''u"x"'''
+# a = '''"x"'''
+# self.check(b, a)
+#
+# def test_unicode_literal_2(self):
+# b = """ur'x'"""
+# a = """r'x'"""
+# self.check(b, a)
+#
+# def test_unicode_literal_3(self):
+# b = """UR'''x''' """
+# a = """R'''x''' """
+# self.check(b, a)
+#
+# class Test_callable(FixerTestCase):
+# fixer = "callable"
+#
+# def test_prefix_preservation(self):
+# b = """callable( x)"""
+# a = """import collections\nisinstance( x, collections.Callable)"""
+# self.check(b, a)
+#
+# b = """if callable(x): pass"""
+# a = """import collections
+# if isinstance(x, collections.Callable): pass"""
+# self.check(b, a)
+#
+# def test_callable_call(self):
+# b = """callable(x)"""
+# a = """import collections\nisinstance(x, collections.Callable)"""
+# self.check(b, a)
+#
+# def test_global_import(self):
+# b = """
+# def spam(foo):
+# callable(foo)"""[1:]
+# a = """
+# import collections
+# def spam(foo):
+# isinstance(foo, collections.Callable)"""[1:]
+# self.check(b, a)
+#
+# b = """
+# import collections
+# def spam(foo):
+# callable(foo)"""[1:]
+# # same output if it was already imported
+# self.check(b, a)
+#
+# b = """
+# from collections import *
+# def spam(foo):
+# callable(foo)"""[1:]
+# a = """
+# from collections import *
+# import collections
+# def spam(foo):
+# isinstance(foo, collections.Callable)"""[1:]
+# self.check(b, a)
+#
+# b = """
+# do_stuff()
+# do_some_other_stuff()
+# assert callable(do_stuff)"""[1:]
+# a = """
+# import collections
+# do_stuff()
+# do_some_other_stuff()
+# assert isinstance(do_stuff, collections.Callable)"""[1:]
+# self.check(b, a)
+#
+# b = """
+# if isinstance(do_stuff, Callable):
+# assert callable(do_stuff)
+# do_stuff(do_stuff)
+# if not callable(do_stuff):
+# exit(1)
+# else:
+# assert callable(do_stuff)
+# else:
+# assert not callable(do_stuff)"""[1:]
+# a = """
+# import collections
+# if isinstance(do_stuff, Callable):
+# assert isinstance(do_stuff, collections.Callable)
+# do_stuff(do_stuff)
+# if not isinstance(do_stuff, collections.Callable):
+# exit(1)
+# else:
+# assert isinstance(do_stuff, collections.Callable)
+# else:
+# assert not isinstance(do_stuff, collections.Callable)"""[1:]
+# self.check(b, a)
+#
+# def test_callable_should_not_change(self):
+# a = """callable(*x)"""
+# self.unchanged(a)
+#
+# a = """callable(x, y)"""
+# self.unchanged(a)
+#
+# a = """callable(x, kw=y)"""
+# self.unchanged(a)
+#
+# a = """callable()"""
+# self.unchanged(a)
+#
+# class Test_filter(FixerTestCase):
+# fixer = "filter"
+#
+# def test_prefix_preservation(self):
+# b = """x = filter( foo, 'abc' )"""
+# a = """x = list(filter( foo, 'abc' ))"""
+# self.check(b, a)
+#
+# b = """x = filter( None , 'abc' )"""
+# a = """x = [_f for _f in 'abc' if _f]"""
+# self.check(b, a)
+#
+# def test_filter_basic(self):
+# b = """x = filter(None, 'abc')"""
+# a = """x = [_f for _f in 'abc' if _f]"""
+# self.check(b, a)
+#
+# b = """x = len(filter(f, 'abc'))"""
+# a = """x = len(list(filter(f, 'abc')))"""
+# self.check(b, a)
+#
+# b = """x = filter(lambda x: x%2 == 0, range(10))"""
+# a = """x = [x for x in range(10) if x%2 == 0]"""
+# self.check(b, a)
+#
+# # Note the parens around x
+# b = """x = filter(lambda (x): x%2 == 0, range(10))"""
+# a = """x = [x for x in range(10) if x%2 == 0]"""
+# self.check(b, a)
+#
+# # XXX This (rare) case is not supported
+# ## b = """x = filter(f, 'abc')[0]"""
+# ## a = """x = list(filter(f, 'abc'))[0]"""
+# ## self.check(b, a)
+#
+# def test_filter_nochange(self):
+# a = """b.join(filter(f, 'abc'))"""
+# self.unchanged(a)
+# a = """(a + foo(5)).join(filter(f, 'abc'))"""
+# self.unchanged(a)
+# a = """iter(filter(f, 'abc'))"""
+# self.unchanged(a)
+# a = """list(filter(f, 'abc'))"""
+# self.unchanged(a)
+# a = """list(filter(f, 'abc'))[0]"""
+# self.unchanged(a)
+# a = """set(filter(f, 'abc'))"""
+# self.unchanged(a)
+# a = """set(filter(f, 'abc')).pop()"""
+# self.unchanged(a)
+# a = """tuple(filter(f, 'abc'))"""
+# self.unchanged(a)
+# a = """any(filter(f, 'abc'))"""
+# self.unchanged(a)
+# a = """all(filter(f, 'abc'))"""
+# self.unchanged(a)
+# a = """sum(filter(f, 'abc'))"""
+# self.unchanged(a)
+# a = """sorted(filter(f, 'abc'))"""
+# self.unchanged(a)
+# a = """sorted(filter(f, 'abc'), key=blah)"""
+# self.unchanged(a)
+# a = """sorted(filter(f, 'abc'), key=blah)[0]"""
+# self.unchanged(a)
+# a = """enumerate(filter(f, 'abc'))"""
+# self.unchanged(a)
+# a = """enumerate(filter(f, 'abc'), start=1)"""
+# self.unchanged(a)
+# a = """for i in filter(f, 'abc'): pass"""
+# self.unchanged(a)
+# a = """[x for x in filter(f, 'abc')]"""
+# self.unchanged(a)
+# a = """(x for x in filter(f, 'abc'))"""
+# self.unchanged(a)
+#
+# def test_future_builtins(self):
+# a = "from future_builtins import spam, filter; filter(f, 'ham')"
+# self.unchanged(a)
+#
+# b = """from future_builtins import spam; x = filter(f, 'abc')"""
+# a = """from future_builtins import spam; x = list(filter(f, 'abc'))"""
+# self.check(b, a)
+#
+# a = "from future_builtins import *; filter(f, 'ham')"
+# self.unchanged(a)
+#
+# class Test_map(FixerTestCase):
+# fixer = "map"
+#
+# def check(self, b, a):
+# self.unchanged("from future_builtins import map; " + b, a)
+# super(Test_map, self).check(b, a)
+#
+# def test_prefix_preservation(self):
+# b = """x = map( f, 'abc' )"""
+# a = """x = list(map( f, 'abc' ))"""
+# self.check(b, a)
+#
+# def test_trailing_comment(self):
+# b = """x = map(f, 'abc') # foo"""
+# a = """x = list(map(f, 'abc')) # foo"""
+# self.check(b, a)
+#
+# def test_None_with_multiple_arguments(self):
+# s = """x = map(None, a, b, c)"""
+# self.warns_unchanged(s, "cannot convert map(None, ...) with "
+# "multiple arguments")
+#
+# def test_map_basic(self):
+# b = """x = map(f, 'abc')"""
+# a = """x = list(map(f, 'abc'))"""
+# self.check(b, a)
+#
+# b = """x = len(map(f, 'abc', 'def'))"""
+# a = """x = len(list(map(f, 'abc', 'def')))"""
+# self.check(b, a)
+#
+# b = """x = map(None, 'abc')"""
+# a = """x = list('abc')"""
+# self.check(b, a)
+#
+# b = """x = map(lambda x: x+1, range(4))"""
+# a = """x = [x+1 for x in range(4)]"""
+# self.check(b, a)
+#
+# # Note the parens around x
+# b = """x = map(lambda (x): x+1, range(4))"""
+# a = """x = [x+1 for x in range(4)]"""
+# self.check(b, a)
+#
+# b = """
+# foo()
+# # foo
+# map(f, x)
+# """
+# a = """
+# foo()
+# # foo
+# list(map(f, x))
+# """
+# self.warns(b, a, "You should use a for loop here")
+#
+# # XXX This (rare) case is not supported
+# ## b = """x = map(f, 'abc')[0]"""
+# ## a = """x = list(map(f, 'abc'))[0]"""
+# ## self.check(b, a)
+#
+# def test_map_nochange(self):
+# a = """b.join(map(f, 'abc'))"""
+# self.unchanged(a)
+# a = """(a + foo(5)).join(map(f, 'abc'))"""
+# self.unchanged(a)
+# a = """iter(map(f, 'abc'))"""
+# self.unchanged(a)
+# a = """list(map(f, 'abc'))"""
+# self.unchanged(a)
+# a = """list(map(f, 'abc'))[0]"""
+# self.unchanged(a)
+# a = """set(map(f, 'abc'))"""
+# self.unchanged(a)
+# a = """set(map(f, 'abc')).pop()"""
+# self.unchanged(a)
+# a = """tuple(map(f, 'abc'))"""
+# self.unchanged(a)
+# a = """any(map(f, 'abc'))"""
+# self.unchanged(a)
+# a = """all(map(f, 'abc'))"""
+# self.unchanged(a)
+# a = """sum(map(f, 'abc'))"""
+# self.unchanged(a)
+# a = """sorted(map(f, 'abc'))"""
+# self.unchanged(a)
+# a = """sorted(map(f, 'abc'), key=blah)"""
+# self.unchanged(a)
+# a = """sorted(map(f, 'abc'), key=blah)[0]"""
+# self.unchanged(a)
+# a = """enumerate(map(f, 'abc'))"""
+# self.unchanged(a)
+# a = """enumerate(map(f, 'abc'), start=1)"""
+# self.unchanged(a)
+# a = """for i in map(f, 'abc'): pass"""
+# self.unchanged(a)
+# a = """[x for x in map(f, 'abc')]"""
+# self.unchanged(a)
+# a = """(x for x in map(f, 'abc'))"""
+# self.unchanged(a)
+#
+# def test_future_builtins(self):
+# a = "from future_builtins import spam, map, eggs; map(f, 'ham')"
+# self.unchanged(a)
+#
+# b = """from future_builtins import spam, eggs; x = map(f, 'abc')"""
+# a = """from future_builtins import spam, eggs; x = list(map(f, 'abc'))"""
+# self.check(b, a)
+#
+# a = "from future_builtins import *; map(f, 'ham')"
+# self.unchanged(a)
+#
+# class Test_zip(FixerTestCase):
+# fixer = "zip"
+#
+# def check(self, b, a):
+# self.unchanged("from future_builtins import zip; " + b, a)
+# super(Test_zip, self).check(b, a)
+#
+# def test_zip_basic(self):
+# b = """x = zip(a, b, c)"""
+# a = """x = list(zip(a, b, c))"""
+# self.check(b, a)
+#
+# b = """x = len(zip(a, b))"""
+# a = """x = len(list(zip(a, b)))"""
+# self.check(b, a)
+#
+# def test_zip_nochange(self):
+# a = """b.join(zip(a, b))"""
+# self.unchanged(a)
+# a = """(a + foo(5)).join(zip(a, b))"""
+# self.unchanged(a)
+# a = """iter(zip(a, b))"""
+# self.unchanged(a)
+# a = """list(zip(a, b))"""
+# self.unchanged(a)
+# a = """list(zip(a, b))[0]"""
+# self.unchanged(a)
+# a = """set(zip(a, b))"""
+# self.unchanged(a)
+# a = """set(zip(a, b)).pop()"""
+# self.unchanged(a)
+# a = """tuple(zip(a, b))"""
+# self.unchanged(a)
+# a = """any(zip(a, b))"""
+# self.unchanged(a)
+# a = """all(zip(a, b))"""
+# self.unchanged(a)
+# a = """sum(zip(a, b))"""
+# self.unchanged(a)
+# a = """sorted(zip(a, b))"""
+# self.unchanged(a)
+# a = """sorted(zip(a, b), key=blah)"""
+# self.unchanged(a)
+# a = """sorted(zip(a, b), key=blah)[0]"""
+# self.unchanged(a)
+# a = """enumerate(zip(a, b))"""
+# self.unchanged(a)
+# a = """enumerate(zip(a, b), start=1)"""
+# self.unchanged(a)
+# a = """for i in zip(a, b): pass"""
+# self.unchanged(a)
+# a = """[x for x in zip(a, b)]"""
+# self.unchanged(a)
+# a = """(x for x in zip(a, b))"""
+# self.unchanged(a)
+#
+# def test_future_builtins(self):
+# a = "from future_builtins import spam, zip, eggs; zip(a, b)"
+# self.unchanged(a)
+#
+# b = """from future_builtins import spam, eggs; x = zip(a, b)"""
+# a = """from future_builtins import spam, eggs; x = list(zip(a, b))"""
+# self.check(b, a)
+#
+# a = "from future_builtins import *; zip(a, b)"
+# self.unchanged(a)
+#
+# class Test_standarderror(FixerTestCase):
+# fixer = "standarderror"
+#
+# def test(self):
+# b = """x = StandardError()"""
+# a = """x = Exception()"""
+# self.check(b, a)
+#
+# b = """x = StandardError(a, b, c)"""
+# a = """x = Exception(a, b, c)"""
+# self.check(b, a)
+#
+# b = """f(2 + StandardError(a, b, c))"""
+# a = """f(2 + Exception(a, b, c))"""
+# self.check(b, a)
+#
+# class Test_types(FixerTestCase):
+# fixer = "types"
+#
+# def test_basic_types_convert(self):
+# b = """types.StringType"""
+# a = """bytes"""
+# self.check(b, a)
+#
+# b = """types.DictType"""
+# a = """dict"""
+# self.check(b, a)
+#
+# b = """types . IntType"""
+# a = """int"""
+# self.check(b, a)
+#
+# b = """types.ListType"""
+# a = """list"""
+# self.check(b, a)
+#
+# b = """types.LongType"""
+# a = """int"""
+# self.check(b, a)
+#
+# b = """types.NoneType"""
+# a = """type(None)"""
+# self.check(b, a)
+#
+# class Test_idioms(FixerTestCase):
+# fixer = "idioms"
+#
+# def test_while(self):
+# b = """while 1: foo()"""
+# a = """while True: foo()"""
+# self.check(b, a)
+#
+# b = """while 1: foo()"""
+# a = """while True: foo()"""
+# self.check(b, a)
+#
+# b = """
+# while 1:
+# foo()
+# """
+# a = """
+# while True:
+# foo()
+# """
+# self.check(b, a)
+#
+# def test_while_unchanged(self):
+# s = """while 11: foo()"""
+# self.unchanged(s)
+#
+# s = """while 0: foo()"""
+# self.unchanged(s)
+#
+# s = """while foo(): foo()"""
+# self.unchanged(s)
+#
+# s = """while []: foo()"""
+# self.unchanged(s)
+#
+# def test_eq_simple(self):
+# b = """type(x) == T"""
+# a = """isinstance(x, T)"""
+# self.check(b, a)
+#
+# b = """if type(x) == T: pass"""
+# a = """if isinstance(x, T): pass"""
+# self.check(b, a)
+#
+# def test_eq_reverse(self):
+# b = """T == type(x)"""
+# a = """isinstance(x, T)"""
+# self.check(b, a)
+#
+# b = """if T == type(x): pass"""
+# a = """if isinstance(x, T): pass"""
+# self.check(b, a)
+#
+# def test_eq_expression(self):
+# b = """type(x+y) == d.get('T')"""
+# a = """isinstance(x+y, d.get('T'))"""
+# self.check(b, a)
+#
+# b = """type( x + y) == d.get('T')"""
+# a = """isinstance(x + y, d.get('T'))"""
+# self.check(b, a)
+#
+# def test_is_simple(self):
+# b = """type(x) is T"""
+# a = """isinstance(x, T)"""
+# self.check(b, a)
+#
+# b = """if type(x) is T: pass"""
+# a = """if isinstance(x, T): pass"""
+# self.check(b, a)
+#
+# def test_is_reverse(self):
+# b = """T is type(x)"""
+# a = """isinstance(x, T)"""
+# self.check(b, a)
+#
+# b = """if T is type(x): pass"""
+# a = """if isinstance(x, T): pass"""
+# self.check(b, a)
+#
+# def test_is_expression(self):
+# b = """type(x+y) is d.get('T')"""
+# a = """isinstance(x+y, d.get('T'))"""
+# self.check(b, a)
+#
+# b = """type( x + y) is d.get('T')"""
+# a = """isinstance(x + y, d.get('T'))"""
+# self.check(b, a)
+#
+# def test_is_not_simple(self):
+# b = """type(x) is not T"""
+# a = """not isinstance(x, T)"""
+# self.check(b, a)
+#
+# b = """if type(x) is not T: pass"""
+# a = """if not isinstance(x, T): pass"""
+# self.check(b, a)
+#
+# def test_is_not_reverse(self):
+# b = """T is not type(x)"""
+# a = """not isinstance(x, T)"""
+# self.check(b, a)
+#
+# b = """if T is not type(x): pass"""
+# a = """if not isinstance(x, T): pass"""
+# self.check(b, a)
+#
+# def test_is_not_expression(self):
+# b = """type(x+y) is not d.get('T')"""
+# a = """not isinstance(x+y, d.get('T'))"""
+# self.check(b, a)
+#
+# b = """type( x + y) is not d.get('T')"""
+# a = """not isinstance(x + y, d.get('T'))"""
+# self.check(b, a)
+#
+# def test_ne_simple(self):
+# b = """type(x) != T"""
+# a = """not isinstance(x, T)"""
+# self.check(b, a)
+#
+# b = """if type(x) != T: pass"""
+# a = """if not isinstance(x, T): pass"""
+# self.check(b, a)
+#
+# def test_ne_reverse(self):
+# b = """T != type(x)"""
+# a = """not isinstance(x, T)"""
+# self.check(b, a)
+#
+# b = """if T != type(x): pass"""
+# a = """if not isinstance(x, T): pass"""
+# self.check(b, a)
+#
+# def test_ne_expression(self):
+# b = """type(x+y) != d.get('T')"""
+# a = """not isinstance(x+y, d.get('T'))"""
+# self.check(b, a)
+#
+# b = """type( x + y) != d.get('T')"""
+# a = """not isinstance(x + y, d.get('T'))"""
+# self.check(b, a)
+#
+# def test_type_unchanged(self):
+# a = """type(x).__name__"""
+# self.unchanged(a)
+#
+# def test_sort_list_call(self):
+# b = """
+# v = list(t)
+# v.sort()
+# foo(v)
+# """
+# a = """
+# v = sorted(t)
+# foo(v)
+# """
+# self.check(b, a)
+#
+# b = """
+# v = list(foo(b) + d)
+# v.sort()
+# foo(v)
+# """
+# a = """
+# v = sorted(foo(b) + d)
+# foo(v)
+# """
+# self.check(b, a)
+#
+# b = """
+# while x:
+# v = list(t)
+# v.sort()
+# foo(v)
+# """
+# a = """
+# while x:
+# v = sorted(t)
+# foo(v)
+# """
+# self.check(b, a)
+#
+# b = """
+# v = list(t)
+# # foo
+# v.sort()
+# foo(v)
+# """
+# a = """
+# v = sorted(t)
+# # foo
+# foo(v)
+# """
+# self.check(b, a)
+#
+# b = r"""
+# v = list( t)
+# v.sort()
+# foo(v)
+# """
+# a = r"""
+# v = sorted( t)
+# foo(v)
+# """
+# self.check(b, a)
+#
+# b = r"""
+# try:
+# m = list(s)
+# m.sort()
+# except: pass
+# """
+#
+# a = r"""
+# try:
+# m = sorted(s)
+# except: pass
+# """
+# self.check(b, a)
+#
+# b = r"""
+# try:
+# m = list(s)
+# # foo
+# m.sort()
+# except: pass
+# """
+#
+# a = r"""
+# try:
+# m = sorted(s)
+# # foo
+# except: pass
+# """
+# self.check(b, a)
+#
+# b = r"""
+# m = list(s)
+# # more comments
+# m.sort()"""
+#
+# a = r"""
+# m = sorted(s)
+# # more comments"""
+# self.check(b, a)
+#
+# def test_sort_simple_expr(self):
+# b = """
+# v = t
+# v.sort()
+# foo(v)
+# """
+# a = """
+# v = sorted(t)
+# foo(v)
+# """
+# self.check(b, a)
+#
+# b = """
+# v = foo(b)
+# v.sort()
+# foo(v)
+# """
+# a = """
+# v = sorted(foo(b))
+# foo(v)
+# """
+# self.check(b, a)
+#
+# b = """
+# v = b.keys()
+# v.sort()
+# foo(v)
+# """
+# a = """
+# v = sorted(b.keys())
+# foo(v)
+# """
+# self.check(b, a)
+#
+# b = """
+# v = foo(b) + d
+# v.sort()
+# foo(v)
+# """
+# a = """
+# v = sorted(foo(b) + d)
+# foo(v)
+# """
+# self.check(b, a)
+#
+# b = """
+# while x:
+# v = t
+# v.sort()
+# foo(v)
+# """
+# a = """
+# while x:
+# v = sorted(t)
+# foo(v)
+# """
+# self.check(b, a)
+#
+# b = """
+# v = t
+# # foo
+# v.sort()
+# foo(v)
+# """
+# a = """
+# v = sorted(t)
+# # foo
+# foo(v)
+# """
+# self.check(b, a)
+#
+# b = r"""
+# v = t
+# v.sort()
+# foo(v)
+# """
+# a = r"""
+# v = sorted(t)
+# foo(v)
+# """
+# self.check(b, a)
+#
+# def test_sort_unchanged(self):
+# s = """
+# v = list(t)
+# w.sort()
+# foo(w)
+# """
+# self.unchanged(s)
+#
+# s = """
+# v = list(t)
+# v.sort(u)
+# foo(v)
+# """
+# self.unchanged(s)
+#
+# class Test_basestring(FixerTestCase):
+# fixer = "basestring"
+#
+# def test_basestring(self):
+# b = """isinstance(x, basestring)"""
+# a = """isinstance(x, str)"""
+# self.check(b, a)
+#
+# class Test_buffer(FixerTestCase):
+# fixer = "buffer"
+#
+# def test_buffer(self):
+# b = """x = buffer(y)"""
+# a = """x = memoryview(y)"""
+# self.check(b, a)
+#
+# def test_slicing(self):
+# b = """buffer(y)[4:5]"""
+# a = """memoryview(y)[4:5]"""
+# self.check(b, a)
+#
+# class Test_future(FixerTestCase):
+# fixer = "future"
+#
+# def test_future(self):
+# b = """from __future__ import braces"""
+# a = """"""
+# self.check(b, a)
+#
+# b = """# comment\nfrom __future__ import braces"""
+# a = """# comment\n"""
+# self.check(b, a)
+#
+# b = """from __future__ import braces\n# comment"""
+# a = """\n# comment"""
+# self.check(b, a)
+#
+# def test_run_order(self):
+# self.assert_runs_after('print')
+#
+# class Test_itertools(FixerTestCase):
+# fixer = "itertools"
+#
+# def checkall(self, before, after):
+# # Because we need to check with and without the itertools prefix
+# # and on each of the three functions, these loops make it all
+# # much easier
+# for i in ('itertools.', ''):
+# for f in ('map', 'filter', 'zip'):
+# b = before %(i+'i'+f)
+# a = after %(f)
+# self.check(b, a)
+#
+# def test_0(self):
+# # A simple example -- test_1 covers exactly the same thing,
+# # but it's not quite as clear.
+# b = "itertools.izip(a, b)"
+# a = "zip(a, b)"
+# self.check(b, a)
+#
+# def test_1(self):
+# b = """%s(f, a)"""
+# a = """%s(f, a)"""
+# self.checkall(b, a)
+#
+# def test_qualified(self):
+# b = """itertools.ifilterfalse(a, b)"""
+# a = """itertools.filterfalse(a, b)"""
+# self.check(b, a)
+#
+# b = """itertools.izip_longest(a, b)"""
+# a = """itertools.zip_longest(a, b)"""
+# self.check(b, a)
+#
+# def test_2(self):
+# b = """ifilterfalse(a, b)"""
+# a = """filterfalse(a, b)"""
+# self.check(b, a)
+#
+# b = """izip_longest(a, b)"""
+# a = """zip_longest(a, b)"""
+# self.check(b, a)
+#
+# def test_space_1(self):
+# b = """ %s(f, a)"""
+# a = """ %s(f, a)"""
+# self.checkall(b, a)
+#
+# def test_space_2(self):
+# b = """ itertools.ifilterfalse(a, b)"""
+# a = """ itertools.filterfalse(a, b)"""
+# self.check(b, a)
+#
+# b = """ itertools.izip_longest(a, b)"""
+# a = """ itertools.zip_longest(a, b)"""
+# self.check(b, a)
+#
+# def test_run_order(self):
+# self.assert_runs_after('map', 'zip', 'filter')
+#
+#
+# class Test_itertools_imports(FixerTestCase):
+# fixer = 'itertools_imports'
+#
+# def test_reduced(self):
+# b = "from itertools import imap, izip, foo"
+# a = "from itertools import foo"
+# self.check(b, a)
+#
+# b = "from itertools import bar, imap, izip, foo"
+# a = "from itertools import bar, foo"
+# self.check(b, a)
+#
+# b = "from itertools import chain, imap, izip"
+# a = "from itertools import chain"
+# self.check(b, a)
+#
+# def test_comments(self):
+# b = "#foo\nfrom itertools import imap, izip"
+# a = "#foo\n"
+# self.check(b, a)
+#
+# def test_none(self):
+# b = "from itertools import imap, izip"
+# a = ""
+# self.check(b, a)
+#
+# b = "from itertools import izip"
+# a = ""
+# self.check(b, a)
+#
+# def test_import_as(self):
+# b = "from itertools import izip, bar as bang, imap"
+# a = "from itertools import bar as bang"
+# self.check(b, a)
+#
+# b = "from itertools import izip as _zip, imap, bar"
+# a = "from itertools import bar"
+# self.check(b, a)
+#
+# b = "from itertools import imap as _map"
+# a = ""
+# self.check(b, a)
+#
+# b = "from itertools import imap as _map, izip as _zip"
+# a = ""
+# self.check(b, a)
+#
+# s = "from itertools import bar as bang"
+# self.unchanged(s)
+#
+# def test_ifilter_and_zip_longest(self):
+# for name in "filterfalse", "zip_longest":
+# b = "from itertools import i%s" % (name,)
+# a = "from itertools import %s" % (name,)
+# self.check(b, a)
+#
+# b = "from itertools import imap, i%s, foo" % (name,)
+# a = "from itertools import %s, foo" % (name,)
+# self.check(b, a)
+#
+# b = "from itertools import bar, i%s, foo" % (name,)
+# a = "from itertools import bar, %s, foo" % (name,)
+# self.check(b, a)
+#
+# def test_import_star(self):
+# s = "from itertools import *"
+# self.unchanged(s)
+#
+#
+# def test_unchanged(self):
+# s = "from itertools import foo"
+# self.unchanged(s)
+#
+#
+# class Test_import(FixerTestCase):
+# fixer = "import"
+#
+# def setUp(self):
+# super(Test_import, self).setUp()
+# # Need to replace fix_import's exists method
+# # so we can check that it's doing the right thing
+# self.files_checked = []
+# self.present_files = set()
+# self.always_exists = True
+# def fake_exists(name):
+# self.files_checked.append(name)
+# return self.always_exists or (name in self.present_files)
+#
+# from lib2to3.fixes import fix_import
+# fix_import.exists = fake_exists
+#
+# def tearDown(self):
+# from lib2to3.fixes import fix_import
+# fix_import.exists = os.path.exists
+#
+# def check_both(self, b, a):
+# self.always_exists = True
+# super(Test_import, self).check(b, a)
+# self.always_exists = False
+# super(Test_import, self).unchanged(b)
+#
+# def test_files_checked(self):
+# def p(path):
+# # Takes a unix path and returns a path with correct separators
+# return os.path.pathsep.join(path.split("/"))
+#
+# self.always_exists = False
+# self.present_files = set(['__init__.py'])
+# expected_extensions = ('.py', os.path.sep, '.pyc', '.so', '.sl', '.pyd')
+# names_to_test = (p("/spam/eggs.py"), "ni.py", p("../../shrubbery.py"))
+#
+# for name in names_to_test:
+# self.files_checked = []
+# self.filename = name
+# self.unchanged("import jam")
+#
+# if os.path.dirname(name):
+# name = os.path.dirname(name) + '/jam'
+# else:
+# name = 'jam'
+# expected_checks = set(name + ext for ext in expected_extensions)
+# expected_checks.add("__init__.py")
+#
+# self.assertEqual(set(self.files_checked), expected_checks)
+#
+# def test_not_in_package(self):
+# s = "import bar"
+# self.always_exists = False
+# self.present_files = set(["bar.py"])
+# self.unchanged(s)
+#
+# def test_with_absolute_import_enabled(self):
+# s = "from __future__ import absolute_import\nimport bar"
+# self.always_exists = False
+# self.present_files = set(["__init__.py", "bar.py"])
+# self.unchanged(s)
+#
+# def test_in_package(self):
+# b = "import bar"
+# a = "from . import bar"
+# self.always_exists = False
+# self.present_files = set(["__init__.py", "bar.py"])
+# self.check(b, a)
+#
+# def test_import_from_package(self):
+# b = "import bar"
+# a = "from . import bar"
+# self.always_exists = False
+# self.present_files = set(["__init__.py", "bar" + os.path.sep])
+# self.check(b, a)
+#
+# def test_already_relative_import(self):
+# s = "from . import bar"
+# self.unchanged(s)
+#
+# def test_comments_and_indent(self):
+# b = "import bar # Foo"
+# a = "from . import bar # Foo"
+# self.check(b, a)
+#
+# def test_from(self):
+# b = "from foo import bar, baz"
+# a = "from .foo import bar, baz"
+# self.check_both(b, a)
+#
+# b = "from foo import bar"
+# a = "from .foo import bar"
+# self.check_both(b, a)
+#
+# b = "from foo import (bar, baz)"
+# a = "from .foo import (bar, baz)"
+# self.check_both(b, a)
+#
+# def test_dotted_from(self):
+# b = "from green.eggs import ham"
+# a = "from .green.eggs import ham"
+# self.check_both(b, a)
+#
+# def test_from_as(self):
+# b = "from green.eggs import ham as spam"
+# a = "from .green.eggs import ham as spam"
+# self.check_both(b, a)
+#
+# def test_import(self):
+# b = "import foo"
+# a = "from . import foo"
+# self.check_both(b, a)
+#
+# b = "import foo, bar"
+# a = "from . import foo, bar"
+# self.check_both(b, a)
+#
+# b = "import foo, bar, x"
+# a = "from . import foo, bar, x"
+# self.check_both(b, a)
+#
+# b = "import x, y, z"
+# a = "from . import x, y, z"
+# self.check_both(b, a)
+#
+# def test_import_as(self):
+# b = "import foo as x"
+# a = "from . import foo as x"
+# self.check_both(b, a)
+#
+# b = "import a as b, b as c, c as d"
+# a = "from . import a as b, b as c, c as d"
+# self.check_both(b, a)
+#
+# def test_local_and_absolute(self):
+# self.always_exists = False
+# self.present_files = set(["foo.py", "__init__.py"])
+#
+# s = "import foo, bar"
+# self.warns_unchanged(s, "absolute and local imports together")
+#
+# def test_dotted_import(self):
+# b = "import foo.bar"
+# a = "from . import foo.bar"
+# self.check_both(b, a)
+#
+# def test_dotted_import_as(self):
+# b = "import foo.bar as bang"
+# a = "from . import foo.bar as bang"
+# self.check_both(b, a)
+#
+# def test_prefix(self):
+# b = """
+# # prefix
+# import foo.bar
+# """
+# a = """
+# # prefix
+# from . import foo.bar
+# """
+# self.check_both(b, a)
+#
+#
+# class Test_set_literal(FixerTestCase):
+#
+# fixer = "set_literal"
+#
+# def test_basic(self):
+# b = """set([1, 2, 3])"""
+# a = """{1, 2, 3}"""
+# self.check(b, a)
+#
+# b = """set((1, 2, 3))"""
+# a = """{1, 2, 3}"""
+# self.check(b, a)
+#
+# b = """set((1,))"""
+# a = """{1}"""
+# self.check(b, a)
+#
+# b = """set([1])"""
+# self.check(b, a)
+#
+# b = """set((a, b))"""
+# a = """{a, b}"""
+# self.check(b, a)
+#
+# b = """set([a, b])"""
+# self.check(b, a)
+#
+# b = """set((a*234, f(args=23)))"""
+# a = """{a*234, f(args=23)}"""
+# self.check(b, a)
+#
+# b = """set([a*23, f(23)])"""
+# a = """{a*23, f(23)}"""
+# self.check(b, a)
+#
+# b = """set([a-234**23])"""
+# a = """{a-234**23}"""
+# self.check(b, a)
+#
+# def test_listcomps(self):
+# b = """set([x for x in y])"""
+# a = """{x for x in y}"""
+# self.check(b, a)
+#
+# b = """set([x for x in y if x == m])"""
+# a = """{x for x in y if x == m}"""
+# self.check(b, a)
+#
+# b = """set([x for x in y for a in b])"""
+# a = """{x for x in y for a in b}"""
+# self.check(b, a)
+#
+# b = """set([f(x) - 23 for x in y])"""
+# a = """{f(x) - 23 for x in y}"""
+# self.check(b, a)
+#
+# def test_whitespace(self):
+# b = """set( [1, 2])"""
+# a = """{1, 2}"""
+# self.check(b, a)
+#
+# b = """set([1 , 2])"""
+# a = """{1 , 2}"""
+# self.check(b, a)
+#
+# b = """set([ 1 ])"""
+# a = """{ 1 }"""
+# self.check(b, a)
+#
+# b = """set( [1] )"""
+# a = """{1}"""
+# self.check(b, a)
+#
+# b = """set([ 1, 2 ])"""
+# a = """{ 1, 2 }"""
+# self.check(b, a)
+#
+# b = """set([x for x in y ])"""
+# a = """{x for x in y }"""
+# self.check(b, a)
+#
+# b = """set(
+# [1, 2]
+# )
+# """
+# a = """{1, 2}\n"""
+# self.check(b, a)
+#
+# def test_comments(self):
+# b = """set((1, 2)) # Hi"""
+# a = """{1, 2} # Hi"""
+# self.check(b, a)
+#
+# # This isn't optimal behavior, but the fixer is optional.
+# b = """
+# # Foo
+# set( # Bar
+# (1, 2)
+# )
+# """
+# a = """
+# # Foo
+# {1, 2}
+# """
+# self.check(b, a)
+#
+# def test_unchanged(self):
+# s = """set()"""
+# self.unchanged(s)
+#
+# s = """set(a)"""
+# self.unchanged(s)
+#
+# s = """set(a, b, c)"""
+# self.unchanged(s)
+#
+# # Don't transform generators because they might have to be lazy.
+# s = """set(x for x in y)"""
+# self.unchanged(s)
+#
+# s = """set(x for x in y if z)"""
+# self.unchanged(s)
+#
+# s = """set(a*823-23**2 + f(23))"""
+# self.unchanged(s)
+#
+#
+# class Test_sys_exc(FixerTestCase):
+# fixer = "sys_exc"
+#
+# def test_0(self):
+# b = "sys.exc_type"
+# a = "sys.exc_info()[0]"
+# self.check(b, a)
+#
+# def test_1(self):
+# b = "sys.exc_value"
+# a = "sys.exc_info()[1]"
+# self.check(b, a)
+#
+# def test_2(self):
+# b = "sys.exc_traceback"
+# a = "sys.exc_info()[2]"
+# self.check(b, a)
+#
+# def test_3(self):
+# b = "sys.exc_type # Foo"
+# a = "sys.exc_info()[0] # Foo"
+# self.check(b, a)
+#
+# def test_4(self):
+# b = "sys. exc_type"
+# a = "sys. exc_info()[0]"
+# self.check(b, a)
+#
+# def test_5(self):
+# b = "sys .exc_type"
+# a = "sys .exc_info()[0]"
+# self.check(b, a)
+#
+#
+# class Test_paren(FixerTestCase):
+# fixer = "paren"
+#
+# def test_0(self):
+# b = """[i for i in 1, 2 ]"""
+# a = """[i for i in (1, 2) ]"""
+# self.check(b, a)
+#
+# def test_1(self):
+# b = """[i for i in 1, 2, ]"""
+# a = """[i for i in (1, 2,) ]"""
+# self.check(b, a)
+#
+# def test_2(self):
+# b = """[i for i in 1, 2 ]"""
+# a = """[i for i in (1, 2) ]"""
+# self.check(b, a)
+#
+# def test_3(self):
+# b = """[i for i in 1, 2 if i]"""
+# a = """[i for i in (1, 2) if i]"""
+# self.check(b, a)
+#
+# def test_4(self):
+# b = """[i for i in 1, 2 ]"""
+# a = """[i for i in (1, 2) ]"""
+# self.check(b, a)
+#
+# def test_5(self):
+# b = """(i for i in 1, 2)"""
+# a = """(i for i in (1, 2))"""
+# self.check(b, a)
+#
+# def test_6(self):
+# b = """(i for i in 1 ,2 if i)"""
+# a = """(i for i in (1 ,2) if i)"""
+# self.check(b, a)
+#
+# def test_unchanged_0(self):
+# s = """[i for i in (1, 2)]"""
+# self.unchanged(s)
+#
+# def test_unchanged_1(self):
+# s = """[i for i in foo()]"""
+# self.unchanged(s)
+#
+# def test_unchanged_2(self):
+# s = """[i for i in (1, 2) if nothing]"""
+# self.unchanged(s)
+#
+# def test_unchanged_3(self):
+# s = """(i for i in (1, 2))"""
+# self.unchanged(s)
+#
+# def test_unchanged_4(self):
+# s = """[i for i in m]"""
+# self.unchanged(s)
+#
+# class Test_metaclass(FixerTestCase):
+#
+# fixer = 'metaclass'
+#
+# def test_unchanged(self):
+# self.unchanged("class X(): pass")
+# self.unchanged("class X(object): pass")
+# self.unchanged("class X(object1, object2): pass")
+# self.unchanged("class X(object1, object2, object3): pass")
+# self.unchanged("class X(metaclass=Meta): pass")
+# self.unchanged("class X(b, arg=23, metclass=Meta): pass")
+# self.unchanged("class X(b, arg=23, metaclass=Meta, other=42): pass")
+#
+# s = """
+# class X:
+# def __metaclass__(self): pass
+# """
+# self.unchanged(s)
+#
+# s = """
+# class X:
+# a[23] = 74
+# """
+# self.unchanged(s)
+#
+# def test_comments(self):
+# b = """
+# class X:
+# # hi
+# __metaclass__ = AppleMeta
+# """
+# a = """
+# class X(metaclass=AppleMeta):
+# # hi
+# pass
+# """
+# self.check(b, a)
+#
+# b = """
+# class X:
+# __metaclass__ = Meta
+# # Bedtime!
+# """
+# a = """
+# class X(metaclass=Meta):
+# pass
+# # Bedtime!
+# """
+# self.check(b, a)
+#
+# def test_meta(self):
+# # no-parent class, odd body
+# b = """
+# class X():
+# __metaclass__ = Q
+# pass
+# """
+# a = """
+# class X(metaclass=Q):
+# pass
+# """
+# self.check(b, a)
+#
+# # one parent class, no body
+# b = """class X(object): __metaclass__ = Q"""
+# a = """class X(object, metaclass=Q): pass"""
+# self.check(b, a)
+#
+#
+# # one parent, simple body
+# b = """
+# class X(object):
+# __metaclass__ = Meta
+# bar = 7
+# """
+# a = """
+# class X(object, metaclass=Meta):
+# bar = 7
+# """
+# self.check(b, a)
+#
+# b = """
+# class X:
+# __metaclass__ = Meta; x = 4; g = 23
+# """
+# a = """
+# class X(metaclass=Meta):
+# x = 4; g = 23
+# """
+# self.check(b, a)
+#
+# # one parent, simple body, __metaclass__ last
+# b = """
+# class X(object):
+# bar = 7
+# __metaclass__ = Meta
+# """
+# a = """
+# class X(object, metaclass=Meta):
+# bar = 7
+# """
+# self.check(b, a)
+#
+# # redefining __metaclass__
+# b = """
+# class X():
+# __metaclass__ = A
+# __metaclass__ = B
+# bar = 7
+# """
+# a = """
+# class X(metaclass=B):
+# bar = 7
+# """
+# self.check(b, a)
+#
+# # multiple inheritance, simple body
+# b = """
+# class X(clsA, clsB):
+# __metaclass__ = Meta
+# bar = 7
+# """
+# a = """
+# class X(clsA, clsB, metaclass=Meta):
+# bar = 7
+# """
+# self.check(b, a)
+#
+# # keywords in the class statement
+# b = """class m(a, arg=23): __metaclass__ = Meta"""
+# a = """class m(a, arg=23, metaclass=Meta): pass"""
+# self.check(b, a)
+#
+# b = """
+# class X(expression(2 + 4)):
+# __metaclass__ = Meta
+# """
+# a = """
+# class X(expression(2 + 4), metaclass=Meta):
+# pass
+# """
+# self.check(b, a)
+#
+# b = """
+# class X(expression(2 + 4), x**4):
+# __metaclass__ = Meta
+# """
+# a = """
+# class X(expression(2 + 4), x**4, metaclass=Meta):
+# pass
+# """
+# self.check(b, a)
+#
+# b = """
+# class X:
+# __metaclass__ = Meta
+# save.py = 23
+# """
+# a = """
+# class X(metaclass=Meta):
+# save.py = 23
+# """
+# self.check(b, a)
+#
+#
+# class Test_getcwdu(FixerTestCase):
+#
+# fixer = 'getcwdu'
+#
+# def test_basic(self):
+# b = """os.getcwdu"""
+# a = """os.getcwd"""
+# self.check(b, a)
+#
+# b = """os.getcwdu()"""
+# a = """os.getcwd()"""
+# self.check(b, a)
+#
+# b = """meth = os.getcwdu"""
+# a = """meth = os.getcwd"""
+# self.check(b, a)
+#
+# b = """os.getcwdu(args)"""
+# a = """os.getcwd(args)"""
+# self.check(b, a)
+#
+# def test_comment(self):
+# b = """os.getcwdu() # Foo"""
+# a = """os.getcwd() # Foo"""
+# self.check(b, a)
+#
+# def test_unchanged(self):
+# s = """os.getcwd()"""
+# self.unchanged(s)
+#
+# s = """getcwdu()"""
+# self.unchanged(s)
+#
+# s = """os.getcwdb()"""
+# self.unchanged(s)
+#
+# def test_indentation(self):
+# b = """
+# if 1:
+# os.getcwdu()
+# """
+# a = """
+# if 1:
+# os.getcwd()
+# """
+# self.check(b, a)
+#
+# def test_multilation(self):
+# b = """os .getcwdu()"""
+# a = """os .getcwd()"""
+# self.check(b, a)
+#
+# b = """os. getcwdu"""
+# a = """os. getcwd"""
+# self.check(b, a)
+#
+# b = """os.getcwdu ( )"""
+# a = """os.getcwd ( )"""
+# self.check(b, a)
+#
+#
+# class Test_operator(FixerTestCase):
+#
+# fixer = "operator"
+#
+# def test_operator_isCallable(self):
+# b = "operator.isCallable(x)"
+# a = "hasattr(x, '__call__')"
+# self.check(b, a)
+#
+# def test_operator_sequenceIncludes(self):
+# b = "operator.sequenceIncludes(x, y)"
+# a = "operator.contains(x, y)"
+# self.check(b, a)
+#
+# b = "operator .sequenceIncludes(x, y)"
+# a = "operator .contains(x, y)"
+# self.check(b, a)
+#
+# b = "operator. sequenceIncludes(x, y)"
+# a = "operator. contains(x, y)"
+# self.check(b, a)
+#
+# def test_operator_isSequenceType(self):
+# b = "operator.isSequenceType(x)"
+# a = "import collections\nisinstance(x, collections.Sequence)"
+# self.check(b, a)
+#
+# def test_operator_isMappingType(self):
+# b = "operator.isMappingType(x)"
+# a = "import collections\nisinstance(x, collections.Mapping)"
+# self.check(b, a)
+#
+# def test_operator_isNumberType(self):
+# b = "operator.isNumberType(x)"
+# a = "import numbers\nisinstance(x, numbers.Number)"
+# self.check(b, a)
+#
+# def test_operator_repeat(self):
+# b = "operator.repeat(x, n)"
+# a = "operator.mul(x, n)"
+# self.check(b, a)
+#
+# b = "operator .repeat(x, n)"
+# a = "operator .mul(x, n)"
+# self.check(b, a)
+#
+# b = "operator. repeat(x, n)"
+# a = "operator. mul(x, n)"
+# self.check(b, a)
+#
+# def test_operator_irepeat(self):
+# b = "operator.irepeat(x, n)"
+# a = "operator.imul(x, n)"
+# self.check(b, a)
+#
+# b = "operator .irepeat(x, n)"
+# a = "operator .imul(x, n)"
+# self.check(b, a)
+#
+# b = "operator. irepeat(x, n)"
+# a = "operator. imul(x, n)"
+# self.check(b, a)
+#
+# def test_bare_isCallable(self):
+# s = "isCallable(x)"
+# t = "You should use 'hasattr(x, '__call__')' here."
+# self.warns_unchanged(s, t)
+#
+# def test_bare_sequenceIncludes(self):
+# s = "sequenceIncludes(x, y)"
+# t = "You should use 'operator.contains(x, y)' here."
+# self.warns_unchanged(s, t)
+#
+# def test_bare_operator_isSequenceType(self):
+# s = "isSequenceType(z)"
+# t = "You should use 'isinstance(z, collections.Sequence)' here."
+# self.warns_unchanged(s, t)
+#
+# def test_bare_operator_isMappingType(self):
+# s = "isMappingType(x)"
+# t = "You should use 'isinstance(x, collections.Mapping)' here."
+# self.warns_unchanged(s, t)
+#
+# def test_bare_operator_isNumberType(self):
+# s = "isNumberType(y)"
+# t = "You should use 'isinstance(y, numbers.Number)' here."
+# self.warns_unchanged(s, t)
+#
+# def test_bare_operator_repeat(self):
+# s = "repeat(x, n)"
+# t = "You should use 'operator.mul(x, n)' here."
+# self.warns_unchanged(s, t)
+#
+# def test_bare_operator_irepeat(self):
+# s = "irepeat(y, 187)"
+# t = "You should use 'operator.imul(y, 187)' here."
+# self.warns_unchanged(s, t)
+#
+#
+# class Test_exitfunc(FixerTestCase):
+#
+# fixer = "exitfunc"
+#
+# def test_simple(self):
+# b = """
+# import sys
+# sys.exitfunc = my_atexit
+# """
+# a = """
+# import sys
+# import atexit
+# atexit.register(my_atexit)
+# """
+# self.check(b, a)
+#
+# def test_names_import(self):
+# b = """
+# import sys, crumbs
+# sys.exitfunc = my_func
+# """
+# a = """
+# import sys, crumbs, atexit
+# atexit.register(my_func)
+# """
+# self.check(b, a)
+#
+# def test_complex_expression(self):
+# b = """
+# import sys
+# sys.exitfunc = do(d)/a()+complex(f=23, g=23)*expression
+# """
+# a = """
+# import sys
+# import atexit
+# atexit.register(do(d)/a()+complex(f=23, g=23)*expression)
+# """
+# self.check(b, a)
+#
+# def test_comments(self):
+# b = """
+# import sys # Foo
+# sys.exitfunc = f # Blah
+# """
+# a = """
+# import sys
+# import atexit # Foo
+# atexit.register(f) # Blah
+# """
+# self.check(b, a)
+#
+# b = """
+# import apples, sys, crumbs, larry # Pleasant comments
+# sys.exitfunc = func
+# """
+# a = """
+# import apples, sys, crumbs, larry, atexit # Pleasant comments
+# atexit.register(func)
+# """
+# self.check(b, a)
+#
+# def test_in_a_function(self):
+# b = """
+# import sys
+# def f():
+# sys.exitfunc = func
+# """
+# a = """
+# import sys
+# import atexit
+# def f():
+# atexit.register(func)
+# """
+# self.check(b, a)
+#
+# def test_no_sys_import(self):
+# b = """sys.exitfunc = f"""
+# a = """atexit.register(f)"""
+# msg = ("Can't find sys import; Please add an atexit import at the "
+# "top of your file.")
+# self.warns(b, a, msg)
+#
+#
+# def test_unchanged(self):
+# s = """f(sys.exitfunc)"""
+# self.unchanged(s)
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_list.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_list.py
new file mode 100644
index 0000000..16fb84c
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_list.py
@@ -0,0 +1,192 @@
+# -*- coding: utf-8 -*-
+"""
+Tests for the backported class:`list` class.
+"""
+
+from __future__ import absolute_import, unicode_literals, print_function
+from future.builtins import *
+from future import utils
+from future.tests.base import unittest, expectedFailurePY2
+
+
+class TestList(unittest.TestCase):
+ def test_isinstance_list(self):
+ self.assertTrue(isinstance([], list))
+ self.assertEqual([1, 2, 3], list([1, 2, 3]))
+
+ def test_isinstance_list_subclass(self):
+ """
+ Issue #89
+ """
+ value = list([1, 2, 3])
+ class Magic(list):
+ pass
+ self.assertTrue(isinstance(value, list))
+ self.assertFalse(isinstance(value, Magic))
+
+ def test_list_empty(self):
+ """
+ list() -> []
+ """
+ self.assertEqual(list(), [])
+
+ def test_list_clear(self):
+ l = list()
+ l.append(1)
+ l.clear()
+ self.assertEqual(len(l), 0)
+ l.extend([2, 3])
+ l.clear()
+ self.assertEqual(len(l), 0)
+
+ def test_list_list(self):
+ self.assertEqual(list(list()), [])
+ self.assertTrue(isinstance(list(list()), list))
+
+ def test_list_list2(self):
+ """
+ Issue #50
+ """
+ l = list([1, 2, 3])
+ l2 = list(l)
+ self.assertEqual(len(l2), 3)
+ self.assertEqual(l2, [1, 2, 3])
+
+ def test_list_equal(self):
+ l = [1, 3, 5]
+ self.assertEqual(list(l), l)
+
+ def test_list_getitem(self):
+ l = list('ABCD')
+ self.assertEqual(l, ['A', 'B', 'C', 'D'])
+ self.assertEqual(l[0], 'A')
+ self.assertEqual(l[-1], 'D')
+ self.assertEqual(l[0:1], ['A'])
+ self.assertEqual(l[0:2], ['A', 'B'])
+ self.assertEqual(''.join(l[:]), 'ABCD')
+
+ def test_list_setitem(self):
+ l = list('ABCD')
+ l[1] = b'B'
+ self.assertEqual(l, ['A', b'B', 'C', 'D'])
+
+ def test_list_iteration(self):
+ l = list('ABCD')
+ for item in l:
+ self.assertTrue(isinstance(item, str))
+
+ def test_list_plus_list(self):
+ l1 = list('ABCD')
+ l2 = ['E', 'F', 'G', 'H']
+ self.assertEqual(l1 + l2, ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'])
+ self.assertEqual(type(l1 + l2), list)
+ self.assertEqual(l2 + l1, ['E', 'F', 'G', 'H', 'A', 'B', 'C', 'D'])
+ self.assertEqual(l2 + l1, list('EFGHABCD'))
+ self.assertEqual(type(l2 + l1), list)
+ self.assertTrue(isinstance(l2 + l1, list))
+
+ def test_list_contains_something(self):
+ l = list('ABCD')
+ self.assertTrue('A' in l)
+ self.assertFalse(['A', 'B'] in l)
+
+ def test_list_index(self):
+ l = list('ABCD')
+ self.assertEqual(l.index('B'), 1)
+ with self.assertRaises(ValueError):
+ l.index('')
+
+ def test_copy(self):
+ l = list('ABCD')
+ l2 = l.copy()
+ self.assertEqual(l, l2)
+ l2.pop()
+ self.assertNotEqual(l, l2)
+
+ # @unittest.skip('Fails on Python <= 2.7.6 due to list subclass slicing bug')
+ def test_slice(self):
+ """
+ Do slices return newlist objects?
+ """
+ l = list(u'abcd')
+ self.assertEqual(l[:2], [u'a', u'b'])
+ # Fails due to bug on Py2:
+ # self.assertEqual(type(l[:2]), list)
+ self.assertEqual(l[-2:], [u'c', u'd'])
+ # Fails due to bug on Py2:
+ # self.assertEqual(type(l[-2:]), list)
+
+ # @unittest.skip('Fails on Python <= 2.7.6 due to list subclass slicing bug')
+ def test_subclassing(self):
+ """
+ Can newlist be subclassed and do list methods then return instances of
+ the same class? (This is the Py3 behaviour).
+ """
+ class SubClass(list):
+ pass
+ l = SubClass(u'abcd')
+ l2 = SubClass(str(u'abcd'))
+ self.assertEqual(type(l), SubClass)
+ self.assertTrue(isinstance(l, list))
+ # Fails on Py2.7 but passes on Py3.3:
+ # self.assertEqual(type(l + l), list)
+ self.assertTrue(isinstance(l[0], str))
+ self.assertEqual(type(l2[0]), str)
+ # This is not true on Py3.3:
+ # self.assertEqual(type(l[:2]), SubClass)
+ self.assertTrue(isinstance(l[:2], list))
+
+ def test_subclassing_2(self):
+ """
+ Tests __new__ method in subclasses. Fails in versions <= 0.11.4
+ """
+ class SubClass(list):
+ def __new__(cls, *args, **kwargs):
+ self = list.__new__(cls, *args, **kwargs)
+ assert type(self) == SubClass
+ return self
+ l = SubClass(u'abcd')
+ self.assertEqual(type(l), SubClass)
+ self.assertEqual(l, [u'a', u'b', u'c', u'd'])
+
+ def test_bool(self):
+ l = list([])
+ l2 = list([1, 3, 5])
+ self.assertFalse(bool(l))
+ self.assertTrue(bool(l2))
+ l2.clear()
+ self.assertFalse(bool(l2))
+
+ @expectedFailurePY2
+ def test_multiple_inheritance(self):
+ """
+ Issue #96 (for newdict instead of newobject)
+ """
+ if utils.PY2:
+ from collections import Container
+ else:
+ from collections.abc import Container
+
+ class Base(list):
+ pass
+
+ class Foo(Base, Container):
+ def __contains__(self, item):
+ return False
+
+ @expectedFailurePY2
+ def test_with_metaclass_and_list(self):
+ """
+ Issue #91 (for newdict instead of newobject)
+ """
+ from future.utils import with_metaclass
+
+ class MetaClass(type):
+ pass
+
+ class TestClass(with_metaclass(MetaClass, list)):
+ pass
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_magicsuper.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_magicsuper.py
new file mode 100644
index 0000000..e5bbe09
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_magicsuper.py
@@ -0,0 +1,135 @@
+"""
+Tests for the super() function.
+
+Based on Ryan Kelly's magicsuper.tests
+"""
+
+from __future__ import absolute_import, division, print_function, unicode_literals
+import future.builtins.newsuper
+from future.builtins import super
+from future.tests.base import unittest
+from future import utils
+
+
+class TestMagicSuper(unittest.TestCase):
+
+ def test_basic_diamond(self):
+ class Base(object):
+ def calc(self,value):
+ return 2 * value
+ class Sub1(Base):
+ def calc(self,value):
+ return 7 + super().calc(value)
+ class Sub2(Base):
+ def calc(self,value):
+ return super().calc(value) - 1
+ class Diamond(Sub1,Sub2):
+ def calc(self,value):
+ return 3 * super().calc(value)
+ b = Base()
+ s1 = Sub1()
+ s2 = Sub2()
+ d = Diamond()
+ for x in range(10):
+ self.assertEqual(b.calc(x),2*x)
+ self.assertEqual(s1.calc(x),7+(2*x))
+ self.assertEqual(s2.calc(x),(2*x)-1)
+ self.assertEqual(d.calc(x),3*(7+((2*x)-1)))
+
+ def test_with_unrelated_methods(self):
+ class Base(object):
+ def hello(self):
+ return "world"
+ class Sub(Base):
+ def hello(self):
+ return "hello " + super().hello()
+ def other(self):
+ pass
+ class SubSub(Sub):
+ def other(self):
+ return super().other()
+ ss = SubSub()
+ self.assertEqual(ss.hello(),"hello world")
+
+ @unittest.skipIf(utils.PY3, "this test isn't relevant on Py3")
+ def test_fails_for_oldstyle_class(self):
+ class OldStyle:
+ def testme(self):
+ return super().testme()
+ o = OldStyle()
+ self.assertRaises(RuntimeError,o.testme)
+
+ def test_fails_for_raw_functions(self):
+ def not_a_method():
+ super().not_a_method()
+ self.assertRaises(RuntimeError,not_a_method)
+ def not_a_method(self):
+ super().not_a_method()
+ if utils.PY2:
+ self.assertRaises(RuntimeError,not_a_method,self)
+ else:
+ self.assertRaises(AttributeError,not_a_method,self)
+
+ def assertSuperEquals(self,sobj1,sobj2):
+ assert sobj1.__self__ is sobj2.__self__
+ assert sobj1.__self_class__ is sobj2.__self_class__
+ assert sobj1.__thisclass__ is sobj2.__thisclass__
+
+ def test_call_with_args_does_nothing(self):
+ if utils.PY2:
+ from __builtin__ import super as builtin_super
+ else:
+ from builtins import super as builtin_super
+ class Base(object):
+ def calc(self,value):
+ return 2 * value
+ class Sub1(Base):
+ def calc(self,value):
+ return 7 + super().calc(value)
+ class Sub2(Base):
+ def calc(self,value):
+ return super().calc(value) - 1
+ class Diamond(Sub1,Sub2):
+ def calc(self,value):
+ return 3 * super().calc(value)
+ for cls in (Base,Sub1,Sub2,Diamond,):
+ obj = cls()
+ self.assertSuperEquals(builtin_super(cls), super(cls))
+ self.assertSuperEquals(builtin_super(cls,obj), super(cls,obj))
+
+ @unittest.skipIf(utils.PY3, "this test isn't relevant for Py3's super()")
+ def test_superm(self):
+ class Base(object):
+ def getit(self):
+ return 2
+ class Sub(Base):
+ def getit(self):
+ return 10 * future.builtins.newsuper.superm()
+ s = Sub()
+ self.assertEqual(s.getit(),20)
+
+ def test_use_inside_dunder_new(self):
+ class Terminal(str):
+ def __new__(cls, value, token_type):
+ self = super().__new__(cls, value)
+ self.token_type = token_type
+ return self
+ DOT = Terminal(".", "dit")
+ self.assertTrue(isinstance(DOT, str))
+ self.assertTrue(isinstance(DOT, Terminal))
+
+ def test_use_inside_classmethod(self):
+ class Base(object):
+ @classmethod
+ def getit(cls):
+ return 42
+ class Singleton(Base):
+ @classmethod
+ def getit(cls):
+ print(super())
+ return super().getit() + 1
+ self.assertEqual(Singleton.getit(), 43)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_object.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_object.py
new file mode 100644
index 0000000..4f99cb5
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_object.py
@@ -0,0 +1,289 @@
+"""
+Tests to make sure the newobject object (which defines Python 2-compatible
+``__unicode__`` and ``next`` methods) is working.
+"""
+
+from __future__ import absolute_import, division
+from future import utils
+from future.builtins import object, str, next, int, super
+from future.utils import implements_iterator, python_2_unicode_compatible
+from future.tests.base import unittest, expectedFailurePY2
+
+
+class TestNewObject(unittest.TestCase):
+ def test_object_implements_py2_unicode_method(self):
+ my_unicode_str = u'Unicode string: \u5b54\u5b50'
+ class A(object):
+ def __str__(self):
+ return my_unicode_str
+ a = A()
+ self.assertEqual(len(str(a)), 18)
+ if utils.PY2:
+ self.assertTrue(hasattr(a, '__unicode__'))
+ else:
+ self.assertFalse(hasattr(a, '__unicode__'))
+ self.assertEqual(str(a), my_unicode_str)
+ self.assertTrue(isinstance(str(a).encode('utf-8'), bytes))
+ if utils.PY2:
+ self.assertTrue(type(unicode(a)) == unicode)
+ self.assertEqual(unicode(a), my_unicode_str)
+
+ # Manual equivalent on Py2 without the decorator:
+ if not utils.PY3:
+ class B(object):
+ def __unicode__(self):
+ return u'Unicode string: \u5b54\u5b50'
+ def __str__(self):
+ return unicode(self).encode('utf-8')
+ b = B()
+ assert str(a) == str(b)
+
+ def test_implements_py2_iterator(self):
+
+ class Upper(object):
+ def __init__(self, iterable):
+ self._iter = iter(iterable)
+ def __next__(self): # note the Py3 interface
+ return next(self._iter).upper()
+ def __iter__(self):
+ return self
+
+ self.assertEqual(list(Upper('hello')), list('HELLO'))
+
+ # Try combining it with the next() function:
+
+ class MyIter(object):
+ def __next__(self):
+ return 'Next!'
+ def __iter__(self):
+ return self
+
+ itr = MyIter()
+ self.assertEqual(next(itr), 'Next!')
+
+ itr2 = MyIter()
+ for i, item in enumerate(itr2):
+ if i >= 10:
+ break
+ self.assertEqual(item, 'Next!')
+
+ def test_implements_py2_nonzero(self):
+
+ class EvenIsTrue(object):
+ """
+ An integer that evaluates to True if even.
+ """
+ def __init__(self, my_int):
+ self.my_int = my_int
+ def __bool__(self):
+ return self.my_int % 2 == 0
+ def __add__(self, other):
+ return type(self)(self.my_int + other)
+
+ k = EvenIsTrue(5)
+ self.assertFalse(k)
+ self.assertFalse(bool(k))
+ self.assertTrue(k + 1)
+ self.assertTrue(bool(k + 1))
+ self.assertFalse(k + 2)
+
+
+ def test_int_implements_py2_nonzero(self):
+ """
+ Tests whether the newint object provides a __nonzero__ method that
+ maps to __bool__ in case the user redefines __bool__ in a subclass of
+ newint.
+ """
+
+ class EvenIsTrue(int):
+ """
+ An integer that evaluates to True if even.
+ """
+ def __bool__(self):
+ return self % 2 == 0
+ def __add__(self, other):
+ val = super().__add__(other)
+ return type(self)(val)
+
+ k = EvenIsTrue(5)
+ self.assertFalse(k)
+ self.assertFalse(bool(k))
+ self.assertTrue(k + 1)
+ self.assertTrue(bool(k + 1))
+ self.assertFalse(k + 2)
+
+ def test_non_iterator(self):
+ """
+ The default behaviour of next(o) for a newobject o should be to raise a
+ TypeError, as with the corresponding builtin object.
+ """
+ o = object()
+ with self.assertRaises(TypeError):
+ next(o)
+
+ def test_bool_empty_object(self):
+ """
+ The default result of bool(newobject()) should be True, as with builtin
+ objects.
+ """
+ o = object()
+ self.assertTrue(bool(o))
+
+ class MyClass(object):
+ pass
+
+ obj = MyClass()
+ self.assertTrue(bool(obj))
+
+ def test_isinstance_object_subclass(self):
+ """
+ This was failing before
+ """
+ class A(object):
+ pass
+ a = A()
+
+ class B(object):
+ pass
+ b = B()
+
+ self.assertFalse(isinstance(a, B))
+ self.assertFalse(isinstance(b, A))
+ self.assertTrue(isinstance(a, A))
+ self.assertTrue(isinstance(b, B))
+
+ class C(A):
+ pass
+ c = C()
+
+ self.assertTrue(isinstance(c, A))
+ self.assertFalse(isinstance(c, B))
+ self.assertFalse(isinstance(a, C))
+ self.assertFalse(isinstance(b, C))
+ self.assertTrue(isinstance(c, C))
+
+ @expectedFailurePY2
+ def test_types_isinstance_newobject(self):
+ a = list()
+ b = dict()
+ c = set()
+ self.assertTrue(isinstance(a, object))
+ self.assertTrue(isinstance(b, object))
+ self.assertTrue(isinstance(c, object))
+
+ # Old-style class instances on Py2 should still report as an instance
+ # of object as usual on Py2:
+ class D:
+ pass
+ d = D()
+ self.assertTrue(isinstance(d, object))
+
+ e = object()
+ self.assertTrue(isinstance(e, object))
+
+ class F(object):
+ pass
+ f = F()
+ self.assertTrue(isinstance(f, object))
+
+ class G(F):
+ pass
+ g = G()
+ self.assertTrue(isinstance(g, object))
+
+ class H():
+ pass
+ h = H()
+ self.assertTrue(isinstance(h, object))
+
+ def test_long_special_method(self):
+ class A(object):
+ def __int__(self):
+ return 0
+ a = A()
+ self.assertEqual(int(a), 0)
+ if utils.PY2:
+ self.assertEqual(long(a), 0)
+
+ def test_multiple_inheritance(self):
+ """
+ Issue #96
+ """
+ if utils.PY2:
+ from collections import Container
+ else:
+ from collections.abc import Container
+
+ class Base(object):
+ pass
+
+ class Foo(Base, Container):
+ def __contains__(self, item):
+ return False
+
+ def test_with_metaclass_and_object(self):
+ """
+ Issue #91
+ """
+ from future.utils import with_metaclass
+
+ class MetaClass(type):
+ pass
+
+ class TestClass(with_metaclass(MetaClass, object)):
+ pass
+
+ def test_bool(self):
+ """
+ Issue #211
+ """
+ from builtins import object
+
+ class ResultSet(object):
+ def __len__(self):
+ return 0
+
+ self.assertTrue(bool(ResultSet()) is False)
+
+ class ResultSet(object):
+ def __len__(self):
+ return 2
+
+ self.assertTrue(bool(ResultSet()) is True)
+
+ def test_bool2(self):
+ """
+ If __bool__ is defined, the presence or absence of __len__ should
+ be irrelevant.
+ """
+ from builtins import object
+
+ class TrueThing(object):
+ def __bool__(self):
+ return True
+ def __len__(self):
+ raise RuntimeError('__len__ should not be called')
+
+ self.assertTrue(bool(TrueThing()))
+
+ class FalseThing(object):
+ def __bool__(self):
+ return False
+ def __len__(self):
+ raise RuntimeError('__len__ should not be called')
+
+ self.assertFalse(bool(FalseThing()))
+
+ def test_cannot_assign_new_attributes_to_object(self):
+ """
+ New attributes cannot be assigned to object() instances in Python.
+ The same should apply to newobject.
+ """
+ from builtins import object
+
+ with self.assertRaises(AttributeError):
+ object().arbitrary_attribute_name = True
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_pasteurize.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_pasteurize.py
new file mode 100644
index 0000000..2b6e2ee
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_pasteurize.py
@@ -0,0 +1,256 @@
+# -*- coding: utf-8 -*-
+"""
+This module contains snippets of Python 3 code (invalid Python 2) and
+tests for whether they can be passed to ``pasteurize`` and
+immediately run under both Python 2 and Python 3.
+"""
+
+from __future__ import print_function, absolute_import
+
+import pprint
+from subprocess import Popen, PIPE
+import tempfile
+import os
+
+from future.tests.base import CodeHandler, unittest, skip26
+
+
+class TestPasteurize(CodeHandler):
+ """
+ After running ``pasteurize``, these Python 3 code snippets should run
+ on both Py3 and Py2.
+ """
+
+ def setUp(self):
+ # For tests that need a text file:
+ _, self.textfilename = tempfile.mkstemp(text=True)
+ super(TestPasteurize, self).setUp()
+
+ def tearDown(self):
+ os.unlink(self.textfilename)
+
+ @skip26 # Python 2.6's lib2to3 causes the "from builtins import
+ # range" line to be stuck at the bottom of the module!
+ def test_range_slice(self):
+ """
+ After running ``pasteurize``, this Python 3 code should run
+ quickly on both Py3 and Py2 without a MemoryError
+ """
+ code = '''
+ for i in range(10**8)[:10]:
+ pass
+ '''
+ self.unchanged(code, from3=True)
+
+ def test_print(self):
+ """
+ This Python 3-only code is a SyntaxError on Py2 without the
+ print_function import from __future__.
+ """
+ code = '''
+ import sys
+ print('Hello', file=sys.stderr)
+ '''
+ self.unchanged(code, from3=True)
+
+ def test_division(self):
+ """
+ True division should not be screwed up by conversion from 3 to both
+ """
+ code = '''
+ x = 3 / 2
+ assert x == 1.5
+ '''
+ self.unchanged(code, from3=True)
+
+ # TODO: write / fix the raise_ fixer so that it uses the raise_ function
+ @unittest.expectedFailure
+ def test_exception_indentation(self):
+ """
+ As of v0.11.2, pasteurize broke the indentation of ``raise`` statements
+ using with_traceback. Test for this.
+ """
+ before = '''
+ import sys
+ if True:
+ try:
+ 'string' + 1
+ except TypeError:
+ ty, va, tb = sys.exc_info()
+ raise TypeError("can't do that!").with_traceback(tb)
+ '''
+ after = '''
+ import sys
+ from future.utils import raise_with_traceback
+ if True:
+ try:
+ 'string' + 1
+ except TypeError:
+ ty, va, tb = sys.exc_info()
+ raise_with_traceback(TypeError("can't do that!"), tb)
+ '''
+ self.convert_check(before, after, from3=True)
+
+ # TODO: fix and test this test
+ @unittest.expectedFailure
+ def test_urllib_request(self):
+ """
+ Example Python 3 code using the new urllib.request module.
+
+ Does the ``pasteurize`` script handle this?
+ """
+ before = """
+ import pprint
+ import urllib.request
+
+ URL = 'http://pypi.python.org/pypi/{}/json'
+ package = 'future'
+
+ r = urllib.request.urlopen(URL.format(package))
+ pprint.pprint(r.read())
+ """
+ after = """
+ import pprint
+ import future.standard_library.urllib.request as urllib_request
+
+ URL = 'http://pypi.python.org/pypi/{}/json'
+ package = 'future'
+
+ r = urllib_request.urlopen(URL.format(package))
+ pprint.pprint(r.read())
+ """
+
+ self.convert_check(before, after, from3=True)
+
+ def test_urllib_refactor2(self):
+ before = """
+ import urllib.request, urllib.parse
+
+ f = urllib.request.urlopen(url, timeout=15)
+ filename = urllib.parse.urlparse(url)[2].split('/')[-1]
+ """
+
+ after = """
+ from future.standard_library.urllib import request as urllib_request
+ from future.standard_library.urllib import parse as urllib_parse
+
+ f = urllib_request.urlopen(url, timeout=15)
+ filename = urllib_parse.urlparse(url)[2].split('/')[-1]
+ """
+
+ def test_correct_exit_status(self):
+ """
+ Issue #119: futurize and pasteurize were not exiting with the correct
+ status code. This is because the status code returned from
+ libfuturize.main.main() etc. was a ``newint``, which sys.exit() always
+ translates into 1!
+ """
+ from libpasteurize.main import main
+ # Try pasteurizing this test script:
+ retcode = main([self.textfilename])
+ self.assertTrue(isinstance(retcode, int)) # i.e. Py2 builtin int
+
+
+class TestFuturizeAnnotations(CodeHandler):
+ @unittest.expectedFailure
+ def test_return_annotations_alone(self):
+ before = "def foo() -> 'bar': pass"
+ after = """
+ def foo(): pass
+ foo.__annotations__ = {'return': 'bar'}
+ """
+ self.convert_check(before, after, from3=True)
+
+ b = """
+ def foo() -> "bar":
+ print "baz"
+ print "what's next, again?"
+ """
+ a = """
+ def foo():
+ print "baz"
+ print "what's next, again?"
+ """
+ self.convert_check(b, a, from3=True)
+
+ @unittest.expectedFailure
+ def test_single_param_annotations(self):
+ b = "def foo(bar:'baz'): pass"
+ a = """
+ def foo(bar): pass
+ foo.__annotations__ = {'bar': 'baz'}
+ """
+ self.convert_check(b, a, from3=True)
+
+ b = """
+ def foo(bar:"baz"="spam"):
+ print("what's next, again?")
+ print("whatever.")
+ """
+ a = """
+ def foo(bar="spam"):
+ print("what's next, again?")
+ print("whatever.")
+ foo.__annotations__ = {'bar': 'baz'}
+ """
+ self.convert_check(b, a, from3=True)
+
+ def test_multiple_param_annotations(self):
+ b = "def foo(bar:'spam'=False, baz:'eggs'=True, ham:False='spaghetti'): pass"
+ a = "def foo(bar=False, baz=True, ham='spaghetti'): pass"
+ self.convert_check(b, a, from3=True)
+
+ b = """
+ def foo(bar:"spam"=False, baz:"eggs"=True, ham:False="spam"):
+ print("this is filler, just doing a suite")
+ print("suites require multiple lines.")
+ """
+ a = """
+ def foo(bar=False, baz=True, ham="spam"):
+ print("this is filler, just doing a suite")
+ print("suites require multiple lines.")
+ """
+ self.convert_check(b, a, from3=True)
+
+ def test_mixed_annotations(self):
+ b = "def foo(bar=False, baz:'eggs'=True, ham:False='spaghetti') -> 'zombies': pass"
+ a = "def foo(bar=False, baz=True, ham='spaghetti'): pass"
+ self.convert_check(b, a, from3=True)
+
+ b = """
+ def foo(bar:"spam"=False, baz=True, ham:False="spam") -> 'air':
+ print("this is filler, just doing a suite")
+ print("suites require multiple lines.")
+ """
+ a = """
+ def foo(bar=False, baz=True, ham="spam"):
+ print("this is filler, just doing a suite")
+ print("suites require multiple lines.")
+ """
+ self.convert_check(b, a, from3=True)
+
+ b = "def foo(bar) -> 'brains': pass"
+ a = "def foo(bar): pass"
+ self.convert_check(b, a, from3=True)
+
+ def test_functions_unchanged(self):
+ s = "def foo(): pass"
+ self.unchanged(s, from3=True)
+
+ s = """
+ def foo():
+ pass
+ pass
+ """
+ self.unchanged(s, from3=True)
+
+ s = """
+ def foo(bar='baz'):
+ pass
+ pass
+ """
+ self.unchanged(s, from3=True)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_py2_str_literals_to_bytes.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_py2_str_literals_to_bytes.py
new file mode 100644
index 0000000..47866c8
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_py2_str_literals_to_bytes.py
@@ -0,0 +1 @@
+a = '123'
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_range.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_range.py
new file mode 100644
index 0000000..dba1522
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_range.py
@@ -0,0 +1,216 @@
+# -*- coding: utf-8 -*-
+"""
+Tests for the backported class:`range` class.
+"""
+
+from future.builtins import range
+from future.tests.base import unittest
+
+from operator import attrgetter
+
+from future.utils import PY2
+
+if PY2:
+ from collections import Iterator, Sequence
+else:
+ from collections.abc import Iterator, Sequence
+
+
+class RangeTests(unittest.TestCase):
+ def test_range(self):
+ self.assertTrue(isinstance(range(0), Sequence))
+ self.assertTrue(isinstance(reversed(range(0)), Iterator))
+
+ def test_bool_range(self):
+ self.assertFalse(range(0))
+ self.assertTrue(range(1))
+ self.assertFalse(range(1, 1))
+ self.assertFalse(range(5, 2))
+
+ def test_equality_range(self):
+ self.assertEqual(range(7), range(7))
+ self.assertEqual(range(0), range(1, 1))
+ self.assertEqual(range(0, 10, 3), range(0, 11, 3))
+
+ def test_contains(self):
+ self.assertIn(1, range(2))
+ self.assertNotIn(10, range(2))
+ self.assertNotIn(None, range(2))
+ self.assertNotIn("", range(2))
+
+ # Use strict equality of attributes when slicing to catch subtle differences
+ def assertRangesEqual(self, r1, r2):
+ by_attrs = attrgetter('start', 'stop', 'step')
+ self.assertEqual(by_attrs(r1), by_attrs(r2))
+
+ def test_slice_empty_range(self):
+ self.assertRangesEqual(range(0)[:], range(0))
+ self.assertRangesEqual(range(0)[::-1], range(-1, -1, -1))
+
+ def test_slice_overflow_range(self):
+ r = range(8)
+ self.assertRangesEqual(r[2:200], range(2, 8))
+ self.assertRangesEqual(r[-200:-2], range(0, 6))
+
+ def test_slice_range(self):
+ r = range(-8, 8)
+ self.assertRangesEqual(r[:], range(-8, 8))
+ self.assertRangesEqual(r[:2], range(-8, -6))
+ self.assertRangesEqual(r[:-2], range(-8, 6))
+ self.assertRangesEqual(r[2:], range(-6, 8))
+ self.assertRangesEqual(r[-2:], range(6, 8))
+ self.assertRangesEqual(r[2:-2], range(-6, 6))
+
+ def test_rev_slice_range(self):
+ r = range(-8, 8)
+ self.assertRangesEqual(r[::-1], range(7, -9, -1))
+ self.assertRangesEqual(r[:2:-1], range(7, -6, -1))
+ self.assertRangesEqual(r[:-2:-1], range(7, 6, -1))
+ self.assertRangesEqual(r[2::-1], range(-6, -9, -1))
+ self.assertRangesEqual(r[-2::-1], range(6, -9, -1))
+ self.assertRangesEqual(r[-2:2:-1], range(6, -6, -1))
+
+ def test_slice_rev_range(self):
+ r = range(8, -8, -1)
+ self.assertRangesEqual(r[:], range(8, -8, -1))
+ self.assertRangesEqual(r[:2], range(8, 6, -1))
+ self.assertRangesEqual(r[:-2], range(8, -6, -1))
+ self.assertRangesEqual(r[2:], range(6, -8, -1))
+ self.assertRangesEqual(r[-2:], range(-6, -8, -1))
+ self.assertRangesEqual(r[2:-2], range(6, -6, -1))
+
+ def test_rev_slice_rev_range(self):
+ r = range(8, -8, -1)
+ self.assertRangesEqual(r[::-1], range(-7, 9))
+ self.assertRangesEqual(r[:2:-1], range(-7, 6))
+ self.assertRangesEqual(r[:-2:-1], range(-7, -6))
+ self.assertRangesEqual(r[2::-1], range(6, 9))
+ self.assertRangesEqual(r[-2::-1], range(-6, 9))
+ self.assertRangesEqual(r[-2:2:-1], range(-6, 6))
+
+ def test_stepped_slice_range(self):
+ r = range(-8, 8)
+ self.assertRangesEqual(r[::2], range(-8, 8, 2))
+ self.assertRangesEqual(r[:2:2], range(-8, -6, 2))
+ self.assertRangesEqual(r[:-2:2], range(-8, 6, 2))
+ self.assertRangesEqual(r[2::2], range(-6, 8, 2))
+ self.assertRangesEqual(r[-2::2], range(6, 8, 2))
+ self.assertRangesEqual(r[2:-2:2], range(-6, 6, 2))
+
+ def test_rev_stepped_slice_range(self):
+ r = range(-8, 8)
+ self.assertRangesEqual(r[::-2], range(7, -9, -2))
+ self.assertRangesEqual(r[:2:-2], range(7, -6, -2))
+ self.assertRangesEqual(r[:-2:-2], range(7, 6, -2))
+ self.assertRangesEqual(r[2::-2], range(-6, -9, -2))
+ self.assertRangesEqual(r[-2::-2], range(6, -9, -2))
+ self.assertRangesEqual(r[-2:2:-2], range(6, -6, -2))
+
+ def test_stepped_slice_rev_range(self):
+ r = range(8, -8, -1)
+ self.assertRangesEqual(r[::2], range(8, -8, -2))
+ self.assertRangesEqual(r[:2:2], range(8, 6, -2))
+ self.assertRangesEqual(r[:-2:2], range(8, -6, -2))
+ self.assertRangesEqual(r[2::2], range(6, -8, -2))
+ self.assertRangesEqual(r[-2::2], range(-6, -8, -2))
+ self.assertRangesEqual(r[2:-2:2], range(6, -6, -2))
+
+ def test_rev_stepped_slice_rev_range(self):
+ r = range(8, -8, -1)
+ self.assertRangesEqual(r[::-2], range(-7, 9, 2))
+ self.assertRangesEqual(r[:2:-2], range(-7, 6, 2))
+ self.assertRangesEqual(r[:-2:-2], range(-7, -6, 2))
+ self.assertRangesEqual(r[2::-2], range(6, 9, 2))
+ self.assertRangesEqual(r[-2::-2], range(-6, 9, 2))
+ self.assertRangesEqual(r[-2:2:-2], range(-6, 6, 2))
+
+ def test_slice_stepped_range(self):
+ r = range(-8, 8, 2)
+ self.assertRangesEqual(r[:], range(-8, 8, 2))
+ self.assertRangesEqual(r[:2], range(-8, -4, 2))
+ self.assertRangesEqual(r[:-2], range(-8, 4, 2))
+ self.assertRangesEqual(r[2:], range(-4, 8, 2))
+ self.assertRangesEqual(r[-2:], range(4, 8, 2))
+ self.assertRangesEqual(r[2:-2], range(-4, 4, 2))
+
+ def test_rev_slice_stepped_range(self):
+ r = range(-8, 8, 2)
+ self.assertRangesEqual(r[::-1], range(6, -10, -2))
+ self.assertRangesEqual(r[:2:-1], range(6, -4, -2))
+ self.assertRangesEqual(r[:-2:-1], range(6, 4, -2))
+ self.assertRangesEqual(r[2::-1], range(-4, -10, -2))
+ self.assertRangesEqual(r[-2::-1], range(4, -10, -2))
+ self.assertRangesEqual(r[-2:2:-1], range(4, -4, -2))
+
+ def test_slice_rev_stepped_range(self):
+ r = range(8, -8, -2)
+ self.assertRangesEqual(r[:], range(8, -8, -2))
+ self.assertRangesEqual(r[:2], range(8, 4, -2))
+ self.assertRangesEqual(r[:-2], range(8, -4, -2))
+ self.assertRangesEqual(r[2:], range(4, -8, -2))
+ self.assertRangesEqual(r[-2:], range(-4, -8, -2))
+ self.assertRangesEqual(r[2:-2], range(4, -4, -2))
+
+ def test_rev_slice_rev_stepped_range(self):
+ r = range(8, -8, -2)
+ self.assertRangesEqual(r[::-1], range(-6, 10, 2))
+ self.assertRangesEqual(r[:2:-1], range(-6, 4, 2))
+ self.assertRangesEqual(r[:-2:-1], range(-6, -4, 2))
+ self.assertRangesEqual(r[2::-1], range(4, 10, 2))
+ self.assertRangesEqual(r[-2::-1], range(-4, 10, 2))
+ self.assertRangesEqual(r[-2:2:-1], range(-4, 4, 2))
+
+ def test_stepped_slice_stepped_range(self):
+ r = range(-8, 8, 2)
+ self.assertRangesEqual(r[::2], range(-8, 8, 4))
+ self.assertRangesEqual(r[:2:2], range(-8, -4, 4))
+ self.assertRangesEqual(r[:-2:2], range(-8, 4, 4))
+ self.assertRangesEqual(r[2::2], range(-4, 8, 4))
+ self.assertRangesEqual(r[-2::2], range(4, 8, 4))
+ self.assertRangesEqual(r[2:-2:2], range(-4, 4, 4))
+
+ def test_rev_stepped_slice_stepped_range(self):
+ r = range(-8, 8, 2)
+ self.assertRangesEqual(r[::-2], range(6, -10, -4))
+ self.assertRangesEqual(r[:2:-2], range(6, -4, -4))
+ self.assertRangesEqual(r[:-2:-2], range(6, 4, -4))
+ self.assertRangesEqual(r[2::-2], range(-4, -10, -4))
+ self.assertRangesEqual(r[-2::-2], range(4, -10, -4))
+ self.assertRangesEqual(r[-2:2:-2], range(4, -4, -4))
+
+ def test_stepped_slice_rev_stepped_range(self):
+ r = range(8, -8, -2)
+ self.assertRangesEqual(r[::2], range(8, -8, -4))
+ self.assertRangesEqual(r[:2:2], range(8, 4, -4))
+ self.assertRangesEqual(r[:-2:2], range(8, -4, -4))
+ self.assertRangesEqual(r[2::2], range(4, -8, -4))
+ self.assertRangesEqual(r[-2::2], range(-4, -8, -4))
+ self.assertRangesEqual(r[2:-2:2], range(4, -4, -4))
+
+ def test_rev_stepped_slice_rev_stepped_range(self):
+ r = range(8, -8, -2)
+ self.assertRangesEqual(r[::-2], range(-6, 10, 4))
+ self.assertRangesEqual(r[:2:-2], range(-6, 4, 4))
+ self.assertRangesEqual(r[:-2:-2], range(-6, -4, 4))
+ self.assertRangesEqual(r[2::-2], range(4, 10, 4))
+ self.assertRangesEqual(r[-2::-2], range(-4, 10, 4))
+ self.assertRangesEqual(r[-2:2:-2], range(-4, 4, 4))
+
+ def test_slice_zero_step(self):
+ msg = '^slice step cannot be zero$'
+ with self.assertRaisesRegex(ValueError, msg):
+ range(8)[::0]
+
+ def test_properties(self):
+ # Exception string differs between PY2/3
+ r = range(0)
+ with self.assertRaises(AttributeError):
+ r.start = 0
+ with self.assertRaises(AttributeError):
+ r.stop = 0
+ with self.assertRaises(AttributeError):
+ r.step = 0
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_requests.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_requests.py
new file mode 100644
index 0000000..e362a1f
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_requests.py
@@ -0,0 +1,107 @@
+"""
+Tests for whether the standard library hooks in ``future`` are compatible with
+the ``requests`` package.
+"""
+
+from __future__ import absolute_import, unicode_literals, print_function
+from future import standard_library
+from future.tests.base import unittest, CodeHandler
+import textwrap
+import sys
+import os
+import io
+
+
+# Don't import requests first. This avoids the problem we want to expose:
+# with standard_library.suspend_hooks():
+# try:
+# import requests
+# except ImportError:
+# requests = None
+
+
+class write_module(object):
+ """
+ A context manager to streamline the tests. Creates a temp file for a
+ module designed to be imported by the ``with`` block, then removes it
+ afterwards.
+ """
+ def __init__(self, code, tempdir):
+ self.code = code
+ self.tempdir = tempdir
+
+ def __enter__(self):
+ print('Creating {0}test_imports_future_stdlib.py ...'.format(self.tempdir))
+ with io.open(self.tempdir + 'test_imports_future_stdlib.py', 'wt',
+ encoding='utf-8') as f:
+ f.write(textwrap.dedent(self.code))
+ sys.path.insert(0, self.tempdir)
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ """
+ If an exception occurred, we leave the file for inspection.
+ """
+ sys.path.remove(self.tempdir)
+ if exc_type is None:
+ # No exception occurred
+ os.remove(self.tempdir + 'test_imports_future_stdlib.py')
+ try:
+ os.remove(self.tempdir + 'test_imports_future_stdlib.pyc')
+ except OSError:
+ pass
+
+
+class TestRequests(CodeHandler):
+ """
+ This class tests whether the requests module conflicts with the
+ standard library import hooks, as in issue #19.
+ """
+ def test_remove_hooks_then_requests(self):
+ code = """
+ from future import standard_library
+ standard_library.install_hooks()
+
+ import builtins
+ import http.client
+ import html.parser
+ """
+ with write_module(code, self.tempdir):
+ import test_imports_future_stdlib
+ standard_library.remove_hooks()
+ try:
+ import requests
+ except ImportError:
+ print("Requests doesn't seem to be available. Skipping requests test ...")
+ else:
+ r = requests.get('http://google.com')
+ self.assertTrue(r)
+ self.assertTrue(True)
+
+
+ def test_requests_cm(self):
+ """
+ Tests whether requests can be used importing standard_library modules
+ previously with the hooks context manager
+ """
+ code = """
+ from future import standard_library
+ with standard_library.hooks():
+ import builtins
+ import html.parser
+ import http.client
+ """
+ with write_module(code, self.tempdir):
+ import test_imports_future_stdlib
+ try:
+ import requests
+ except ImportError:
+ print("Requests doesn't seem to be available. Skipping requests test ...")
+ else:
+ r = requests.get('http://google.com')
+ self.assertTrue(r)
+ self.assertTrue(True)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_standard_library.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_standard_library.py
new file mode 100644
index 0000000..3ac5d2d
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_standard_library.py
@@ -0,0 +1,624 @@
+"""
+Tests for the future.standard_library module
+"""
+
+from __future__ import absolute_import, print_function
+from future import standard_library
+from future import utils
+from future.tests.base import unittest, CodeHandler, expectedFailurePY2
+
+import sys
+import tempfile
+import os
+import copy
+import textwrap
+from subprocess import CalledProcessError
+
+
+class TestStandardLibraryReorganization(CodeHandler):
+
+ def setUp(self):
+ self.interpreter = sys.executable
+ standard_library.install_aliases()
+ super(TestStandardLibraryReorganization, self).setUp()
+
+ def tearDown(self):
+ # standard_library.remove_hooks()
+ pass
+
+ def test_can_import_several(self):
+ """
+ This test failed in v0.12-pre if e.g.
+ future/standard_library/email/header.py contained:
+
+ from future import standard_library
+ standard_library.remove_hooks()
+ """
+
+ import future.moves.urllib.parse as urllib_parse
+ import future.moves.urllib.request as urllib_request
+
+ import http.server
+ for m in [urllib_parse, urllib_request, http.server]:
+ self.assertTrue(m is not None)
+
+ def test_is_py2_stdlib_module(self):
+ """
+ Tests whether the internal is_py2_stdlib_module function (called by the
+ sys.modules scrubbing functions) is reliable.
+ """
+ externalmodules = [standard_library, utils]
+ self.assertTrue(not any([standard_library.is_py2_stdlib_module(module)
+ for module in externalmodules]))
+
+ py2modules = [sys, tempfile, copy, textwrap]
+ if utils.PY2:
+ # Debugging:
+ for module in py2modules:
+ if hasattr(module, '__file__'):
+ print(module.__file__, file=sys.stderr)
+ self.assertTrue(all([standard_library.is_py2_stdlib_module(module)
+ for module in py2modules]))
+ else:
+ self.assertTrue(
+ not any ([standard_library.is_py2_stdlib_module(module)
+ for module in py2modules]))
+
+ # @unittest.skip("No longer relevant")
+ # def test_all_modules_identical(self):
+ # """
+ # Tests whether all of the old imports in RENAMES are accessible
+ # under their new names.
+ # """
+ # for (oldname, newname) in standard_library.RENAMES.items():
+ # if newname == 'winreg' and sys.platform not in ['win32', 'win64']:
+ # continue
+ # if newname in standard_library.REPLACED_MODULES:
+ # # Skip this check for e.g. the stdlib's ``test`` module,
+ # # which we have replaced completely.
+ # continue
+ # oldmod = __import__(oldname)
+ # newmod = __import__(newname)
+ # if '.' not in oldname:
+ # self.assertEqual(oldmod, newmod)
+
+ @expectedFailurePY2
+ def test_suspend_hooks(self):
+ """
+ Code like the try/except block here appears in Pyflakes v0.6.1. This
+ method tests whether suspend_hooks() works as advertised.
+ """
+ example_PY2_check = False
+ with standard_library.suspend_hooks():
+ # An example of fragile import code that we don't want to break:
+ try:
+ import builtins
+ except ImportError:
+ example_PY2_check = True
+ if utils.PY2:
+ self.assertTrue(example_PY2_check)
+ else:
+ self.assertFalse(example_PY2_check)
+ # The import should succeed again now:
+ import builtins
+
+ @expectedFailurePY2
+ def test_disable_hooks(self):
+ """
+ Tests the old (deprecated) names. These deprecated aliases should be
+ removed by version 1.0
+ """
+ example_PY2_check = False
+
+ standard_library.enable_hooks() # deprecated name
+ old_meta_path = copy.copy(sys.meta_path)
+
+ standard_library.disable_hooks()
+ standard_library.scrub_future_sys_modules()
+ if utils.PY2:
+ self.assertTrue(len(old_meta_path) == len(sys.meta_path) + 1)
+ else:
+ self.assertTrue(len(old_meta_path) == len(sys.meta_path))
+
+ # An example of fragile import code that we don't want to break:
+ try:
+ import builtins
+ except ImportError:
+ example_PY2_check = True
+ if utils.PY2:
+ self.assertTrue(example_PY2_check)
+ else:
+ self.assertFalse(example_PY2_check)
+
+ standard_library.install_hooks()
+
+ # Imports should succeed again now:
+ import builtins
+ import html
+ if utils.PY2:
+ self.assertTrue(standard_library.detect_hooks())
+ self.assertTrue(len(old_meta_path) == len(sys.meta_path))
+
+ @expectedFailurePY2
+ def test_remove_hooks2(self):
+ """
+ As above, but with the new names
+ """
+ example_PY2_check = False
+
+ standard_library.install_hooks()
+ old_meta_path = copy.copy(sys.meta_path)
+
+ standard_library.remove_hooks()
+ standard_library.scrub_future_sys_modules()
+ if utils.PY2:
+ self.assertTrue(len(old_meta_path) == len(sys.meta_path) + 1)
+ else:
+ self.assertTrue(len(old_meta_path) == len(sys.meta_path))
+
+ # An example of fragile import code that we don't want to break:
+ try:
+ import builtins
+ except ImportError:
+ example_PY2_check = True
+ if utils.PY2:
+ self.assertTrue(example_PY2_check)
+ else:
+ self.assertFalse(example_PY2_check)
+ standard_library.install_hooks()
+ # The import should succeed again now:
+ import builtins
+ self.assertTrue(len(old_meta_path) == len(sys.meta_path))
+
+ def test_detect_hooks(self):
+ """
+ Tests whether the future.standard_library.detect_hooks is doing
+ its job.
+ """
+ standard_library.install_hooks()
+ if utils.PY2:
+ self.assertTrue(standard_library.detect_hooks())
+
+ meta_path = copy.copy(sys.meta_path)
+
+ standard_library.remove_hooks()
+ if utils.PY2:
+ self.assertEqual(len(meta_path), len(sys.meta_path) + 1)
+ self.assertFalse(standard_library.detect_hooks())
+
+ @unittest.skipIf(utils.PY3, 'not testing for old urllib on Py3')
+ def test_old_urllib_import(self):
+ """
+ Tests whether an imported module can import the old urllib package.
+ Importing future.standard_library in a script should be possible and
+ not disrupt any uses of the old Py2 standard library names in modules
+ imported by that script.
+ """
+ code1 = '''
+ from future import standard_library
+ with standard_library.suspend_hooks():
+ import module_importing_old_urllib
+ '''
+ self._write_test_script(code1, 'runme.py')
+ code2 = '''
+ import urllib
+ assert 'urlopen' in dir(urllib)
+ print('Import succeeded!')
+ '''
+ self._write_test_script(code2, 'module_importing_old_urllib.py')
+ output = self._run_test_script('runme.py')
+ print(output)
+ self.assertTrue(True)
+
+ def test_sys_intern(self):
+ """
+ Py2's builtin intern() has been moved to the sys module. Tests
+ whether sys.intern is available.
+ """
+ from sys import intern
+ if utils.PY3:
+ self.assertEqual(intern('hello'), 'hello')
+ else:
+ # intern() requires byte-strings on Py2:
+ self.assertEqual(intern(b'hello'), b'hello')
+
+ def test_sys_maxsize(self):
+ """
+ Tests whether sys.maxsize is available.
+ """
+ from sys import maxsize
+ self.assertTrue(maxsize > 0)
+
+ def test_itertools_filterfalse(self):
+ """
+ Tests whether itertools.filterfalse is available.
+ """
+ from itertools import filterfalse
+ not_div_by_3 = filterfalse(lambda x: x % 3 == 0, range(8))
+ self.assertEqual(list(not_div_by_3), [1, 2, 4, 5, 7])
+
+ def test_itertools_zip_longest(self):
+ """
+ Tests whether itertools.zip_longest is available.
+ """
+ from itertools import zip_longest
+ a = (1, 2)
+ b = [2, 4, 6]
+ self.assertEqual(list(zip_longest(a, b)),
+ [(1, 2), (2, 4), (None, 6)])
+
+ def test_ChainMap(self):
+ """
+ Tests whether collections.ChainMap is available.
+ """
+ from collections import ChainMap
+ cm = ChainMap()
+
+ @unittest.expectedFailure
+ @unittest.skipIf(utils.PY3, 'generic import tests are for Py2 only')
+ def test_import_failure_from_module(self):
+ """
+ Tests whether e.g. "import socketserver" succeeds in a module
+ imported by another module that has used and removed the stdlib hooks.
+ We want this to fail; the stdlib hooks should not bleed to imported
+ modules too without their explicitly invoking them.
+ """
+ code1 = '''
+ from future import standard_library
+ standard_library.install_hooks()
+ standard_library.remove_hooks()
+ import importme2
+ '''
+ code2 = '''
+ import socketserver
+ print('Uh oh. importme2 should have raised an ImportError.')
+ '''
+ self._write_test_script(code1, 'importme1.py')
+ self._write_test_script(code2, 'importme2.py')
+ with self.assertRaises(CalledProcessError):
+ output = self._run_test_script('importme1.py')
+
+ # Disabled since v0.16.0:
+ # def test_configparser(self):
+ # import configparser
+
+ def test_copyreg(self):
+ import copyreg
+
+ def test_pickle(self):
+ import pickle
+
+ def test_profile(self):
+ import profile
+
+ def test_stringio(self):
+ from io import StringIO
+ s = StringIO(u'test')
+ for method in ['tell', 'read', 'seek', 'close', 'flush']:
+ self.assertTrue(hasattr(s, method))
+
+ def test_bytesio(self):
+ from io import BytesIO
+ s = BytesIO(b'test')
+ for method in ['tell', 'read', 'seek', 'close', 'flush', 'getvalue']:
+ self.assertTrue(hasattr(s, method))
+
+ def test_queue(self):
+ import queue
+ q = queue.Queue()
+ q.put('thing')
+ self.assertFalse(q.empty())
+
+ def test_reprlib(self):
+ import reprlib
+ self.assertTrue(True)
+
+ def test_socketserver(self):
+ import socketserver
+ self.assertTrue(True)
+
+ @unittest.skip("Not testing tkinter import (it may be installed separately from Python)")
+ def test_tkinter(self):
+ import tkinter
+ self.assertTrue(True)
+
+ def test_builtins(self):
+ import builtins
+ self.assertTrue(hasattr(builtins, 'tuple'))
+
+ @unittest.skip("ssl redirect support on pypi isn't working as expected for now ...")
+ def test_urllib_request_ssl_redirect(self):
+ """
+ This site redirects to https://...
+ It therefore requires ssl support.
+ """
+ import future.moves.urllib.request as urllib_request
+ from pprint import pprint
+ URL = 'http://pypi.python.org/pypi/{0}/json'
+ package = 'future'
+ r = urllib_request.urlopen(URL.format(package))
+ # pprint(r.read().decode('utf-8'))
+ self.assertTrue(True)
+
+ def test_moves_urllib_request_http(self):
+ """
+ This site (python-future.org) uses plain http (as of 2014-09-23).
+ """
+ import future.moves.urllib.request as urllib_request
+ from pprint import pprint
+ URL = 'http://python-future.org'
+ r = urllib_request.urlopen(URL)
+ data = r.read()
+ self.assertTrue(b'</html>' in data)
+
+ def test_urllib_request_http(self):
+ """
+ This site (python-future.org) uses plain http (as of 2014-09-23).
+ """
+ import urllib.request as urllib_request
+ from pprint import pprint
+ URL = 'http://python-future.org'
+ r = urllib_request.urlopen(URL)
+ data = r.read()
+ self.assertTrue(b'</html>' in data)
+
+ def test_html_import(self):
+ import html
+ import html.entities
+ import html.parser
+ self.assertTrue(True)
+
+ def test_http_client_import(self):
+ import http.client
+ self.assertTrue(True)
+
+ def test_other_http_imports(self):
+ import http
+ import http.server
+ import http.cookies
+ import http.cookiejar
+ self.assertTrue(True)
+
+ def test_urllib_imports_moves(self):
+ import future.moves.urllib
+ import future.moves.urllib.parse
+ import future.moves.urllib.request
+ import future.moves.urllib.robotparser
+ import future.moves.urllib.error
+ import future.moves.urllib.response
+ self.assertTrue(True)
+
+ def test_urllib_imports_install_aliases(self):
+ with standard_library.suspend_hooks():
+ standard_library.install_aliases()
+ import urllib
+ import urllib.parse
+ import urllib.request
+ import urllib.robotparser
+ import urllib.error
+ import urllib.response
+ self.assertTrue(True)
+
+ def test_urllib_imports_cm(self):
+ with standard_library.hooks():
+ import urllib
+ import urllib.parse
+ import urllib.request
+ import urllib.robotparser
+ import urllib.error
+ import urllib.response
+ self.assertTrue(True)
+
+ def test_urllib_imports_install_hooks(self):
+ standard_library.remove_hooks()
+ standard_library.install_hooks()
+ import urllib
+ import urllib.parse
+ import urllib.request
+ import urllib.robotparser
+ import urllib.error
+ import urllib.response
+ self.assertTrue(True)
+
+ def test_underscore_prefixed_modules(self):
+ import _thread
+ import _dummy_thread
+ import _markupbase
+ self.assertTrue(True)
+
+ def test_reduce(self):
+ """
+ reduce has been moved to the functools module
+ """
+ import functools
+ self.assertEqual(functools.reduce(lambda x, y: x+y, range(1, 6)), 15)
+
+ def test_collections_userstuff(self):
+ """
+ UserDict, UserList, and UserString have been moved to the
+ collections module.
+ """
+ from collections import UserDict
+ from collections import UserList
+ from collections import UserString
+ self.assertTrue(True)
+
+ def test_reload(self):
+ """
+ reload has been moved to the imp module
+ """
+ import imp
+ imp.reload(imp)
+ self.assertTrue(True)
+
+ def test_install_aliases(self):
+ """
+ Does the install_aliases() interface monkey-patch urllib etc. successfully?
+ """
+ from future.standard_library import remove_hooks, install_aliases
+ remove_hooks()
+ install_aliases()
+
+ from collections import Counter, OrderedDict # backported to Py2.6
+ from collections import UserDict, UserList, UserString
+
+ # Requires Python dbm support:
+ # import dbm
+ # import dbm.dumb
+ # import dbm.gnu
+ # import dbm.ndbm
+
+ from itertools import filterfalse, zip_longest
+
+ from subprocess import check_output # backported to Py2.6
+ from subprocess import getoutput, getstatusoutput
+
+ from sys import intern
+
+ # test_support may not be available (e.g. on Anaconda Py2.6):
+ # import test.support
+
+ import urllib.error
+ import urllib.parse
+ import urllib.request
+ import urllib.response
+ import urllib.robotparser
+
+ self.assertTrue('urlopen' in dir(urllib.request))
+
+
+class TestFutureMoves(CodeHandler):
+ def test_future_moves_urllib_request(self):
+ from future.moves.urllib import request as urllib_request
+ functions = ['getproxies',
+ 'pathname2url',
+ 'proxy_bypass',
+ 'quote',
+ 'request_host',
+ 'splitattr',
+ 'splithost',
+ 'splitpasswd',
+ 'splitport',
+ 'splitquery',
+ 'splittag',
+ 'splittype',
+ 'splituser',
+ 'splitvalue',
+ 'thishost',
+ 'to_bytes',
+ 'unquote',
+ # 'unquote_to_bytes', # Is there an equivalent in the Py2 stdlib?
+ 'unwrap',
+ 'url2pathname',
+ 'urlcleanup',
+ 'urljoin',
+ 'urlopen',
+ 'urlparse',
+ 'urlretrieve',
+ 'urlsplit',
+ 'urlunparse']
+ self.assertTrue(all(fn in dir(urllib_request) for fn in functions))
+
+ def test_future_moves(self):
+ """
+ Ensure everything is available from the future.moves interface that we
+ claim and expect. (Issue #104).
+ """
+ from future.moves.collections import Counter, OrderedDict # backported to Py2.6
+ from future.moves.collections import UserDict, UserList, UserString
+
+ from future.moves import configparser
+ from future.moves import copyreg
+
+ from future.moves.itertools import filterfalse, zip_longest
+
+ from future.moves import html
+ import future.moves.html.entities
+ import future.moves.html.parser
+
+ from future.moves import http
+ import future.moves.http.client
+ import future.moves.http.cookies
+ import future.moves.http.cookiejar
+ import future.moves.http.server
+
+ from future.moves import queue
+
+ from future.moves import socketserver
+
+ from future.moves.subprocess import check_output # even on Py2.6
+ from future.moves.subprocess import getoutput, getstatusoutput
+
+ from future.moves.sys import intern
+
+ from future.moves import urllib
+ import future.moves.urllib.error
+ import future.moves.urllib.parse
+ import future.moves.urllib.request
+ import future.moves.urllib.response
+ import future.moves.urllib.robotparser
+
+ try:
+ # Is _winreg available on Py2? If so, ensure future.moves._winreg is available too:
+ import _winreg
+ except ImportError:
+ pass
+ else:
+ from future.moves import winreg
+
+ from future.moves import xmlrpc
+ import future.moves.xmlrpc.client
+ import future.moves.xmlrpc.server
+
+ from future.moves import _dummy_thread
+ from future.moves import _markupbase
+ from future.moves import _thread
+
+ def test_future_moves_dbm(self):
+ """
+ Do the dbm imports work?
+ """
+ from future.moves import dbm
+ dbm.ndbm
+ from future.moves.dbm import dumb
+ try:
+ # Is gdbm available on Py2? If so, ensure dbm.gnu is available too:
+ import gdbm
+ except ImportError:
+ pass
+ else:
+ from future.moves.dbm import gnu
+ from future.moves.dbm import ndbm
+
+
+# Running the following tkinter test causes the following bizzare test failure:
+#
+# ======================================================================
+# FAIL: test_open_default_encoding (future.tests.test_builtins.BuiltinTest)
+# ----------------------------------------------------------------------
+# Traceback (most recent call last):
+# File "/home/user/Install/BleedingEdge/python-future/future/tests/test_builtins.py", line 1219, in test_open_default_encoding
+# self.assertEqual(fp.encoding, current_locale_encoding)
+# AssertionError: 'ANSI_X3.4-1968' != 'ISO-8859-1'
+#
+# ----------------------------------------------------------------------
+#
+# def test_future_moves_tkinter(self):
+# """
+# Do the tkinter imports work?
+# """
+# from future.moves import tkinter
+# from future.moves.tkinter import dialog
+# from future.moves.tkinter import filedialog
+# from future.moves.tkinter import scrolledtext
+# from future.moves.tkinter import simpledialog
+# from future.moves.tkinter import tix
+# from future.moves.tkinter import constants
+# from future.moves.tkinter import dnd
+# from future.moves.tkinter import colorchooser
+# from future.moves.tkinter import commondialog
+# from future.moves.tkinter import font
+# from future.moves.tkinter import messagebox
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_str.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_str.py
new file mode 100644
index 0000000..5108548
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_str.py
@@ -0,0 +1,591 @@
+# -*- coding: utf-8 -*-
+"""
+Tests for the backported class:`str` class.
+"""
+
+from __future__ import absolute_import, unicode_literals, print_function
+from future.builtins import *
+from future import utils
+from future.tests.base import unittest, expectedFailurePY2
+
+import os
+
+TEST_UNICODE_STR = u'ℝεα∂@ßʟ℮ ☂ℯṧт υηḯ¢☺ḓ℮'
+
+
+class TestStr(unittest.TestCase):
+ def test_str(self):
+ self.assertFalse(str is bytes)
+ self.assertEqual(str('blah'), u'blah') # u'' prefix: Py3.3 and Py2 only
+ self.assertEqual(str(b'1234'), "b'1234'")
+
+ def test_bool_str(self):
+ s1 = str(u'abc')
+ s2 = u'abc'
+ s3 = str(u'')
+ s4 = u''
+ self.assertEqual(bool(s1), bool(s2))
+ self.assertEqual(bool(s3), bool(s4))
+
+ def test_os_path_join(self):
+ """
+ Issue #15: can't os.path.join(u'abc', str(u'def'))
+ """
+ self.assertEqual(os.path.join(u'abc', str(u'def')),
+ u'abc{0}def'.format(os.sep))
+
+ def test_str_encode_utf8(self):
+ b = str(TEST_UNICODE_STR).encode('utf-8')
+ self.assertTrue(isinstance(b, bytes))
+ self.assertFalse(isinstance(b, str))
+ s = b.decode('utf-8')
+ self.assertTrue(isinstance(s, str))
+ self.assertEqual(s, TEST_UNICODE_STR)
+
+ def test_str_encode_cp1251(self):
+ b1 = b'\xcd\xeb\xff'
+ s1 = str(b1, 'cp1251')
+ self.assertEqual(s1, u'Нля')
+
+ b2 = bytes(b'\xcd\xeb\xff')
+ s2 = str(b2, 'cp1251')
+ self.assertEqual(s2, u'Нля')
+
+ def test_str_encode_decode_with_py2_str_arg(self):
+ # Try passing a standard Py2 string (as if unicode_literals weren't imported)
+ b = str(TEST_UNICODE_STR).encode(utils.bytes_to_native_str(b'utf-8'))
+ self.assertTrue(isinstance(b, bytes))
+ self.assertFalse(isinstance(b, str))
+ s = b.decode(utils.bytes_to_native_str(b'utf-8'))
+ self.assertTrue(isinstance(s, str))
+ self.assertEqual(s, TEST_UNICODE_STR)
+
+ def test_str_encode_decode_big5(self):
+ a = u'Unicode string: \u5b54\u5b50'
+ self.assertEqual(str(a), a.encode('big5').decode('big5'))
+
+ def test_str_empty(self):
+ """
+ str() -> u''
+ """
+ self.assertEqual(str(), u'')
+
+ def test_str_iterable_of_ints(self):
+ self.assertEqual(str([65, 66, 67]), '[65, 66, 67]')
+ self.assertNotEqual(str([65, 66, 67]), 'ABC')
+
+ def test_str_str(self):
+ self.assertEqual(str('ABC'), u'ABC')
+ self.assertEqual(str('ABC'), 'ABC')
+
+ def test_str_is_str(self):
+ s = str(u'ABC')
+ self.assertTrue(str(s) is s)
+ self.assertEqual(repr(str(s)), "'ABC'")
+
+ def test_str_fromhex(self):
+ self.assertFalse(hasattr(str, 'fromhex'))
+
+ def test_str_hasattr_decode(self):
+ """
+ This test tests whether hasattr(s, 'decode') is False, like it is on Py3.
+
+ Sometimes code (such as http.client in Py3.3) checks hasattr(mystring,
+ 'decode') to determine if a string-like thing needs encoding. It would
+ be nice to have this return False so the string can be treated on Py2
+ like a Py3 string.
+ """
+ s = str(u'abcd')
+ self.assertFalse(hasattr(s, 'decode'))
+ self.assertTrue(hasattr(s, 'encode'))
+
+ def test_isinstance_str(self):
+ self.assertTrue(isinstance(str('blah'), str))
+
+ def test_isinstance_str_subclass(self):
+ """
+ Issue #89
+ """
+ value = str(u'abc')
+ class Magic(str):
+ pass
+ self.assertTrue(isinstance(value, str))
+ self.assertFalse(isinstance(value, Magic))
+
+ def test_str_getitem(self):
+ s = str('ABCD')
+ self.assertNotEqual(s[0], 65)
+ self.assertEqual(s[0], 'A')
+ self.assertEqual(s[-1], 'D')
+ self.assertEqual(s[0:1], 'A')
+ self.assertEqual(s[:], u'ABCD')
+
+ @unittest.expectedFailure
+ def test_u_literal_creates_newstr_object(self):
+ """
+ It would nice if the u'' or '' literal syntax could be coaxed
+ into producing our new str objects somehow ...
+ """
+ s = u'ABCD'
+ self.assertTrue(isinstance(s, str))
+ self.assertFalse(repr(b).startswith('b'))
+
+ def test_repr(self):
+ s = str('ABCD')
+ self.assertFalse(repr(s).startswith('b'))
+
+ def test_str(self):
+ b = str('ABCD')
+ self.assertTrue(str(b), 'ABCD')
+
+ def test_str_setitem(self):
+ s = 'ABCD'
+ with self.assertRaises(TypeError):
+ s[0] = b'B'
+
+ def test_str_iteration(self):
+ s = str('ABCD')
+ for item in s:
+ self.assertFalse(isinstance(item, int))
+ self.assertTrue(isinstance(item, str))
+ self.assertNotEqual(list(s), [65, 66, 67, 68])
+ self.assertEqual(list(s), ['A', 'B', 'C', 'D'])
+
+ def test_str_plus_bytes(self):
+ s = str(u'ABCD')
+ b = b'EFGH'
+ # We allow this now:
+ # with self.assertRaises(TypeError):
+ # s + b
+ # str objects don't have an __radd__ method, so the following
+ # does not raise a TypeError. Is this a problem?
+ # with self.assertRaises(TypeError):
+ # b + s
+
+ # Now with our custom bytes object:
+ b2 = bytes(b'EFGH')
+ with self.assertRaises(TypeError):
+ s + b2
+ with self.assertRaises(TypeError):
+ b2 + s
+
+ def test_str_plus_str(self):
+ s1 = str('ABCD')
+ s2 = s1 + s1
+ self.assertEqual(s2, u'ABCDABCD')
+ self.assertTrue(isinstance(s2, str))
+
+ s3 = s1 + u'ZYXW'
+ self.assertEqual(s3, 'ABCDZYXW')
+ self.assertTrue(isinstance(s3, str))
+
+ s4 = 'ZYXW' + s1
+ self.assertEqual(s4, 'ZYXWABCD')
+ self.assertTrue(isinstance(s4, str))
+
+ def test_str_join_str(self):
+ s = str(' * ')
+ strings = ['AB', 'EFGH', 'IJKL', TEST_UNICODE_STR]
+ result = s.join(strings)
+ self.assertEqual(result, 'AB * EFGH * IJKL * ' + TEST_UNICODE_STR)
+ self.assertTrue(isinstance(result, str))
+
+ def test_str_join_bytes(self):
+ s = str('ABCD')
+ byte_strings1 = [b'EFGH', u'IJKL']
+ # We allow this on Python 2 for compatibility with old libraries:
+ if utils.PY2:
+ self.assertEqual(s.join(byte_strings1), u'EFGHABCDIJKL')
+
+ byte_strings2 = [bytes(b'EFGH'), u'IJKL']
+ with self.assertRaises(TypeError):
+ s.join(byte_strings2)
+
+ def test_str_join_staticmethod(self):
+ """
+ Issue #33
+ """
+ c = str.join('-', ['a', 'b'])
+ self.assertEqual(c, 'a-b')
+ self.assertEqual(type(c), str)
+
+ def test_str_join_staticmethod_workaround_1(self):
+ """
+ Issue #33
+ """
+ c = str('-').join(['a', 'b'])
+ self.assertEqual(c, 'a-b')
+ self.assertEqual(type(c), str)
+
+ def test_str_join_staticmethod_workaround_2(self):
+ """
+ Issue #33
+ """
+ c = str.join(str('-'), ['a', 'b'])
+ self.assertEqual(c, 'a-b')
+ self.assertEqual(type(c), str)
+
+ def test_str_replace(self):
+ s = str('ABCD')
+ c = s.replace('A', 'F')
+ self.assertEqual(c, 'FBCD')
+ self.assertTrue(isinstance(c, str))
+
+ with self.assertRaises(TypeError):
+ s.replace(bytes(b'A'), u'F')
+ with self.assertRaises(TypeError):
+ s.replace(u'A', bytes(b'F'))
+
+ def test_str_partition(self):
+ s1 = str('ABCD')
+ parts = s1.partition('B')
+ self.assertEqual(parts, ('A', 'B', 'CD'))
+ self.assertTrue(all([isinstance(p, str) for p in parts]))
+
+ s2 = str('ABCDABCD')
+ parts = s2.partition('B')
+ self.assertEqual(parts, ('A', 'B', 'CDABCD'))
+
+ def test_str_rpartition(self):
+ s2 = str('ABCDABCD')
+ parts = s2.rpartition('B')
+ self.assertEqual(parts, ('ABCDA', 'B', 'CD'))
+ self.assertTrue(all([isinstance(p, str) for p in parts]))
+
+ def test_str_contains_something(self):
+ s = str('ABCD')
+ self.assertTrue('A' in s)
+ if utils.PY2:
+ self.assertTrue(b'A' in s)
+ with self.assertRaises(TypeError):
+ bytes(b'A') in s
+ with self.assertRaises(TypeError):
+ 65 in s # unlike bytes
+
+ self.assertTrue('AB' in s)
+ self.assertFalse(str([65, 66]) in s) # unlike bytes
+ self.assertFalse('AC' in s)
+ self.assertFalse('Z' in s)
+
+ def test_str_index(self):
+ s = str('ABCD')
+ self.assertEqual(s.index('B'), 1)
+ with self.assertRaises(TypeError):
+ s.index(67)
+ with self.assertRaises(TypeError):
+ s.index(bytes(b'C'))
+
+ def test_startswith(self):
+ s = str('abcd')
+ self.assertTrue(s.startswith('a'))
+ self.assertTrue(s.startswith(('a', 'd')))
+ self.assertTrue(s.startswith(str('ab')))
+ if utils.PY2:
+ # We allow this, because e.g. Python 2 os.path.join concatenates
+ # its arg with a byte-string '/' indiscriminately.
+ self.assertFalse(s.startswith(b'A'))
+ self.assertTrue(s.startswith(b'a'))
+ with self.assertRaises(TypeError) as cm:
+ self.assertFalse(s.startswith(bytes(b'A')))
+ with self.assertRaises(TypeError) as cm:
+ s.startswith((bytes(b'A'), bytes(b'B')))
+ with self.assertRaises(TypeError) as cm:
+ s.startswith(65)
+
+ def test_join(self):
+ sep = str('-')
+ self.assertEqual(sep.join('abcd'), 'a-b-c-d')
+ if utils.PY2:
+ sep.join(b'abcd')
+ with self.assertRaises(TypeError) as cm:
+ sep.join(bytes(b'abcd'))
+
+ def test_endswith(self):
+ s = str('abcd')
+ self.assertTrue(s.endswith('d'))
+ self.assertTrue(s.endswith(('b', 'd')))
+ self.assertTrue(s.endswith(str('cd')))
+ self.assertFalse(s.endswith(('A', 'B')))
+ if utils.PY2:
+ self.assertFalse(s.endswith(b'D'))
+ self.assertTrue(s.endswith((b'D', b'd')))
+ with self.assertRaises(TypeError) as cm:
+ s.endswith(65)
+ with self.assertRaises(TypeError) as cm:
+ s.endswith((bytes(b'D'),))
+
+ def test_split(self):
+ s = str('ABCD')
+ self.assertEqual(s.split('B'), ['A', 'CD'])
+ if utils.PY2:
+ self.assertEqual(s.split(b'B'), ['A', 'CD'])
+ with self.assertRaises(TypeError) as cm:
+ s.split(bytes(b'B'))
+
+ def test_rsplit(self):
+ s = str('ABCD')
+ self.assertEqual(s.rsplit('B'), ['A', 'CD'])
+ if utils.PY2:
+ self.assertEqual(s.rsplit(b'B'), ['A', 'CD'])
+ with self.assertRaises(TypeError) as cm:
+ s.rsplit(bytes(b'B'))
+
+ def test_eq_bytes(self):
+ s = str('ABCD')
+ b = bytes(b'ABCD')
+ self.assertNotEqual(s, b)
+ self.assertNotEqual(str(''), bytes(b''))
+ native_s = 'ABCD'
+ native_b = b'ABCD'
+ self.assertFalse(b == native_s)
+ self.assertTrue(b != native_s)
+
+ # Fails on Py2:
+ # self.assertNotEqual(native_s, b)
+ # with no obvious way to change this.
+
+ # For backward compatibility with broken string-handling code in
+ # Py2 libraries, we allow the following:
+
+ if utils.PY2:
+ self.assertTrue(native_b == s)
+ self.assertFalse(s != native_b)
+
+ def test_eq(self):
+ s = str('ABCD')
+ self.assertEqual('ABCD', s)
+ self.assertEqual(s, 'ABCD')
+ self.assertEqual(s, s)
+ self.assertTrue(u'ABCD' == s)
+ if utils.PY2:
+ self.assertTrue(b'ABCD' == s)
+ else:
+ self.assertFalse(b'ABCD' == s)
+ self.assertFalse(bytes(b'ABCD') == s)
+
+ # We want to ensure comparison against unknown types return
+ # NotImplemented so that the interpreter can rerun the test with the
+ # other class. We expect the operator to return False if both return
+ # NotImplemented.
+ class OurCustomString(object):
+ def __init__(self, string):
+ self.string = string
+
+ def __eq__(self, other):
+ return NotImplemented
+
+ our_str = OurCustomString("foobar")
+ new_str = str("foobar")
+
+ self.assertFalse(our_str == new_str)
+ self.assertFalse(new_str == our_str)
+ self.assertIs(new_str.__eq__(our_str), NotImplemented)
+ self.assertIs(our_str.__eq__(new_str), NotImplemented)
+
+ def test_hash(self):
+ s = str('ABCD')
+ self.assertIsInstance(hash(s),int)
+
+ def test_ne(self):
+ s = str('ABCD')
+ self.assertNotEqual('A', s)
+ self.assertNotEqual(s, 'A')
+ self.assertNotEqual(s, 5)
+ self.assertNotEqual(2.7, s)
+ self.assertNotEqual(s, ['A', 'B', 'C', 'D'])
+ if utils.PY2:
+ self.assertFalse(b'ABCD' != s)
+ else:
+ self.assertTrue(b'ABCD' != s)
+ self.assertTrue(bytes(b'ABCD') != s)
+
+ def test_cmp(self):
+ s = str(u'ABC')
+ with self.assertRaises(TypeError):
+ s > 3
+ with self.assertRaises(TypeError):
+ s < 1000
+ with self.assertRaises(TypeError):
+ s <= 3
+ with self.assertRaises(TypeError):
+ s >= int(3)
+ with self.assertRaises(TypeError):
+ s < 3.3
+ with self.assertRaises(TypeError):
+ s > (3.3 + 3j)
+ with self.assertRaises(TypeError):
+ s >= (1, 2)
+ with self.assertRaises(TypeError):
+ s <= [1, 2]
+
+ def test_mul(self):
+ s = str(u'ABC')
+ c = s * 4
+ self.assertTrue(isinstance(c, str))
+ self.assertEqual(c, u'ABCABCABCABC')
+ d = s * int(4)
+ self.assertTrue(isinstance(d, str))
+ self.assertEqual(d, u'ABCABCABCABC')
+ if utils.PY2:
+ e = s * long(4)
+ self.assertTrue(isinstance(e, str))
+ self.assertEqual(e, u'ABCABCABCABC')
+ with self.assertRaises(TypeError):
+ s * 3.3
+ with self.assertRaises(TypeError):
+ s * (3.3 + 3j)
+
+ def test_rmul(self):
+ s = str(u'XYZ')
+ c = 3 * s
+ self.assertTrue(isinstance(c, str))
+ self.assertEqual(c, u'XYZXYZXYZ')
+ d = s * int(3)
+ self.assertTrue(isinstance(d, str))
+ self.assertEqual(d, u'XYZXYZXYZ')
+ if utils.PY2:
+ e = long(3) * s
+ self.assertTrue(isinstance(e, str))
+ self.assertEqual(e, u'XYZXYZXYZ')
+ with self.assertRaises(TypeError):
+ 3.3 * s
+ with self.assertRaises(TypeError):
+ (3.3 + 3j) * s
+
+ @unittest.skip('Fails on Python <= 2.7.6 due to string subclass slicing bug')
+ def test_slice(self):
+ """
+ Do slices return newstr objects?
+ """
+ s = str(u'abcd')
+ self.assertEqual(s[:2], u'ab')
+ self.assertEqual(type(s[:2]), str)
+ self.assertEqual(s[-2:], u'cd')
+ self.assertEqual(type(s[-2:]), str)
+
+ @unittest.skip('Fails on Python <= 2.7.6 due to string subclass slicing bug')
+ def test_subclassing(self):
+ """
+ Can newstr be subclassed and do str methods then return instances of
+ the same class? (This is the Py3 behaviour).
+ """
+ class SubClass(str):
+ pass
+ s = SubClass(u'abcd')
+ self.assertEqual(type(s), SubClass)
+ self.assertEqual(type(s + s), str)
+ self.assertEqual(type(s[0]), str)
+ self.assertEqual(type(s[:2]), str)
+ self.assertEqual(type(s.join([u'_', u'_', u'_'])), str)
+
+ def test_subclassing_2(self):
+ """
+ Tests __new__ method in subclasses. Fails in versions <= 0.11.4
+ """
+ class SubClass(str):
+ def __new__(cls, *args, **kwargs):
+ self = str.__new__(cls, *args, **kwargs)
+ assert type(self) == SubClass
+ return self
+ s = SubClass(u'abcd')
+ self.assertTrue(True)
+
+ # From Python 3.3: test_unicode.py
+ def checkequalnofix(self, result, object, methodname, *args):
+ method = getattr(object, methodname)
+ realresult = method(*args)
+ self.assertEqual(realresult, result)
+ self.assertTrue(type(realresult) is type(result))
+
+ # if the original is returned make sure that
+ # this doesn't happen with subclasses
+ if realresult is object:
+ class usub(str):
+ def __repr__(self):
+ return 'usub(%r)' % str.__repr__(self)
+ object = usub(object)
+ method = getattr(object, methodname)
+ realresult = method(*args)
+ self.assertEqual(realresult, result)
+ self.assertTrue(object is not realresult)
+
+ type2test = str
+
+ def test_maketrans_translate(self):
+ # these work with plain translate()
+ self.checkequalnofix('bbbc', 'abababc', 'translate',
+ {ord('a'): None})
+ self.checkequalnofix('iiic', 'abababc', 'translate',
+ {ord('a'): None, ord('b'): ord('i')})
+ self.checkequalnofix('iiix', 'abababc', 'translate',
+ {ord('a'): None, ord('b'): ord('i'), ord('c'): 'x'})
+ self.checkequalnofix('c', 'abababc', 'translate',
+ {ord('a'): None, ord('b'): ''})
+ self.checkequalnofix('xyyx', 'xzx', 'translate',
+ {ord('z'): 'yy'})
+ # this needs maketrans()
+ self.checkequalnofix('abababc', 'abababc', 'translate',
+ {'b': '<i>'})
+ tbl = self.type2test.maketrans({'a': None, 'b': '<i>'})
+ self.checkequalnofix('<i><i><i>c', 'abababc', 'translate', tbl)
+ # test alternative way of calling maketrans()
+ tbl = self.type2test.maketrans('abc', 'xyz', 'd')
+ self.checkequalnofix('xyzzy', 'abdcdcbdddd', 'translate', tbl)
+
+ self.assertRaises(TypeError, self.type2test.maketrans)
+ self.assertRaises(ValueError, self.type2test.maketrans, 'abc', 'defg')
+ self.assertRaises(TypeError, self.type2test.maketrans, 2, 'def')
+ self.assertRaises(TypeError, self.type2test.maketrans, 'abc', 2)
+ self.assertRaises(TypeError, self.type2test.maketrans, 'abc', 'def', 2)
+ self.assertRaises(ValueError, self.type2test.maketrans, {'xy': 2})
+ self.assertRaises(TypeError, self.type2test.maketrans, {(1,): 2})
+
+ self.assertRaises(TypeError, 'hello'.translate)
+ self.assertRaises(TypeError, 'abababc'.translate, 'abc', 'xyz')
+
+ @expectedFailurePY2
+ def test_multiple_inheritance(self):
+ """
+ Issue #96 (for newstr instead of newobject)
+ """
+ if utils.PY2:
+ from collections import Container
+ else:
+ from collections.abc import Container
+
+ class Base(str):
+ pass
+
+ class Foo(Base, Container):
+ def __contains__(self, item):
+ return False
+
+ @expectedFailurePY2
+ def test_with_metaclass_and_str(self):
+ """
+ Issue #91 (for newstr instead of newobject)
+ """
+ from future.utils import with_metaclass
+
+ class MetaClass(type):
+ pass
+
+ class TestClass(with_metaclass(MetaClass, str)):
+ pass
+
+ def test_surrogateescape_encoding(self):
+ """
+ Tests whether surrogateescape encoding works correctly.
+ """
+ pairs = [(u'\udcc3', b'\xc3'),
+ (u'\udcff', b'\xff')]
+
+ for (s, b) in pairs:
+ encoded = str(s).encode('utf-8', 'surrogateescape')
+ self.assertEqual(b, encoded)
+ self.assertTrue(isinstance(encoded, bytes))
+ self.assertEqual(s, encoded.decode('utf-8', 'surrogateescape'))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_super.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_super.py
new file mode 100644
index 0000000..0376c1d
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_super.py
@@ -0,0 +1,347 @@
+"""Unit tests for new super() implementation."""
+
+from __future__ import absolute_import, division, unicode_literals
+import sys
+
+from future.tests.base import unittest, skip26, expectedFailurePY2
+from future import utils
+from future.builtins import super
+
+
+class A(object):
+ def f(self):
+ return 'A'
+ @classmethod
+ def cm(cls):
+ return (cls, 'A')
+
+class B(A):
+ def f(self):
+ return super().f() + 'B'
+ @classmethod
+ def cm(cls):
+ return (cls, super().cm(), 'B')
+
+class C(A):
+ def f(self):
+ return super().f() + 'C'
+ @classmethod
+ def cm(cls):
+ return (cls, super().cm(), 'C')
+
+class D(C, B):
+ def f(self):
+ return super().f() + 'D'
+ def cm(cls):
+ return (cls, super().cm(), 'D')
+
+class E(D):
+ pass
+
+class F(E):
+ f = E.f
+
+class G(A):
+ pass
+
+
+class TestSuper(unittest.TestCase):
+
+ def test_basics_working(self):
+ self.assertEqual(D().f(), 'ABCD')
+
+ def test_class_getattr_working(self):
+ self.assertEqual(D.f(D()), 'ABCD')
+
+ def test_subclass_no_override_working(self):
+ self.assertEqual(E().f(), 'ABCD')
+ self.assertEqual(E.f(E()), 'ABCD')
+
+ @expectedFailurePY2 # not working yet: infinite loop
+ def test_unbound_method_transfer_working(self):
+ self.assertEqual(F().f(), 'ABCD')
+ self.assertEqual(F.f(F()), 'ABCD')
+
+ def test_class_methods_still_working(self):
+ self.assertEqual(A.cm(), (A, 'A'))
+ self.assertEqual(A().cm(), (A, 'A'))
+ self.assertEqual(G.cm(), (G, 'A'))
+ self.assertEqual(G().cm(), (G, 'A'))
+
+ def test_super_in_class_methods_working(self):
+ d = D()
+ self.assertEqual(d.cm(), (d, (D, (D, (D, 'A'), 'B'), 'C'), 'D'))
+ e = E()
+ self.assertEqual(e.cm(), (e, (E, (E, (E, 'A'), 'B'), 'C'), 'D'))
+
+ def test_super_with_closure(self):
+ # Issue4360: super() did not work in a function that
+ # contains a closure
+ class E(A):
+ def f(self):
+ def nested():
+ self
+ return super().f() + 'E'
+
+ self.assertEqual(E().f(), 'AE')
+
+ # We declare this test invalid: __class__ should be a class.
+ # def test___class___set(self):
+ # # See issue #12370
+ # class X(A):
+ # def f(self):
+ # return super().f()
+ # __class__ = 413
+ # x = X()
+ # self.assertEqual(x.f(), 'A')
+ # self.assertEqual(x.__class__, 413)
+
+ @unittest.skipIf(utils.PY2, "no __class__ on Py2")
+ def test___class___instancemethod(self):
+ # See issue #14857
+ class X(object):
+ def f(self):
+ return __class__
+ self.assertIs(X().f(), X)
+
+ @unittest.skipIf(utils.PY2, "no __class__ on Py2")
+ def test___class___classmethod(self):
+ # See issue #14857
+ class X(object):
+ @classmethod
+ def f(cls):
+ return __class__
+ self.assertIs(X.f(), X)
+
+ @unittest.skipIf(utils.PY2, "no __class__ on Py2")
+ def test___class___staticmethod(self):
+ # See issue #14857
+ class X(object):
+ @staticmethod
+ def f():
+ return __class__
+ self.assertIs(X.f(), X)
+
+ def test_obscure_super_errors(self):
+ def f():
+ super()
+ self.assertRaises(RuntimeError, f)
+ def f(x):
+ del x
+ super()
+ self.assertRaises(RuntimeError, f, None)
+ # class X(object):
+ # def f(x):
+ # nonlocal __class__
+ # del __class__
+ # super()
+ # self.assertRaises(RuntimeError, X().f)
+
+ def test_cell_as_self(self):
+ class X(object):
+ def meth(self):
+ super()
+
+ def f():
+ k = X()
+ def g():
+ return k
+ return g
+ c = f().__closure__[0]
+ self.assertRaises(TypeError, X.meth, c)
+
+ def test_properties(self):
+ class Harmless(object):
+ bomb = ''
+
+ def walk(self):
+ return self.bomb
+
+ class Dangerous(Harmless):
+ @property
+ def bomb(self):
+ raise Exception("Kaboom")
+
+ def walk(self):
+ return super().walk()
+
+ class Elite(Dangerous):
+ bomb = 'Defused'
+
+ self.assertEqual(Elite().walk(), 'Defused')
+
+
+class TestSuperFromTestDescrDotPy(unittest.TestCase):
+ """
+ These are from Python 3.3.5/Lib/test/test_descr.py
+ """
+ @skip26
+ def test_classmethods(self):
+ # Testing class methods...
+ class C(object):
+ def foo(*a): return a
+ goo = classmethod(foo)
+ c = C()
+ self.assertEqual(C.goo(1), (C, 1))
+ self.assertEqual(c.goo(1), (C, 1))
+ self.assertEqual(c.foo(1), (c, 1))
+ class D(C):
+ pass
+ d = D()
+ self.assertEqual(D.goo(1), (D, 1))
+ self.assertEqual(d.goo(1), (D, 1))
+ self.assertEqual(d.foo(1), (d, 1))
+ self.assertEqual(D.foo(d, 1), (d, 1))
+ # Test for a specific crash (SF bug 528132)
+ def f(cls, arg): return (cls, arg)
+ ff = classmethod(f)
+ self.assertEqual(ff.__get__(0, int)(42), (int, 42))
+ self.assertEqual(ff.__get__(0)(42), (int, 42))
+
+ # Test super() with classmethods (SF bug 535444)
+ self.assertEqual(C.goo.__self__, C)
+ self.assertEqual(D.goo.__self__, D)
+ self.assertEqual(super(D,D).goo.__self__, D)
+ self.assertEqual(super(D,d).goo.__self__, D)
+ self.assertEqual(super(D,D).goo(), (D,))
+ self.assertEqual(super(D,d).goo(), (D,))
+
+ # Verify that a non-callable will raise
+ meth = classmethod(1).__get__(1)
+ self.assertRaises(TypeError, meth)
+
+ # Verify that classmethod() doesn't allow keyword args
+ try:
+ classmethod(f, kw=1)
+ except TypeError:
+ pass
+ else:
+ self.fail("classmethod shouldn't accept keyword args")
+
+ # cm = classmethod(f)
+ # self.assertEqual(cm.__dict__, {})
+ # cm.x = 42
+ # self.assertEqual(cm.x, 42)
+ # self.assertEqual(cm.__dict__, {"x" : 42})
+ # del cm.x
+ # self.assertTrue(not hasattr(cm, "x"))
+
+ def test_supers(self):
+ # Testing super...
+
+ class A(object):
+ def meth(self, a):
+ return "A(%r)" % a
+
+ self.assertEqual(A().meth(1), "A(1)")
+
+ class B(A):
+ def __init__(self):
+ self.__super = super(B, self)
+ def meth(self, a):
+ return "B(%r)" % a + self.__super.meth(a)
+
+ self.assertEqual(B().meth(2), "B(2)A(2)")
+
+ class C(A):
+ def meth(self, a):
+ return "C(%r)" % a + self.__super.meth(a)
+ C._C__super = super(C)
+
+ self.assertEqual(C().meth(3), "C(3)A(3)")
+
+ class D(C, B):
+ def meth(self, a):
+ return "D(%r)" % a + super(D, self).meth(a)
+
+ self.assertEqual(D().meth(4), "D(4)C(4)B(4)A(4)")
+
+ # # Test for subclassing super
+
+ # class mysuper(super):
+ # def __init__(self, *args):
+ # return super(mysuper, self).__init__(*args)
+
+ # class E(D):
+ # def meth(self, a):
+ # return "E(%r)" % a + mysuper(E, self).meth(a)
+
+ # self.assertEqual(E().meth(5), "E(5)D(5)C(5)B(5)A(5)")
+
+ # class F(E):
+ # def meth(self, a):
+ # s = self.__super # == mysuper(F, self)
+ # return "F(%r)[%s]" % (a, s.__class__.__name__) + s.meth(a)
+ # F._F__super = mysuper(F)
+
+ # self.assertEqual(F().meth(6), "F(6)[mysuper]E(6)D(6)C(6)B(6)A(6)")
+
+ # Make sure certain errors are raised
+
+ try:
+ super(D, 42)
+ except TypeError:
+ pass
+ else:
+ self.fail("shouldn't allow super(D, 42)")
+
+ try:
+ super(D, C())
+ except TypeError:
+ pass
+ else:
+ self.fail("shouldn't allow super(D, C())")
+
+ try:
+ super(D).__get__(12)
+ except TypeError:
+ pass
+ else:
+ self.fail("shouldn't allow super(D).__get__(12)")
+
+ try:
+ super(D).__get__(C())
+ except TypeError:
+ pass
+ else:
+ self.fail("shouldn't allow super(D).__get__(C())")
+
+ # Make sure data descriptors can be overridden and accessed via super
+ # (new feature in Python 2.3)
+
+ class DDbase(object):
+ def getx(self): return 42
+ x = property(getx)
+
+ class DDsub(DDbase):
+ def getx(self): return "hello"
+ x = property(getx)
+
+ dd = DDsub()
+ self.assertEqual(dd.x, "hello")
+ self.assertEqual(super(DDsub, dd).x, 42)
+
+ # Ensure that super() lookup of descriptor from classmethod
+ # works (SF ID# 743627)
+
+ class Base(object):
+ aProp = property(lambda self: "foo")
+
+ class Sub(Base):
+ @classmethod
+ def test(klass):
+ return super(Sub,klass).aProp
+
+ self.assertEqual(Sub.test(), Base.aProp)
+
+ # Verify that super() doesn't allow keyword args
+ try:
+ super(Base, kw=1)
+ except TypeError:
+ pass
+ else:
+ self.assertEqual("super shouldn't accept keyword args")
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_surrogateescape.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_surrogateescape.py
new file mode 100644
index 0000000..7789ce9
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_surrogateescape.py
@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*-
+"""
+Tests for the surrogateescape codec
+"""
+
+from __future__ import absolute_import, division, unicode_literals
+from future.builtins import (bytes, dict, int, range, round, str, super,
+ ascii, chr, hex, input, next, oct, open, pow,
+ filter, map, zip)
+from future.utils.surrogateescape import register_surrogateescape
+from future.tests.base import unittest, expectedFailurePY26, expectedFailurePY2
+
+
+class TestSurrogateEscape(unittest.TestCase):
+ def setUp(self):
+ register_surrogateescape()
+
+ @expectedFailurePY26 # Python 2.6 str.decode() takes no keyword args
+ def test_surrogateescape(self):
+ """
+ From the backport of the email package
+ """
+ s = b'From: foo@bar.com\nTo: baz\nMime-Version: 1.0\nContent-Type: text/plain; charset=utf-8\nContent-Transfer-Encoding: base64\n\ncMO2c3RhbA\xc3\xa1=\n'
+ u = 'From: foo@bar.com\nTo: baz\nMime-Version: 1.0\nContent-Type: text/plain; charset=utf-8\nContent-Transfer-Encoding: base64\n\ncMO2c3RhbA\udcc3\udca1=\n'
+ s2 = s.decode('ASCII', errors='surrogateescape')
+ self.assertEqual(s2, u)
+
+ def test_encode_ascii_surrogateescape(self):
+ """
+ This crops up in the email module. It would be nice if it worked ...
+ """
+ payload = str(u'cMO2c3RhbA\udcc3\udca1=\n')
+ b = payload.encode('ascii', 'surrogateescape')
+ self.assertEqual(b, b'cMO2c3RhbA\xc3\xa1=\n')
+
+ def test_encode_ascii_unicode(self):
+ """
+ Verify that exceptions are raised properly.
+ """
+ self.assertRaises(UnicodeEncodeError, u'\N{SNOWMAN}'.encode, 'US-ASCII', 'surrogateescape')
+
+ @expectedFailurePY2
+ def test_encode_ascii_surrogateescape_non_newstr(self):
+ """
+ As above but without a newstr object. Fails on Py2.
+ """
+ payload = u'cMO2c3RhbA\udcc3\udca1=\n'
+ b = payload.encode('ascii', 'surrogateescape')
+ self.assertEqual(b, b'cMO2c3RhbA\xc3\xa1=\n')
+
+
+class SurrogateEscapeTest(unittest.TestCase):
+ """
+ These tests are from Python 3.3's test suite
+ """
+ def setUp(self):
+ register_surrogateescape()
+
+ def test_utf8(self):
+ # Bad byte
+ self.assertEqual(b"foo\x80bar".decode("utf-8", "surrogateescape"),
+ "foo\udc80bar")
+ self.assertEqual(str("foo\udc80bar").encode("utf-8", "surrogateescape"),
+ b"foo\x80bar")
+ # bad-utf-8 encoded surrogate
+ # self.assertEqual(b"\xed\xb0\x80".decode("utf-8", "surrogateescape"),
+ # "\udced\udcb0\udc80")
+ self.assertEqual(str("\udced\udcb0\udc80").encode("utf-8", "surrogateescape"),
+ b"\xed\xb0\x80")
+
+ def test_ascii(self):
+ # bad byte
+ self.assertEqual(b"foo\x80bar".decode("ascii", "surrogateescape"),
+ "foo\udc80bar")
+ # Fails:
+ # self.assertEqual("foo\udc80bar".encode("ascii", "surrogateescape"),
+ # b"foo\x80bar")
+
+ @expectedFailurePY2
+ def test_charmap(self):
+ # bad byte: \xa5 is unmapped in iso-8859-3
+ self.assertEqual(b"foo\xa5bar".decode("iso-8859-3", "surrogateescape"),
+ "foo\udca5bar")
+ self.assertEqual("foo\udca5bar".encode("iso-8859-3", "surrogateescape"),
+ b"foo\xa5bar")
+
+ def test_latin1(self):
+ # Issue6373
+ self.assertEqual("\udce4\udceb\udcef\udcf6\udcfc".encode("latin-1", "surrogateescape"),
+ b"\xe4\xeb\xef\xf6\xfc")
+
+ # FIXME:
+ @expectedFailurePY2
+ def test_encoding_works_normally(self):
+ """
+ Test that encoding into various encodings (particularly utf-16)
+ still works with the surrogateescape error handler in action ...
+ """
+ TEST_UNICODE_STR = u'ℝεα∂@ßʟ℮ ☂ℯṧт υηḯ¢☺ḓ℮'
+ # Tk icon as a .gif:
+ TEST_BYTE_STR = b'GIF89a\x0e\x00\x0b\x00\x80\xff\x00\xff\x00\x00\xc0\xc0\xc0!\xf9\x04\x01\x00\x00\x01\x00,\x00\x00\x00\x00\x0e\x00\x0b\x00@\x02\x1f\x0c\x8e\x10\xbb\xcan\x90\x99\xaf&\xd8\x1a\xce\x9ar\x06F\xd7\xf1\x90\xa1c\x9e\xe8\x84\x99\x89\x97\xa2J\x01\x00;\x1a\x14\x00;;\xba\nD\x14\x00\x00;;'
+ # s1 = 'quéstionable'
+ s1 = TEST_UNICODE_STR
+ b1 = s1.encode('utf-8')
+ b2 = s1.encode('utf-16')
+ # b3 = s1.encode('latin-1')
+ self.assertEqual(b1, str(s1).encode('utf-8', 'surrogateescape'))
+ self.assertEqual(b2, str(s1).encode('utf-16', 'surrogateescape'))
+ # self.assertEqual(b3, str(s1).encode('latin-1', 'surrogateescape'))
+
+ s2 = 'きたないのよりきれいな方がいい'
+ b4 = s2.encode('utf-8')
+ b5 = s2.encode('utf-16')
+ b6 = s2.encode('shift-jis')
+ self.assertEqual(b4, str(s2).encode('utf-8', 'surrogateescape'))
+ self.assertEqual(b5, str(s2).encode('utf-16', 'surrogateescape'))
+ self.assertEqual(b6, str(s2).encode('shift-jis', 'surrogateescape'))
+
+ def test_decoding_works_normally(self):
+ """
+ Test that decoding into various encodings (particularly utf-16)
+ still works with the surrogateescape error handler in action ...
+ """
+ s1 = 'quéstionable'
+ b1 = s1.encode('utf-8')
+ b2 = s1.encode('utf-16')
+ b3 = s1.encode('latin-1')
+ self.assertEqual(s1, b1.decode('utf-8', 'surrogateescape'))
+ self.assertEqual(s1, b2.decode('utf-16', 'surrogateescape'))
+ self.assertEqual(s1, b3.decode('latin-1', 'surrogateescape'))
+
+ s2 = '文'
+ b4 = s2.encode('utf-8')
+ b5 = s2.encode('utf-16')
+ b6 = s2.encode('shift-jis')
+ self.assertEqual(s2, b4.decode('utf-8', 'surrogateescape'))
+ self.assertEqual(s2, b5.decode('utf-16', 'surrogateescape'))
+ self.assertEqual(s2, b6.decode('shift-jis', 'surrogateescape'))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_urllib.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_urllib.py
new file mode 100644
index 0000000..278bafb
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_urllib.py
@@ -0,0 +1,1386 @@
+"""Regresssion tests for urllib"""
+from __future__ import absolute_import, division, unicode_literals
+
+import io
+import os
+import sys
+import tempfile
+from nturl2path import url2pathname, pathname2url
+from base64 import b64encode
+import collections
+
+from future.builtins import bytes, chr, hex, open, range, str, int
+from future.backports.urllib import parse as urllib_parse
+from future.backports.urllib import request as urllib_request
+from future.backports.urllib import error as urllib_error
+from future.backports.http import client as http_client
+from future.backports.test import support
+from future.backports.email import message as email_message
+from future.tests.base import unittest, skip26, expectedFailurePY26
+
+
+def hexescape(char):
+ """Escape char as RFC 2396 specifies"""
+ hex_repr = hex(ord(char))[2:].upper()
+ if len(hex_repr) == 1:
+ hex_repr = "0%s" % hex_repr
+ return "%" + hex_repr
+
+# Shortcut for testing FancyURLopener
+_urlopener = None
+
+
+def urlopen(url, data=None, proxies=None):
+ """urlopen(url [, data]) -> open file-like object"""
+ global _urlopener
+ if proxies is not None:
+ opener = urllib_request.FancyURLopener(proxies=proxies)
+ elif not _urlopener:
+ with support.check_warnings(
+ ('FancyURLopener style of invoking requests is deprecated.',
+ DeprecationWarning)):
+ opener = urllib_request.FancyURLopener()
+ _urlopener = opener
+ else:
+ opener = _urlopener
+ if data is None:
+ return opener.open(url)
+ else:
+ return opener.open(url, data)
+
+
+class FakeHTTPMixin(object):
+ def fakehttp(self, fakedata):
+ class FakeSocket(io.BytesIO):
+ io_refs = 1
+
+ def sendall(self, data):
+ FakeHTTPConnection.buf = data
+
+ def makefile(self, *args, **kwds):
+ self.io_refs += 1
+ return self
+
+ def read(self, amt=None):
+ if self.closed:
+ return b""
+ return io.BytesIO.read(self, amt)
+
+ def readline(self, length=None):
+ if self.closed:
+ return b""
+ return io.BytesIO.readline(self, length)
+
+ def close(self):
+ self.io_refs -= 1
+ if self.io_refs == 0:
+ io.BytesIO.close(self)
+
+ class FakeHTTPConnection(http_client.HTTPConnection):
+
+ # buffer to store data for verification in urlopen tests.
+ buf = None
+
+ def connect(self):
+ self.sock = FakeSocket(fakedata)
+
+ self._connection_class = http_client.HTTPConnection
+ http_client.HTTPConnection = FakeHTTPConnection
+
+ def unfakehttp(self):
+ http_client.HTTPConnection = self._connection_class
+
+
+class urlopen_FileTests(unittest.TestCase):
+ """Test urlopen() opening a temporary file.
+
+ Try to test as much functionality as possible so as to cut down on reliance
+ on connecting to the Net for testing.
+
+ """
+
+ def setUp(self):
+ # Create a temp file to use for testing
+ self.text = bytes("test_urllib: %s\n" % self.__class__.__name__,
+ "ascii")
+ f = open(support.TESTFN, 'wb')
+ try:
+ f.write(self.text)
+ finally:
+ f.close()
+ self.pathname = support.TESTFN
+ self.returned_obj = urlopen("file:%s" % self.pathname)
+
+ def tearDown(self):
+ """Shut down the open object"""
+ self.returned_obj.close()
+ os.remove(support.TESTFN)
+
+ def test_interface(self):
+ # Make sure object returned by urlopen() has the specified methods
+ for attr in ("read", "readline", "readlines", "fileno",
+ "close", "info", "geturl", "getcode", "__iter__"):
+ self.assertTrue(hasattr(self.returned_obj, attr),
+ "object returned by urlopen() lacks %s attribute" %
+ attr)
+
+ def test_read(self):
+ self.assertEqual(self.text, self.returned_obj.read())
+
+ def test_readline(self):
+ self.assertEqual(self.text, self.returned_obj.readline())
+ self.assertEqual(b'', self.returned_obj.readline(),
+ "calling readline() after exhausting the file did not"
+ " return an empty string")
+
+ def test_readlines(self):
+ lines_list = self.returned_obj.readlines()
+ self.assertEqual(len(lines_list), 1,
+ "readlines() returned the wrong number of lines")
+ self.assertEqual(lines_list[0], self.text,
+ "readlines() returned improper text")
+
+ def test_fileno(self):
+ file_num = self.returned_obj.fileno()
+ self.assertIsInstance(file_num, int, "fileno() did not return an int")
+ self.assertEqual(os.read(file_num, len(self.text)), self.text,
+ "Reading on the file descriptor returned by fileno() "
+ "did not return the expected text")
+
+ def test_close(self):
+ # Test close() by calling it here and then having it be called again
+ # by the tearDown() method for the test
+ self.returned_obj.close()
+
+ 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)
+
+ def test_getcode(self):
+ self.assertIsNone(self.returned_obj.getcode())
+
+ def test_iter(self):
+ # Test iterator
+ # Don't need to count number of iterations since test would fail the
+ # instant it returned anything beyond the first line from the
+ # comparison.
+ # Use the iterator in the usual implicit way to test for ticket #4608.
+ for line in self.returned_obj:
+ self.assertEqual(line, self.text)
+
+ def test_relativelocalfile(self):
+ self.assertRaises(ValueError,urllib_request.urlopen,'./' + self.pathname)
+
+class ProxyTests(unittest.TestCase):
+
+ def setUp(self):
+ # Records changes to env vars
+ self.env = support.EnvironmentVarGuard()
+ # Delete all proxy related env vars
+ for k in list(os.environ):
+ if 'proxy' in k.lower():
+ self.env.unset(k)
+
+ def tearDown(self):
+ # Restore all proxy related env vars
+ self.env.__exit__()
+ del self.env
+
+ def test_getproxies_environment_keep_no_proxies(self):
+ self.env.set('NO_PROXY', 'localhost')
+ proxies = urllib_request.getproxies_environment()
+ # getproxies_environment use lowered case truncated (no '_proxy') keys
+ self.assertEqual('localhost', proxies['no'])
+ # List of no_proxies with space.
+ self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com')
+ self.assertTrue(urllib_request.proxy_bypass_environment('anotherdomain.com'))
+
+class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin):
+ """Test urlopen() opening a fake http connection."""
+
+ def check_read(self, ver):
+ self.fakehttp(b"HTTP/" + ver + b" 200 OK\r\n\r\nHello!")
+ try:
+ fp = urlopen("http://python.org/")
+ self.assertEqual(fp.readline(), b"Hello!")
+ self.assertEqual(fp.readline(), b"")
+ self.assertEqual(fp.geturl(), 'http://python.org/')
+ self.assertEqual(fp.getcode(), 200)
+ finally:
+ self.unfakehttp()
+
+ def test_url_fragment(self):
+ # Issue #11703: geturl() omits fragments in the original URL.
+ url = 'http://docs.python.org/library/urllib.html#OK'
+ self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!")
+ try:
+ fp = urllib_request.urlopen(url)
+ self.assertEqual(fp.geturl(), url)
+ finally:
+ self.unfakehttp()
+
+ def test_willclose(self):
+ self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!")
+ try:
+ resp = urlopen("http://www.python.org")
+ self.assertTrue(resp.fp.will_close)
+ finally:
+ self.unfakehttp()
+
+ @expectedFailurePY26
+ def test_read_0_9(self):
+ # "0.9" response accepted (but not "simple responses" without
+ # a status line)
+ self.check_read(b"0.9")
+
+ @expectedFailurePY26
+ def test_read_1_0(self):
+ self.check_read(b"1.0")
+
+ @expectedFailurePY26
+ def test_read_1_1(self):
+ self.check_read(b"1.1")
+
+ def test_read_bogus(self):
+ # urlopen() should raise IOError for many error codes.
+ self.fakehttp(b'''HTTP/1.1 401 Authentication Required
+Date: Wed, 02 Jan 2008 03:03:54 GMT
+Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
+Connection: close
+Content-Type: text/html; charset=iso-8859-1
+''')
+ try:
+ self.assertRaises(IOError, urlopen, "http://python.org/")
+ finally:
+ self.unfakehttp()
+
+ def test_invalid_redirect(self):
+ # urlopen() should raise IOError for many error codes.
+ self.fakehttp(b'''HTTP/1.1 302 Found
+Date: Wed, 02 Jan 2008 03:03:54 GMT
+Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
+Location: file://guidocomputer.athome.com:/python/license
+Connection: close
+Content-Type: text/html; charset=iso-8859-1
+''')
+ try:
+ self.assertRaises(urllib_error.HTTPError, urlopen,
+ "http://python.org/")
+ finally:
+ self.unfakehttp()
+
+ def test_empty_socket(self):
+ # urlopen() raises IOError if the underlying socket does not send any
+ # data. (#1680230)
+ self.fakehttp(b'')
+ try:
+ self.assertRaises(IOError, urlopen, "http://something")
+ finally:
+ self.unfakehttp()
+
+ def test_missing_localfile(self):
+ # Test for #10836
+ # 3.3 - URLError is not captured, explicit IOError is raised.
+ with self.assertRaises(IOError):
+ urlopen('file://localhost/a/file/which/doesnot/exists.py')
+
+ def test_file_notexists(self):
+ fd, tmp_file = tempfile.mkstemp()
+ tmp_fileurl = 'file://localhost/' + tmp_file.replace(os.path.sep, '/')
+ try:
+ self.assertTrue(os.path.exists(tmp_file))
+ with urlopen(tmp_fileurl) as fobj:
+ self.assertTrue(fobj)
+ finally:
+ os.close(fd)
+ os.unlink(tmp_file)
+ self.assertFalse(os.path.exists(tmp_file))
+ # 3.3 - IOError instead of URLError
+ with self.assertRaises(IOError):
+ urlopen(tmp_fileurl)
+
+ def test_ftp_nohost(self):
+ test_ftp_url = 'ftp:///path'
+ # 3.3 - IOError instead of URLError
+ with self.assertRaises(IOError):
+ urlopen(test_ftp_url)
+
+ def test_ftp_nonexisting(self):
+ # 3.3 - IOError instead of URLError
+ with self.assertRaises(IOError):
+ urlopen('ftp://localhost/a/file/which/doesnot/exists.py')
+
+
+ @expectedFailurePY26
+ def test_userpass_inurl(self):
+ self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
+ try:
+ fp = urlopen("http://user:pass@python.org/")
+ self.assertEqual(fp.readline(), b"Hello!")
+ self.assertEqual(fp.readline(), b"")
+ self.assertEqual(fp.geturl(), 'http://user:pass@python.org/')
+ self.assertEqual(fp.getcode(), 200)
+ finally:
+ self.unfakehttp()
+
+ @expectedFailurePY26
+ def test_userpass_inurl_w_spaces(self):
+ self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
+ try:
+ userpass = "a b:c d"
+ url = "http://{0}@python.org/".format(userpass)
+ fakehttp_wrapper = http_client.HTTPConnection
+ authorization = ("Authorization: Basic %s\r\n" %
+ b64encode(userpass.encode("ASCII")).decode("ASCII"))
+ fp = urlopen(url)
+ # The authorization header must be in place
+ self.assertIn(authorization, fakehttp_wrapper.buf.decode("UTF-8"))
+ self.assertEqual(fp.readline(), b"Hello!")
+ self.assertEqual(fp.readline(), b"")
+ # the spaces are quoted in URL so no match
+ self.assertNotEqual(fp.geturl(), url)
+ self.assertEqual(fp.getcode(), 200)
+ finally:
+ self.unfakehttp()
+
+ def test_URLopener_deprecation(self):
+ with support.check_warnings(('',DeprecationWarning)):
+ urllib_request.URLopener()
+
+class urlretrieve_FileTests(unittest.TestCase):
+ """Test urllib.urlretrieve() on local files"""
+
+ def setUp(self):
+ # Create a list of temporary files. Each item in the list is a file
+ # name (absolute path or relative to the current working directory).
+ # All files in this list will be deleted in the tearDown method. Note,
+ # this only helps to makes sure temporary files get deleted, but it
+ # does nothing about trying to close files that may still be open. It
+ # is the responsibility of the developer to properly close files even
+ # when exceptional conditions occur.
+ self.tempFiles = []
+
+ # Create a temporary file.
+ self.registerFileForCleanUp(support.TESTFN)
+ self.text = b'testing urllib.urlretrieve'
+ try:
+ FILE = open(support.TESTFN, 'wb')
+ FILE.write(self.text)
+ FILE.close()
+ finally:
+ try: FILE.close()
+ except: pass
+
+ def tearDown(self):
+ # Delete the temporary files.
+ for each in self.tempFiles:
+ try: os.remove(each)
+ except: pass
+
+ def constructLocalFileUrl(self, filePath):
+ filePath = os.path.abspath(filePath)
+ try:
+ filePath.encode("utf-8")
+ except UnicodeEncodeError:
+ raise unittest.SkipTest("filePath is not encodable to utf8")
+ return "file://%s" % urllib_request.pathname2url(filePath)
+
+ def createNewTempFile(self, data=b""):
+ """Creates a new temporary file containing the specified data,
+ registers the file for deletion during the test fixture tear down, and
+ returns the absolute path of the file."""
+
+ newFd, newFilePath = tempfile.mkstemp()
+ try:
+ self.registerFileForCleanUp(newFilePath)
+ newFile = os.fdopen(newFd, "wb")
+ newFile.write(data)
+ newFile.close()
+ finally:
+ try: newFile.close()
+ except: pass
+ return newFilePath
+
+ def registerFileForCleanUp(self, fileName):
+ self.tempFiles.append(fileName)
+
+ def test_basic(self):
+ # Make sure that a local file just gets its own location returned and
+ # a headers value is returned.
+ result = urllib_request.urlretrieve("file:%s" % support.TESTFN)
+ self.assertEqual(result[0], support.TESTFN)
+ self.assertIsInstance(result[1], email_message.Message,
+ "did not get a email.message.Message instance "
+ "as second returned value")
+
+ def test_copy(self):
+ # Test that setting the filename argument works.
+ second_temp = "%s.2" % support.TESTFN
+ self.registerFileForCleanUp(second_temp)
+ result = urllib_request.urlretrieve(self.constructLocalFileUrl(
+ support.TESTFN), second_temp)
+ self.assertEqual(second_temp, result[0])
+ self.assertTrue(os.path.exists(second_temp), "copy of the file was not "
+ "made")
+ FILE = open(second_temp, 'rb')
+ try:
+ text = FILE.read()
+ FILE.close()
+ finally:
+ try: FILE.close()
+ except: pass
+ self.assertEqual(self.text, text)
+
+ def test_reporthook(self):
+ # Make sure that the reporthook works.
+ def hooktester(block_count, block_read_size, file_size, count_holder=[0]):
+ self.assertIsInstance(block_count, int)
+ self.assertIsInstance(block_read_size, int)
+ self.assertIsInstance(file_size, int)
+ self.assertEqual(block_count, count_holder[0])
+ count_holder[0] = count_holder[0] + 1
+ second_temp = "%s.2" % support.TESTFN
+ self.registerFileForCleanUp(second_temp)
+ urllib_request.urlretrieve(
+ self.constructLocalFileUrl(support.TESTFN),
+ second_temp, hooktester)
+
+ def test_reporthook_0_bytes(self):
+ # Test on zero length file. Should call reporthook only 1 time.
+ report = []
+ def hooktester(block_count, block_read_size, file_size, _report=report):
+ _report.append((block_count, block_read_size, file_size))
+ srcFileName = self.createNewTempFile()
+ urllib_request.urlretrieve(self.constructLocalFileUrl(srcFileName),
+ support.TESTFN, hooktester)
+ self.assertEqual(len(report), 1)
+ self.assertEqual(report[0][2], 0)
+
+ def test_reporthook_5_bytes(self):
+ # Test on 5 byte file. Should call reporthook only 2 times (once when
+ # the "network connection" is established and once when the block is
+ # read).
+ report = []
+ def hooktester(block_count, block_read_size, file_size, _report=report):
+ _report.append((block_count, block_read_size, file_size))
+ srcFileName = self.createNewTempFile(b"x" * 5)
+ urllib_request.urlretrieve(self.constructLocalFileUrl(srcFileName),
+ support.TESTFN, hooktester)
+ self.assertEqual(len(report), 2)
+ self.assertEqual(report[0][2], 5)
+ self.assertEqual(report[1][2], 5)
+
+ def test_reporthook_8193_bytes(self):
+ # Test on 8193 byte file. Should call reporthook only 3 times (once
+ # when the "network connection" is established, once for the next 8192
+ # bytes, and once for the last byte).
+ report = []
+ def hooktester(block_count, block_read_size, file_size, _report=report):
+ _report.append((block_count, block_read_size, file_size))
+ srcFileName = self.createNewTempFile(b"x" * 8193)
+ urllib_request.urlretrieve(self.constructLocalFileUrl(srcFileName),
+ support.TESTFN, hooktester)
+ self.assertEqual(len(report), 3)
+ self.assertEqual(report[0][2], 8193)
+ self.assertEqual(report[0][1], 8192)
+ self.assertEqual(report[1][1], 8192)
+ self.assertEqual(report[2][1], 8192)
+
+
+class urlretrieve_HttpTests(unittest.TestCase, FakeHTTPMixin):
+ """Test urllib.urlretrieve() using fake http connections"""
+
+ @skip26
+ def test_short_content_raises_ContentTooShortError(self):
+ self.fakehttp(b'''HTTP/1.1 200 OK
+Date: Wed, 02 Jan 2008 03:03:54 GMT
+Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
+Connection: close
+Content-Length: 100
+Content-Type: text/html; charset=iso-8859-1
+
+FF
+''')
+
+ def _reporthook(par1, par2, par3):
+ pass
+
+ with self.assertRaises(urllib_error.ContentTooShortError):
+ try:
+ urllib_request.urlretrieve('http://example.com/',
+ reporthook=_reporthook)
+ finally:
+ self.unfakehttp()
+
+ @skip26
+ def test_short_content_raises_ContentTooShortError_without_reporthook(self):
+ self.fakehttp(b'''HTTP/1.1 200 OK
+Date: Wed, 02 Jan 2008 03:03:54 GMT
+Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
+Connection: close
+Content-Length: 100
+Content-Type: text/html; charset=iso-8859-1
+
+FF
+''')
+ with self.assertRaises(urllib_error.ContentTooShortError):
+ try:
+ urllib_request.urlretrieve('http://example.com/')
+ finally:
+ self.unfakehttp()
+
+
+class QuotingTests(unittest.TestCase):
+ """Tests for urllib.quote() and urllib.quote_plus()
+
+ According to RFC 2396 (Uniform Resource Identifiers), to escape a
+ character you write it as '%' + <2 character US-ASCII hex value>.
+ The Python code of ``'%' + hex(ord(<character>))[2:]`` escapes a
+ character properly. Case does not matter on the hex letters.
+
+ The various character sets specified are:
+
+ Reserved characters : ";/?:@&=+$,"
+ Have special meaning in URIs and must be escaped if not being used for
+ their special meaning
+ Data characters : letters, digits, and "-_.!~*'()"
+ Unreserved and do not need to be escaped; can be, though, if desired
+ Control characters : 0x00 - 0x1F, 0x7F
+ Have no use in URIs so must be escaped
+ space : 0x20
+ Must be escaped
+ Delimiters : '<>#%"'
+ Must be escaped
+ Unwise : "{}|\^[]`"
+ Must be escaped
+
+ """
+
+ def test_never_quote(self):
+ # Make sure quote() does not quote letters, digits, and "_,.-"
+ do_not_quote = '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ "abcdefghijklmnopqrstuvwxyz",
+ "0123456789",
+ "_.-"])
+ result = urllib_parse.quote(do_not_quote)
+ self.assertEqual(do_not_quote, result,
+ "using quote(): %r != %r" % (do_not_quote, result))
+ result = urllib_parse.quote_plus(do_not_quote)
+ self.assertEqual(do_not_quote, result,
+ "using quote_plus(): %r != %r" % (do_not_quote, result))
+
+ def test_default_safe(self):
+ # Test '/' is default value for 'safe' parameter
+ self.assertEqual(urllib_parse.quote.__defaults__[0], '/')
+
+ def test_safe(self):
+ # Test setting 'safe' parameter does what it should do
+ quote_by_default = "<>"
+ result = urllib_parse.quote(quote_by_default, safe=quote_by_default)
+ self.assertEqual(quote_by_default, result,
+ "using quote(): %r != %r" % (quote_by_default, result))
+ result = urllib_parse.quote_plus(quote_by_default,
+ safe=quote_by_default)
+ self.assertEqual(quote_by_default, result,
+ "using quote_plus(): %r != %r" %
+ (quote_by_default, result))
+ # Safe expressed as bytes rather than str
+ result = urllib_parse.quote(quote_by_default, safe=b"<>")
+ self.assertEqual(quote_by_default, result,
+ "using quote(): %r != %r" % (quote_by_default, result))
+ # "Safe" non-ASCII characters should have no effect
+ # (Since URIs are not allowed to have non-ASCII characters)
+ result = urllib_parse.quote("a\xfcb", encoding="latin-1", safe="\xfc")
+ expect = urllib_parse.quote("a\xfcb", encoding="latin-1", safe="")
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" %
+ (expect, result))
+ # Same as above, but using a bytes rather than str
+ result = urllib_parse.quote("a\xfcb", encoding="latin-1", safe=b"\xfc")
+ expect = urllib_parse.quote("a\xfcb", encoding="latin-1", safe="")
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" %
+ (expect, result))
+
+ def test_default_quoting(self):
+ # Make sure all characters that should be quoted are by default sans
+ # space (separate test for that).
+ should_quote = [chr(num) for num in range(32)] # For 0x00 - 0x1F
+ should_quote.append('<>#%"{}|\^[]`')
+ should_quote.append(chr(127)) # For 0x7F
+ should_quote = ''.join(should_quote)
+ for char in should_quote:
+ result = urllib_parse.quote(char)
+ self.assertEqual(hexescape(char), result,
+ "using quote(): "
+ "%s should be escaped to %s, not %s" %
+ (char, hexescape(char), result))
+ result = urllib_parse.quote_plus(char)
+ self.assertEqual(hexescape(char), result,
+ "using quote_plus(): "
+ "%s should be escapes to %s, not %s" %
+ (char, hexescape(char), result))
+ del should_quote
+ partial_quote = "ab[]cd"
+ expected = "ab%5B%5Dcd"
+ result = urllib_parse.quote(partial_quote)
+ self.assertEqual(expected, result,
+ "using quote(): %r != %r" % (expected, result))
+ result = urllib_parse.quote_plus(partial_quote)
+ self.assertEqual(expected, result,
+ "using quote_plus(): %r != %r" % (expected, result))
+
+ def test_quoting_space(self):
+ # Make sure quote() and quote_plus() handle spaces as specified in
+ # their unique way
+ result = urllib_parse.quote(' ')
+ self.assertEqual(result, hexescape(' '),
+ "using quote(): %r != %r" % (result, hexescape(' ')))
+ result = urllib_parse.quote_plus(' ')
+ self.assertEqual(result, '+',
+ "using quote_plus(): %r != +" % result)
+ given = "a b cd e f"
+ expect = given.replace(' ', hexescape(' '))
+ result = urllib_parse.quote(given)
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ expect = given.replace(' ', '+')
+ result = urllib_parse.quote_plus(given)
+ self.assertEqual(expect, result,
+ "using quote_plus(): %r != %r" % (expect, result))
+
+ def test_quoting_plus(self):
+ self.assertEqual(urllib_parse.quote_plus('alpha+beta gamma'),
+ 'alpha%2Bbeta+gamma')
+ self.assertEqual(urllib_parse.quote_plus('alpha+beta gamma', '+'),
+ 'alpha+beta+gamma')
+ # Test with bytes
+ self.assertEqual(urllib_parse.quote_plus(b'alpha+beta gamma'),
+ 'alpha%2Bbeta+gamma')
+ # Test with safe bytes
+ self.assertEqual(urllib_parse.quote_plus('alpha+beta gamma', b'+'),
+ 'alpha+beta+gamma')
+
+ def test_quote_bytes(self):
+ # Bytes should quote directly to percent-encoded values
+ given = b"\xa2\xd8ab\xff"
+ expect = "%A2%D8ab%FF"
+ result = urllib_parse.quote(given)
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ # Encoding argument should raise type error on bytes input
+ self.assertRaises(TypeError, urllib_parse.quote, given,
+ encoding="latin-1")
+ # quote_from_bytes should work the same
+ result = urllib_parse.quote_from_bytes(given)
+ self.assertEqual(expect, result,
+ "using quote_from_bytes(): %r != %r"
+ % (expect, result))
+
+ def test_quote_with_unicode(self):
+ # Characters in Latin-1 range, encoded by default in UTF-8
+ given = "\xa2\xd8ab\xff"
+ expect = "%C2%A2%C3%98ab%C3%BF"
+ result = urllib_parse.quote(given)
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ # Characters in Latin-1 range, encoded by with None (default)
+ result = urllib_parse.quote(given, encoding=None, errors=None)
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ # Characters in Latin-1 range, encoded with Latin-1
+ given = "\xa2\xd8ab\xff"
+ expect = "%A2%D8ab%FF"
+ result = urllib_parse.quote(given, encoding="latin-1")
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ # Characters in BMP, encoded by default in UTF-8
+ given = "\u6f22\u5b57" # "Kanji"
+ expect = "%E6%BC%A2%E5%AD%97"
+ result = urllib_parse.quote(given)
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ # Characters in BMP, encoded with Latin-1
+ given = "\u6f22\u5b57"
+ self.assertRaises(UnicodeEncodeError, urllib_parse.quote, given,
+ encoding="latin-1")
+ # Characters in BMP, encoded with Latin-1, with replace error handling
+ given = "\u6f22\u5b57"
+ expect = "%3F%3F" # "??"
+ result = urllib_parse.quote(given, encoding="latin-1",
+ errors="replace")
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ # Characters in BMP, Latin-1, with xmlcharref error handling
+ given = "\u6f22\u5b57"
+ expect = "%26%2328450%3B%26%2323383%3B" # "&#28450;&#23383;"
+ result = urllib_parse.quote(given, encoding="latin-1",
+ errors="xmlcharrefreplace")
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+
+ def test_quote_plus_with_unicode(self):
+ # Encoding (latin-1) test for quote_plus
+ given = "\xa2\xd8 \xff"
+ expect = "%A2%D8+%FF"
+ result = urllib_parse.quote_plus(given, encoding="latin-1")
+ self.assertEqual(expect, result,
+ "using quote_plus(): %r != %r" % (expect, result))
+ # Errors test for quote_plus
+ given = "ab\u6f22\u5b57 cd"
+ expect = "ab%3F%3F+cd"
+ result = urllib_parse.quote_plus(given, encoding="latin-1",
+ errors="replace")
+ self.assertEqual(expect, result,
+ "using quote_plus(): %r != %r" % (expect, result))
+
+
+class UnquotingTests(unittest.TestCase):
+ """Tests for unquote() and unquote_plus()
+
+ See the doc string for quoting_Tests for details on quoting and such.
+
+ """
+
+ def test_unquoting(self):
+ # Make sure unquoting of all ASCII values works
+ escape_list = []
+ for num in range(128):
+ given = hexescape(chr(num))
+ expect = chr(num)
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+ result = urllib_parse.unquote_plus(given)
+ self.assertEqual(expect, result,
+ "using unquote_plus(): %r != %r" %
+ (expect, result))
+ escape_list.append(given)
+ escape_string = ''.join(escape_list)
+ del escape_list
+ result = urllib_parse.unquote(escape_string)
+ self.assertEqual(result.count('%'), 1,
+ "using unquote(): not all characters escaped: "
+ "%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''))
+
+ def test_unquoting_badpercent(self):
+ # Test unquoting on bad percent-escapes
+ given = '%xab'
+ expect = given
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result, "using unquote(): %r != %r"
+ % (expect, result))
+ given = '%x'
+ expect = given
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result, "using unquote(): %r != %r"
+ % (expect, result))
+ given = '%'
+ expect = given
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result, "using unquote(): %r != %r"
+ % (expect, result))
+ # unquote_to_bytes
+ given = '%xab'
+ expect = bytes(given, 'ascii')
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+ given = '%x'
+ expect = bytes(given, 'ascii')
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+ given = '%'
+ expect = bytes(given, 'ascii')
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+ self.assertRaises((TypeError, AttributeError), urllib_parse.unquote_to_bytes, None)
+ self.assertRaises((TypeError, AttributeError), urllib_parse.unquote_to_bytes, ())
+
+ def test_unquoting_mixed_case(self):
+ # Test unquoting on mixed-case hex digits in the percent-escapes
+ given = '%Ab%eA'
+ expect = b'\xab\xea'
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result,
+ "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+
+ def test_unquoting_parts(self):
+ # Make sure unquoting works when have non-quoted characters
+ # interspersed
+ given = 'ab%sd' % hexescape('c')
+ expect = "abcd"
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ result = urllib_parse.unquote_plus(given)
+ self.assertEqual(expect, result,
+ "using unquote_plus(): %r != %r" % (expect, result))
+
+ def test_unquoting_plus(self):
+ # Test difference between unquote() and unquote_plus()
+ given = "are+there+spaces..."
+ expect = given
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+ expect = given.replace('+', ' ')
+ result = urllib_parse.unquote_plus(given)
+ self.assertEqual(expect, result,
+ "using unquote_plus(): %r != %r" % (expect, result))
+
+ def test_unquote_to_bytes(self):
+ given = 'br%C3%BCckner_sapporo_20050930.doc'
+ expect = b'br\xc3\xbcckner_sapporo_20050930.doc'
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result,
+ "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+ # Test on a string with unescaped non-ASCII characters
+ # (Technically an invalid URI; expect those characters to be UTF-8
+ # encoded).
+ result = urllib_parse.unquote_to_bytes("\u6f22%C3%BC")
+ expect = b'\xe6\xbc\xa2\xc3\xbc' # UTF-8 for "\u6f22\u00fc"
+ self.assertEqual(expect, result,
+ "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+ # Test with a bytes as input
+ given = b'%A2%D8ab%FF'
+ expect = b'\xa2\xd8ab\xff'
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result,
+ "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+ # Test with a bytes as input, with unescaped non-ASCII bytes
+ # (Technically an invalid URI; expect those bytes to be preserved)
+ given = b'%A2\xd8ab%FF'
+ expect = b'\xa2\xd8ab\xff'
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result,
+ "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+
+ def test_unquote_with_unicode(self):
+ # Characters in the Latin-1 range, encoded with UTF-8
+ given = 'br%C3%BCckner_sapporo_20050930.doc'
+ expect = 'br\u00fcckner_sapporo_20050930.doc'
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+ # Characters in the Latin-1 range, encoded with None (default)
+ result = urllib_parse.unquote(given, encoding=None, errors=None)
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # Characters in the Latin-1 range, encoded with Latin-1
+ result = urllib_parse.unquote('br%FCckner_sapporo_20050930.doc',
+ encoding="latin-1")
+ expect = 'br\u00fcckner_sapporo_20050930.doc'
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # Characters in BMP, encoded with UTF-8
+ given = "%E6%BC%A2%E5%AD%97"
+ expect = "\u6f22\u5b57" # "Kanji"
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # Decode with UTF-8, invalid sequence
+ given = "%F3%B1"
+ expect = "\ufffd" # Replacement character
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # Decode with UTF-8, invalid sequence, replace errors
+ result = urllib_parse.unquote(given, errors="replace")
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # Decode with UTF-8, invalid sequence, ignoring errors
+ given = "%F3%B1"
+ expect = ""
+ result = urllib_parse.unquote(given, errors="ignore")
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # A mix of non-ASCII and percent-encoded characters, UTF-8
+ result = urllib_parse.unquote("\u6f22%C3%BC")
+ expect = '\u6f22\u00fc'
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # A mix of non-ASCII and percent-encoded characters, Latin-1
+ # (Note, the string contains non-Latin-1-representable characters)
+ result = urllib_parse.unquote("\u6f22%FC", encoding="latin-1")
+ expect = '\u6f22\u00fc'
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+class urlencode_Tests(unittest.TestCase):
+ """Tests for urlencode()"""
+
+ def help_inputtype(self, given, test_type):
+ """Helper method for testing different input types.
+
+ 'given' must lead to only the pairs:
+ * 1st, 1
+ * 2nd, 2
+ * 3rd, 3
+
+ Test cannot assume anything about order. Docs make no guarantee and
+ have possible dictionary input.
+
+ """
+ expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
+ result = urllib_parse.urlencode(given)
+ for expected in expect_somewhere:
+ self.assertIn(expected, result,
+ "testing %s: %s not found in %s" %
+ (test_type, expected, result))
+ self.assertEqual(result.count('&'), 2,
+ "testing %s: expected 2 '&'s; got %s" %
+ (test_type, result.count('&')))
+ amp_location = result.index('&')
+ on_amp_left = result[amp_location - 1]
+ on_amp_right = result[amp_location + 1]
+ self.assertTrue(on_amp_left.isdigit() and on_amp_right.isdigit(),
+ "testing %s: '&' not located in proper place in %s" %
+ (test_type, result))
+ self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps
+ "testing %s: "
+ "unexpected number of characters: %s != %s" %
+ (test_type, len(result), (5 * 3) + 2))
+
+ def test_using_mapping(self):
+ # Test passing in a mapping object as an argument.
+ self.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'},
+ "using dict as input type")
+
+ def test_using_sequence(self):
+ # Test passing in a sequence of two-item sequences as an argument.
+ self.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')],
+ "using sequence of two-item tuples as input")
+
+ def test_quoting(self):
+ # Make sure keys and values are quoted using quote_plus()
+ given = {"&":"="}
+ expect = "%s=%s" % (hexescape('&'), hexescape('='))
+ result = urllib_parse.urlencode(given)
+ self.assertEqual(expect, result)
+ given = {"key name":"A bunch of pluses"}
+ expect = "key+name=A+bunch+of+pluses"
+ result = urllib_parse.urlencode(given)
+ self.assertEqual(expect, result)
+
+ def test_doseq(self):
+ # Test that passing True for 'doseq' parameter works correctly
+ given = {'sequence':['1', '2', '3']}
+ expect = "sequence=%s" % urllib_parse.quote_plus(str(['1', '2', '3']))
+ result = urllib_parse.urlencode(given)
+ self.assertEqual(expect, result)
+ result = urllib_parse.urlencode(given, True)
+ for value in given["sequence"]:
+ expect = "sequence=%s" % value
+ self.assertIn(expect, result)
+ self.assertEqual(result.count('&'), 2,
+ "Expected 2 '&'s, got %s" % result.count('&'))
+
+ def test_empty_sequence(self):
+ self.assertEqual("", urllib_parse.urlencode({}))
+ self.assertEqual("", urllib_parse.urlencode([]))
+
+ def test_nonstring_values(self):
+ self.assertEqual("a=1", urllib_parse.urlencode({"a": 1}))
+ self.assertEqual("a=None", urllib_parse.urlencode({"a": None}))
+
+ def test_nonstring_seq_values(self):
+ from future.backports import OrderedDict
+ self.assertEqual("a=1&a=2", urllib_parse.urlencode({"a": [1, 2]}, True))
+ self.assertEqual("a=None&a=a",
+ urllib_parse.urlencode({"a": [None, "a"]}, True))
+ data = OrderedDict([("a", 1), ("b", 1)])
+ self.assertEqual("a=a&a=b",
+ urllib_parse.urlencode({"a": data}, True))
+
+ def test_urlencode_encoding(self):
+ # ASCII encoding. Expect %3F with errors="replace'
+ given = (('\u00a0', '\u00c1'),)
+ expect = '%3F=%3F'
+ result = urllib_parse.urlencode(given, encoding="ASCII", errors="replace")
+ self.assertEqual(expect, result)
+
+ # Default is UTF-8 encoding.
+ given = (('\u00a0', '\u00c1'),)
+ expect = '%C2%A0=%C3%81'
+ result = urllib_parse.urlencode(given)
+ self.assertEqual(expect, result)
+
+ # Latin-1 encoding.
+ given = (('\u00a0', '\u00c1'),)
+ expect = '%A0=%C1'
+ result = urllib_parse.urlencode(given, encoding="latin-1")
+ self.assertEqual(expect, result)
+
+ def test_urlencode_encoding_doseq(self):
+ # ASCII Encoding. Expect %3F with errors="replace'
+ given = (('\u00a0', '\u00c1'),)
+ expect = '%3F=%3F'
+ result = urllib_parse.urlencode(given, doseq=True,
+ encoding="ASCII", errors="replace")
+ self.assertEqual(expect, result)
+
+ # ASCII Encoding. On a sequence of values.
+ given = (("\u00a0", (1, "\u00c1")),)
+ expect = '%3F=1&%3F=%3F'
+ result = urllib_parse.urlencode(given, True,
+ encoding="ASCII", errors="replace")
+ self.assertEqual(expect, result)
+
+ # Utf-8
+ given = (("\u00a0", "\u00c1"),)
+ expect = '%C2%A0=%C3%81'
+ result = urllib_parse.urlencode(given, True)
+ self.assertEqual(expect, result)
+
+ given = (("\u00a0", (42, "\u00c1")),)
+ expect = '%C2%A0=42&%C2%A0=%C3%81'
+ result = urllib_parse.urlencode(given, True)
+ self.assertEqual(expect, result)
+
+ # latin-1
+ given = (("\u00a0", "\u00c1"),)
+ expect = '%A0=%C1'
+ result = urllib_parse.urlencode(given, True, encoding="latin-1")
+ self.assertEqual(expect, result)
+
+ given = (("\u00a0", (42, "\u00c1")),)
+ expect = '%A0=42&%A0=%C1'
+ result = urllib_parse.urlencode(given, True, encoding="latin-1")
+ self.assertEqual(expect, result)
+
+ def test_urlencode_bytes(self):
+ given = ((b'\xa0\x24', b'\xc1\x24'),)
+ expect = '%A0%24=%C1%24'
+ result = urllib_parse.urlencode(given)
+ self.assertEqual(expect, result)
+ result = urllib_parse.urlencode(given, True)
+ self.assertEqual(expect, result)
+
+ # Sequence of values
+ given = ((b'\xa0\x24', (42, b'\xc1\x24')),)
+ expect = '%A0%24=42&%A0%24=%C1%24'
+ result = urllib_parse.urlencode(given, True)
+ self.assertEqual(expect, result)
+
+ def test_urlencode_encoding_safe_parameter(self):
+
+ # Send '$' (\x24) as safe character
+ # Default utf-8 encoding
+
+ given = ((b'\xa0\x24', b'\xc1\x24'),)
+ result = urllib_parse.urlencode(given, safe=":$")
+ expect = '%A0$=%C1$'
+ self.assertEqual(expect, result)
+
+ given = ((b'\xa0\x24', b'\xc1\x24'),)
+ result = urllib_parse.urlencode(given, doseq=True, safe=":$")
+ expect = '%A0$=%C1$'
+ self.assertEqual(expect, result)
+
+ # Safe parameter in sequence
+ given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),)
+ expect = '%A0$=%C1$&%A0$=13&%A0$=42'
+ result = urllib_parse.urlencode(given, True, safe=":$")
+ self.assertEqual(expect, result)
+
+ # Test all above in latin-1 encoding
+
+ given = ((b'\xa0\x24', b'\xc1\x24'),)
+ result = urllib_parse.urlencode(given, safe=":$",
+ encoding="latin-1")
+ expect = '%A0$=%C1$'
+ self.assertEqual(expect, result)
+
+ given = ((b'\xa0\x24', b'\xc1\x24'),)
+ expect = '%A0$=%C1$'
+ result = urllib_parse.urlencode(given, doseq=True, safe=":$",
+ encoding="latin-1")
+
+ given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),)
+ expect = '%A0$=%C1$&%A0$=13&%A0$=42'
+ result = urllib_parse.urlencode(given, True, safe=":$",
+ encoding="latin-1")
+ self.assertEqual(expect, result)
+
+class Pathname_Tests(unittest.TestCase):
+ """Test pathname2url() and url2pathname()"""
+
+ def test_basic(self):
+ # Make sure simple tests pass
+ expected_path = os.path.join("parts", "of", "a", "path")
+ expected_url = "parts/of/a/path"
+ result = urllib_request.pathname2url(expected_path)
+ self.assertEqual(expected_url, result,
+ "pathname2url() failed; %s != %s" %
+ (result, expected_url))
+ result = urllib_request.url2pathname(expected_url)
+ self.assertEqual(expected_path, result,
+ "url2pathame() failed; %s != %s" %
+ (result, expected_path))
+
+ def test_quoting(self):
+ # Test automatic quoting and unquoting works for pathnam2url() and
+ # url2pathname() respectively
+ given = os.path.join("needs", "quot=ing", "here")
+ expect = "needs/%s/here" % urllib_parse.quote("quot=ing")
+ result = urllib_request.pathname2url(given)
+ self.assertEqual(expect, result,
+ "pathname2url() failed; %s != %s" %
+ (expect, result))
+ expect = given
+ result = urllib_request.url2pathname(result)
+ self.assertEqual(expect, result,
+ "url2pathname() failed; %s != %s" %
+ (expect, result))
+ given = os.path.join("make sure", "using_quote")
+ expect = "%s/using_quote" % urllib_parse.quote("make sure")
+ result = urllib_request.pathname2url(given)
+ self.assertEqual(expect, result,
+ "pathname2url() failed; %s != %s" %
+ (expect, result))
+ given = "make+sure/using_unquote"
+ expect = os.path.join("make+sure", "using_unquote")
+ result = urllib_request.url2pathname(given)
+ self.assertEqual(expect, result,
+ "url2pathname() failed; %s != %s" %
+ (expect, result))
+
+ @unittest.skipUnless(sys.platform == 'win32',
+ 'test specific to the urllib.url2path function.')
+ def test_ntpath(self):
+ given = ('/C:/', '///C:/', '/C|//')
+ expect = 'C:\\'
+ for url in given:
+ result = urllib_request.url2pathname(url)
+ self.assertEqual(expect, result,
+ 'urllib_request..url2pathname() failed; %s != %s' %
+ (expect, result))
+ given = '///C|/path'
+ expect = 'C:\\path'
+ result = urllib_request.url2pathname(given)
+ self.assertEqual(expect, result,
+ 'urllib_request.url2pathname() failed; %s != %s' %
+ (expect, result))
+
+class Utility_Tests(unittest.TestCase):
+ """Testcase to test the various utility functions in the urllib."""
+
+ def test_splitpasswd(self):
+ """Some of password examples are not sensible, but it is added to
+ confirming to RFC2617 and addressing issue4675.
+ """
+ self.assertEqual(('user', 'ab'),urllib_parse.splitpasswd('user:ab'))
+ self.assertEqual(('user', 'a\nb'),urllib_parse.splitpasswd('user:a\nb'))
+ self.assertEqual(('user', 'a\tb'),urllib_parse.splitpasswd('user:a\tb'))
+ self.assertEqual(('user', 'a\rb'),urllib_parse.splitpasswd('user:a\rb'))
+ self.assertEqual(('user', 'a\fb'),urllib_parse.splitpasswd('user:a\fb'))
+ self.assertEqual(('user', 'a\vb'),urllib_parse.splitpasswd('user:a\vb'))
+ self.assertEqual(('user', 'a:b'),urllib_parse.splitpasswd('user:a:b'))
+ self.assertEqual(('user', 'a b'),urllib_parse.splitpasswd('user:a b'))
+ self.assertEqual(('user 2', 'ab'),urllib_parse.splitpasswd('user 2:ab'))
+ self.assertEqual(('user+1', 'a+b'),urllib_parse.splitpasswd('user+1:a+b'))
+
+ def test_thishost(self):
+ """Test the urllib_request.thishost utility function returns a tuple"""
+ self.assertIsInstance(urllib_request.thishost(), tuple)
+
+
+class URLopener_Tests(unittest.TestCase):
+ """Testcase to test the open method of URLopener class."""
+
+ def test_quoted_open(self):
+ class DummyURLopener(urllib_request.URLopener):
+ def open_spam(self, url):
+ return url
+ with support.check_warnings(
+ ('DummyURLopener style of invoking requests is deprecated.',
+ DeprecationWarning)):
+ self.assertEqual(DummyURLopener().open(
+ 'spam://example/ /'),'//example/%20/')
+
+ # test the safe characters are not quoted by urlopen
+ self.assertEqual(DummyURLopener().open(
+ "spam://c:|windows%/:=&?~#+!$,;'@()*[]|/path/"),
+ "//c:|windows%/:=&?~#+!$,;'@()*[]|/path/")
+
+# Just commented them out.
+# Can't really tell why keep failing in windows and sparc.
+# 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!
+# . Facundo
+#
+# def server(evt):
+# import socket, time
+# serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# serv.settimeout(3)
+# serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+# serv.bind(("", 9093))
+# serv.listen(5)
+# try:
+# conn, addr = serv.accept()
+# conn.send("1 Hola mundo\n")
+# cantdata = 0
+# while cantdata < 13:
+# data = conn.recv(13-cantdata)
+# cantdata += len(data)
+# time.sleep(.3)
+# conn.send("2 No more lines\n")
+# conn.close()
+# except socket.timeout:
+# pass
+# finally:
+# serv.close()
+# evt.set()
+#
+# class FTPWrapperTests(unittest.TestCase):
+#
+# def setUp(self):
+# import ftplib, time, threading
+# ftplib.FTP.port = 9093
+# self.evt = threading.Event()
+# threading.Thread(target=server, args=(self.evt,)).start()
+# time.sleep(.1)
+#
+# def tearDown(self):
+# self.evt.wait()
+#
+# def testBasic(self):
+# # connects
+# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
+# ftp.close()
+#
+# def testTimeoutNone(self):
+# # global default timeout is ignored
+# import socket
+# self.assertTrue(socket.getdefaulttimeout() is None)
+# socket.setdefaulttimeout(30)
+# try:
+# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
+# finally:
+# socket.setdefaulttimeout(None)
+# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
+# ftp.close()
+#
+# def testTimeoutDefault(self):
+# # global default timeout is used
+# import socket
+# self.assertTrue(socket.getdefaulttimeout() is None)
+# socket.setdefaulttimeout(30)
+# try:
+# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
+# finally:
+# socket.setdefaulttimeout(None)
+# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
+# ftp.close()
+#
+# def testTimeoutValue(self):
+# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [],
+# timeout=30)
+# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
+# ftp.close()
+
+class RequestTests(unittest.TestCase):
+ """Unit tests for urllib_request.Request."""
+
+ def test_default_values(self):
+ Request = urllib_request.Request
+ request = Request("http://www.python.org")
+ self.assertEqual(request.get_method(), 'GET')
+ request = Request("http://www.python.org", {})
+ self.assertEqual(request.get_method(), 'POST')
+
+ def test_with_method_arg(self):
+ Request = urllib_request.Request
+ request = Request("http://www.python.org", method='HEAD')
+ self.assertEqual(request.method, 'HEAD')
+ self.assertEqual(request.get_method(), 'HEAD')
+ request = Request("http://www.python.org", {}, method='HEAD')
+ self.assertEqual(request.method, 'HEAD')
+ self.assertEqual(request.get_method(), 'HEAD')
+ request = Request("http://www.python.org", method='GET')
+ self.assertEqual(request.get_method(), 'GET')
+ request.method = 'HEAD'
+ self.assertEqual(request.get_method(), 'HEAD')
+
+
+class URL2PathNameTests(unittest.TestCase):
+
+ @expectedFailurePY26
+ def test_converting_drive_letter(self):
+ self.assertEqual(url2pathname("///C|"), 'C:')
+ self.assertEqual(url2pathname("///C:"), 'C:')
+ self.assertEqual(url2pathname("///C|/"), 'C:\\')
+
+ def test_converting_when_no_drive_letter(self):
+ # cannot end a raw string in \
+ self.assertEqual(url2pathname("///C/test/"), r'\\\C\test' '\\')
+ self.assertEqual(url2pathname("////C/test/"), r'\\C\test' '\\')
+
+ def test_simple_compare(self):
+ self.assertEqual(url2pathname("///C|/foo/bar/spam.foo"),
+ r'C:\foo\bar\spam.foo')
+
+ def test_non_ascii_drive_letter(self):
+ self.assertRaises(IOError, url2pathname, "///\u00e8|/")
+
+ def test_roundtrip_url2pathname(self):
+ list_of_paths = ['C:',
+ r'\\\C\test\\',
+ r'C:\foo\bar\spam.foo'
+ ]
+ for path in list_of_paths:
+ self.assertEqual(url2pathname(pathname2url(path)), path)
+
+class PathName2URLTests(unittest.TestCase):
+
+ def test_converting_drive_letter(self):
+ self.assertEqual(pathname2url("C:"), '///C:')
+ self.assertEqual(pathname2url("C:\\"), '///C:')
+
+ def test_converting_when_no_drive_letter(self):
+ self.assertEqual(pathname2url(r"\\\folder\test" "\\"),
+ '/////folder/test/')
+ self.assertEqual(pathname2url(r"\\folder\test" "\\"),
+ '////folder/test/')
+ self.assertEqual(pathname2url(r"\folder\test" "\\"),
+ '/folder/test/')
+
+ def test_simple_compare(self):
+ self.assertEqual(pathname2url(r'C:\foo\bar\spam.foo'),
+ "///C:/foo/bar/spam.foo" )
+
+ def test_long_drive_letter(self):
+ self.assertRaises(IOError, pathname2url, "XX:\\")
+
+ def test_roundtrip_pathname2url(self):
+ list_of_paths = ['///C:',
+ '/////folder/test/',
+ '///C:/foo/bar/spam.foo']
+ for path in list_of_paths:
+ self.assertEqual(pathname2url(url2pathname(path)), path)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_urllib2.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_urllib2.py
new file mode 100644
index 0000000..2d69dad
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_urllib2.py
@@ -0,0 +1,1569 @@
+from __future__ import absolute_import, division, unicode_literals
+import os
+import io
+import socket
+import array
+import sys
+
+import http.client
+from future.standard_library import install_aliases
+from future.backports.test import support
+import future.backports.urllib.request as urllib_request
+# The proxy bypass method imported below has logic specific to the OSX
+# proxy config data structure but is testable on all platforms.
+from future.backports.urllib.request import Request, OpenerDirector, _proxy_bypass_macosx_sysconf
+import future.backports.urllib.error as urllib_error
+from future.tests.base import unittest, skip26
+from future.builtins import bytes, dict, int, open, str, zip
+from future.utils import text_to_native_str
+
+install_aliases() # for base64.encodebytes on Py2
+
+# from future.tests.test_http_cookiejar import interact_netscape
+
+class FakeResponse(object):
+ def __init__(self, headers=[], url=None):
+ """
+ headers: list of RFC822-style 'Key: value' strings
+ """
+ import email
+ # The email.message_from_string is available on both Py2.7 and Py3.3
+ self._headers = email.message_from_string("\n".join(headers))
+ self._url = url
+ def info(self): return self._headers
+
+
+def interact_netscape(cookiejar, url, *set_cookie_hdrs):
+ return _interact(cookiejar, url, set_cookie_hdrs, "Set-Cookie")
+
+def _interact(cookiejar, url, set_cookie_hdrs, hdr_name):
+ """Perform a single request / response cycle, returning Cookie: header."""
+ req = urllib_request.Request(url)
+ cookiejar.add_cookie_header(req)
+ cookie_hdr = req.get_header("Cookie", "")
+ headers = []
+ for hdr in set_cookie_hdrs:
+ headers.append("%s: %s" % (hdr_name, hdr))
+ res = FakeResponse(headers, url)
+ cookiejar.extract_cookies(res, req)
+ return cookie_hdr
+
+
+# XXX
+# Request
+# CacheFTPHandler (hard to write)
+# parse_keqv_list, parse_http_list, HTTPDigestAuthHandler
+
+class TrivialTests(unittest.TestCase):
+
+ def test___all__(self):
+ # Verify which names are exposed
+ for module in 'request', 'response', 'parse', 'error', 'robotparser':
+ context = {}
+ exec('from future.backports.urllib.%s import *' % module, context)
+ del context['__builtins__']
+ if module == 'request' and os.name == 'nt':
+ u, p = context.pop('url2pathname'), context.pop('pathname2url')
+ self.assertEqual(u.__module__, 'nturl2path')
+ self.assertEqual(p.__module__, 'nturl2path')
+ for k, v in context.items():
+ self.assertEqual(v.__module__, 'future.backports.urllib.%s' % module,
+ "%r is exposed in 'future.backports.urllib.%s' but defined in %r" %
+ (k, module, v.__module__))
+
+ def test_trivial(self):
+ # A couple trivial tests
+
+ self.assertRaises(ValueError, urllib_request.urlopen, 'bogus url')
+
+ # XXX Name hacking to get this to work on Windows.
+ fname = os.path.abspath(urllib_request.__file__).replace('\\', '/')
+
+ if os.name == 'nt':
+ file_url = "file:///%s" % fname
+ else:
+ file_url = "file://%s" % fname
+
+ f = urllib_request.urlopen(file_url)
+
+ f.read()
+ f.close()
+
+ def test_parse_http_list(self):
+ tests = [
+ ('a,b,c', ['a', 'b', 'c']),
+ ('path"o,l"og"i"cal, example', ['path"o,l"og"i"cal', 'example']),
+ ('a, b, "c", "d", "e,f", g, h',
+ ['a', 'b', '"c"', '"d"', '"e,f"', 'g', 'h']),
+ ('a="b\\"c", d="e\\,f", g="h\\\\i"',
+ ['a="b"c"', 'd="e,f"', 'g="h\\i"'])]
+ for string, list in tests:
+ self.assertEqual(urllib_request.parse_http_list(string), list)
+
+ def test_URLError_reasonstr(self):
+ err = urllib_error.URLError('reason')
+ self.assertIn(err.reason, str(err))
+
+class RequestHdrsTests(unittest.TestCase):
+
+ def test_request_headers_dict(self):
+ """
+ The Request.headers dictionary is not a documented interface. It
+ should stay that way, because the complete set of headers are only
+ accessible through the .get_header(), .has_header(), .header_items()
+ interface. However, .headers pre-dates those methods, and so real code
+ will be using the dictionary.
+
+ The introduction in 2.4 of those methods was a mistake for the same
+ reason: code that previously saw all (urllib2 user)-provided headers in
+ .headers now sees only a subset.
+
+ """
+ url = "http://example.com"
+ self.assertEqual(Request(url,
+ headers={"Spam-eggs": "blah"}
+ ).headers["Spam-eggs"], "blah")
+ self.assertEqual(Request(url,
+ headers={"spam-EggS": "blah"}
+ ).headers["Spam-eggs"], "blah")
+
+ def test_request_headers_methods(self):
+ """
+ Note the case normalization of header names here, to
+ .capitalize()-case. This should be preserved for
+ backwards-compatibility. (In the HTTP case, normalization to
+ .title()-case is done by urllib2 before sending headers to
+ http.client).
+
+ Note that e.g. r.has_header("spam-EggS") is currently False, and
+ r.get_header("spam-EggS") returns None, but that could be changed in
+ future.
+
+ Method r.remove_header should remove items both from r.headers and
+ r.unredirected_hdrs dictionaries
+ """
+ url = "http://example.com"
+ req = Request(url, headers={"Spam-eggs": "blah"})
+ self.assertTrue(req.has_header("Spam-eggs"))
+ self.assertEqual(req.header_items(), [('Spam-eggs', 'blah')])
+
+ req.add_header("Foo-Bar", "baz")
+ self.assertEqual(sorted(req.header_items()),
+ [('Foo-bar', 'baz'), ('Spam-eggs', 'blah')])
+ self.assertFalse(req.has_header("Not-there"))
+ self.assertIsNone(req.get_header("Not-there"))
+ self.assertEqual(req.get_header("Not-there", "default"), "default")
+
+
+ def test_password_manager(self):
+ mgr = urllib_request.HTTPPasswordMgr()
+ add = mgr.add_password
+ find_user_pass = mgr.find_user_password
+ add("Some Realm", "http://example.com/", "joe", "password")
+ add("Some Realm", "http://example.com/ni", "ni", "ni")
+ add("c", "http://example.com/foo", "foo", "ni")
+ add("c", "http://example.com/bar", "bar", "nini")
+ add("b", "http://example.com/", "first", "blah")
+ add("b", "http://example.com/", "second", "spam")
+ add("a", "http://example.com", "1", "a")
+ add("Some Realm", "http://c.example.com:3128", "3", "c")
+ add("Some Realm", "d.example.com", "4", "d")
+ add("Some Realm", "e.example.com:3128", "5", "e")
+
+ self.assertEqual(find_user_pass("Some Realm", "example.com"),
+ ('joe', 'password'))
+
+ #self.assertEqual(find_user_pass("Some Realm", "http://example.com/ni"),
+ # ('ni', 'ni'))
+
+ self.assertEqual(find_user_pass("Some Realm", "http://example.com"),
+ ('joe', 'password'))
+ self.assertEqual(find_user_pass("Some Realm", "http://example.com/"),
+ ('joe', 'password'))
+ self.assertEqual(
+ find_user_pass("Some Realm", "http://example.com/spam"),
+ ('joe', 'password'))
+ self.assertEqual(
+ find_user_pass("Some Realm", "http://example.com/spam/spam"),
+ ('joe', 'password'))
+ self.assertEqual(find_user_pass("c", "http://example.com/foo"),
+ ('foo', 'ni'))
+ self.assertEqual(find_user_pass("c", "http://example.com/bar"),
+ ('bar', 'nini'))
+ self.assertEqual(find_user_pass("b", "http://example.com/"),
+ ('second', 'spam'))
+
+ # No special relationship between a.example.com and example.com:
+
+ self.assertEqual(find_user_pass("a", "http://example.com/"),
+ ('1', 'a'))
+ self.assertEqual(find_user_pass("a", "http://a.example.com/"),
+ (None, None))
+
+ # Ports:
+
+ self.assertEqual(find_user_pass("Some Realm", "c.example.com"),
+ (None, None))
+ self.assertEqual(find_user_pass("Some Realm", "c.example.com:3128"),
+ ('3', 'c'))
+ self.assertEqual(
+ find_user_pass("Some Realm", "http://c.example.com:3128"),
+ ('3', 'c'))
+ self.assertEqual(find_user_pass("Some Realm", "d.example.com"),
+ ('4', 'd'))
+ self.assertEqual(find_user_pass("Some Realm", "e.example.com:3128"),
+ ('5', 'e'))
+
+ def test_password_manager_default_port(self):
+ """
+ The point to note here is that we can't guess the default port if
+ there's no scheme. This applies to both add_password and
+ find_user_password.
+ """
+ mgr = urllib_request.HTTPPasswordMgr()
+ add = mgr.add_password
+ find_user_pass = mgr.find_user_password
+ add("f", "http://g.example.com:80", "10", "j")
+ add("g", "http://h.example.com", "11", "k")
+ add("h", "i.example.com:80", "12", "l")
+ add("i", "j.example.com", "13", "m")
+ self.assertEqual(find_user_pass("f", "g.example.com:100"),
+ (None, None))
+ self.assertEqual(find_user_pass("f", "g.example.com:80"),
+ ('10', 'j'))
+ self.assertEqual(find_user_pass("f", "g.example.com"),
+ (None, None))
+ self.assertEqual(find_user_pass("f", "http://g.example.com:100"),
+ (None, None))
+ self.assertEqual(find_user_pass("f", "http://g.example.com:80"),
+ ('10', 'j'))
+ self.assertEqual(find_user_pass("f", "http://g.example.com"),
+ ('10', 'j'))
+ self.assertEqual(find_user_pass("g", "h.example.com"), ('11', 'k'))
+ self.assertEqual(find_user_pass("g", "h.example.com:80"), ('11', 'k'))
+ self.assertEqual(find_user_pass("g", "http://h.example.com:80"),
+ ('11', 'k'))
+ self.assertEqual(find_user_pass("h", "i.example.com"), (None, None))
+ self.assertEqual(find_user_pass("h", "i.example.com:80"), ('12', 'l'))
+ self.assertEqual(find_user_pass("h", "http://i.example.com:80"),
+ ('12', 'l'))
+ self.assertEqual(find_user_pass("i", "j.example.com"), ('13', 'm'))
+ self.assertEqual(find_user_pass("i", "j.example.com:80"),
+ (None, None))
+ self.assertEqual(find_user_pass("i", "http://j.example.com"),
+ ('13', 'm'))
+ self.assertEqual(find_user_pass("i", "http://j.example.com:80"),
+ (None, None))
+
+
+class MockOpener(object):
+ addheaders = []
+ def open(self, req, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
+ self.req, self.data, self.timeout = req, data, timeout
+ def error(self, proto, *args):
+ self.proto, self.args = proto, args
+
+class MockFile(object):
+ def read(self, count=None): pass
+ def readline(self, count=None): pass
+ def close(self): pass
+
+class MockHeaders(dict):
+ def getheaders(self, name):
+ return list(self.values())
+
+class MockResponse(io.StringIO):
+ def __init__(self, code, msg, headers, data, url=None):
+ io.StringIO.__init__(self, data)
+ self.code, self.msg, self.headers, self.url = code, msg, headers, url
+ def info(self):
+ return self.headers
+ def geturl(self):
+ return self.url
+
+class MockCookieJar(object):
+ def add_cookie_header(self, request):
+ self.ach_req = request
+ def extract_cookies(self, response, request):
+ self.ec_req, self.ec_r = request, response
+
+class FakeMethod(object):
+ def __init__(self, meth_name, action, handle):
+ self.meth_name = meth_name
+ self.handle = handle
+ self.action = action
+ def __call__(self, *args):
+ return self.handle(self.meth_name, self.action, *args)
+
+class MockHTTPResponse(io.IOBase):
+ def __init__(self, fp, msg, status, reason):
+ self.fp = fp
+ self.msg = msg
+ self.status = status
+ self.reason = reason
+ self.code = 200
+
+ def read(self):
+ return ''
+
+ def info(self):
+ return {}
+
+ def geturl(self):
+ return self.url
+
+
+class MockHTTPClass(object):
+ def __init__(self):
+ self.level = 0
+ self.req_headers = []
+ self.data = None
+ self.raise_on_endheaders = False
+ self.sock = None
+ self._tunnel_headers = {}
+
+ def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
+ self.host = host
+ self.timeout = timeout
+ return self
+
+ def set_debuglevel(self, level):
+ self.level = level
+
+ def set_tunnel(self, host, port=None, headers=None):
+ self._tunnel_host = host
+ self._tunnel_port = port
+ if headers:
+ self._tunnel_headers = headers
+ else:
+ self._tunnel_headers.clear()
+
+ def request(self, method, url, body=None, headers=None):
+ self.method = method
+ self.selector = url
+ if headers is not None:
+ self.req_headers += headers.items()
+ self.req_headers.sort()
+ if body:
+ self.data = body
+ if self.raise_on_endheaders:
+ import socket
+ raise socket.error()
+ def getresponse(self):
+ return MockHTTPResponse(MockFile(), {}, 200, "OK")
+
+ def close(self):
+ pass
+
+class MockHandler(object):
+ # useful for testing handler machinery
+ # see add_ordered_mock_handlers() docstring
+ handler_order = 500
+ def __init__(self, methods):
+ self._define_methods(methods)
+ def _define_methods(self, methods):
+ for spec in methods:
+ if len(spec) == 2: name, action = spec
+ else: name, action = spec, None
+ meth = FakeMethod(name, action, self.handle)
+ setattr(self.__class__, name, meth)
+ def handle(self, fn_name, action, *args, **kwds):
+ self.parent.calls.append((self, fn_name, args, kwds))
+ if action is None:
+ return None
+ elif action == "return self":
+ return self
+ elif action == "return response":
+ res = MockResponse(200, "OK", {}, "")
+ return res
+ elif action == "return request":
+ return Request("http://blah/")
+ elif action.startswith("error"):
+ code = action[action.rfind(" ")+1:]
+ try:
+ code = int(code)
+ except ValueError:
+ pass
+ res = MockResponse(200, "OK", {}, "")
+ return self.parent.error("http", args[0], res, code, "", {})
+ elif action == "raise":
+ raise urllib_error.URLError("blah")
+ assert False
+ def close(self): pass
+ def add_parent(self, parent):
+ self.parent = parent
+ self.parent.calls = []
+ def __lt__(self, other):
+ if not hasattr(other, "handler_order"):
+ # No handler_order, leave in original order. Yuck.
+ return True
+ return self.handler_order < other.handler_order
+
+def add_ordered_mock_handlers(opener, meth_spec):
+ """Create MockHandlers and add them to an OpenerDirector.
+
+ meth_spec: list of lists of tuples and strings defining methods to define
+ on handlers. eg:
+
+ [["http_error", "ftp_open"], ["http_open"]]
+
+ defines methods .http_error() and .ftp_open() on one handler, and
+ .http_open() on another. These methods just record their arguments and
+ return None. Using a tuple instead of a string causes the method to
+ perform some action (see MockHandler.handle()), eg:
+
+ [["http_error"], [("http_open", "return request")]]
+
+ defines .http_error() on one handler (which simply returns None), and
+ .http_open() on another handler, which returns a Request object.
+
+ """
+ handlers = []
+ count = 0
+ for meths in meth_spec:
+ class MockHandlerSubclass(MockHandler): pass
+ h = MockHandlerSubclass(meths)
+ h.handler_order += count
+ h.add_parent(opener)
+ count = count + 1
+ handlers.append(h)
+ opener.add_handler(h)
+ return handlers
+
+def build_test_opener(*handler_instances):
+ opener = OpenerDirector()
+ for h in handler_instances:
+ opener.add_handler(h)
+ return opener
+
+class MockHTTPHandler(urllib_request.BaseHandler):
+ # useful for testing redirections and auth
+ # sends supplied headers and code as first response
+ # sends 200 OK as second response
+ def __init__(self, code, headers):
+ self.code = code
+ self.headers = headers
+ self.reset()
+ def reset(self):
+ self._count = 0
+ self.requests = []
+ def http_open(self, req):
+ import future.backports.email as email
+ import copy
+ self.requests.append(copy.deepcopy(req))
+ if self._count == 0:
+ self._count = self._count + 1
+ name = http.client.responses[self.code]
+ msg = email.message_from_string(self.headers)
+ return self.parent.error(
+ "http", req, MockFile(), self.code, name, msg)
+ else:
+ self.req = req
+ msg = email.message_from_string("\r\n\r\n")
+ return MockResponse(200, "OK", msg, "", req.get_full_url())
+
+class MockHTTPSHandler(urllib_request.AbstractHTTPHandler):
+ # Useful for testing the Proxy-Authorization request by verifying the
+ # properties of httpcon
+
+ def __init__(self):
+ urllib_request.AbstractHTTPHandler.__init__(self)
+ self.httpconn = MockHTTPClass()
+
+ def https_open(self, req):
+ return self.do_open(self.httpconn, req)
+
+class MockPasswordManager(object):
+ def add_password(self, realm, uri, user, password):
+ self.realm = realm
+ self.url = uri
+ self.user = user
+ self.password = password
+ def find_user_password(self, realm, authuri):
+ self.target_realm = realm
+ self.target_url = authuri
+ return self.user, self.password
+
+
+class OpenerDirectorTests(unittest.TestCase):
+
+ def test_add_non_handler(self):
+ class NonHandler(object):
+ pass
+ self.assertRaises(TypeError,
+ OpenerDirector().add_handler, NonHandler())
+
+ def test_badly_named_methods(self):
+ # test work-around for three methods that accidentally follow the
+ # naming conventions for handler methods
+ # (*_open() / *_request() / *_response())
+
+ # These used to call the accidentally-named methods, causing a
+ # TypeError in real code; here, returning self from these mock
+ # methods would either cause no exception, or AttributeError.
+
+ from future.backports.urllib.error import URLError
+
+ o = OpenerDirector()
+ meth_spec = [
+ [("do_open", "return self"), ("proxy_open", "return self")],
+ [("redirect_request", "return self")],
+ ]
+ add_ordered_mock_handlers(o, meth_spec)
+ o.add_handler(urllib_request.UnknownHandler())
+ for scheme in "do", "proxy", "redirect":
+ self.assertRaises(URLError, o.open, scheme+"://example.com/")
+
+ def test_handled(self):
+ # handler returning non-None means no more handlers will be called
+ o = OpenerDirector()
+ meth_spec = [
+ ["http_open", "ftp_open", "http_error_302"],
+ ["ftp_open"],
+ [("http_open", "return self")],
+ [("http_open", "return self")],
+ ]
+ handlers = add_ordered_mock_handlers(o, meth_spec)
+
+ req = Request("http://example.com/")
+ r = o.open(req)
+ # Second .http_open() gets called, third doesn't, since second returned
+ # non-None. Handlers without .http_open() never get any methods called
+ # on them.
+ # In fact, second mock handler defining .http_open() returns self
+ # (instead of response), which becomes the OpenerDirector's return
+ # value.
+ self.assertEqual(r, handlers[2])
+ calls = [(handlers[0], "http_open"), (handlers[2], "http_open")]
+ for expected, got in zip(calls, o.calls):
+ handler, name, args, kwds = got
+ self.assertEqual((handler, name), expected)
+ self.assertEqual(args, (req,))
+
+ def test_handler_order(self):
+ o = OpenerDirector()
+ handlers = []
+ for meths, handler_order in [
+ ([("http_open", "return self")], 500),
+ (["http_open"], 0),
+ ]:
+ class MockHandlerSubclass(MockHandler): pass
+ h = MockHandlerSubclass(meths)
+ h.handler_order = handler_order
+ handlers.append(h)
+ o.add_handler(h)
+
+ o.open("http://example.com/")
+ # handlers called in reverse order, thanks to their sort order
+ self.assertEqual(o.calls[0][0], handlers[1])
+ self.assertEqual(o.calls[1][0], handlers[0])
+
+ def test_raise(self):
+ # raising URLError stops processing of request
+ o = OpenerDirector()
+ meth_spec = [
+ [("http_open", "raise")],
+ [("http_open", "return self")],
+ ]
+ handlers = add_ordered_mock_handlers(o, meth_spec)
+
+ req = Request("http://example.com/")
+ self.assertRaises(urllib_error.URLError, o.open, req)
+ self.assertEqual(o.calls, [(handlers[0], "http_open", (req,), {})])
+
+ def test_http_error(self):
+ # XXX http_error_default
+ # http errors are a special case
+ o = OpenerDirector()
+ meth_spec = [
+ [("http_open", "error 302")],
+ [("http_error_400", "raise"), "http_open"],
+ [("http_error_302", "return response"), "http_error_303",
+ "http_error"],
+ [("http_error_302")],
+ ]
+ handlers = add_ordered_mock_handlers(o, meth_spec)
+
+ class Unknown(object):
+ def __eq__(self, other): return True
+
+ req = Request("http://example.com/")
+ o.open(req)
+ assert len(o.calls) == 2
+ calls = [(handlers[0], "http_open", (req,)),
+ (handlers[2], "http_error_302",
+ (req, Unknown(), 302, "", {}))]
+ for expected, got in zip(calls, o.calls):
+ handler, method_name, args = expected
+ self.assertEqual((handler, method_name), got[:2])
+ self.assertEqual(args, got[2])
+
+
+ def test_processors(self):
+ # *_request / *_response methods get called appropriately
+ o = OpenerDirector()
+ meth_spec = [
+ [("http_request", "return request"),
+ ("http_response", "return response")],
+ [("http_request", "return request"),
+ ("http_response", "return response")],
+ ]
+ handlers = add_ordered_mock_handlers(o, meth_spec)
+
+ req = Request("http://example.com/")
+ o.open(req)
+ # processor methods are called on *all* handlers that define them,
+ # not just the first handler that handles the request
+ calls = [
+ (handlers[0], "http_request"), (handlers[1], "http_request"),
+ (handlers[0], "http_response"), (handlers[1], "http_response")]
+
+ for i, (handler, name, args, kwds) in enumerate(o.calls):
+ if i < 2:
+ # *_request
+ self.assertEqual((handler, name), calls[i])
+ self.assertEqual(len(args), 1)
+ self.assertIsInstance(args[0], Request)
+ else:
+ # *_response
+ self.assertEqual((handler, name), calls[i])
+ self.assertEqual(len(args), 2)
+ self.assertIsInstance(args[0], Request)
+ # response from opener.open is None, because there's no
+ # handler that defines http_open to handle it
+ self.assertTrue(args[1] is None or
+ isinstance(args[1], MockResponse))
+
+ def test_method_deprecations(self):
+ req = Request("http://www.example.com")
+
+ with self.assertWarns(DeprecationWarning):
+ req.add_data("data")
+ with self.assertWarns(DeprecationWarning):
+ req.get_data()
+ with self.assertWarns(DeprecationWarning):
+ req.has_data()
+ with self.assertWarns(DeprecationWarning):
+ req.get_host()
+ with self.assertWarns(DeprecationWarning):
+ req.get_selector()
+ with self.assertWarns(DeprecationWarning):
+ req.is_unverifiable()
+ with self.assertWarns(DeprecationWarning):
+ req.get_origin_req_host()
+ with self.assertWarns(DeprecationWarning):
+ req.get_type()
+
+
+def sanepathname2url(path):
+ try:
+ path.encode("utf-8")
+ except UnicodeEncodeError:
+ raise unittest.SkipTest("path is not encodable to utf8")
+ urlpath = urllib_request.pathname2url(path)
+ if os.name == "nt" and urlpath.startswith("///"):
+ urlpath = urlpath[2:]
+ # XXX don't ask me about the mac...
+ return urlpath
+
+class HandlerTests(unittest.TestCase):
+
+ def test_ftp(self):
+ class MockFTPWrapper(object):
+ def __init__(self, data): self.data = data
+ def retrfile(self, filename, filetype):
+ self.filename, self.filetype = filename, filetype
+ return io.StringIO(self.data), len(self.data)
+ def close(self): pass
+
+ class NullFTPHandler(urllib_request.FTPHandler):
+ def __init__(self, data): self.data = data
+ def connect_ftp(self, user, passwd, host, port, dirs,
+ timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
+ self.user, self.passwd = user, passwd
+ self.host, self.port = host, port
+ self.dirs = dirs
+ self.ftpwrapper = MockFTPWrapper(self.data)
+ return self.ftpwrapper
+
+ import ftplib
+ data = "rheum rhaponicum"
+ 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",
+ ["foo", "bar"], "baz.html", "text/html"),
+ ("ftp://parrot@localhost/foo/bar/baz.html",
+ "localhost", ftplib.FTP_PORT, "parrot", "", "I",
+ ["foo", "bar"], "baz.html", "text/html"),
+ ("ftp://%25parrot@localhost/foo/bar/baz.html",
+ "localhost", ftplib.FTP_PORT, "%parrot", "", "I",
+ ["foo", "bar"], "baz.html", "text/html"),
+ ("ftp://%2542parrot@localhost/foo/bar/baz.html",
+ "localhost", ftplib.FTP_PORT, "%42parrot", "", "I",
+ ["foo", "bar"], "baz.html", "text/html"),
+ ("ftp://localhost:80/foo/bar/",
+ "localhost", 80, "", "", "D",
+ ["foo", "bar"], "", None),
+ ("ftp://localhost/baz.gif;type=a",
+ "localhost", ftplib.FTP_PORT, "", "", "A",
+ [], "baz.gif", guessed_mime),
+ ]:
+ req = Request(url)
+ req.timeout = None
+ r = h.ftp_open(req)
+ # ftp authentication not yet implemented by FTPHandler
+ self.assertEqual(h.user, user)
+ self.assertEqual(h.passwd, passwd)
+ self.assertEqual(h.host, socket.gethostbyname(host))
+ self.assertEqual(h.port, port)
+ self.assertEqual(h.dirs, dirs)
+ self.assertEqual(h.ftpwrapper.filename, filename)
+ self.assertEqual(h.ftpwrapper.filetype, type_)
+ headers = r.info()
+ self.assertEqual(headers.get("Content-type"), mimetype)
+ self.assertEqual(int(headers["Content-length"]), len(data))
+
+ def test_file(self):
+ import future.backports.email.utils as email_utils
+ import socket
+ h = urllib_request.FileHandler()
+ o = h.parent = MockOpener()
+
+ TESTFN = support.TESTFN
+ urlpath = sanepathname2url(os.path.abspath(TESTFN))
+ towrite = b"hello, world\n"
+ urls = [
+ "file://localhost%s" % urlpath,
+ "file://%s" % urlpath,
+ "file://%s%s" % (socket.gethostbyname('localhost'), urlpath),
+ ]
+ try:
+ localaddr = socket.gethostbyname(socket.gethostname())
+ except socket.gaierror:
+ localaddr = ''
+ if localaddr:
+ urls.append("file://%s%s" % (localaddr, urlpath))
+
+ for url in urls:
+ f = open(TESTFN, "wb")
+ try:
+ try:
+ f.write(towrite)
+ finally:
+ f.close()
+
+ r = h.file_open(Request(url))
+ try:
+ data = r.read()
+ headers = r.info()
+ respurl = r.geturl()
+ finally:
+ r.close()
+ stats = os.stat(TESTFN)
+ modified = email_utils.formatdate(stats.st_mtime, usegmt=True)
+ finally:
+ os.remove(TESTFN)
+ self.assertEqual(data, towrite)
+ self.assertEqual(headers["Content-type"], "text/plain")
+ self.assertEqual(headers["Content-length"], "13")
+ self.assertEqual(headers["Last-modified"], modified)
+ self.assertEqual(respurl, url)
+
+ for url in [
+ "file://localhost:80%s" % urlpath,
+ "file:///file_does_not_exist.txt",
+ "file://%s:80%s/%s" % (socket.gethostbyname('localhost'),
+ os.getcwd(), TESTFN),
+ "file://somerandomhost.ontheinternet.com%s/%s" %
+ (os.getcwd(), TESTFN),
+ ]:
+ try:
+ f = open(TESTFN, "wb")
+ try:
+ f.write(towrite)
+ finally:
+ f.close()
+
+ self.assertRaises(urllib_error.URLError,
+ h.file_open, Request(url))
+ finally:
+ os.remove(TESTFN)
+
+ h = urllib_request.FileHandler()
+ o = h.parent = MockOpener()
+ # XXXX why does // mean ftp (and /// mean not ftp!), and where
+ # is file: scheme specified? I think this is really a bug, and
+ # what was intended was to distinguish between URLs like:
+ # file:/blah.txt (a file)
+ # file://localhost/blah.txt (a file)
+ # file:///blah.txt (a file)
+ # file://ftp.example.com/blah.txt (an ftp URL)
+ for url, ftp in [
+ ("file://ftp.example.com//foo.txt", False),
+ ("file://ftp.example.com///foo.txt", False),
+# XXXX bug: fails with OSError, should be URLError
+ ("file://ftp.example.com/foo.txt", False),
+ ("file://somehost//foo/something.txt", False),
+ ("file://localhost//foo/something.txt", False),
+ ]:
+ req = Request(url)
+ try:
+ h.file_open(req)
+ # XXXX remove OSError when bug fixed
+ except (urllib_error.URLError, OSError):
+ self.assertFalse(ftp)
+ else:
+ self.assertIs(o.req, req)
+ self.assertEqual(req.type, "ftp")
+ self.assertEqual(req.type == "ftp", ftp)
+
+ @skip26
+ def test_http(self):
+
+ h = urllib_request.AbstractHTTPHandler()
+ o = h.parent = MockOpener()
+
+ url = "http://example.com/"
+ for method, data in [("GET", None), ("POST", b"blah")]:
+ req = Request(url, data, {"Foo": "bar"})
+ req.timeout = None
+ req.add_unredirected_header("Spam", "eggs")
+ http = MockHTTPClass()
+ r = h.do_open(http, req)
+
+ # result attributes
+ r.read; r.readline # wrapped MockFile methods
+ r.info; r.geturl # addinfourl methods
+ r.code, r.msg == 200, "OK" # added from MockHTTPClass.getreply()
+ hdrs = r.info()
+ hdrs.get; hdrs.__contains__ # r.info() gives dict from .getreply()
+ self.assertEqual(r.geturl(), url)
+
+ self.assertEqual(http.host, "example.com")
+ self.assertEqual(http.level, 0)
+ self.assertEqual(http.method, method)
+ self.assertEqual(http.selector, "/")
+ self.assertEqual(http.req_headers,
+ [("Connection", "close"),
+ ("Foo", "bar"), ("Spam", "eggs")])
+ self.assertEqual(http.data, data)
+
+ # check socket.error converted to URLError
+ http.raise_on_endheaders = True
+ self.assertRaises(urllib_error.URLError, h.do_open, http, req)
+
+ # Check for TypeError on POST data which is str.
+ req = Request("http://example.com/","badpost")
+ self.assertRaises(TypeError, h.do_request_, req)
+
+ # check adding of standard headers
+ o.addheaders = [("Spam", "eggs")]
+ for data in b"", None: # POST, GET
+ req = Request("http://example.com/", data)
+ r = MockResponse(200, "OK", {}, "")
+ newreq = h.do_request_(req)
+ if data is None: # GET
+ self.assertNotIn("Content-length", req.unredirected_hdrs)
+ self.assertNotIn("Content-type", req.unredirected_hdrs)
+ else: # POST
+ self.assertEqual(req.unredirected_hdrs["Content-length"], "0")
+ self.assertEqual(req.unredirected_hdrs["Content-type"],
+ "application/x-www-form-urlencoded")
+ # XXX the details of Host could be better tested
+ self.assertEqual(req.unredirected_hdrs["Host"], "example.com")
+ self.assertEqual(req.unredirected_hdrs["Spam"], "eggs")
+
+ # don't clobber existing headers
+ req.add_unredirected_header("Content-length", "foo")
+ req.add_unredirected_header("Content-type", "bar")
+ req.add_unredirected_header("Host", "baz")
+ req.add_unredirected_header("Spam", "foo")
+ newreq = h.do_request_(req)
+ self.assertEqual(req.unredirected_hdrs["Content-length"], "foo")
+ self.assertEqual(req.unredirected_hdrs["Content-type"], "bar")
+ self.assertEqual(req.unredirected_hdrs["Host"], "baz")
+ self.assertEqual(req.unredirected_hdrs["Spam"], "foo")
+
+ # Check iterable body support
+ def iterable_body():
+ yield b"one"
+ yield b"two"
+ yield b"three"
+
+ for headers in {}, {"Content-Length": 11}:
+ req = Request("http://example.com/", iterable_body(), headers)
+ if not headers:
+ # Having an iterable body without a Content-Length should
+ # raise an exception
+ self.assertRaises(ValueError, h.do_request_, req)
+ else:
+ newreq = h.do_request_(req)
+
+ # A file object.
+ # Test only Content-Length attribute of request.
+
+ file_obj = io.BytesIO()
+ file_obj.write(b"Something\nSomething\nSomething\n")
+
+ for headers in {}, {"Content-Length": 30}:
+ req = Request("http://example.com/", file_obj, headers)
+ if not headers:
+ # Having an iterable body without a Content-Length should
+ # raise an exception
+ self.assertRaises(ValueError, h.do_request_, req)
+ else:
+ newreq = h.do_request_(req)
+ self.assertEqual(int(newreq.get_header('Content-length')),30)
+
+ file_obj.close()
+
+ # array.array Iterable - Content Length is calculated
+
+ iterable_array = array.array(text_to_native_str("I"),
+ [1,2,3,4])
+
+ for headers in {}, {"Content-Length": 16}:
+ req = Request("http://example.com/", iterable_array, headers)
+ newreq = h.do_request_(req)
+ self.assertEqual(int(newreq.get_header('Content-length')),16)
+
+ @skip26
+ def test_http_doubleslash(self):
+ # Checks the presence of any unnecessary double slash in url does not
+ # break anything. Previously, a double slash directly after the host
+ # could cause incorrect parsing.
+ h = urllib_request.AbstractHTTPHandler()
+ h.parent = MockOpener()
+
+ data = b""
+ ds_urls = [
+ "http://example.com/foo/bar/baz.html",
+ "http://example.com//foo/bar/baz.html",
+ "http://example.com/foo//bar/baz.html",
+ "http://example.com/foo/bar//baz.html"
+ ]
+
+ for ds_url in ds_urls:
+ ds_req = Request(ds_url, data)
+
+ # Check whether host is determined correctly if there is no proxy
+ np_ds_req = h.do_request_(ds_req)
+ self.assertEqual(np_ds_req.unredirected_hdrs["Host"],"example.com")
+
+ # Check whether host is determined correctly if there is a proxy
+ ds_req.set_proxy("someproxy:3128",None)
+ p_ds_req = h.do_request_(ds_req)
+ self.assertEqual(p_ds_req.unredirected_hdrs["Host"],"example.com")
+
+ def test_fixpath_in_weirdurls(self):
+ # Issue4493: urllib2 to supply '/' when to urls where path does not
+ # start with'/'
+
+ h = urllib_request.AbstractHTTPHandler()
+ h.parent = MockOpener()
+
+ weird_url = 'http://www.python.org?getspam'
+ req = Request(weird_url)
+ newreq = h.do_request_(req)
+ self.assertEqual(newreq.host,'www.python.org')
+ self.assertEqual(newreq.selector,'/?getspam')
+
+ url_without_path = 'http://www.python.org'
+ req = Request(url_without_path)
+ newreq = h.do_request_(req)
+ self.assertEqual(newreq.host,'www.python.org')
+ self.assertEqual(newreq.selector,'')
+
+
+ def test_errors(self):
+ h = urllib_request.HTTPErrorProcessor()
+ o = h.parent = MockOpener()
+
+ url = "http://example.com/"
+ req = Request(url)
+ # all 2xx are passed through
+ r = MockResponse(200, "OK", {}, "", url)
+ newr = h.http_response(req, r)
+ self.assertIs(r, newr)
+ self.assertFalse(hasattr(o, "proto")) # o.error not called
+ r = MockResponse(202, "Accepted", {}, "", url)
+ newr = h.http_response(req, r)
+ self.assertIs(r, newr)
+ self.assertFalse(hasattr(o, "proto")) # o.error not called
+ r = MockResponse(206, "Partial content", {}, "", url)
+ newr = h.http_response(req, r)
+ self.assertIs(r, newr)
+ self.assertFalse(hasattr(o, "proto")) # o.error not called
+ # anything else calls o.error (and MockOpener returns None, here)
+ r = MockResponse(502, "Bad gateway", {}, "", url)
+ self.assertIsNone(h.http_response(req, r))
+ self.assertEqual(o.proto, "http") # o.error called
+ self.assertEqual(o.args, (req, r, 502, "Bad gateway", {}))
+
+ def test_cookies(self):
+ cj = MockCookieJar()
+ h = urllib_request.HTTPCookieProcessor(cj)
+ h.parent = MockOpener()
+
+ req = Request("http://example.com/")
+ r = MockResponse(200, "OK", {}, "")
+ newreq = h.http_request(req)
+ self.assertIs(cj.ach_req, req)
+ self.assertIs(cj.ach_req, newreq)
+ self.assertEqual(req.origin_req_host, "example.com")
+ self.assertFalse(req.unverifiable)
+ newr = h.http_response(req, r)
+ self.assertIs(cj.ec_req, req)
+ self.assertIs(cj.ec_r, r)
+ self.assertIs(r, newr)
+
+ def test_redirect(self):
+ from_url = "http://example.com/a.html"
+ to_url = "http://example.com/b.html"
+ h = urllib_request.HTTPRedirectHandler()
+ o = h.parent = MockOpener()
+
+ # ordinary redirect behaviour
+ for code in 301, 302, 303, 307:
+ for data in None, "blah\nblah\n":
+ method = getattr(h, "http_error_%s" % code)
+ req = Request(from_url, data)
+ req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
+ req.add_header("Nonsense", "viking=withhold")
+ if data is not None:
+ req.add_header("Content-Length", str(len(data)))
+ req.add_unredirected_header("Spam", "spam")
+ try:
+ method(req, MockFile(), code, "Blah",
+ MockHeaders({"location": to_url}))
+ except urllib_error.HTTPError:
+ # 307 in response to POST requires user OK
+ self.assertTrue(code == 307 and data is not None)
+ self.assertEqual(o.req.get_full_url(), to_url)
+ try:
+ self.assertEqual(o.req.get_method(), "GET")
+ except AttributeError:
+ self.assertFalse(o.req.data)
+
+ # now it's a GET, there should not be headers regarding content
+ # (possibly dragged from before being a POST)
+ headers = [x.lower() for x in o.req.headers]
+ self.assertNotIn("content-length", headers)
+ self.assertNotIn("content-type", headers)
+
+ self.assertEqual(o.req.headers["Nonsense"],
+ "viking=withhold")
+ self.assertNotIn("Spam", o.req.headers)
+ self.assertNotIn("Spam", o.req.unredirected_hdrs)
+
+ # loop detection
+ req = Request(from_url)
+ req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
+ def redirect(h, req, url=to_url):
+ h.http_error_302(req, MockFile(), 302, "Blah",
+ MockHeaders({"location": url}))
+ # Note that the *original* request shares the same record of
+ # redirections with the sub-requests caused by the redirections.
+
+ # detect infinite loop redirect of a URL to itself
+ req = Request(from_url, origin_req_host="example.com")
+ count = 0
+ req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
+ try:
+ while 1:
+ redirect(h, req, "http://example.com/")
+ count = count + 1
+ except urllib_error.HTTPError:
+ # don't stop until max_repeats, because cookies may introduce state
+ self.assertEqual(count, urllib_request.HTTPRedirectHandler.max_repeats)
+
+ # detect endless non-repeating chain of redirects
+ req = Request(from_url, origin_req_host="example.com")
+ count = 0
+ req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
+ try:
+ while 1:
+ redirect(h, req, "http://example.com/%d" % count)
+ count = count + 1
+ except urllib_error.HTTPError:
+ self.assertEqual(count,
+ urllib_request.HTTPRedirectHandler.max_redirections)
+
+
+ def test_invalid_redirect(self):
+ from_url = "http://example.com/a.html"
+ valid_schemes = ['http','https','ftp']
+ invalid_schemes = ['file','imap','ldap']
+ schemeless_url = "example.com/b.html"
+ h = urllib_request.HTTPRedirectHandler()
+ o = h.parent = MockOpener()
+ req = Request(from_url)
+ req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
+
+ for scheme in invalid_schemes:
+ invalid_url = scheme + '://' + schemeless_url
+ self.assertRaises(urllib_error.HTTPError, h.http_error_302,
+ req, MockFile(), 302, "Security Loophole",
+ MockHeaders({"location": invalid_url}))
+
+ for scheme in valid_schemes:
+ valid_url = scheme + '://' + schemeless_url
+ h.http_error_302(req, MockFile(), 302, "That's fine",
+ MockHeaders({"location": valid_url}))
+ self.assertEqual(o.req.get_full_url(), valid_url)
+
+ def test_relative_redirect(self):
+ from future.backports.urllib import parse as urllib_parse
+ from_url = "http://example.com/a.html"
+ relative_url = "/b.html"
+ h = urllib_request.HTTPRedirectHandler()
+ o = h.parent = MockOpener()
+ req = Request(from_url)
+ req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
+
+ valid_url = urllib_parse.urljoin(from_url,relative_url)
+ h.http_error_302(req, MockFile(), 302, "That's fine",
+ MockHeaders({"location": valid_url}))
+ self.assertEqual(o.req.get_full_url(), valid_url)
+
+ def test_cookie_redirect(self):
+ # cookies shouldn't leak into redirected requests
+ from future.backports.http.cookiejar import CookieJar
+
+ cj = CookieJar()
+ interact_netscape(cj, "http://www.example.com/", "spam=eggs")
+ hh = MockHTTPHandler(302, "Location: http://www.cracker.com/\r\n\r\n")
+ hdeh = urllib_request.HTTPDefaultErrorHandler()
+ hrh = urllib_request.HTTPRedirectHandler()
+ cp = urllib_request.HTTPCookieProcessor(cj)
+ o = build_test_opener(hh, hdeh, hrh, cp)
+ o.open("http://www.example.com/")
+ self.assertFalse(hh.req.has_header("Cookie"))
+
+ def test_redirect_fragment(self):
+ redirected_url = 'http://www.example.com/index.html#OK\r\n\r\n'
+ hh = MockHTTPHandler(302, 'Location: ' + redirected_url)
+ hdeh = urllib_request.HTTPDefaultErrorHandler()
+ hrh = urllib_request.HTTPRedirectHandler()
+ o = build_test_opener(hh, hdeh, hrh)
+ fp = o.open('http://www.example.com')
+ self.assertEqual(fp.geturl(), redirected_url.strip())
+
+ def test_proxy(self):
+ o = OpenerDirector()
+ ph = urllib_request.ProxyHandler(dict(http="proxy.example.com:3128"))
+ o.add_handler(ph)
+ meth_spec = [
+ [("http_open", "return response")]
+ ]
+ handlers = add_ordered_mock_handlers(o, meth_spec)
+
+ req = Request("http://acme.example.com/")
+ self.assertEqual(req.host, "acme.example.com")
+ o.open(req)
+ self.assertEqual(req.host, "proxy.example.com:3128")
+
+ self.assertEqual([(handlers[0], "http_open")],
+ [tup[0:2] for tup in o.calls])
+
+ def test_proxy_no_proxy(self):
+ os.environ['no_proxy'] = 'python.org'
+ o = OpenerDirector()
+ ph = urllib_request.ProxyHandler(dict(http="proxy.example.com"))
+ o.add_handler(ph)
+ req = Request("http://www.perl.org/")
+ self.assertEqual(req.host, "www.perl.org")
+ o.open(req)
+ self.assertEqual(req.host, "proxy.example.com")
+ req = Request("http://www.python.org")
+ self.assertEqual(req.host, "www.python.org")
+ o.open(req)
+ self.assertEqual(req.host, "www.python.org")
+ del os.environ['no_proxy']
+
+ def test_proxy_no_proxy_all(self):
+ os.environ['no_proxy'] = '*'
+ o = OpenerDirector()
+ ph = urllib_request.ProxyHandler(dict(http="proxy.example.com"))
+ o.add_handler(ph)
+ req = Request("http://www.python.org")
+ self.assertEqual(req.host, "www.python.org")
+ o.open(req)
+ self.assertEqual(req.host, "www.python.org")
+ del os.environ['no_proxy']
+
+
+ def test_proxy_https(self):
+ o = OpenerDirector()
+ ph = urllib_request.ProxyHandler(dict(https="proxy.example.com:3128"))
+ o.add_handler(ph)
+ meth_spec = [
+ [("https_open", "return response")]
+ ]
+ handlers = add_ordered_mock_handlers(o, meth_spec)
+
+ req = Request("https://www.example.com/")
+ self.assertEqual(req.host, "www.example.com")
+ o.open(req)
+ self.assertEqual(req.host, "proxy.example.com:3128")
+ self.assertEqual([(handlers[0], "https_open")],
+ [tup[0:2] for tup in o.calls])
+
+ def test_proxy_https_proxy_authorization(self):
+ o = OpenerDirector()
+ ph = urllib_request.ProxyHandler(dict(https='proxy.example.com:3128'))
+ o.add_handler(ph)
+ https_handler = MockHTTPSHandler()
+ o.add_handler(https_handler)
+ req = Request("https://www.example.com/")
+ req.add_header("Proxy-Authorization","FooBar")
+ req.add_header("User-Agent","Grail")
+ self.assertEqual(req.host, "www.example.com")
+ self.assertIsNone(req._tunnel_host)
+ o.open(req)
+ # Verify Proxy-Authorization gets tunneled to request.
+ # httpsconn req_headers do not have the Proxy-Authorization header but
+ # the req will have.
+ self.assertNotIn(("Proxy-Authorization","FooBar"),
+ https_handler.httpconn.req_headers)
+ self.assertIn(("User-Agent","Grail"),
+ https_handler.httpconn.req_headers)
+ self.assertIsNotNone(req._tunnel_host)
+ self.assertEqual(req.host, "proxy.example.com:3128")
+ self.assertEqual(req.get_header("Proxy-authorization"),"FooBar")
+
+ # TODO: This should be only for OSX
+ @unittest.skipUnless(sys.platform == 'darwin', "only relevant for OSX")
+ def test_osx_proxy_bypass(self):
+ bypass = {
+ 'exclude_simple': False,
+ 'exceptions': ['foo.bar', '*.bar.com', '127.0.0.1', '10.10',
+ '10.0/16']
+ }
+ # Check hosts that should trigger the proxy bypass
+ for host in ('foo.bar', 'www.bar.com', '127.0.0.1', '10.10.0.1',
+ '10.0.0.1'):
+ self.assertTrue(_proxy_bypass_macosx_sysconf(host, bypass),
+ 'expected bypass of %s to be True' % host)
+ # Check hosts that should not trigger the proxy bypass
+ for host in ('abc.foo.bar', 'bar.com', '127.0.0.2', '10.11.0.1', 'test'):
+ self.assertFalse(_proxy_bypass_macosx_sysconf(host, bypass),
+ 'expected bypass of %s to be False' % host)
+
+ # Check the exclude_simple flag
+ bypass = {'exclude_simple': True, 'exceptions': []}
+ self.assertTrue(_proxy_bypass_macosx_sysconf('test', bypass))
+
+ def test_basic_auth(self, quote_char='"'):
+ opener = OpenerDirector()
+ password_manager = MockPasswordManager()
+ auth_handler = urllib_request.HTTPBasicAuthHandler(password_manager)
+ realm = "ACME Widget Store"
+ http_handler = MockHTTPHandler(
+ 401, 'WWW-Authenticate: Basic realm=%s%s%s\r\n\r\n' %
+ (quote_char, realm, quote_char) )
+ opener.add_handler(auth_handler)
+ opener.add_handler(http_handler)
+ self._test_basic_auth(opener, auth_handler, "Authorization",
+ realm, http_handler, password_manager,
+ "http://acme.example.com/protected",
+ "http://acme.example.com/protected",
+ )
+
+ def test_basic_auth_with_single_quoted_realm(self):
+ self.test_basic_auth(quote_char="'")
+
+ def test_basic_auth_with_unquoted_realm(self):
+ opener = OpenerDirector()
+ password_manager = MockPasswordManager()
+ auth_handler = urllib_request.HTTPBasicAuthHandler(password_manager)
+ realm = "ACME Widget Store"
+ http_handler = MockHTTPHandler(
+ 401, 'WWW-Authenticate: Basic realm=%s\r\n\r\n' % realm)
+ opener.add_handler(auth_handler)
+ opener.add_handler(http_handler)
+ with self.assertWarns(UserWarning):
+ self._test_basic_auth(opener, auth_handler, "Authorization",
+ realm, http_handler, password_manager,
+ "http://acme.example.com/protected",
+ "http://acme.example.com/protected",
+ )
+
+ def test_proxy_basic_auth(self):
+ opener = OpenerDirector()
+ ph = urllib_request.ProxyHandler(dict(http="proxy.example.com:3128"))
+ opener.add_handler(ph)
+ password_manager = MockPasswordManager()
+ auth_handler = urllib_request.ProxyBasicAuthHandler(password_manager)
+ realm = "ACME Networks"
+ http_handler = MockHTTPHandler(
+ 407, 'Proxy-Authenticate: Basic realm="%s"\r\n\r\n' % realm)
+ opener.add_handler(auth_handler)
+ opener.add_handler(http_handler)
+ self._test_basic_auth(opener, auth_handler, "Proxy-authorization",
+ realm, http_handler, password_manager,
+ "http://acme.example.com:3128/protected",
+ "proxy.example.com:3128",
+ )
+
+ def test_basic_and_digest_auth_handlers(self):
+ # HTTPDigestAuthHandler raised an exception if it couldn't handle a 40*
+ # response (http://python.org/sf/1479302), where it should instead
+ # return None to allow another handler (especially
+ # HTTPBasicAuthHandler) to handle the response.
+
+ # Also (http://python.org/sf/14797027, RFC 2617 section 1.2), we must
+ # try digest first (since it's the strongest auth scheme), so we record
+ # order of calls here to check digest comes first:
+ class RecordingOpenerDirector(OpenerDirector):
+ def __init__(self):
+ OpenerDirector.__init__(self)
+ self.recorded = []
+ def record(self, info):
+ self.recorded.append(info)
+ class TestDigestAuthHandler(urllib_request.HTTPDigestAuthHandler):
+ def http_error_401(self, *args, **kwds):
+ self.parent.record("digest")
+ urllib_request.HTTPDigestAuthHandler.http_error_401(self,
+ *args, **kwds)
+ class TestBasicAuthHandler(urllib_request.HTTPBasicAuthHandler):
+ def http_error_401(self, *args, **kwds):
+ self.parent.record("basic")
+ urllib_request.HTTPBasicAuthHandler.http_error_401(self,
+ *args, **kwds)
+
+ opener = RecordingOpenerDirector()
+ password_manager = MockPasswordManager()
+ digest_handler = TestDigestAuthHandler(password_manager)
+ basic_handler = TestBasicAuthHandler(password_manager)
+ realm = "ACME Networks"
+ http_handler = MockHTTPHandler(
+ 401, 'WWW-Authenticate: Basic realm="%s"\r\n\r\n' % realm)
+ opener.add_handler(basic_handler)
+ opener.add_handler(digest_handler)
+ opener.add_handler(http_handler)
+
+ # check basic auth isn't blocked by digest handler failing
+ self._test_basic_auth(opener, basic_handler, "Authorization",
+ realm, http_handler, password_manager,
+ "http://acme.example.com/protected",
+ "http://acme.example.com/protected",
+ )
+ # check digest was tried before basic (twice, because
+ # _test_basic_auth called .open() twice)
+ self.assertEqual(opener.recorded, ["digest", "basic"]*2)
+
+ def test_unsupported_auth_digest_handler(self):
+ opener = OpenerDirector()
+ # While using DigestAuthHandler
+ digest_auth_handler = urllib_request.HTTPDigestAuthHandler(None)
+ http_handler = MockHTTPHandler(
+ 401, 'WWW-Authenticate: Kerberos\r\n\r\n')
+ opener.add_handler(digest_auth_handler)
+ opener.add_handler(http_handler)
+ self.assertRaises(ValueError,opener.open,"http://www.example.com")
+
+ def test_unsupported_auth_basic_handler(self):
+ # While using BasicAuthHandler
+ opener = OpenerDirector()
+ basic_auth_handler = urllib_request.HTTPBasicAuthHandler(None)
+ http_handler = MockHTTPHandler(
+ 401, 'WWW-Authenticate: NTLM\r\n\r\n')
+ opener.add_handler(basic_auth_handler)
+ opener.add_handler(http_handler)
+ self.assertRaises(ValueError,opener.open,"http://www.example.com")
+
+ def _test_basic_auth(self, opener, auth_handler, auth_header,
+ realm, http_handler, password_manager,
+ request_url, protected_url):
+ import base64
+ user, password = "wile", "coyote"
+
+ # .add_password() fed through to password manager
+ auth_handler.add_password(realm, request_url, user, password)
+ self.assertEqual(realm, password_manager.realm)
+ self.assertEqual(request_url, password_manager.url)
+ self.assertEqual(user, password_manager.user)
+ self.assertEqual(password, password_manager.password)
+
+ opener.open(request_url)
+
+ # should have asked the password manager for the username/password
+ self.assertEqual(password_manager.target_realm, realm)
+ self.assertEqual(password_manager.target_url, protected_url)
+
+ # expect one request without authorization, then one with
+ self.assertEqual(len(http_handler.requests), 2)
+ self.assertFalse(http_handler.requests[0].has_header(auth_header))
+ userpass = bytes('%s:%s' % (user, password), "ascii")
+ auth_hdr_value = ('Basic ' +
+ base64.encodebytes(userpass).strip().decode())
+ self.assertEqual(http_handler.requests[1].get_header(auth_header),
+ auth_hdr_value)
+ self.assertEqual(http_handler.requests[1].unredirected_hdrs[auth_header],
+ auth_hdr_value)
+ # if the password manager can't find a password, the handler won't
+ # handle the HTTP auth error
+ password_manager.user = password_manager.password = None
+ http_handler.reset()
+ opener.open(request_url)
+ self.assertEqual(len(http_handler.requests), 1)
+ self.assertFalse(http_handler.requests[0].has_header(auth_header))
+
+
+class MiscTests(unittest.TestCase):
+
+ def opener_has_handler(self, opener, handler_class):
+ self.assertTrue(any(h.__class__ == handler_class
+ for h in opener.handlers))
+
+ def test_build_opener(self):
+ class MyHTTPHandler(urllib_request.HTTPHandler): pass
+ class FooHandler(urllib_request.BaseHandler):
+ def foo_open(self): pass
+ class BarHandler(urllib_request.BaseHandler):
+ def bar_open(self): pass
+
+ build_opener = urllib_request.build_opener
+
+ o = build_opener(FooHandler, BarHandler)
+ self.opener_has_handler(o, FooHandler)
+ self.opener_has_handler(o, BarHandler)
+
+ # can take a mix of classes and instances
+ o = build_opener(FooHandler, BarHandler())
+ self.opener_has_handler(o, FooHandler)
+ self.opener_has_handler(o, BarHandler)
+
+ # subclasses of default handlers override default handlers
+ o = build_opener(MyHTTPHandler)
+ self.opener_has_handler(o, MyHTTPHandler)
+
+ # a particular case of overriding: default handlers can be passed
+ # in explicitly
+ o = build_opener()
+ self.opener_has_handler(o, urllib_request.HTTPHandler)
+ o = build_opener(urllib_request.HTTPHandler)
+ self.opener_has_handler(o, urllib_request.HTTPHandler)
+ o = build_opener(urllib_request.HTTPHandler())
+ self.opener_has_handler(o, urllib_request.HTTPHandler)
+
+ # Issue2670: multiple handlers sharing the same base class
+ class MyOtherHTTPHandler(urllib_request.HTTPHandler): pass
+ o = build_opener(MyHTTPHandler, MyOtherHTTPHandler)
+ self.opener_has_handler(o, MyHTTPHandler)
+ self.opener_has_handler(o, MyOtherHTTPHandler)
+
+ def test_HTTPError_interface(self):
+ """
+ Issue 13211 reveals that HTTPError didn't implement the URLError
+ interface even though HTTPError is a subclass of URLError.
+ """
+ msg = 'something bad happened'
+ url = code = fp = None
+ hdrs = 'Content-Length: 42'
+ err = urllib_error.HTTPError(url, code, msg, hdrs, fp)
+ self.assertTrue(hasattr(err, 'reason'))
+ self.assertEqual(err.reason, 'something bad happened')
+ self.assertTrue(hasattr(err, 'hdrs'))
+ self.assertEqual(err.hdrs, 'Content-Length: 42')
+ expected_errmsg = 'HTTP Error %s: %s' % (err.code, err.msg)
+ self.assertEqual(str(err), expected_errmsg)
+
+
+class RequestTests(unittest.TestCase):
+
+ def setUp(self):
+ self.get = Request("http://www.python.org/~jeremy/")
+ self.post = Request("http://www.python.org/~jeremy/",
+ "data",
+ headers={"X-Test": "test"})
+
+ def test_method(self):
+ self.assertEqual("POST", self.post.get_method())
+ self.assertEqual("GET", self.get.get_method())
+
+ def test_data(self):
+ self.assertFalse(self.get.data)
+ self.assertEqual("GET", self.get.get_method())
+ self.get.data = "spam"
+ self.assertTrue(self.get.data)
+ self.assertEqual("POST", self.get.get_method())
+
+ def test_get_full_url(self):
+ self.assertEqual("http://www.python.org/~jeremy/",
+ self.get.get_full_url())
+
+ def test_selector(self):
+ self.assertEqual("/~jeremy/", self.get.selector)
+ req = Request("http://www.python.org/")
+ self.assertEqual("/", req.selector)
+
+ def test_get_type(self):
+ self.assertEqual("http", self.get.type)
+
+ def test_get_host(self):
+ self.assertEqual("www.python.org", self.get.host)
+
+ def test_get_host_unquote(self):
+ req = Request("http://www.%70ython.org/")
+ self.assertEqual("www.python.org", req.host)
+
+ def test_proxy(self):
+ self.assertFalse(self.get.has_proxy())
+ self.get.set_proxy("www.perl.org", "http")
+ self.assertTrue(self.get.has_proxy())
+ self.assertEqual("www.python.org", self.get.origin_req_host)
+ self.assertEqual("www.perl.org", self.get.host)
+
+ def test_wrapped_url(self):
+ req = Request("<URL:http://www.python.org>")
+ self.assertEqual("www.python.org", req.host)
+
+ def test_url_fragment(self):
+ req = Request("http://www.python.org/?qs=query#fragment=true")
+ self.assertEqual("/?qs=query", req.selector)
+ req = Request("http://www.python.org/#fun=true")
+ self.assertEqual("/", req.selector)
+
+ # Issue 11703: geturl() omits fragment in the original URL.
+ url = 'http://docs.python.org/library/urllib2.html#OK'
+ req = Request(url)
+ self.assertEqual(req.get_full_url(), url)
+
+ def test_HTTPError_interface_call(self):
+ """
+ Issue 15701 - HTTPError interface has info method available from URLError
+ """
+ err = urllib_request.HTTPError(msg="something bad happened", url=None,
+ code=None, hdrs='Content-Length:42', fp=None)
+ self.assertTrue(hasattr(err, 'reason'))
+ assert hasattr(err, 'reason')
+ assert hasattr(err, 'info')
+ assert callable(err.info)
+ try:
+ err.info()
+ except AttributeError:
+ self.fail('err.info call failed.')
+ self.assertEqual(err.info(), "Content-Length:42")
+
+def test_main(verbose=None):
+ # support.run_doctest(test_urllib2, verbose)
+ # support.run_doctest(urllib_request, verbose)
+ tests = (TrivialTests,
+ OpenerDirectorTests,
+ HandlerTests,
+ MiscTests,
+ RequestTests,
+ RequestHdrsTests)
+ support.run_unittest(*tests)
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_urllib_response.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_urllib_response.py
new file mode 100644
index 0000000..e8f4b4f
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_urllib_response.py
@@ -0,0 +1,45 @@
+"""Unit tests for code in urllib.response."""
+
+from __future__ import absolute_import, division, unicode_literals
+
+from future.backports import urllib
+import future.backports.urllib.response as urllib_response
+from future.backports.test import support as test_support
+from future.tests.base import unittest
+
+
+class File(object):
+
+ def __init__(self):
+ self.closed = False
+
+ def read(self, bytes):
+ pass
+
+ def readline(self):
+ pass
+
+ def close(self):
+ self.closed = True
+
+
+class Testaddbase(unittest.TestCase):
+
+ # TODO(jhylton): Write tests for other functionality of addbase()
+
+ def setUp(self):
+ self.fp = File()
+ self.addbase = urllib_response.addbase(self.fp)
+
+ def test_with(self):
+ def f():
+ with self.addbase as spam:
+ pass
+ self.assertFalse(self.fp.closed)
+ f()
+ self.assertTrue(self.fp.closed)
+ self.assertRaises(ValueError, f)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_urllib_toplevel.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_urllib_toplevel.py
new file mode 100644
index 0000000..11e7720
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_urllib_toplevel.py
@@ -0,0 +1,1401 @@
+"""Regresssion tests for urllib"""
+from __future__ import absolute_import, division, unicode_literals
+
+import io
+import os
+import sys
+import tempfile
+from nturl2path import url2pathname, pathname2url
+from base64 import b64encode
+import collections
+
+PY2 = sys.version_info[0] == 2
+
+from future.builtins import bytes, chr, hex, open, range, str, int
+from future.standard_library import install_aliases
+install_aliases()
+from urllib import parse as urllib_parse
+from urllib import request as urllib_request
+from urllib import error as urllib_error
+from http import client as http_client
+try:
+ from future.moves.test import support
+except ImportError:
+ from future.backports.test import support
+if PY2:
+ from future.backports.email import message as email_message
+else:
+ from email import message as email_message
+# from future.backports.email import message as email_message
+from future.tests.base import unittest, skip26, expectedFailurePY26, expectedFailurePY2
+
+
+def hexescape(char):
+ """Escape char as RFC 2396 specifies"""
+ hex_repr = hex(ord(char))[2:].upper()
+ if len(hex_repr) == 1:
+ hex_repr = "0%s" % hex_repr
+ return "%" + hex_repr
+
+# Shortcut for testing FancyURLopener
+_urlopener = None
+
+
+def urlopen(url, data=None, proxies=None):
+ """urlopen(url [, data]) -> open file-like object"""
+ global _urlopener
+ if proxies is not None:
+ opener = urllib_request.FancyURLopener(proxies=proxies)
+ elif not _urlopener:
+ with support.check_warnings(
+ ('FancyURLopener style of invoking requests is deprecated.',
+ DeprecationWarning)):
+ opener = urllib_request.FancyURLopener()
+ _urlopener = opener
+ else:
+ opener = _urlopener
+ if data is None:
+ return opener.open(url)
+ else:
+ return opener.open(url, data)
+
+
+class FakeHTTPMixin(object):
+ def fakehttp(self, fakedata):
+ class FakeSocket(io.BytesIO):
+ io_refs = 1
+
+ def sendall(self, data):
+ FakeHTTPConnection.buf = data
+
+ def makefile(self, *args, **kwds):
+ self.io_refs += 1
+ return self
+
+ def read(self, amt=None):
+ if self.closed:
+ return b""
+ return io.BytesIO.read(self, amt)
+
+ def readline(self, length=None):
+ if self.closed:
+ return b""
+ return io.BytesIO.readline(self, length)
+
+ def close(self):
+ self.io_refs -= 1
+ if self.io_refs == 0:
+ io.BytesIO.close(self)
+
+ class FakeHTTPConnection(http_client.HTTPConnection):
+
+ # buffer to store data for verification in urlopen tests.
+ buf = None
+
+ def connect(self):
+ self.sock = FakeSocket(fakedata)
+
+ self._connection_class = http_client.HTTPConnection
+ http_client.HTTPConnection = FakeHTTPConnection
+
+ def unfakehttp(self):
+ http_client.HTTPConnection = self._connection_class
+
+
+class urlopen_FileTests(unittest.TestCase):
+ """Test urlopen() opening a temporary file.
+
+ Try to test as much functionality as possible so as to cut down on reliance
+ on connecting to the Net for testing.
+
+ """
+
+ def setUp(self):
+ # Create a temp file to use for testing
+ self.text = bytes("test_urllib: %s\n" % self.__class__.__name__,
+ "ascii")
+ f = open(support.TESTFN, 'wb')
+ try:
+ f.write(self.text)
+ finally:
+ f.close()
+ self.pathname = support.TESTFN
+ self.returned_obj = urlopen("file:%s" % self.pathname)
+
+ def tearDown(self):
+ """Shut down the open object"""
+ self.returned_obj.close()
+ os.remove(support.TESTFN)
+
+ def test_interface(self):
+ # Make sure object returned by urlopen() has the specified methods
+ for attr in ("read", "readline", "readlines", "fileno",
+ "close", "info", "geturl", "getcode", "__iter__"):
+ self.assertTrue(hasattr(self.returned_obj, attr),
+ "object returned by urlopen() lacks %s attribute" %
+ attr)
+
+ def test_read(self):
+ self.assertEqual(self.text, self.returned_obj.read())
+
+ def test_readline(self):
+ self.assertEqual(self.text, self.returned_obj.readline())
+ self.assertEqual(b'', self.returned_obj.readline(),
+ "calling readline() after exhausting the file did not"
+ " return an empty string")
+
+ def test_readlines(self):
+ lines_list = self.returned_obj.readlines()
+ self.assertEqual(len(lines_list), 1,
+ "readlines() returned the wrong number of lines")
+ self.assertEqual(lines_list[0], self.text,
+ "readlines() returned improper text")
+
+ def test_fileno(self):
+ file_num = self.returned_obj.fileno()
+ self.assertIsInstance(file_num, int, "fileno() did not return an int")
+ self.assertEqual(os.read(file_num, len(self.text)), self.text,
+ "Reading on the file descriptor returned by fileno() "
+ "did not return the expected text")
+
+ def test_close(self):
+ # Test close() by calling it here and then having it be called again
+ # by the tearDown() method for the test
+ self.returned_obj.close()
+
+ 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)
+
+ def test_getcode(self):
+ self.assertIsNone(self.returned_obj.getcode())
+
+ def test_iter(self):
+ # Test iterator
+ # Don't need to count number of iterations since test would fail the
+ # instant it returned anything beyond the first line from the
+ # comparison.
+ # Use the iterator in the usual implicit way to test for ticket #4608.
+ for line in self.returned_obj:
+ self.assertEqual(line, self.text)
+
+ def test_relativelocalfile(self):
+ self.assertRaises(ValueError,urllib_request.urlopen,'./' + self.pathname)
+
+class ProxyTests(unittest.TestCase):
+
+ def setUp(self):
+ # Records changes to env vars
+ self.env = support.EnvironmentVarGuard()
+ # Delete all proxy related env vars
+ for k in list(os.environ):
+ if 'proxy' in k.lower():
+ self.env.unset(k)
+
+ def tearDown(self):
+ # Restore all proxy related env vars
+ self.env.__exit__()
+ del self.env
+
+ def test_getproxies_environment_keep_no_proxies(self):
+ self.env.set('NO_PROXY', 'localhost')
+ proxies = urllib_request.getproxies_environment()
+ # getproxies_environment use lowered case truncated (no '_proxy') keys
+ self.assertEqual('localhost', proxies['no'])
+ # List of no_proxies with space.
+ self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com')
+ self.assertTrue(urllib_request.proxy_bypass_environment('anotherdomain.com'))
+
+class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin):
+ """Test urlopen() opening a fake http connection."""
+
+ def check_read(self, ver):
+ self.fakehttp(b"HTTP/" + ver + b" 200 OK\r\n\r\nHello!")
+ try:
+ fp = urlopen("http://python.org/")
+ self.assertEqual(fp.readline(), b"Hello!")
+ self.assertEqual(fp.readline(), b"")
+ self.assertEqual(fp.geturl(), 'http://python.org/')
+ self.assertEqual(fp.getcode(), 200)
+ finally:
+ self.unfakehttp()
+
+ @unittest.skip('skipping test that uses https')
+ def test_url_fragment(self):
+ # Issue #11703: geturl() omits fragments in the original URL.
+ url = 'http://docs.python.org/library/urllib.html#OK'
+ self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!")
+ try:
+ fp = urllib_request.urlopen(url)
+ self.assertEqual(fp.geturl(), url)
+ finally:
+ self.unfakehttp()
+
+ @unittest.skip('skipping test that uses https')
+ def test_willclose(self):
+ self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!")
+ try:
+ resp = urlopen("http://www.python.org")
+ self.assertTrue(resp.fp.will_close)
+ finally:
+ self.unfakehttp()
+
+ @expectedFailurePY2
+ def test_read_0_9(self):
+ # "0.9" response accepted (but not "simple responses" without
+ # a status line)
+ self.check_read(b"0.9")
+
+ @expectedFailurePY2
+ def test_read_1_0(self):
+ self.check_read(b"1.0")
+
+ @expectedFailurePY2
+ def test_read_1_1(self):
+ self.check_read(b"1.1")
+
+ @expectedFailurePY2
+ def test_read_bogus(self):
+ # urlopen() should raise IOError for many error codes.
+ self.fakehttp(b'''HTTP/1.1 401 Authentication Required
+Date: Wed, 02 Jan 2008 03:03:54 GMT
+Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
+Connection: close
+Content-Type: text/html; charset=iso-8859-1
+''')
+ try:
+ self.assertRaises(OSError, urlopen, "http://python.org/")
+ finally:
+ self.unfakehttp()
+
+ @unittest.skip('skipping test that uses https')
+ def test_invalid_redirect(self):
+ # urlopen() should raise IOError for many error codes.
+ self.fakehttp(b'''HTTP/1.1 302 Found
+Date: Wed, 02 Jan 2008 03:03:54 GMT
+Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
+Location: file://guidocomputer.athome.com:/python/license
+Connection: close
+Content-Type: text/html; charset=iso-8859-1
+''')
+ try:
+ self.assertRaises(urllib_error.HTTPError, urlopen,
+ "http://python.org/")
+ finally:
+ self.unfakehttp()
+
+ def test_empty_socket(self):
+ # urlopen() raises IOError if the underlying socket does not send any
+ # data. (#1680230)
+ self.fakehttp(b'')
+ try:
+ self.assertRaises(IOError, urlopen, "http://something")
+ finally:
+ self.unfakehttp()
+
+ def test_missing_localfile(self):
+ # Test for #10836
+ # 3.3 - URLError is not captured, explicit IOError is raised.
+ with self.assertRaises(IOError):
+ urlopen('file://localhost/a/file/which/doesnot/exists.py')
+
+ def test_file_notexists(self):
+ fd, tmp_file = tempfile.mkstemp()
+ tmp_fileurl = 'file://localhost/' + tmp_file.replace(os.path.sep, '/')
+ try:
+ self.assertTrue(os.path.exists(tmp_file))
+ with urlopen(tmp_fileurl) as fobj:
+ self.assertTrue(fobj)
+ finally:
+ os.close(fd)
+ os.unlink(tmp_file)
+ self.assertFalse(os.path.exists(tmp_file))
+ # 3.3 - IOError instead of URLError
+ with self.assertRaises(IOError):
+ urlopen(tmp_fileurl)
+
+ def test_ftp_nohost(self):
+ test_ftp_url = 'ftp:///path'
+ # 3.3 - IOError instead of URLError
+ with self.assertRaises(IOError):
+ urlopen(test_ftp_url)
+
+ def test_ftp_nonexisting(self):
+ # 3.3 - IOError instead of URLError
+ with self.assertRaises(IOError):
+ urlopen('ftp://localhost/a/file/which/doesnot/exists.py')
+
+
+ @expectedFailurePY2
+ def test_userpass_inurl(self):
+ self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
+ try:
+ fp = urlopen("http://user:pass@python.org/")
+ self.assertEqual(fp.readline(), b"Hello!")
+ self.assertEqual(fp.readline(), b"")
+ self.assertEqual(fp.geturl(), 'http://user:pass@python.org/')
+ self.assertEqual(fp.getcode(), 200)
+ finally:
+ self.unfakehttp()
+
+ @expectedFailurePY2
+ def test_userpass_inurl_w_spaces(self):
+ self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
+ try:
+ userpass = "a b:c d"
+ url = "http://{0}@python.org/".format(userpass)
+ fakehttp_wrapper = http_client.HTTPConnection
+ authorization = ("Authorization: Basic %s\r\n" %
+ b64encode(userpass.encode("ASCII")).decode("ASCII"))
+ fp = urlopen(url)
+ # The authorization header must be in place
+ self.assertIn(authorization, fakehttp_wrapper.buf.decode("UTF-8"))
+ self.assertEqual(fp.readline(), b"Hello!")
+ self.assertEqual(fp.readline(), b"")
+ # the spaces are quoted in URL so no match
+ self.assertNotEqual(fp.geturl(), url)
+ self.assertEqual(fp.getcode(), 200)
+ finally:
+ self.unfakehttp()
+
+ def test_URLopener_deprecation(self):
+ with support.check_warnings(('',DeprecationWarning)):
+ urllib_request.URLopener()
+
+class urlretrieve_FileTests(unittest.TestCase):
+ """Test urllib.urlretrieve() on local files"""
+
+ def setUp(self):
+ # Create a list of temporary files. Each item in the list is a file
+ # name (absolute path or relative to the current working directory).
+ # All files in this list will be deleted in the tearDown method. Note,
+ # this only helps to makes sure temporary files get deleted, but it
+ # does nothing about trying to close files that may still be open. It
+ # is the responsibility of the developer to properly close files even
+ # when exceptional conditions occur.
+ self.tempFiles = []
+
+ # Create a temporary file.
+ self.registerFileForCleanUp(support.TESTFN)
+ self.text = b'testing urllib.urlretrieve'
+ try:
+ FILE = open(support.TESTFN, 'wb')
+ FILE.write(self.text)
+ FILE.close()
+ finally:
+ try: FILE.close()
+ except: pass
+
+ def tearDown(self):
+ # Delete the temporary files.
+ for each in self.tempFiles:
+ try: os.remove(each)
+ except: pass
+
+ def constructLocalFileUrl(self, filePath):
+ filePath = os.path.abspath(filePath)
+ try:
+ filePath.encode("utf-8")
+ except UnicodeEncodeError:
+ raise unittest.SkipTest("filePath is not encodable to utf8")
+ return "file://%s" % urllib_request.pathname2url(filePath)
+
+ def createNewTempFile(self, data=b""):
+ """Creates a new temporary file containing the specified data,
+ registers the file for deletion during the test fixture tear down, and
+ returns the absolute path of the file."""
+
+ newFd, newFilePath = tempfile.mkstemp()
+ try:
+ self.registerFileForCleanUp(newFilePath)
+ newFile = os.fdopen(newFd, "wb")
+ newFile.write(data)
+ newFile.close()
+ finally:
+ try: newFile.close()
+ except: pass
+ return newFilePath
+
+ def registerFileForCleanUp(self, fileName):
+ self.tempFiles.append(fileName)
+
+ def test_basic(self):
+ # Make sure that a local file just gets its own location returned and
+ # a headers value is returned.
+ result = urllib_request.urlretrieve("file:%s" % support.TESTFN)
+ self.assertEqual(result[0], support.TESTFN)
+ self.assertIsInstance(result[1], email_message.Message,
+ "did not get a email.message.Message instance "
+ "as second returned value")
+
+ def test_copy(self):
+ # Test that setting the filename argument works.
+ second_temp = "%s.2" % support.TESTFN
+ self.registerFileForCleanUp(second_temp)
+ result = urllib_request.urlretrieve(self.constructLocalFileUrl(
+ support.TESTFN), second_temp)
+ self.assertEqual(second_temp, result[0])
+ self.assertTrue(os.path.exists(second_temp), "copy of the file was not "
+ "made")
+ FILE = open(second_temp, 'rb')
+ try:
+ text = FILE.read()
+ FILE.close()
+ finally:
+ try: FILE.close()
+ except: pass
+ self.assertEqual(self.text, text)
+
+ def test_reporthook(self):
+ # Make sure that the reporthook works.
+ def hooktester(block_count, block_read_size, file_size, count_holder=[0]):
+ self.assertIsInstance(block_count, int)
+ self.assertIsInstance(block_read_size, int)
+ self.assertIsInstance(file_size, int)
+ self.assertEqual(block_count, count_holder[0])
+ count_holder[0] = count_holder[0] + 1
+ second_temp = "%s.2" % support.TESTFN
+ self.registerFileForCleanUp(second_temp)
+ urllib_request.urlretrieve(
+ self.constructLocalFileUrl(support.TESTFN),
+ second_temp, hooktester)
+
+ def test_reporthook_0_bytes(self):
+ # Test on zero length file. Should call reporthook only 1 time.
+ report = []
+ def hooktester(block_count, block_read_size, file_size, _report=report):
+ _report.append((block_count, block_read_size, file_size))
+ srcFileName = self.createNewTempFile()
+ urllib_request.urlretrieve(self.constructLocalFileUrl(srcFileName),
+ support.TESTFN, hooktester)
+ self.assertEqual(len(report), 1)
+ self.assertEqual(report[0][2], 0)
+
+ def test_reporthook_5_bytes(self):
+ # Test on 5 byte file. Should call reporthook only 2 times (once when
+ # the "network connection" is established and once when the block is
+ # read).
+ report = []
+ def hooktester(block_count, block_read_size, file_size, _report=report):
+ _report.append((block_count, block_read_size, file_size))
+ srcFileName = self.createNewTempFile(b"x" * 5)
+ urllib_request.urlretrieve(self.constructLocalFileUrl(srcFileName),
+ support.TESTFN, hooktester)
+ self.assertEqual(len(report), 2)
+ self.assertEqual(report[0][2], 5)
+ self.assertEqual(report[1][2], 5)
+
+ def test_reporthook_8193_bytes(self):
+ # Test on 8193 byte file. Should call reporthook only 3 times (once
+ # when the "network connection" is established, once for the next 8192
+ # bytes, and once for the last byte).
+ report = []
+ def hooktester(block_count, block_read_size, file_size, _report=report):
+ _report.append((block_count, block_read_size, file_size))
+ srcFileName = self.createNewTempFile(b"x" * 8193)
+ urllib_request.urlretrieve(self.constructLocalFileUrl(srcFileName),
+ support.TESTFN, hooktester)
+ self.assertEqual(len(report), 3)
+ self.assertEqual(report[0][2], 8193)
+ self.assertEqual(report[0][1], 8192)
+ self.assertEqual(report[1][1], 8192)
+ self.assertEqual(report[2][1], 8192)
+
+
+class urlretrieve_HttpTests(unittest.TestCase, FakeHTTPMixin):
+ """Test urllib.urlretrieve() using fake http connections"""
+
+ @expectedFailurePY2
+ def test_short_content_raises_ContentTooShortError(self):
+ self.fakehttp(b'''HTTP/1.1 200 OK
+Date: Wed, 02 Jan 2008 03:03:54 GMT
+Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
+Connection: close
+Content-Length: 100
+Content-Type: text/html; charset=iso-8859-1
+
+FF
+''')
+
+ def _reporthook(par1, par2, par3):
+ pass
+
+ with self.assertRaises(urllib_error.ContentTooShortError):
+ try:
+ urllib_request.urlretrieve('http://example.com/',
+ reporthook=_reporthook)
+ finally:
+ self.unfakehttp()
+
+ @expectedFailurePY2
+ def test_short_content_raises_ContentTooShortError_without_reporthook(self):
+ self.fakehttp(b'''HTTP/1.1 200 OK
+Date: Wed, 02 Jan 2008 03:03:54 GMT
+Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
+Connection: close
+Content-Length: 100
+Content-Type: text/html; charset=iso-8859-1
+
+FF
+''')
+ with self.assertRaises(urllib_error.ContentTooShortError):
+ try:
+ urllib_request.urlretrieve('http://example.com/')
+ finally:
+ self.unfakehttp()
+
+
+class QuotingTests(unittest.TestCase):
+ """Tests for urllib.quote() and urllib.quote_plus()
+
+ According to RFC 2396 (Uniform Resource Identifiers), to escape a
+ character you write it as '%' + <2 character US-ASCII hex value>.
+ The Python code of ``'%' + hex(ord(<character>))[2:]`` escapes a
+ character properly. Case does not matter on the hex letters.
+
+ The various character sets specified are:
+
+ Reserved characters : ";/?:@&=+$,"
+ Have special meaning in URIs and must be escaped if not being used for
+ their special meaning
+ Data characters : letters, digits, and "-_.!~*'()"
+ Unreserved and do not need to be escaped; can be, though, if desired
+ Control characters : 0x00 - 0x1F, 0x7F
+ Have no use in URIs so must be escaped
+ space : 0x20
+ Must be escaped
+ Delimiters : '<>#%"'
+ Must be escaped
+ Unwise : "{}|\^[]`"
+ Must be escaped
+
+ """
+
+ def test_never_quote(self):
+ # Make sure quote() does not quote letters, digits, and "_,.-"
+ do_not_quote = '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ "abcdefghijklmnopqrstuvwxyz",
+ "0123456789",
+ "_.-"])
+ result = urllib_parse.quote(do_not_quote)
+ self.assertEqual(do_not_quote, result,
+ "using quote(): %r != %r" % (do_not_quote, result))
+ result = urllib_parse.quote_plus(do_not_quote)
+ self.assertEqual(do_not_quote, result,
+ "using quote_plus(): %r != %r" % (do_not_quote, result))
+
+ def test_default_safe(self):
+ # Test '/' is default value for 'safe' parameter
+ self.assertEqual(urllib_parse.quote.__defaults__[0], '/')
+
+ def test_safe(self):
+ # Test setting 'safe' parameter does what it should do
+ quote_by_default = "<>"
+ result = urllib_parse.quote(quote_by_default, safe=quote_by_default)
+ self.assertEqual(quote_by_default, result,
+ "using quote(): %r != %r" % (quote_by_default, result))
+ result = urllib_parse.quote_plus(quote_by_default,
+ safe=quote_by_default)
+ self.assertEqual(quote_by_default, result,
+ "using quote_plus(): %r != %r" %
+ (quote_by_default, result))
+ # Safe expressed as bytes rather than str
+ result = urllib_parse.quote(quote_by_default, safe=b"<>")
+ self.assertEqual(quote_by_default, result,
+ "using quote(): %r != %r" % (quote_by_default, result))
+ # "Safe" non-ASCII characters should have no effect
+ # (Since URIs are not allowed to have non-ASCII characters)
+ result = urllib_parse.quote("a\xfcb", encoding="latin-1", safe="\xfc")
+ expect = urllib_parse.quote("a\xfcb", encoding="latin-1", safe="")
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" %
+ (expect, result))
+ # Same as above, but using a bytes rather than str
+ result = urllib_parse.quote("a\xfcb", encoding="latin-1", safe=b"\xfc")
+ expect = urllib_parse.quote("a\xfcb", encoding="latin-1", safe="")
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" %
+ (expect, result))
+
+ def test_default_quoting(self):
+ # Make sure all characters that should be quoted are by default sans
+ # space (separate test for that).
+ should_quote = [chr(num) for num in range(32)] # For 0x00 - 0x1F
+ should_quote.append('<>#%"{}|\^[]`')
+ should_quote.append(chr(127)) # For 0x7F
+ should_quote = ''.join(should_quote)
+ for char in should_quote:
+ result = urllib_parse.quote(char)
+ self.assertEqual(hexescape(char), result,
+ "using quote(): "
+ "%s should be escaped to %s, not %s" %
+ (char, hexescape(char), result))
+ result = urllib_parse.quote_plus(char)
+ self.assertEqual(hexescape(char), result,
+ "using quote_plus(): "
+ "%s should be escapes to %s, not %s" %
+ (char, hexescape(char), result))
+ del should_quote
+ partial_quote = "ab[]cd"
+ expected = "ab%5B%5Dcd"
+ result = urllib_parse.quote(partial_quote)
+ self.assertEqual(expected, result,
+ "using quote(): %r != %r" % (expected, result))
+ result = urllib_parse.quote_plus(partial_quote)
+ self.assertEqual(expected, result,
+ "using quote_plus(): %r != %r" % (expected, result))
+
+ def test_quoting_space(self):
+ # Make sure quote() and quote_plus() handle spaces as specified in
+ # their unique way
+ result = urllib_parse.quote(' ')
+ self.assertEqual(result, hexescape(' '),
+ "using quote(): %r != %r" % (result, hexescape(' ')))
+ result = urllib_parse.quote_plus(' ')
+ self.assertEqual(result, '+',
+ "using quote_plus(): %r != +" % result)
+ given = "a b cd e f"
+ expect = given.replace(' ', hexescape(' '))
+ result = urllib_parse.quote(given)
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ expect = given.replace(' ', '+')
+ result = urllib_parse.quote_plus(given)
+ self.assertEqual(expect, result,
+ "using quote_plus(): %r != %r" % (expect, result))
+
+ def test_quoting_plus(self):
+ self.assertEqual(urllib_parse.quote_plus('alpha+beta gamma'),
+ 'alpha%2Bbeta+gamma')
+ self.assertEqual(urllib_parse.quote_plus('alpha+beta gamma', '+'),
+ 'alpha+beta+gamma')
+ # Test with bytes
+ self.assertEqual(urllib_parse.quote_plus(b'alpha+beta gamma'),
+ 'alpha%2Bbeta+gamma')
+ # Test with safe bytes
+ self.assertEqual(urllib_parse.quote_plus('alpha+beta gamma', b'+'),
+ 'alpha+beta+gamma')
+
+ def test_quote_bytes(self):
+ # Bytes should quote directly to percent-encoded values
+ given = b"\xa2\xd8ab\xff"
+ expect = "%A2%D8ab%FF"
+ result = urllib_parse.quote(given)
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ # Encoding argument should raise type error on bytes input
+ self.assertRaises(TypeError, urllib_parse.quote, given,
+ encoding="latin-1")
+ # quote_from_bytes should work the same
+ result = urllib_parse.quote_from_bytes(given)
+ self.assertEqual(expect, result,
+ "using quote_from_bytes(): %r != %r"
+ % (expect, result))
+
+ def test_quote_with_unicode(self):
+ # Characters in Latin-1 range, encoded by default in UTF-8
+ given = "\xa2\xd8ab\xff"
+ expect = "%C2%A2%C3%98ab%C3%BF"
+ result = urllib_parse.quote(given)
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ # Characters in Latin-1 range, encoded by with None (default)
+ result = urllib_parse.quote(given, encoding=None, errors=None)
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ # Characters in Latin-1 range, encoded with Latin-1
+ given = "\xa2\xd8ab\xff"
+ expect = "%A2%D8ab%FF"
+ result = urllib_parse.quote(given, encoding="latin-1")
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ # Characters in BMP, encoded by default in UTF-8
+ given = "\u6f22\u5b57" # "Kanji"
+ expect = "%E6%BC%A2%E5%AD%97"
+ result = urllib_parse.quote(given)
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ # Characters in BMP, encoded with Latin-1
+ given = "\u6f22\u5b57"
+ self.assertRaises(UnicodeEncodeError, urllib_parse.quote, given,
+ encoding="latin-1")
+ # Characters in BMP, encoded with Latin-1, with replace error handling
+ given = "\u6f22\u5b57"
+ expect = "%3F%3F" # "??"
+ result = urllib_parse.quote(given, encoding="latin-1",
+ errors="replace")
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ # Characters in BMP, Latin-1, with xmlcharref error handling
+ given = "\u6f22\u5b57"
+ expect = "%26%2328450%3B%26%2323383%3B" # "&#28450;&#23383;"
+ result = urllib_parse.quote(given, encoding="latin-1",
+ errors="xmlcharrefreplace")
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+
+ def test_quote_plus_with_unicode(self):
+ # Encoding (latin-1) test for quote_plus
+ given = "\xa2\xd8 \xff"
+ expect = "%A2%D8+%FF"
+ result = urllib_parse.quote_plus(given, encoding="latin-1")
+ self.assertEqual(expect, result,
+ "using quote_plus(): %r != %r" % (expect, result))
+ # Errors test for quote_plus
+ given = "ab\u6f22\u5b57 cd"
+ expect = "ab%3F%3F+cd"
+ result = urllib_parse.quote_plus(given, encoding="latin-1",
+ errors="replace")
+ self.assertEqual(expect, result,
+ "using quote_plus(): %r != %r" % (expect, result))
+
+
+class UnquotingTests(unittest.TestCase):
+ """Tests for unquote() and unquote_plus()
+
+ See the doc string for quoting_Tests for details on quoting and such.
+
+ """
+
+ def test_unquoting(self):
+ # Make sure unquoting of all ASCII values works
+ escape_list = []
+ for num in range(128):
+ given = hexescape(chr(num))
+ expect = chr(num)
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+ result = urllib_parse.unquote_plus(given)
+ self.assertEqual(expect, result,
+ "using unquote_plus(): %r != %r" %
+ (expect, result))
+ escape_list.append(given)
+ escape_string = ''.join(escape_list)
+ del escape_list
+ result = urllib_parse.unquote(escape_string)
+ self.assertEqual(result.count('%'), 1,
+ "using unquote(): not all characters escaped: "
+ "%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''))
+
+ def test_unquoting_badpercent(self):
+ # Test unquoting on bad percent-escapes
+ given = '%xab'
+ expect = given
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result, "using unquote(): %r != %r"
+ % (expect, result))
+ given = '%x'
+ expect = given
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result, "using unquote(): %r != %r"
+ % (expect, result))
+ given = '%'
+ expect = given
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result, "using unquote(): %r != %r"
+ % (expect, result))
+ # unquote_to_bytes
+ given = '%xab'
+ expect = bytes(given, 'ascii')
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+ given = '%x'
+ expect = bytes(given, 'ascii')
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+ given = '%'
+ expect = bytes(given, 'ascii')
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+ self.assertRaises((TypeError, AttributeError), urllib_parse.unquote_to_bytes, None)
+ self.assertRaises((TypeError, AttributeError), urllib_parse.unquote_to_bytes, ())
+
+ def test_unquoting_mixed_case(self):
+ # Test unquoting on mixed-case hex digits in the percent-escapes
+ given = '%Ab%eA'
+ expect = b'\xab\xea'
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result,
+ "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+
+ def test_unquoting_parts(self):
+ # Make sure unquoting works when have non-quoted characters
+ # interspersed
+ given = 'ab%sd' % hexescape('c')
+ expect = "abcd"
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result,
+ "using quote(): %r != %r" % (expect, result))
+ result = urllib_parse.unquote_plus(given)
+ self.assertEqual(expect, result,
+ "using unquote_plus(): %r != %r" % (expect, result))
+
+ def test_unquoting_plus(self):
+ # Test difference between unquote() and unquote_plus()
+ given = "are+there+spaces..."
+ expect = given
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+ expect = given.replace('+', ' ')
+ result = urllib_parse.unquote_plus(given)
+ self.assertEqual(expect, result,
+ "using unquote_plus(): %r != %r" % (expect, result))
+
+ def test_unquote_to_bytes(self):
+ given = 'br%C3%BCckner_sapporo_20050930.doc'
+ expect = b'br\xc3\xbcckner_sapporo_20050930.doc'
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result,
+ "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+ # Test on a string with unescaped non-ASCII characters
+ # (Technically an invalid URI; expect those characters to be UTF-8
+ # encoded).
+ result = urllib_parse.unquote_to_bytes("\u6f22%C3%BC")
+ expect = b'\xe6\xbc\xa2\xc3\xbc' # UTF-8 for "\u6f22\u00fc"
+ self.assertEqual(expect, result,
+ "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+ # Test with a bytes as input
+ given = b'%A2%D8ab%FF'
+ expect = b'\xa2\xd8ab\xff'
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result,
+ "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+ # Test with a bytes as input, with unescaped non-ASCII bytes
+ # (Technically an invalid URI; expect those bytes to be preserved)
+ given = b'%A2\xd8ab%FF'
+ expect = b'\xa2\xd8ab\xff'
+ result = urllib_parse.unquote_to_bytes(given)
+ self.assertEqual(expect, result,
+ "using unquote_to_bytes(): %r != %r"
+ % (expect, result))
+
+ def test_unquote_with_unicode(self):
+ # Characters in the Latin-1 range, encoded with UTF-8
+ given = 'br%C3%BCckner_sapporo_20050930.doc'
+ expect = 'br\u00fcckner_sapporo_20050930.doc'
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+ # Characters in the Latin-1 range, encoded with None (default)
+ result = urllib_parse.unquote(given, encoding=None, errors=None)
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # Characters in the Latin-1 range, encoded with Latin-1
+ result = urllib_parse.unquote('br%FCckner_sapporo_20050930.doc',
+ encoding="latin-1")
+ expect = 'br\u00fcckner_sapporo_20050930.doc'
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # Characters in BMP, encoded with UTF-8
+ given = "%E6%BC%A2%E5%AD%97"
+ expect = "\u6f22\u5b57" # "Kanji"
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # Decode with UTF-8, invalid sequence
+ given = "%F3%B1"
+ expect = "\ufffd" # Replacement character
+ result = urllib_parse.unquote(given)
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # Decode with UTF-8, invalid sequence, replace errors
+ result = urllib_parse.unquote(given, errors="replace")
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # Decode with UTF-8, invalid sequence, ignoring errors
+ given = "%F3%B1"
+ expect = ""
+ result = urllib_parse.unquote(given, errors="ignore")
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # A mix of non-ASCII and percent-encoded characters, UTF-8
+ result = urllib_parse.unquote("\u6f22%C3%BC")
+ expect = '\u6f22\u00fc'
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+ # A mix of non-ASCII and percent-encoded characters, Latin-1
+ # (Note, the string contains non-Latin-1-representable characters)
+ result = urllib_parse.unquote("\u6f22%FC", encoding="latin-1")
+ expect = '\u6f22\u00fc'
+ self.assertEqual(expect, result,
+ "using unquote(): %r != %r" % (expect, result))
+
+class urlencode_Tests(unittest.TestCase):
+ """Tests for urlencode()"""
+
+ def help_inputtype(self, given, test_type):
+ """Helper method for testing different input types.
+
+ 'given' must lead to only the pairs:
+ * 1st, 1
+ * 2nd, 2
+ * 3rd, 3
+
+ Test cannot assume anything about order. Docs make no guarantee and
+ have possible dictionary input.
+
+ """
+ expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
+ result = urllib_parse.urlencode(given)
+ for expected in expect_somewhere:
+ self.assertIn(expected, result,
+ "testing %s: %s not found in %s" %
+ (test_type, expected, result))
+ self.assertEqual(result.count('&'), 2,
+ "testing %s: expected 2 '&'s; got %s" %
+ (test_type, result.count('&')))
+ amp_location = result.index('&')
+ on_amp_left = result[amp_location - 1]
+ on_amp_right = result[amp_location + 1]
+ self.assertTrue(on_amp_left.isdigit() and on_amp_right.isdigit(),
+ "testing %s: '&' not located in proper place in %s" %
+ (test_type, result))
+ self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps
+ "testing %s: "
+ "unexpected number of characters: %s != %s" %
+ (test_type, len(result), (5 * 3) + 2))
+
+ def test_using_mapping(self):
+ # Test passing in a mapping object as an argument.
+ self.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'},
+ "using dict as input type")
+
+ def test_using_sequence(self):
+ # Test passing in a sequence of two-item sequences as an argument.
+ self.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')],
+ "using sequence of two-item tuples as input")
+
+ def test_quoting(self):
+ # Make sure keys and values are quoted using quote_plus()
+ given = {"&":"="}
+ expect = "%s=%s" % (hexescape('&'), hexescape('='))
+ result = urllib_parse.urlencode(given)
+ self.assertEqual(expect, result)
+ given = {"key name":"A bunch of pluses"}
+ expect = "key+name=A+bunch+of+pluses"
+ result = urllib_parse.urlencode(given)
+ self.assertEqual(expect, result)
+
+ def test_doseq(self):
+ # Test that passing True for 'doseq' parameter works correctly
+ given = {'sequence':['1', '2', '3']}
+ expect = "sequence=%s" % urllib_parse.quote_plus(str(['1', '2', '3']))
+ result = urllib_parse.urlencode(given)
+ self.assertEqual(expect, result)
+ result = urllib_parse.urlencode(given, True)
+ for value in given["sequence"]:
+ expect = "sequence=%s" % value
+ self.assertIn(expect, result)
+ self.assertEqual(result.count('&'), 2,
+ "Expected 2 '&'s, got %s" % result.count('&'))
+
+ def test_empty_sequence(self):
+ self.assertEqual("", urllib_parse.urlencode({}))
+ self.assertEqual("", urllib_parse.urlencode([]))
+
+ def test_nonstring_values(self):
+ self.assertEqual("a=1", urllib_parse.urlencode({"a": 1}))
+ self.assertEqual("a=None", urllib_parse.urlencode({"a": None}))
+
+ def test_nonstring_seq_values(self):
+ from future.backports import OrderedDict # for Py2.6
+ self.assertEqual("a=1&a=2", urllib_parse.urlencode({"a": [1, 2]}, True))
+ self.assertEqual("a=None&a=a",
+ urllib_parse.urlencode({"a": [None, "a"]}, True))
+ data = OrderedDict([("a", 1), ("b", 1)])
+ self.assertEqual("a=a&a=b",
+ urllib_parse.urlencode({"a": data}, True))
+
+ def test_urlencode_encoding(self):
+ # ASCII encoding. Expect %3F with errors="replace'
+ given = (('\u00a0', '\u00c1'),)
+ expect = '%3F=%3F'
+ result = urllib_parse.urlencode(given, encoding="ASCII", errors="replace")
+ self.assertEqual(expect, result)
+
+ # Default is UTF-8 encoding.
+ given = (('\u00a0', '\u00c1'),)
+ expect = '%C2%A0=%C3%81'
+ result = urllib_parse.urlencode(given)
+ self.assertEqual(expect, result)
+
+ # Latin-1 encoding.
+ given = (('\u00a0', '\u00c1'),)
+ expect = '%A0=%C1'
+ result = urllib_parse.urlencode(given, encoding="latin-1")
+ self.assertEqual(expect, result)
+
+ def test_urlencode_encoding_doseq(self):
+ # ASCII Encoding. Expect %3F with errors="replace'
+ given = (('\u00a0', '\u00c1'),)
+ expect = '%3F=%3F'
+ result = urllib_parse.urlencode(given, doseq=True,
+ encoding="ASCII", errors="replace")
+ self.assertEqual(expect, result)
+
+ # ASCII Encoding. On a sequence of values.
+ given = (("\u00a0", (1, "\u00c1")),)
+ expect = '%3F=1&%3F=%3F'
+ result = urllib_parse.urlencode(given, True,
+ encoding="ASCII", errors="replace")
+ self.assertEqual(expect, result)
+
+ # Utf-8
+ given = (("\u00a0", "\u00c1"),)
+ expect = '%C2%A0=%C3%81'
+ result = urllib_parse.urlencode(given, True)
+ self.assertEqual(expect, result)
+
+ given = (("\u00a0", (42, "\u00c1")),)
+ expect = '%C2%A0=42&%C2%A0=%C3%81'
+ result = urllib_parse.urlencode(given, True)
+ self.assertEqual(expect, result)
+
+ # latin-1
+ given = (("\u00a0", "\u00c1"),)
+ expect = '%A0=%C1'
+ result = urllib_parse.urlencode(given, True, encoding="latin-1")
+ self.assertEqual(expect, result)
+
+ given = (("\u00a0", (42, "\u00c1")),)
+ expect = '%A0=42&%A0=%C1'
+ result = urllib_parse.urlencode(given, True, encoding="latin-1")
+ self.assertEqual(expect, result)
+
+ def test_urlencode_bytes(self):
+ given = ((b'\xa0\x24', b'\xc1\x24'),)
+ expect = '%A0%24=%C1%24'
+ result = urllib_parse.urlencode(given)
+ self.assertEqual(expect, result)
+ result = urllib_parse.urlencode(given, True)
+ self.assertEqual(expect, result)
+
+ # Sequence of values
+ given = ((b'\xa0\x24', (42, b'\xc1\x24')),)
+ expect = '%A0%24=42&%A0%24=%C1%24'
+ result = urllib_parse.urlencode(given, True)
+ self.assertEqual(expect, result)
+
+ def test_urlencode_encoding_safe_parameter(self):
+
+ # Send '$' (\x24) as safe character
+ # Default utf-8 encoding
+
+ given = ((b'\xa0\x24', b'\xc1\x24'),)
+ result = urllib_parse.urlencode(given, safe=":$")
+ expect = '%A0$=%C1$'
+ self.assertEqual(expect, result)
+
+ given = ((b'\xa0\x24', b'\xc1\x24'),)
+ result = urllib_parse.urlencode(given, doseq=True, safe=":$")
+ expect = '%A0$=%C1$'
+ self.assertEqual(expect, result)
+
+ # Safe parameter in sequence
+ given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),)
+ expect = '%A0$=%C1$&%A0$=13&%A0$=42'
+ result = urllib_parse.urlencode(given, True, safe=":$")
+ self.assertEqual(expect, result)
+
+ # Test all above in latin-1 encoding
+
+ given = ((b'\xa0\x24', b'\xc1\x24'),)
+ result = urllib_parse.urlencode(given, safe=":$",
+ encoding="latin-1")
+ expect = '%A0$=%C1$'
+ self.assertEqual(expect, result)
+
+ given = ((b'\xa0\x24', b'\xc1\x24'),)
+ expect = '%A0$=%C1$'
+ result = urllib_parse.urlencode(given, doseq=True, safe=":$",
+ encoding="latin-1")
+
+ given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),)
+ expect = '%A0$=%C1$&%A0$=13&%A0$=42'
+ result = urllib_parse.urlencode(given, True, safe=":$",
+ encoding="latin-1")
+ self.assertEqual(expect, result)
+
+class Pathname_Tests(unittest.TestCase):
+ """Test pathname2url() and url2pathname()"""
+
+ def test_basic(self):
+ # Make sure simple tests pass
+ expected_path = os.path.join("parts", "of", "a", "path")
+ expected_url = "parts/of/a/path"
+ result = urllib_request.pathname2url(expected_path)
+ self.assertEqual(expected_url, result,
+ "pathname2url() failed; %s != %s" %
+ (result, expected_url))
+ result = urllib_request.url2pathname(expected_url)
+ self.assertEqual(expected_path, result,
+ "url2pathame() failed; %s != %s" %
+ (result, expected_path))
+
+ def test_quoting(self):
+ # Test automatic quoting and unquoting works for pathnam2url() and
+ # url2pathname() respectively
+ given = os.path.join("needs", "quot=ing", "here")
+ expect = "needs/%s/here" % urllib_parse.quote("quot=ing")
+ result = urllib_request.pathname2url(given)
+ self.assertEqual(expect, result,
+ "pathname2url() failed; %s != %s" %
+ (expect, result))
+ expect = given
+ result = urllib_request.url2pathname(result)
+ self.assertEqual(expect, result,
+ "url2pathname() failed; %s != %s" %
+ (expect, result))
+ given = os.path.join("make sure", "using_quote")
+ expect = "%s/using_quote" % urllib_parse.quote("make sure")
+ result = urllib_request.pathname2url(given)
+ self.assertEqual(expect, result,
+ "pathname2url() failed; %s != %s" %
+ (expect, result))
+ given = "make+sure/using_unquote"
+ expect = os.path.join("make+sure", "using_unquote")
+ result = urllib_request.url2pathname(given)
+ self.assertEqual(expect, result,
+ "url2pathname() failed; %s != %s" %
+ (expect, result))
+
+ @unittest.skipUnless(sys.platform == 'win32',
+ 'test specific to the urllib.url2path function.')
+ def test_ntpath(self):
+ given = ('/C:/', '///C:/', '/C|//')
+ expect = 'C:\\'
+ for url in given:
+ result = urllib_request.url2pathname(url)
+ self.assertEqual(expect, result,
+ 'urllib_request..url2pathname() failed; %s != %s' %
+ (expect, result))
+ given = '///C|/path'
+ expect = 'C:\\path'
+ result = urllib_request.url2pathname(given)
+ self.assertEqual(expect, result,
+ 'urllib_request.url2pathname() failed; %s != %s' %
+ (expect, result))
+
+class Utility_Tests(unittest.TestCase):
+ """Testcase to test the various utility functions in the urllib."""
+
+ def test_splitpasswd(self):
+ """Some of password examples are not sensible, but it is added to
+ confirming to RFC2617 and addressing issue4675.
+ """
+ self.assertEqual(('user', 'ab'),urllib_parse.splitpasswd('user:ab'))
+ self.assertEqual(('user', 'a\nb'),urllib_parse.splitpasswd('user:a\nb'))
+ self.assertEqual(('user', 'a\tb'),urllib_parse.splitpasswd('user:a\tb'))
+ self.assertEqual(('user', 'a\rb'),urllib_parse.splitpasswd('user:a\rb'))
+ self.assertEqual(('user', 'a\fb'),urllib_parse.splitpasswd('user:a\fb'))
+ self.assertEqual(('user', 'a\vb'),urllib_parse.splitpasswd('user:a\vb'))
+ self.assertEqual(('user', 'a:b'),urllib_parse.splitpasswd('user:a:b'))
+ self.assertEqual(('user', 'a b'),urllib_parse.splitpasswd('user:a b'))
+ self.assertEqual(('user 2', 'ab'),urllib_parse.splitpasswd('user 2:ab'))
+ self.assertEqual(('user+1', 'a+b'),urllib_parse.splitpasswd('user+1:a+b'))
+
+ def test_thishost(self):
+ """Test the urllib_request.thishost utility function returns a tuple"""
+ self.assertIsInstance(urllib_request.thishost(), tuple)
+
+
+class URLopener_Tests(unittest.TestCase):
+ """Testcase to test the open method of URLopener class."""
+
+ def test_quoted_open(self):
+ class DummyURLopener(urllib_request.URLopener):
+ def open_spam(self, url):
+ return url
+ with support.check_warnings(
+ ('DummyURLopener style of invoking requests is deprecated.',
+ DeprecationWarning)):
+ self.assertEqual(DummyURLopener().open(
+ 'spam://example/ /'),'//example/%20/')
+
+ # test the safe characters are not quoted by urlopen
+ self.assertEqual(DummyURLopener().open(
+ "spam://c:|windows%/:=&?~#+!$,;'@()*[]|/path/"),
+ "//c:|windows%/:=&?~#+!$,;'@()*[]|/path/")
+
+# Just commented them out.
+# Can't really tell why keep failing in windows and sparc.
+# 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!
+# . Facundo
+#
+# def server(evt):
+# import socket, time
+# serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# serv.settimeout(3)
+# serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+# serv.bind(("", 9093))
+# serv.listen(5)
+# try:
+# conn, addr = serv.accept()
+# conn.send("1 Hola mundo\n")
+# cantdata = 0
+# while cantdata < 13:
+# data = conn.recv(13-cantdata)
+# cantdata += len(data)
+# time.sleep(.3)
+# conn.send("2 No more lines\n")
+# conn.close()
+# except socket.timeout:
+# pass
+# finally:
+# serv.close()
+# evt.set()
+#
+# class FTPWrapperTests(unittest.TestCase):
+#
+# def setUp(self):
+# import ftplib, time, threading
+# ftplib.FTP.port = 9093
+# self.evt = threading.Event()
+# threading.Thread(target=server, args=(self.evt,)).start()
+# time.sleep(.1)
+#
+# def tearDown(self):
+# self.evt.wait()
+#
+# def testBasic(self):
+# # connects
+# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
+# ftp.close()
+#
+# def testTimeoutNone(self):
+# # global default timeout is ignored
+# import socket
+# self.assertTrue(socket.getdefaulttimeout() is None)
+# socket.setdefaulttimeout(30)
+# try:
+# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
+# finally:
+# socket.setdefaulttimeout(None)
+# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
+# ftp.close()
+#
+# def testTimeoutDefault(self):
+# # global default timeout is used
+# import socket
+# self.assertTrue(socket.getdefaulttimeout() is None)
+# socket.setdefaulttimeout(30)
+# try:
+# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
+# finally:
+# socket.setdefaulttimeout(None)
+# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
+# ftp.close()
+#
+# def testTimeoutValue(self):
+# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [],
+# timeout=30)
+# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
+# ftp.close()
+
+class RequestTests(unittest.TestCase):
+ """Unit tests for urllib_request.Request."""
+
+ def test_default_values(self):
+ Request = urllib_request.Request
+ request = Request("http://www.python.org")
+ self.assertEqual(request.get_method(), 'GET')
+ request = Request("http://www.python.org", {})
+ self.assertEqual(request.get_method(), 'POST')
+
+ def test_with_method_arg(self):
+ Request = urllib_request.Request
+ request = Request("http://www.python.org", method='HEAD')
+ self.assertEqual(request.method, 'HEAD')
+ self.assertEqual(request.get_method(), 'HEAD')
+ request = Request("http://www.python.org", {}, method='HEAD')
+ self.assertEqual(request.method, 'HEAD')
+ self.assertEqual(request.get_method(), 'HEAD')
+ request = Request("http://www.python.org", method='GET')
+ self.assertEqual(request.get_method(), 'GET')
+ request.method = 'HEAD'
+ self.assertEqual(request.get_method(), 'HEAD')
+
+
+class URL2PathNameTests(unittest.TestCase):
+
+ @expectedFailurePY26
+ def test_converting_drive_letter(self):
+ self.assertEqual(url2pathname("///C|"), 'C:')
+ self.assertEqual(url2pathname("///C:"), 'C:')
+ self.assertEqual(url2pathname("///C|/"), 'C:\\')
+
+ def test_converting_when_no_drive_letter(self):
+ # cannot end a raw string in \
+ self.assertEqual(url2pathname("///C/test/"), r'\\\C\test' '\\')
+ self.assertEqual(url2pathname("////C/test/"), r'\\C\test' '\\')
+
+ def test_simple_compare(self):
+ self.assertEqual(url2pathname("///C|/foo/bar/spam.foo"),
+ r'C:\foo\bar\spam.foo')
+
+ def test_non_ascii_drive_letter(self):
+ self.assertRaises(IOError, url2pathname, "///\u00e8|/")
+
+ def test_roundtrip_url2pathname(self):
+ list_of_paths = ['C:',
+ r'\\\C\test\\',
+ r'C:\foo\bar\spam.foo'
+ ]
+ for path in list_of_paths:
+ self.assertEqual(url2pathname(pathname2url(path)), path)
+
+class PathName2URLTests(unittest.TestCase):
+
+ def test_converting_drive_letter(self):
+ self.assertEqual(pathname2url("C:"), '///C:')
+ self.assertEqual(pathname2url("C:\\"), '///C:')
+
+ def test_converting_when_no_drive_letter(self):
+ self.assertEqual(pathname2url(r"\\\folder\test" "\\"),
+ '/////folder/test/')
+ self.assertEqual(pathname2url(r"\\folder\test" "\\"),
+ '////folder/test/')
+ self.assertEqual(pathname2url(r"\folder\test" "\\"),
+ '/folder/test/')
+
+ def test_simple_compare(self):
+ self.assertEqual(pathname2url(r'C:\foo\bar\spam.foo'),
+ "///C:/foo/bar/spam.foo" )
+
+ def test_long_drive_letter(self):
+ self.assertRaises(IOError, pathname2url, "XX:\\")
+
+ def test_roundtrip_pathname2url(self):
+ list_of_paths = ['///C:',
+ '/////folder/test/',
+ '///C:/foo/bar/spam.foo']
+ for path in list_of_paths:
+ self.assertEqual(pathname2url(url2pathname(path)), path)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_urllibnet.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_urllibnet.py
new file mode 100644
index 0000000..f9639bf
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_urllibnet.py
@@ -0,0 +1,231 @@
+#!/usr/bin/env python3
+from __future__ import absolute_import, division, unicode_literals
+
+import contextlib
+import socket
+import sys
+import os
+import time
+
+from future import utils
+from future.backports.test import support
+
+import future.moves.urllib.request as urllib_request
+# import future.backports.email.message as email_message
+# from future.backports.email.message import Message
+import email.message as email_message
+from email.message import Message
+
+from future.tests.base import unittest, skip26
+from future.builtins import int, open
+
+
+class URLTimeoutTest(unittest.TestCase):
+ # XXX this test doesn't seem to test anything useful.
+
+ TIMEOUT = 30.0
+
+ def setUp(self):
+ socket.setdefaulttimeout(self.TIMEOUT)
+
+ def tearDown(self):
+ socket.setdefaulttimeout(None)
+
+ def testURLread(self):
+ with support.transient_internet("www.python.org"):
+ f = urllib_request.urlopen("http://www.python.org/")
+ x = f.read()
+
+
+class urlopenNetworkTests(unittest.TestCase):
+ """Tests urllib.reqest.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
+ tests exercising the optional 'data' and 'proxies' arguments. No tests
+ for transparent redirection have been written.
+
+ setUp is not used for always constructing a connection to
+ http://www.python.org/ since there a few tests that don't use that address
+ and making a connection is expensive enough to warrant minimizing unneeded
+ connections.
+
+ """
+
+ @contextlib.contextmanager
+ def urlopen(self, *args, **kwargs):
+ resource = args[0]
+ with support.transient_internet(resource):
+ r = urllib_request.urlopen(*args, **kwargs)
+ try:
+ yield r
+ finally:
+ r.close()
+
+ def test_basic(self):
+ # Simple test expected to pass.
+ with self.urlopen("http://www.python.org/") as open_url:
+ for attr in ("read", "readline", "readlines", "fileno", "close",
+ "info", "geturl"):
+ self.assertTrue(hasattr(open_url, attr), "object returned from "
+ "urlopen lacks the %s attribute" % attr)
+ self.assertTrue(open_url.read(), "calling 'read' failed")
+
+ def test_readlines(self):
+ # Test both readline and readlines.
+ with self.urlopen("http://www.python.org/") as open_url:
+ self.assertIsInstance(open_url.readline(), bytes,
+ "readline did not return a string")
+ self.assertIsInstance(open_url.readlines(), list,
+ "readlines did not return a list")
+
+ @unittest.skipIf(utils.PY2, 'test not applicable on Py2')
+ def test_info(self):
+ # Test 'info'.
+ with self.urlopen("http://www.python.org/") as open_url:
+ info_obj = open_url.info()
+ self.assertIsInstance(info_obj, email_message.Message,
+ "object returned by 'info' is not an "
+ "instance of email_message.Message")
+ self.assertEqual(info_obj.get_content_subtype(), "html")
+
+ def test_geturl(self):
+ # Make sure same URL as opened is returned by geturl.
+ URL = "https://www.python.org/" # EJS: changed recently from http:// ?!
+ with self.urlopen(URL) as open_url:
+ gotten_url = open_url.geturl()
+ self.assertEqual(gotten_url, URL)
+
+ def test_getcode(self):
+ # test getcode() with the fancy opener to get 404 error codes
+ URL = "http://www.python.org/XXXinvalidXXX"
+ with support.transient_internet(URL):
+ open_url = urllib_request.FancyURLopener().open(URL)
+ try:
+ code = open_url.getcode()
+ finally:
+ open_url.close()
+ self.assertEqual(code, 404)
+
+ # On Windows, socket handles are not file descriptors; this
+ # test can't pass on Windows.
+ @unittest.skipIf(sys.platform in ('darwin', 'win32',), 'not appropriate for Windows')
+ @unittest.skipIf(utils.PY36_PLUS, 'test not applicable on Python 3.5 and higher')
+ @skip26
+ def test_fileno(self):
+ # Make sure fd returned by fileno is valid.
+ with self.urlopen("http://www.python.org/", timeout=None) as open_url:
+ fd = open_url.fileno()
+ with os.fdopen(fd, 'rb') as f:
+ self.assertTrue(f.read(), "reading from file created using fd "
+ "returned by fileno failed")
+
+ def test_bad_address(self):
+ # Make sure proper exception is raised when connecting to a bogus
+ # address.
+ bogus_domain = "sadflkjsasf.i.nvali.d"
+ try:
+ socket.gethostbyname(bogus_domain)
+ except (OSError, socket.error): # for Py3 and Py2 respectively
+ # socket.gaierror is too narrow, since getaddrinfo() may also
+ # fail with EAI_SYSTEM and ETIMEDOUT (seen on Ubuntu 13.04),
+ # i.e. Python's TimeoutError.
+ pass
+ else:
+ # This happens with some overzealous DNS providers such as OpenDNS
+ self.skipTest("%r should not resolve for test to work" % bogus_domain)
+ self.assertRaises(IOError,
+ # SF patch 809915: In Sep 2003, VeriSign started
+ # highjacking invalid .com and .net addresses to
+ # boost traffic to their own site. This test
+ # started failing then. One hopes the .invalid
+ # domain will be spared to serve its defined
+ # purpose.
+ # urllib.urlopen, "http://www.sadflkjsasadf.com/")
+ urllib_request.urlopen,
+ "http://sadflkjsasf.i.nvali.d/")
+
+
+class urlretrieveNetworkTests(unittest.TestCase):
+ """Tests urllib_request.urlretrieve using the network."""
+
+ @contextlib.contextmanager
+ def urlretrieve(self, *args, **kwargs):
+ resource = args[0]
+ with support.transient_internet(resource):
+ file_location, info = urllib_request.urlretrieve(*args, **kwargs)
+ try:
+ yield file_location, info
+ finally:
+ support.unlink(file_location)
+
+ def test_basic(self):
+ # Test basic functionality.
+ with self.urlretrieve("http://www.python.org/") as (file_location, info):
+ self.assertTrue(os.path.exists(file_location), "file location returned by"
+ " urlretrieve is not a valid path")
+ with open(file_location, 'rb') as f:
+ self.assertTrue(f.read(), "reading from the file location returned"
+ " by urlretrieve failed")
+
+ def test_specified_path(self):
+ # Make sure that specifying the location of the file to write to works.
+ with self.urlretrieve("http://www.python.org/",
+ support.TESTFN) as (file_location, info):
+ self.assertEqual(file_location, support.TESTFN)
+ self.assertTrue(os.path.exists(file_location))
+ with open(file_location, 'rb') as f:
+ self.assertTrue(f.read(), "reading from temporary file failed")
+
+ @unittest.skipIf(utils.PY2, 'test not applicable on Py2')
+ def test_header(self):
+ # Make sure header returned as 2nd value from urlretrieve is good.
+ with self.urlretrieve("http://www.python.org/") as (file_location, info):
+ self.assertIsInstance(info, email_message.Message,
+ "info is not an instance of email_message.Message")
+
+ logo = "http://www.python.org/static/community_logos/python-logo-master-v3-TM.png"
+
+ def test_data_header(self):
+ with self.urlretrieve(self.logo) as (file_location, fileheaders):
+ datevalue = fileheaders.get('Date')
+ dateformat = '%a, %d %b %Y %H:%M:%S GMT'
+ try:
+ time.strptime(datevalue, dateformat)
+ except ValueError:
+ self.fail('Date value not in %r format', dateformat)
+
+ def test_reporthook(self):
+ records = []
+ def recording_reporthook(blocks, block_size, total_size):
+ records.append((blocks, block_size, total_size))
+
+ with self.urlretrieve(self.logo, reporthook=recording_reporthook) as (
+ file_location, fileheaders):
+ expected_size = int(fileheaders['Content-Length'])
+
+ records_repr = repr(records) # For use in error messages.
+ self.assertGreater(len(records), 1, msg="There should always be two "
+ "calls; the first one before the transfer starts.")
+ self.assertEqual(records[0][0], 0)
+ self.assertGreater(records[0][1], 0,
+ msg="block size can't be 0 in %s" % records_repr)
+ self.assertEqual(records[0][2], expected_size)
+ self.assertEqual(records[-1][2], expected_size)
+
+ block_sizes = set(block_size for _, block_size, _ in records)
+ self.assertEqual(set([records[0][1]]), block_sizes,
+ msg="block sizes in %s must be equal" % records_repr)
+ self.assertGreaterEqual(records[-1][0]*records[0][1], expected_size,
+ msg="number of blocks * block size must be"
+ " >= total size in %s" % records_repr)
+
+
+def test_main():
+ # support.requires('network')
+ support.run_unittest(URLTimeoutTest,
+ urlopenNetworkTests,
+ urlretrieveNetworkTests)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_urlparse.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_urlparse.py
new file mode 100644
index 0000000..64e8de6
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_urlparse.py
@@ -0,0 +1,860 @@
+#! /usr/bin/env python3
+"""
+Python 3.3 tests for urllib.parse
+"""
+
+from __future__ import unicode_literals
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+from future import standard_library
+
+import future.backports.urllib.parse as urllib_parse
+from future.tests.base import unittest
+
+RFC1808_BASE = "http://a/b/c/d;p?q#f"
+RFC2396_BASE = "http://a/b/c/d;p?q"
+RFC3986_BASE = 'http://a/b/c/d;p?q'
+SIMPLE_BASE = 'http://a/b/c/d'
+
+# A list of test cases. Each test case is a two-tuple that contains
+# a string with the query and a dictionary with the expected result.
+
+parse_qsl_test_cases = [
+ ("", []),
+ ("&", []),
+ ("&&", []),
+ ("=", [('', '')]),
+ ("=a", [('', 'a')]),
+ ("a", [('a', '')]),
+ ("a=", [('a', '')]),
+ ("a=", [('a', '')]),
+ ("&a=b", [('a', 'b')]),
+ ("a=a+b&b=b+c", [('a', 'a b'), ('b', 'b c')]),
+ ("a=1&a=2", [('a', '1'), ('a', '2')]),
+ (b"", []),
+ (b"&", []),
+ (b"&&", []),
+ (b"=", [(b'', b'')]),
+ (b"=a", [(b'', b'a')]),
+ (b"a", [(b'a', b'')]),
+ (b"a=", [(b'a', b'')]),
+ (b"a=", [(b'a', b'')]),
+ (b"&a=b", [(b'a', b'b')]),
+ (b"a=a+b&b=b+c", [(b'a', b'a b'), (b'b', b'b c')]),
+ (b"a=1&a=2", [(b'a', b'1'), (b'a', b'2')]),
+]
+
+class UrlParseTestCase(unittest.TestCase):
+
+ def checkRoundtrips(self, url, parsed, split):
+ result = urllib_parse.urlparse(url)
+ self.assertEqual(result, parsed)
+ t = (result.scheme, result.netloc, result.path,
+ result.params, result.query, result.fragment)
+ self.assertEqual(t, parsed)
+ # put it back together and it should be the same
+ result2 = urllib_parse.urlunparse(result)
+ self.assertEqual(result2, url)
+ self.assertEqual(result2, result.geturl())
+
+ # the result of geturl() is a fixpoint; we can always parse it
+ # again to get the same result:
+ result3 = urllib_parse.urlparse(result.geturl())
+ self.assertEqual(result3.geturl(), result.geturl())
+ self.assertEqual(result3, result)
+ self.assertEqual(result3.scheme, result.scheme)
+ self.assertEqual(result3.netloc, result.netloc)
+ self.assertEqual(result3.path, result.path)
+ self.assertEqual(result3.params, result.params)
+ self.assertEqual(result3.query, result.query)
+ self.assertEqual(result3.fragment, result.fragment)
+ self.assertEqual(result3.username, result.username)
+ self.assertEqual(result3.password, result.password)
+ self.assertEqual(result3.hostname, result.hostname)
+ self.assertEqual(result3.port, result.port)
+
+ # check the roundtrip using urlsplit() as well
+ result = urllib_parse.urlsplit(url)
+ self.assertEqual(result, split)
+ t = (result.scheme, result.netloc, result.path,
+ result.query, result.fragment)
+ self.assertEqual(t, split)
+ result2 = urllib_parse.urlunsplit(result)
+ self.assertEqual(result2, url)
+ self.assertEqual(result2, result.geturl())
+
+ # check the fixpoint property of re-parsing the result of geturl()
+ result3 = urllib_parse.urlsplit(result.geturl())
+ self.assertEqual(result3.geturl(), result.geturl())
+ self.assertEqual(result3, result)
+ self.assertEqual(result3.scheme, result.scheme)
+ self.assertEqual(result3.netloc, result.netloc)
+ self.assertEqual(result3.path, result.path)
+ self.assertEqual(result3.query, result.query)
+ self.assertEqual(result3.fragment, result.fragment)
+ self.assertEqual(result3.username, result.username)
+ self.assertEqual(result3.password, result.password)
+ self.assertEqual(result3.hostname, result.hostname)
+ self.assertEqual(result3.port, result.port)
+
+ def test_qsl(self):
+ for orig, expect in parse_qsl_test_cases:
+ result = urllib_parse.parse_qsl(orig, keep_blank_values=True)
+ self.assertEqual(result, expect, "Error parsing %r" % orig)
+ expect_without_blanks = [v for v in expect if len(v[1])]
+ result = urllib_parse.parse_qsl(orig, keep_blank_values=False)
+ self.assertEqual(result, expect_without_blanks,
+ "Error parsing %r" % orig)
+
+ def test_roundtrips(self):
+ str_cases = [
+ ('file:///tmp/junk.txt',
+ ('file', '', '/tmp/junk.txt', '', '', ''),
+ ('file', '', '/tmp/junk.txt', '', '')),
+ ('imap://mail.python.org/mbox1',
+ ('imap', 'mail.python.org', '/mbox1', '', '', ''),
+ ('imap', 'mail.python.org', '/mbox1', '', '')),
+ ('mms://wms.sys.hinet.net/cts/Drama/09006251100.asf',
+ ('mms', 'wms.sys.hinet.net', '/cts/Drama/09006251100.asf',
+ '', '', ''),
+ ('mms', 'wms.sys.hinet.net', '/cts/Drama/09006251100.asf',
+ '', '')),
+ ('nfs://server/path/to/file.txt',
+ ('nfs', 'server', '/path/to/file.txt', '', '', ''),
+ ('nfs', 'server', '/path/to/file.txt', '', '')),
+ ('svn+ssh://svn.zope.org/repos/main/ZConfig/trunk/',
+ ('svn+ssh', 'svn.zope.org', '/repos/main/ZConfig/trunk/',
+ '', '', ''),
+ ('svn+ssh', 'svn.zope.org', '/repos/main/ZConfig/trunk/',
+ '', '')),
+ ('git+ssh://git@github.com/user/project.git',
+ ('git+ssh', 'git@github.com','/user/project.git',
+ '','',''),
+ ('git+ssh', 'git@github.com','/user/project.git',
+ '', '')),
+ ]
+ def _encode(t):
+ return (t[0].encode('ascii'),
+ tuple(x.encode('ascii') for x in t[1]),
+ tuple(x.encode('ascii') for x in t[2]))
+ bytes_cases = [_encode(x) for x in str_cases]
+ for url, parsed, split in str_cases + bytes_cases:
+ self.checkRoundtrips(url, parsed, split)
+
+ def test_http_roundtrips(self):
+ # urllib_parse.urlsplit treats 'http:' as an optimized special case,
+ # so we test both 'http:' and 'https:' in all the following.
+ # Three cheers for white box knowledge!
+ str_cases = [
+ ('://www.python.org',
+ ('www.python.org', '', '', '', ''),
+ ('www.python.org', '', '', '')),
+ ('://www.python.org#abc',
+ ('www.python.org', '', '', '', 'abc'),
+ ('www.python.org', '', '', 'abc')),
+ ('://www.python.org?q=abc',
+ ('www.python.org', '', '', 'q=abc', ''),
+ ('www.python.org', '', 'q=abc', '')),
+ ('://www.python.org/#abc',
+ ('www.python.org', '/', '', '', 'abc'),
+ ('www.python.org', '/', '', 'abc')),
+ ('://a/b/c/d;p?q#f',
+ ('a', '/b/c/d', 'p', 'q', 'f'),
+ ('a', '/b/c/d;p', 'q', 'f')),
+ ]
+ def _encode(t):
+ return (t[0].encode('ascii'),
+ tuple(x.encode('ascii') for x in t[1]),
+ tuple(x.encode('ascii') for x in t[2]))
+ bytes_cases = [_encode(x) for x in str_cases]
+ str_schemes = ('http', 'https')
+ bytes_schemes = (b'http', b'https')
+ str_tests = str_schemes, str_cases
+ bytes_tests = bytes_schemes, bytes_cases
+ for schemes, test_cases in (str_tests, bytes_tests):
+ for scheme in schemes:
+ for url, parsed, split in test_cases:
+ url = scheme + url
+ parsed = (scheme,) + parsed
+ split = (scheme,) + split
+ self.checkRoundtrips(url, parsed, split)
+
+ def checkJoin(self, base, relurl, expected):
+ str_components = (base, relurl, expected)
+ self.assertEqual(urllib_parse.urljoin(base, relurl), expected)
+ bytes_components = baseb, relurlb, expectedb = [
+ x.encode('ascii') for x in str_components]
+ self.assertEqual(urllib_parse.urljoin(baseb, relurlb), expectedb)
+
+ def test_unparse_parse(self):
+ str_cases = ['Python', './Python','x-newscheme://foo.com/stuff','x://y','x:/y','x:/','/',]
+ bytes_cases = [x.encode('ascii') for x in str_cases]
+ for u in str_cases + bytes_cases:
+ self.assertEqual(urllib_parse.urlunsplit(urllib_parse.urlsplit(u)), u)
+ self.assertEqual(urllib_parse.urlunparse(urllib_parse.urlparse(u)), u)
+
+ def test_RFC1808(self):
+ # "normal" cases from RFC 1808:
+ self.checkJoin(RFC1808_BASE, 'g:h', 'g:h')
+ self.checkJoin(RFC1808_BASE, 'g', 'http://a/b/c/g')
+ self.checkJoin(RFC1808_BASE, './g', 'http://a/b/c/g')
+ self.checkJoin(RFC1808_BASE, 'g/', 'http://a/b/c/g/')
+ self.checkJoin(RFC1808_BASE, '/g', 'http://a/g')
+ self.checkJoin(RFC1808_BASE, '//g', 'http://g')
+ self.checkJoin(RFC1808_BASE, 'g?y', 'http://a/b/c/g?y')
+ self.checkJoin(RFC1808_BASE, 'g?y/./x', 'http://a/b/c/g?y/./x')
+ self.checkJoin(RFC1808_BASE, '#s', 'http://a/b/c/d;p?q#s')
+ self.checkJoin(RFC1808_BASE, 'g#s', 'http://a/b/c/g#s')
+ self.checkJoin(RFC1808_BASE, 'g#s/./x', 'http://a/b/c/g#s/./x')
+ self.checkJoin(RFC1808_BASE, 'g?y#s', 'http://a/b/c/g?y#s')
+ self.checkJoin(RFC1808_BASE, 'g;x', 'http://a/b/c/g;x')
+ self.checkJoin(RFC1808_BASE, 'g;x?y#s', 'http://a/b/c/g;x?y#s')
+ self.checkJoin(RFC1808_BASE, '.', 'http://a/b/c/')
+ self.checkJoin(RFC1808_BASE, './', 'http://a/b/c/')
+ self.checkJoin(RFC1808_BASE, '..', 'http://a/b/')
+ self.checkJoin(RFC1808_BASE, '../', 'http://a/b/')
+ self.checkJoin(RFC1808_BASE, '../g', 'http://a/b/g')
+ self.checkJoin(RFC1808_BASE, '../..', 'http://a/')
+ self.checkJoin(RFC1808_BASE, '../../', 'http://a/')
+ self.checkJoin(RFC1808_BASE, '../../g', 'http://a/g')
+
+ # "abnormal" cases from RFC 1808:
+ self.checkJoin(RFC1808_BASE, '', 'http://a/b/c/d;p?q#f')
+ self.checkJoin(RFC1808_BASE, '../../../g', 'http://a/../g')
+ self.checkJoin(RFC1808_BASE, '../../../../g', 'http://a/../../g')
+ self.checkJoin(RFC1808_BASE, '/./g', 'http://a/./g')
+ self.checkJoin(RFC1808_BASE, '/../g', 'http://a/../g')
+ self.checkJoin(RFC1808_BASE, 'g.', 'http://a/b/c/g.')
+ self.checkJoin(RFC1808_BASE, '.g', 'http://a/b/c/.g')
+ self.checkJoin(RFC1808_BASE, 'g..', 'http://a/b/c/g..')
+ self.checkJoin(RFC1808_BASE, '..g', 'http://a/b/c/..g')
+ self.checkJoin(RFC1808_BASE, './../g', 'http://a/b/g')
+ self.checkJoin(RFC1808_BASE, './g/.', 'http://a/b/c/g/')
+ self.checkJoin(RFC1808_BASE, 'g/./h', 'http://a/b/c/g/h')
+ self.checkJoin(RFC1808_BASE, 'g/../h', 'http://a/b/c/h')
+
+ # RFC 1808 and RFC 1630 disagree on these (according to RFC 1808),
+ # so we'll not actually run these tests (which expect 1808 behavior).
+ #self.checkJoin(RFC1808_BASE, 'http:g', 'http:g')
+ #self.checkJoin(RFC1808_BASE, 'http:', 'http:')
+
+ def test_RFC2368(self):
+ # Issue 11467: path that starts with a number is not parsed correctly
+ self.assertEqual(urllib_parse.urlparse('mailto:1337@example.org'),
+ ('mailto', '', '1337@example.org', '', '', ''))
+
+ def test_RFC2396(self):
+ # cases from RFC 2396
+
+
+ self.checkJoin(RFC2396_BASE, 'g:h', 'g:h')
+ self.checkJoin(RFC2396_BASE, 'g', 'http://a/b/c/g')
+ self.checkJoin(RFC2396_BASE, './g', 'http://a/b/c/g')
+ self.checkJoin(RFC2396_BASE, 'g/', 'http://a/b/c/g/')
+ self.checkJoin(RFC2396_BASE, '/g', 'http://a/g')
+ self.checkJoin(RFC2396_BASE, '//g', 'http://g')
+ self.checkJoin(RFC2396_BASE, 'g?y', 'http://a/b/c/g?y')
+ self.checkJoin(RFC2396_BASE, '#s', 'http://a/b/c/d;p?q#s')
+ self.checkJoin(RFC2396_BASE, 'g#s', 'http://a/b/c/g#s')
+ self.checkJoin(RFC2396_BASE, 'g?y#s', 'http://a/b/c/g?y#s')
+ self.checkJoin(RFC2396_BASE, 'g;x', 'http://a/b/c/g;x')
+ self.checkJoin(RFC2396_BASE, 'g;x?y#s', 'http://a/b/c/g;x?y#s')
+ self.checkJoin(RFC2396_BASE, '.', 'http://a/b/c/')
+ self.checkJoin(RFC2396_BASE, './', 'http://a/b/c/')
+ self.checkJoin(RFC2396_BASE, '..', 'http://a/b/')
+ self.checkJoin(RFC2396_BASE, '../', 'http://a/b/')
+ self.checkJoin(RFC2396_BASE, '../g', 'http://a/b/g')
+ self.checkJoin(RFC2396_BASE, '../..', 'http://a/')
+ self.checkJoin(RFC2396_BASE, '../../', 'http://a/')
+ self.checkJoin(RFC2396_BASE, '../../g', 'http://a/g')
+ self.checkJoin(RFC2396_BASE, '', RFC2396_BASE)
+ self.checkJoin(RFC2396_BASE, '../../../g', 'http://a/../g')
+ self.checkJoin(RFC2396_BASE, '../../../../g', 'http://a/../../g')
+ self.checkJoin(RFC2396_BASE, '/./g', 'http://a/./g')
+ self.checkJoin(RFC2396_BASE, '/../g', 'http://a/../g')
+ self.checkJoin(RFC2396_BASE, 'g.', 'http://a/b/c/g.')
+ self.checkJoin(RFC2396_BASE, '.g', 'http://a/b/c/.g')
+ self.checkJoin(RFC2396_BASE, 'g..', 'http://a/b/c/g..')
+ self.checkJoin(RFC2396_BASE, '..g', 'http://a/b/c/..g')
+ self.checkJoin(RFC2396_BASE, './../g', 'http://a/b/g')
+ self.checkJoin(RFC2396_BASE, './g/.', 'http://a/b/c/g/')
+ self.checkJoin(RFC2396_BASE, 'g/./h', 'http://a/b/c/g/h')
+ self.checkJoin(RFC2396_BASE, 'g/../h', 'http://a/b/c/h')
+ self.checkJoin(RFC2396_BASE, 'g;x=1/./y', 'http://a/b/c/g;x=1/y')
+ self.checkJoin(RFC2396_BASE, 'g;x=1/../y', 'http://a/b/c/y')
+ self.checkJoin(RFC2396_BASE, 'g?y/./x', 'http://a/b/c/g?y/./x')
+ self.checkJoin(RFC2396_BASE, 'g?y/../x', 'http://a/b/c/g?y/../x')
+ self.checkJoin(RFC2396_BASE, 'g#s/./x', 'http://a/b/c/g#s/./x')
+ self.checkJoin(RFC2396_BASE, 'g#s/../x', 'http://a/b/c/g#s/../x')
+
+ def test_RFC3986(self):
+ # Test cases from RFC3986
+ self.checkJoin(RFC3986_BASE, '?y','http://a/b/c/d;p?y')
+ self.checkJoin(RFC2396_BASE, ';x', 'http://a/b/c/;x')
+ self.checkJoin(RFC3986_BASE, 'g:h','g:h')
+ self.checkJoin(RFC3986_BASE, 'g','http://a/b/c/g')
+ self.checkJoin(RFC3986_BASE, './g','http://a/b/c/g')
+ self.checkJoin(RFC3986_BASE, 'g/','http://a/b/c/g/')
+ self.checkJoin(RFC3986_BASE, '/g','http://a/g')
+ self.checkJoin(RFC3986_BASE, '//g','http://g')
+ self.checkJoin(RFC3986_BASE, '?y','http://a/b/c/d;p?y')
+ self.checkJoin(RFC3986_BASE, 'g?y','http://a/b/c/g?y')
+ self.checkJoin(RFC3986_BASE, '#s','http://a/b/c/d;p?q#s')
+ self.checkJoin(RFC3986_BASE, 'g#s','http://a/b/c/g#s')
+ self.checkJoin(RFC3986_BASE, 'g?y#s','http://a/b/c/g?y#s')
+ self.checkJoin(RFC3986_BASE, ';x','http://a/b/c/;x')
+ self.checkJoin(RFC3986_BASE, 'g;x','http://a/b/c/g;x')
+ self.checkJoin(RFC3986_BASE, 'g;x?y#s','http://a/b/c/g;x?y#s')
+ self.checkJoin(RFC3986_BASE, '','http://a/b/c/d;p?q')
+ self.checkJoin(RFC3986_BASE, '.','http://a/b/c/')
+ self.checkJoin(RFC3986_BASE, './','http://a/b/c/')
+ self.checkJoin(RFC3986_BASE, '..','http://a/b/')
+ self.checkJoin(RFC3986_BASE, '../','http://a/b/')
+ self.checkJoin(RFC3986_BASE, '../g','http://a/b/g')
+ self.checkJoin(RFC3986_BASE, '../..','http://a/')
+ self.checkJoin(RFC3986_BASE, '../../','http://a/')
+ self.checkJoin(RFC3986_BASE, '../../g','http://a/g')
+
+ #Abnormal Examples
+
+ # The 'abnormal scenarios' are incompatible with RFC2986 parsing
+ # Tests are here for reference.
+
+ #self.checkJoin(RFC3986_BASE, '../../../g','http://a/g')
+ #self.checkJoin(RFC3986_BASE, '../../../../g','http://a/g')
+ #self.checkJoin(RFC3986_BASE, '/./g','http://a/g')
+ #self.checkJoin(RFC3986_BASE, '/../g','http://a/g')
+
+ self.checkJoin(RFC3986_BASE, 'g.','http://a/b/c/g.')
+ self.checkJoin(RFC3986_BASE, '.g','http://a/b/c/.g')
+ self.checkJoin(RFC3986_BASE, 'g..','http://a/b/c/g..')
+ self.checkJoin(RFC3986_BASE, '..g','http://a/b/c/..g')
+ self.checkJoin(RFC3986_BASE, './../g','http://a/b/g')
+ self.checkJoin(RFC3986_BASE, './g/.','http://a/b/c/g/')
+ self.checkJoin(RFC3986_BASE, 'g/./h','http://a/b/c/g/h')
+ self.checkJoin(RFC3986_BASE, 'g/../h','http://a/b/c/h')
+ self.checkJoin(RFC3986_BASE, 'g;x=1/./y','http://a/b/c/g;x=1/y')
+ self.checkJoin(RFC3986_BASE, 'g;x=1/../y','http://a/b/c/y')
+ self.checkJoin(RFC3986_BASE, 'g?y/./x','http://a/b/c/g?y/./x')
+ self.checkJoin(RFC3986_BASE, 'g?y/../x','http://a/b/c/g?y/../x')
+ self.checkJoin(RFC3986_BASE, 'g#s/./x','http://a/b/c/g#s/./x')
+ self.checkJoin(RFC3986_BASE, 'g#s/../x','http://a/b/c/g#s/../x')
+ #self.checkJoin(RFC3986_BASE, 'http:g','http:g') # strict parser
+ self.checkJoin(RFC3986_BASE, 'http:g','http://a/b/c/g') #relaxed parser
+
+ # Test for issue9721
+ self.checkJoin('http://a/b/c/de', ';x','http://a/b/c/;x')
+
+ def test_urljoins(self):
+ self.checkJoin(SIMPLE_BASE, 'g:h','g:h')
+ self.checkJoin(SIMPLE_BASE, 'http:g','http://a/b/c/g')
+ self.checkJoin(SIMPLE_BASE, 'http:','http://a/b/c/d')
+ self.checkJoin(SIMPLE_BASE, 'g','http://a/b/c/g')
+ self.checkJoin(SIMPLE_BASE, './g','http://a/b/c/g')
+ self.checkJoin(SIMPLE_BASE, 'g/','http://a/b/c/g/')
+ self.checkJoin(SIMPLE_BASE, '/g','http://a/g')
+ self.checkJoin(SIMPLE_BASE, '//g','http://g')
+ self.checkJoin(SIMPLE_BASE, '?y','http://a/b/c/d?y')
+ self.checkJoin(SIMPLE_BASE, 'g?y','http://a/b/c/g?y')
+ self.checkJoin(SIMPLE_BASE, 'g?y/./x','http://a/b/c/g?y/./x')
+ self.checkJoin(SIMPLE_BASE, '.','http://a/b/c/')
+ self.checkJoin(SIMPLE_BASE, './','http://a/b/c/')
+ self.checkJoin(SIMPLE_BASE, '..','http://a/b/')
+ self.checkJoin(SIMPLE_BASE, '../','http://a/b/')
+ self.checkJoin(SIMPLE_BASE, '../g','http://a/b/g')
+ self.checkJoin(SIMPLE_BASE, '../..','http://a/')
+ self.checkJoin(SIMPLE_BASE, '../../g','http://a/g')
+ self.checkJoin(SIMPLE_BASE, '../../../g','http://a/../g')
+ self.checkJoin(SIMPLE_BASE, './../g','http://a/b/g')
+ self.checkJoin(SIMPLE_BASE, './g/.','http://a/b/c/g/')
+ self.checkJoin(SIMPLE_BASE, '/./g','http://a/./g')
+ self.checkJoin(SIMPLE_BASE, 'g/./h','http://a/b/c/g/h')
+ self.checkJoin(SIMPLE_BASE, 'g/../h','http://a/b/c/h')
+ self.checkJoin(SIMPLE_BASE, 'http:g','http://a/b/c/g')
+ self.checkJoin(SIMPLE_BASE, 'http:','http://a/b/c/d')
+ self.checkJoin(SIMPLE_BASE, 'http:?y','http://a/b/c/d?y')
+ self.checkJoin(SIMPLE_BASE, 'http:g?y','http://a/b/c/g?y')
+ self.checkJoin(SIMPLE_BASE, 'http:g?y/./x','http://a/b/c/g?y/./x')
+ self.checkJoin('http:///', '..','http:///')
+ self.checkJoin('', 'http://a/b/c/g?y/./x','http://a/b/c/g?y/./x')
+ self.checkJoin('', 'http://a/./g', 'http://a/./g')
+ self.checkJoin('svn://pathtorepo/dir1', 'dir2', 'svn://pathtorepo/dir2')
+ self.checkJoin('svn+ssh://pathtorepo/dir1', 'dir2', 'svn+ssh://pathtorepo/dir2')
+
+ def test_RFC2732(self):
+ str_cases = [
+ ('http://Test.python.org:5432/foo/', 'test.python.org', 5432),
+ ('http://12.34.56.78:5432/foo/', '12.34.56.78', 5432),
+ ('http://[::1]:5432/foo/', '::1', 5432),
+ ('http://[dead:beef::1]:5432/foo/', 'dead:beef::1', 5432),
+ ('http://[dead:beef::]:5432/foo/', 'dead:beef::', 5432),
+ ('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]:5432/foo/',
+ 'dead:beef:cafe:5417:affe:8fa3:deaf:feed', 5432),
+ ('http://[::12.34.56.78]:5432/foo/', '::12.34.56.78', 5432),
+ ('http://[::ffff:12.34.56.78]:5432/foo/',
+ '::ffff:12.34.56.78', 5432),
+ ('http://Test.python.org/foo/', 'test.python.org', None),
+ ('http://12.34.56.78/foo/', '12.34.56.78', None),
+ ('http://[::1]/foo/', '::1', None),
+ ('http://[dead:beef::1]/foo/', 'dead:beef::1', None),
+ ('http://[dead:beef::]/foo/', 'dead:beef::', None),
+ ('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/',
+ 'dead:beef:cafe:5417:affe:8fa3:deaf:feed', None),
+ ('http://[::12.34.56.78]/foo/', '::12.34.56.78', None),
+ ('http://[::ffff:12.34.56.78]/foo/',
+ '::ffff:12.34.56.78', None),
+ ]
+ def _encode(t):
+ return t[0].encode('ascii'), t[1].encode('ascii'), t[2]
+ bytes_cases = [_encode(x) for x in str_cases]
+ for url, hostname, port in str_cases + bytes_cases:
+ urlparsed = urllib_parse.urlparse(url)
+ self.assertEqual((urlparsed.hostname, urlparsed.port) , (hostname, port))
+
+ str_cases = [
+ 'http://::12.34.56.78]/',
+ 'http://[::1/foo/',
+ 'ftp://[::1/foo/bad]/bad',
+ 'http://[::1/foo/bad]/bad',
+ 'http://[::ffff:12.34.56.78']
+ bytes_cases = [x.encode('ascii') for x in str_cases]
+ for invalid_url in str_cases + bytes_cases:
+ self.assertRaises(ValueError, urllib_parse.urlparse, invalid_url)
+
+ def test_urldefrag(self):
+ str_cases = [
+ ('http://python.org#frag', 'http://python.org', 'frag'),
+ ('http://python.org', 'http://python.org', ''),
+ ('http://python.org/#frag', 'http://python.org/', 'frag'),
+ ('http://python.org/', 'http://python.org/', ''),
+ ('http://python.org/?q#frag', 'http://python.org/?q', 'frag'),
+ ('http://python.org/?q', 'http://python.org/?q', ''),
+ ('http://python.org/p#frag', 'http://python.org/p', 'frag'),
+ ('http://python.org/p?q', 'http://python.org/p?q', ''),
+ (RFC1808_BASE, 'http://a/b/c/d;p?q', 'f'),
+ (RFC2396_BASE, 'http://a/b/c/d;p?q', ''),
+ ]
+ def _encode(t):
+ return type(t)(x.encode('ascii') for x in t)
+ bytes_cases = [_encode(x) for x in str_cases]
+ for url, defrag, frag in str_cases + bytes_cases:
+ result = urllib_parse.urldefrag(url)
+ self.assertEqual(result.geturl(), url)
+ self.assertEqual(result, (defrag, frag))
+ self.assertEqual(result.url, defrag)
+ self.assertEqual(result.fragment, frag)
+
+ def test_urlsplit_attributes(self):
+ url = "HTTP://WWW.PYTHON.ORG/doc/#frag"
+ p = urllib_parse.urlsplit(url)
+ self.assertEqual(p.scheme, "http")
+ self.assertEqual(p.netloc, "WWW.PYTHON.ORG")
+ self.assertEqual(p.path, "/doc/")
+ self.assertEqual(p.query, "")
+ self.assertEqual(p.fragment, "frag")
+ self.assertEqual(p.username, None)
+ self.assertEqual(p.password, None)
+ self.assertEqual(p.hostname, "www.python.org")
+ self.assertEqual(p.port, None)
+ # geturl() won't return exactly the original URL in this case
+ # since the scheme is always case-normalized
+ # We handle this by ignoring the first 4 characters of the URL
+ self.assertEqual(p.geturl()[4:], url[4:])
+
+ url = "http://User:Pass@www.python.org:080/doc/?query=yes#frag"
+ p = urllib_parse.urlsplit(url)
+ self.assertEqual(p.scheme, "http")
+ self.assertEqual(p.netloc, "User:Pass@www.python.org:080")
+ self.assertEqual(p.path, "/doc/")
+ self.assertEqual(p.query, "query=yes")
+ self.assertEqual(p.fragment, "frag")
+ self.assertEqual(p.username, "User")
+ self.assertEqual(p.password, "Pass")
+ self.assertEqual(p.hostname, "www.python.org")
+ self.assertEqual(p.port, 80)
+ self.assertEqual(p.geturl(), url)
+
+ # Addressing issue1698, which suggests Username can contain
+ # "@" characters. Though not RFC compliant, many ftp sites allow
+ # and request email addresses as usernames.
+
+ url = "http://User@example.com:Pass@www.python.org:080/doc/?query=yes#frag"
+ p = urllib_parse.urlsplit(url)
+ self.assertEqual(p.scheme, "http")
+ self.assertEqual(p.netloc, "User@example.com:Pass@www.python.org:080")
+ self.assertEqual(p.path, "/doc/")
+ self.assertEqual(p.query, "query=yes")
+ self.assertEqual(p.fragment, "frag")
+ self.assertEqual(p.username, "User@example.com")
+ self.assertEqual(p.password, "Pass")
+ self.assertEqual(p.hostname, "www.python.org")
+ self.assertEqual(p.port, 80)
+ self.assertEqual(p.geturl(), url)
+
+ # And check them all again, only with bytes this time
+ url = b"HTTP://WWW.PYTHON.ORG/doc/#frag"
+ p = urllib_parse.urlsplit(url)
+ self.assertEqual(p.scheme, b"http")
+ self.assertEqual(p.netloc, b"WWW.PYTHON.ORG")
+ self.assertEqual(p.path, b"/doc/")
+ self.assertEqual(p.query, b"")
+ self.assertEqual(p.fragment, b"frag")
+ self.assertEqual(p.username, None)
+ self.assertEqual(p.password, None)
+ self.assertEqual(p.hostname, b"www.python.org")
+ self.assertEqual(p.port, None)
+ self.assertEqual(p.geturl()[4:], url[4:])
+
+ url = b"http://User:Pass@www.python.org:080/doc/?query=yes#frag"
+ p = urllib_parse.urlsplit(url)
+ self.assertEqual(p.scheme, b"http")
+ self.assertEqual(p.netloc, b"User:Pass@www.python.org:080")
+ self.assertEqual(p.path, b"/doc/")
+ self.assertEqual(p.query, b"query=yes")
+ self.assertEqual(p.fragment, b"frag")
+ self.assertEqual(p.username, b"User")
+ self.assertEqual(p.password, b"Pass")
+ self.assertEqual(p.hostname, b"www.python.org")
+ self.assertEqual(p.port, 80)
+ self.assertEqual(p.geturl(), url)
+
+ url = b"http://User@example.com:Pass@www.python.org:080/doc/?query=yes#frag"
+ p = urllib_parse.urlsplit(url)
+ self.assertEqual(p.scheme, b"http")
+ self.assertEqual(p.netloc, b"User@example.com:Pass@www.python.org:080")
+ self.assertEqual(p.path, b"/doc/")
+ self.assertEqual(p.query, b"query=yes")
+ self.assertEqual(p.fragment, b"frag")
+ self.assertEqual(p.username, b"User@example.com")
+ self.assertEqual(p.password, b"Pass")
+ self.assertEqual(p.hostname, b"www.python.org")
+ self.assertEqual(p.port, 80)
+ self.assertEqual(p.geturl(), url)
+
+ # Verify an illegal port is returned as None
+ url = b"HTTP://WWW.PYTHON.ORG:65536/doc/#frag"
+ p = urllib_parse.urlsplit(url)
+ self.assertEqual(p.port, None)
+
+ def test_attributes_bad_port(self):
+ """Check handling of non-integer ports."""
+ p = urllib_parse.urlsplit("http://www.example.net:foo")
+ self.assertEqual(p.netloc, "www.example.net:foo")
+ self.assertRaises(ValueError, lambda: p.port)
+
+ p = urllib_parse.urlparse("http://www.example.net:foo")
+ self.assertEqual(p.netloc, "www.example.net:foo")
+ self.assertRaises(ValueError, lambda: p.port)
+
+ # Once again, repeat ourselves to test bytes
+ p = urllib_parse.urlsplit(b"http://www.example.net:foo")
+ self.assertEqual(p.netloc, b"www.example.net:foo")
+ self.assertRaises(ValueError, lambda: p.port)
+
+ p = urllib_parse.urlparse(b"http://www.example.net:foo")
+ self.assertEqual(p.netloc, b"www.example.net:foo")
+ self.assertRaises(ValueError, lambda: p.port)
+
+ def test_attributes_without_netloc(self):
+ # This example is straight from RFC 3261. It looks like it
+ # should allow the username, hostname, and port to be filled
+ # in, but doesn't. Since it's a URI and doesn't use the
+ # scheme://netloc syntax, the netloc and related attributes
+ # should be left empty.
+ uri = "sip:alice@atlanta.com;maddr=239.255.255.1;ttl=15"
+ p = urllib_parse.urlsplit(uri)
+ self.assertEqual(p.netloc, "")
+ self.assertEqual(p.username, None)
+ self.assertEqual(p.password, None)
+ self.assertEqual(p.hostname, None)
+ self.assertEqual(p.port, None)
+ self.assertEqual(p.geturl(), uri)
+
+ p = urllib_parse.urlparse(uri)
+ self.assertEqual(p.netloc, "")
+ self.assertEqual(p.username, None)
+ self.assertEqual(p.password, None)
+ self.assertEqual(p.hostname, None)
+ self.assertEqual(p.port, None)
+ self.assertEqual(p.geturl(), uri)
+
+ # You guessed it, repeating the test with bytes input
+ uri = b"sip:alice@atlanta.com;maddr=239.255.255.1;ttl=15"
+ p = urllib_parse.urlsplit(uri)
+ self.assertEqual(p.netloc, b"")
+ self.assertEqual(p.username, None)
+ self.assertEqual(p.password, None)
+ self.assertEqual(p.hostname, None)
+ self.assertEqual(p.port, None)
+ self.assertEqual(p.geturl(), uri)
+
+ p = urllib_parse.urlparse(uri)
+ self.assertEqual(p.netloc, b"")
+ self.assertEqual(p.username, None)
+ self.assertEqual(p.password, None)
+ self.assertEqual(p.hostname, None)
+ self.assertEqual(p.port, None)
+ self.assertEqual(p.geturl(), uri)
+
+ def test_noslash(self):
+ # Issue 1637: http://foo.com?query is legal
+ self.assertEqual(urllib_parse.urlparse("http://example.com?blahblah=/foo"),
+ ('http', 'example.com', '', '', 'blahblah=/foo', ''))
+ self.assertEqual(urllib_parse.urlparse(b"http://example.com?blahblah=/foo"),
+ (b'http', b'example.com', b'', b'', b'blahblah=/foo', b''))
+
+ def test_withoutscheme(self):
+ # Test urlparse without scheme
+ # Issue 754016: urlparse goes wrong with IP:port without scheme
+ # RFC 1808 specifies that netloc should start with //, urlparse expects
+ # the same, otherwise it classifies the portion of url as path.
+ self.assertEqual(urllib_parse.urlparse("path"),
+ ('','','path','','',''))
+ self.assertEqual(urllib_parse.urlparse("//www.python.org:80"),
+ ('','www.python.org:80','','','',''))
+ self.assertEqual(urllib_parse.urlparse("http://www.python.org:80"),
+ ('http','www.python.org:80','','','',''))
+ # Repeat for bytes input
+ self.assertEqual(urllib_parse.urlparse(b"path"),
+ (b'',b'',b'path',b'',b'',b''))
+ self.assertEqual(urllib_parse.urlparse(b"//www.python.org:80"),
+ (b'',b'www.python.org:80',b'',b'',b'',b''))
+ self.assertEqual(urllib_parse.urlparse(b"http://www.python.org:80"),
+ (b'http',b'www.python.org:80',b'',b'',b'',b''))
+
+ def test_portseparator(self):
+ # Issue 754016 makes changes for port separator ':' from scheme separator
+ self.assertEqual(urllib_parse.urlparse("path:80"),
+ ('','','path:80','','',''))
+ self.assertEqual(urllib_parse.urlparse("http:"),('http','','','','',''))
+ self.assertEqual(urllib_parse.urlparse("https:"),('https','','','','',''))
+ self.assertEqual(urllib_parse.urlparse("http://www.python.org:80"),
+ ('http','www.python.org:80','','','',''))
+ # As usual, need to check bytes input as well
+ self.assertEqual(urllib_parse.urlparse(b"path:80"),
+ (b'',b'',b'path:80',b'',b'',b''))
+ self.assertEqual(urllib_parse.urlparse(b"http:"),(b'http',b'',b'',b'',b'',b''))
+ self.assertEqual(urllib_parse.urlparse(b"https:"),(b'https',b'',b'',b'',b'',b''))
+ self.assertEqual(urllib_parse.urlparse(b"http://www.python.org:80"),
+ (b'http',b'www.python.org:80',b'',b'',b'',b''))
+
+ def test_usingsys(self):
+ # Issue 3314: sys module is used in the error
+ self.assertRaises(TypeError, urllib_parse.urlencode, "foo")
+
+ def test_anyscheme(self):
+ # Issue 7904: s3://foo.com/stuff has netloc "foo.com".
+ self.assertEqual(urllib_parse.urlparse("s3://foo.com/stuff"),
+ ('s3', 'foo.com', '/stuff', '', '', ''))
+ self.assertEqual(urllib_parse.urlparse("x-newscheme://foo.com/stuff"),
+ ('x-newscheme', 'foo.com', '/stuff', '', '', ''))
+ self.assertEqual(urllib_parse.urlparse("x-newscheme://foo.com/stuff?query#fragment"),
+ ('x-newscheme', 'foo.com', '/stuff', '', 'query', 'fragment'))
+ self.assertEqual(urllib_parse.urlparse("x-newscheme://foo.com/stuff?query"),
+ ('x-newscheme', 'foo.com', '/stuff', '', 'query', ''))
+
+ # And for bytes...
+ self.assertEqual(urllib_parse.urlparse(b"s3://foo.com/stuff"),
+ (b's3', b'foo.com', b'/stuff', b'', b'', b''))
+ self.assertEqual(urllib_parse.urlparse(b"x-newscheme://foo.com/stuff"),
+ (b'x-newscheme', b'foo.com', b'/stuff', b'', b'', b''))
+ self.assertEqual(urllib_parse.urlparse(b"x-newscheme://foo.com/stuff?query#fragment"),
+ (b'x-newscheme', b'foo.com', b'/stuff', b'', b'query', b'fragment'))
+ self.assertEqual(urllib_parse.urlparse(b"x-newscheme://foo.com/stuff?query"),
+ (b'x-newscheme', b'foo.com', b'/stuff', b'', b'query', b''))
+
+ def test_mixed_types_rejected(self):
+ # Several functions that process either strings or ASCII encoded bytes
+ # accept multiple arguments. Check they reject mixed type input
+ with self.assertRaisesRegex(TypeError, "Cannot mix str"):
+ urllib_parse.urlparse("www.python.org", b"http")
+ with self.assertRaisesRegex(TypeError, "Cannot mix str"):
+ urllib_parse.urlparse(b"www.python.org", "http")
+ with self.assertRaisesRegex(TypeError, "Cannot mix str"):
+ urllib_parse.urlsplit("www.python.org", b"http")
+ with self.assertRaisesRegex(TypeError, "Cannot mix str"):
+ urllib_parse.urlsplit(b"www.python.org", "http")
+ with self.assertRaisesRegex(TypeError, "Cannot mix str"):
+ urllib_parse.urlunparse(( b"http", "www.python.org","","","",""))
+ with self.assertRaisesRegex(TypeError, "Cannot mix str"):
+ urllib_parse.urlunparse(("http", b"www.python.org","","","",""))
+ with self.assertRaisesRegex(TypeError, "Cannot mix str"):
+ urllib_parse.urlunsplit((b"http", "www.python.org","","",""))
+ with self.assertRaisesRegex(TypeError, "Cannot mix str"):
+ urllib_parse.urlunsplit(("http", b"www.python.org","","",""))
+ with self.assertRaisesRegex(TypeError, "Cannot mix str"):
+ urllib_parse.urljoin("http://python.org", b"http://python.org")
+ with self.assertRaisesRegex(TypeError, "Cannot mix str"):
+ urllib_parse.urljoin(b"http://python.org", "http://python.org")
+
+ def _check_result_type(self, str_type):
+ num_args = len(str_type._fields)
+ bytes_type = str_type._encoded_counterpart
+ self.assertIs(bytes_type._decoded_counterpart, str_type)
+ str_args = ('',) * num_args
+ bytes_args = (b'',) * num_args
+ str_result = str_type(*str_args)
+ bytes_result = bytes_type(*bytes_args)
+ encoding = 'ascii'
+ errors = 'strict'
+ self.assertEqual(str_result, str_args)
+ self.assertEqual(bytes_result.decode(), str_args)
+ self.assertEqual(bytes_result.decode(), str_result)
+ self.assertEqual(bytes_result.decode(encoding), str_args)
+ self.assertEqual(bytes_result.decode(encoding), str_result)
+ self.assertEqual(bytes_result.decode(encoding, errors), str_args)
+ self.assertEqual(bytes_result.decode(encoding, errors), str_result)
+ self.assertEqual(bytes_result, bytes_args)
+ self.assertEqual(str_result.encode(), bytes_args)
+ self.assertEqual(str_result.encode(), bytes_result)
+ self.assertEqual(str_result.encode(encoding), bytes_args)
+ self.assertEqual(str_result.encode(encoding), bytes_result)
+ self.assertEqual(str_result.encode(encoding, errors), bytes_args)
+ self.assertEqual(str_result.encode(encoding, errors), bytes_result)
+
+ def test_result_pairs(self):
+ # Check encoding and decoding between result pairs
+ result_types = [
+ urllib_parse.DefragResult,
+ urllib_parse.SplitResult,
+ urllib_parse.ParseResult,
+ ]
+ for result_type in result_types:
+ self._check_result_type(result_type)
+
+ def test_parse_qs_encoding(self):
+ result = urllib_parse.parse_qs("key=\u0141%E9", encoding="latin-1")
+ self.assertEqual(result, {'key': ['\u0141\xE9']})
+ result = urllib_parse.parse_qs("key=\u0141%C3%A9", encoding="utf-8")
+ self.assertEqual(result, {'key': ['\u0141\xE9']})
+ result = urllib_parse.parse_qs("key=\u0141%C3%A9", encoding="ascii")
+ self.assertEqual(result, {'key': ['\u0141\ufffd\ufffd']})
+ result = urllib_parse.parse_qs("key=\u0141%E9-", encoding="ascii")
+ self.assertEqual(result, {'key': ['\u0141\ufffd-']})
+ result = urllib_parse.parse_qs("key=\u0141%E9-", encoding="ascii",
+ errors="ignore")
+ self.assertEqual(result, {'key': ['\u0141-']})
+
+ def test_parse_qsl_encoding(self):
+ result = urllib_parse.parse_qsl("key=\u0141%E9", encoding="latin-1")
+ self.assertEqual(result, [('key', '\u0141\xE9')])
+ result = urllib_parse.parse_qsl("key=\u0141%C3%A9", encoding="utf-8")
+ self.assertEqual(result, [('key', '\u0141\xE9')])
+ result = urllib_parse.parse_qsl("key=\u0141%C3%A9", encoding="ascii")
+ self.assertEqual(result, [('key', '\u0141\ufffd\ufffd')])
+ result = urllib_parse.parse_qsl("key=\u0141%E9-", encoding="ascii")
+ self.assertEqual(result, [('key', '\u0141\ufffd-')])
+ result = urllib_parse.parse_qsl("key=\u0141%E9-", encoding="ascii",
+ errors="ignore")
+ self.assertEqual(result, [('key', '\u0141-')])
+
+ def test_splitnport(self):
+ # Normal cases are exercised by other tests; ensure that we also
+ # catch cases with no port specified. (testcase ensuring coverage)
+ result = urllib_parse.splitnport('parrot:88')
+ self.assertEqual(result, ('parrot', 88))
+ result = urllib_parse.splitnport('parrot')
+ self.assertEqual(result, ('parrot', -1))
+ result = urllib_parse.splitnport('parrot', 55)
+ self.assertEqual(result, ('parrot', 55))
+ result = urllib_parse.splitnport('parrot:')
+ self.assertEqual(result, ('parrot', None))
+
+ def test_splitquery(self):
+ # Normal cases are exercised by other tests; ensure that we also
+ # catch cases with no port specified (testcase ensuring coverage)
+ result = urllib_parse.splitquery('http://python.org/fake?foo=bar')
+ self.assertEqual(result, ('http://python.org/fake', 'foo=bar'))
+ result = urllib_parse.splitquery('http://python.org/fake?foo=bar?')
+ self.assertEqual(result, ('http://python.org/fake?foo=bar', ''))
+ result = urllib_parse.splitquery('http://python.org/fake')
+ self.assertEqual(result, ('http://python.org/fake', None))
+
+ def test_splitvalue(self):
+ # Normal cases are exercised by other tests; test pathological cases
+ # with no key/value pairs. (testcase ensuring coverage)
+ result = urllib_parse.splitvalue('foo=bar')
+ self.assertEqual(result, ('foo', 'bar'))
+ result = urllib_parse.splitvalue('foo=')
+ self.assertEqual(result, ('foo', ''))
+ result = urllib_parse.splitvalue('foobar')
+ self.assertEqual(result, ('foobar', None))
+
+ def test_to_bytes(self):
+ result = urllib_parse.to_bytes('http://www.python.org')
+ self.assertEqual(result, 'http://www.python.org')
+ self.assertRaises(UnicodeError, urllib_parse.to_bytes,
+ 'http://www.python.org/medi\u00e6val')
+
+ def test_urlencode_sequences(self):
+ # Other tests incidentally urlencode things; test non-covered cases:
+ # Sequence and object values.
+ result = urllib_parse.urlencode({'a': [1, 2], 'b': (3, 4, 5)}, True)
+ # we cannot rely on ordering here
+ assert set(result.split('&')) == set(['a=1', 'a=2', 'b=3', 'b=4', 'b=5'])
+
+ class Trivial(object):
+ def __str__(self):
+ return 'trivial'
+
+ result = urllib_parse.urlencode({'a': Trivial()}, True)
+ self.assertEqual(result, 'a=trivial')
+
+ def test_quote_from_bytes(self):
+ self.assertRaises(TypeError, urllib_parse.quote_from_bytes, 'foo')
+ result = urllib_parse.quote_from_bytes(b'archaeological arcana')
+ self.assertEqual(result, 'archaeological%20arcana')
+ result = urllib_parse.quote_from_bytes(b'')
+ self.assertEqual(result, '')
+
+ def test_unquote_to_bytes(self):
+ result = urllib_parse.unquote_to_bytes('abc%20def')
+ self.assertEqual(result, b'abc def')
+ result = urllib_parse.unquote_to_bytes('')
+ self.assertEqual(result, b'')
+
+ def test_quote_errors(self):
+ self.assertRaises(TypeError, urllib_parse.quote, b'foo',
+ encoding='utf-8')
+ self.assertRaises(TypeError, urllib_parse.quote, b'foo', errors='strict')
+
+ def test_issue14072(self):
+ p1 = urllib_parse.urlsplit('tel:+31-641044153')
+ self.assertEqual(p1.scheme, 'tel')
+ self.assertEqual(p1.path, '+31-641044153')
+ p2 = urllib_parse.urlsplit('tel:+31641044153')
+ self.assertEqual(p2.scheme, 'tel')
+ self.assertEqual(p2.path, '+31641044153')
+ # assert the behavior for urlparse
+ p1 = urllib_parse.urlparse('tel:+31-641044153')
+ self.assertEqual(p1.scheme, 'tel')
+ self.assertEqual(p1.path, '+31-641044153')
+ p2 = urllib_parse.urlparse('tel:+31641044153')
+ self.assertEqual(p2.scheme, 'tel')
+ self.assertEqual(p2.path, '+31641044153')
+
+ def test_telurl_params(self):
+ p1 = urllib_parse.urlparse('tel:123-4;phone-context=+1-650-516')
+ self.assertEqual(p1.scheme, 'tel')
+ self.assertEqual(p1.path, '123-4')
+ self.assertEqual(p1.params, 'phone-context=+1-650-516')
+
+ p1 = urllib_parse.urlparse('tel:+1-201-555-0123')
+ self.assertEqual(p1.scheme, 'tel')
+ self.assertEqual(p1.path, '+1-201-555-0123')
+ self.assertEqual(p1.params, '')
+
+ p1 = urllib_parse.urlparse('tel:7042;phone-context=example.com')
+ self.assertEqual(p1.scheme, 'tel')
+ self.assertEqual(p1.path, '7042')
+ self.assertEqual(p1.params, 'phone-context=example.com')
+
+ p1 = urllib_parse.urlparse('tel:863-1234;phone-context=+1-914-555')
+ self.assertEqual(p1.scheme, 'tel')
+ self.assertEqual(p1.path, '863-1234')
+ self.assertEqual(p1.params, 'phone-context=+1-914-555')
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/Python/Dependencies/future-0.18.2/tests/test_future/test_utils.py b/Python/Dependencies/future-0.18.2/tests/test_future/test_utils.py
new file mode 100644
index 0000000..46f5196
--- /dev/null
+++ b/Python/Dependencies/future-0.18.2/tests/test_future/test_utils.py
@@ -0,0 +1,406 @@
+# -*- coding: utf-8 -*-
+"""
+Tests for the various utility functions and classes in ``future.utils``
+"""
+
+from __future__ import absolute_import, unicode_literals, print_function
+import re, sys, traceback
+from future.builtins import *
+from future.utils import (old_div, istext, isbytes, native, PY2, PY3,
+ native_str, raise_, as_native_str, ensure_new_type,
+ bytes_to_native_str, raise_from)
+from future.tests.base import expectedFailurePY3
+
+from numbers import Integral
+from future.tests.base import unittest, skip26
+
+
+TEST_UNICODE_STR = u'ℝεα∂@ßʟ℮ ☂ℯṧт υηḯ¢☺ḓ℮'
+
+
+class MyExceptionIssue235(Exception):
+ def __init__(self, a, b):
+ super(MyExceptionIssue235, self).__init__('{0}: {1}'.format(a, b))
+
+
+class TestUtils(unittest.TestCase):
+ def setUp(self):
+ self.s = TEST_UNICODE_STR
+ self.s2 = str(self.s)
+ self.b = b'ABCDEFG'
+ self.b2 = bytes(self.b)
+
+ def test_old_div(self):
+ """
+ Tests whether old_div(a, b) is always equal to Python 2's a / b.
+ """
+ self.assertEqual(old_div(1, 2), 0)
+ self.assertEqual(old_div(2, 2), 1)
+ self.assertTrue(isinstance(old_div(2, 2), int))
+
+ self.assertEqual(old_div(3, 2), 1)
+ self.assertTrue(isinstance(old_div(3, 2), int))
+
+ self.assertEqual(old_div(3., 2), 1.5)
+ self.assertTrue(not isinstance(old_div(3., 2), int))
+
+ self.assertEqual(old_div(-1, 2.), -0.5)
+ self.assertTrue(not isinstance(old_div(-1, 2.), int))
+
+ with self.assertRaises(ZeroDivisionError):
+ old_div(0, 0)
+ with self.assertRaises(ZeroDivisionError):
+ old_div(1, 0)
+
+ def test_native_str(self):
+ """
+ Tests whether native_str is really equal to the platform str.
+ """
+ if PY2:
+ import __builtin__
+ builtin_str = __builtin__.str
+ else:
+ import builtins
+ builtin_str = builtins.str
+
+ inputs = [b'blah', u'blah', 'blah']
+ for s in inputs:
+ self.assertEqual(native_str(s), builtin_str(s))
+ self.assertTrue(isinstance(native_str(s), builtin_str))
+
+ def test_native(self):
+ a = int(10**20) # long int
+ b = native(a)
+ self.assertEqual(a, b)
+ if PY2:
+ self.assertEqual(type(b), long)
+ else:
+ self.assertEqual(type(b), int)
+
+ c = bytes(b'ABC')
+ d = native(c)
+ self.assertEqual(c, d)
+ if PY2:
+ self.assertEqual(type(d), type(b'Py2 byte-string'))
+ else:
+ self.assertEqual(type(d), bytes)
+
+ s = str(u'ABC')
+ t = native(s)
+ self.assertEqual(s, t)
+ if PY2:
+ self.assertEqual(type(t), unicode)
+ else:
+ self.assertEqual(type(t), str)
+
+ d1 = dict({'a': 1, 'b': 2})
+ d2 = native(d1)
+ self.assertEqual(d1, d2)
+ self.assertEqual(type(d2), type({}))
+
+ def test_istext(self):
+ self.assertTrue(istext(self.s))
+ self.assertTrue(istext(self.s2))
+ self.assertFalse(istext(self.b))
+ self.assertFalse(istext(self.b2))
+
+ def test_isbytes(self):
+ self.assertTrue(isbytes(self.b))
+ self.assertTrue(isbytes(self.b2))
+ self.assertFalse(isbytes(self.s))
+ self.assertFalse(isbytes(self.s2))
+
+ def test_raise_(self):
+ def valuerror():
+ try:
+ raise ValueError("Apples!")
+ except Exception as e:
+ raise_(e)
+
+ self.assertRaises(ValueError, valuerror)
+
+ def with_value():
+ raise_(IOError, "This is an error")
+
+ self.assertRaises(IOError, with_value)
+
+ try:
+ with_value()
+ except IOError as e:
+ self.assertEqual(str(e), "This is an error")
+
+ def with_traceback():
+ try:
+ raise ValueError("An error")
+ except Exception as e:
+ _, _, traceback = sys.exc_info()
+ raise_(IOError, str(e), traceback)
+
+ self.assertRaises(IOError, with_traceback)
+
+ try:
+ with_traceback()
+ except IOError as e:
+ self.assertEqual(str(e), "An error")
+
+ class Timeout(BaseException):
+ pass
+
+ self.assertRaises(Timeout, raise_, Timeout)
+ self.assertRaises(Timeout, raise_, Timeout())
+
+ if PY3:
+ self.assertRaisesRegexp(
+ TypeError, "class must derive from BaseException",
+ raise_, int)
+
+ def test_raise_from_None(self):
+ try:
+ try:
+ raise TypeError("foo")
+ except:
+ raise_from(ValueError(), None)
+ except ValueError as e:
+ self.assertTrue(isinstance(e.__context__, TypeError))
+ self.assertIsNone(e.__cause__)
+
+ def test_issue_235(self):
+ def foo():
+ raise MyExceptionIssue235(3, 7)
+
+ def bar():
+ try:
+ foo()
+ except Exception as err:
+ raise_from(ValueError('blue'), err)
+
+ try:
+ bar()
+ except ValueError as e:
+ pass
+ # incorrectly raises a TypeError on Py3 as of v0.15.2.
+
+ def test_raise_custom_exception(self):
+ """
+ Test issue #387.
+ """
+ class CustomException(Exception):
+ def __init__(self, severity, message):
+ super().__init__("custom message of severity %d: %s" % (
+ severity, message))
+
+ def raise_custom_exception():
+ try:
+ raise CustomException(1, "hello")
+ except CustomException:
+ raise_(*sys.exc_info())
+
+ self.assertRaises(CustomException, raise_custom_exception)
+
+ @skip26
+ def test_as_native_str(self):
+ """
+ Tests the decorator as_native_str()
+ """
+ class MyClass(object):
+ @as_native_str()
+ def __repr__(self):
+ return u'abc'
+
+ obj = MyClass()
+
+ self.assertEqual(repr(obj), 'abc')
+ if PY2:
+ self.assertEqual(repr(obj), b'abc')
+ else:
+ self.assertEqual(repr(obj), u'abc')
+
+ def test_ensure_new_type(self):
+ s = u'abcd'
+ s2 = str(s)
+ self.assertEqual(ensure_new_type(s), s2)
+ self.assertEqual(type(ensure_new_type(s)), str)
+
+ b = b'xyz'
+ b2 = bytes(b)
+ self.assertEqual(ensure_new_type(b), b2)
+ self.assertEqual(type(ensure_new_type(b)), bytes)
+
+ i = 10000000000000
+ i2 = int(i)
+ self.assertEqual(ensure_new_type(i), i2)
+ self.assertEqual(type(ensure_new_type(i)), int)
+
+ l = []
+ self.assertIs(ensure_new_type(l), l)
+
+ def test_bytes_to_native_str(self):
+ """
+ Test for issue #47
+ """
+ b = bytes(b'abc')
+ s = bytes_to_native_str(b)
+ if PY2:
+ self.assertEqual(s, b)
+ else:
+ self.assertEqual(s, 'abc')
+ self.assertTrue(isinstance(s, native_str))
+ self.assertEqual(type(s), native_str)
+
+
+class TestCause(unittest.TestCase):
+ """
+ Except for the first method, these were adapted from Py3.3's
+ Lib/test/test_raise.py.
+ """
+ def test_normal_use(self):
+ """
+ Adapted from PEP 3134 docs
+ """
+ # Setup:
+ class DatabaseError(Exception):
+ pass
+
+ # Python 2 and 3:
+ from future.utils import raise_from
+
+ class FileDatabase:
+ def __init__(self, filename):
+ try:
+ self.file = open(filename)
+ except IOError as exc:
+ raise_from(DatabaseError('failed to open'), exc)
+
+ # Testing the above:
+ try:
+ fd = FileDatabase('non_existent_file.txt')
+ except Exception as e:
+ assert isinstance(e.__cause__, IOError) # FileNotFoundError on
+ # Py3.3+ inherits from IOError
+
+ def testCauseSyntax(self):
+ try:
+ try:
+ try:
+ raise TypeError
+ except Exception:
+ raise_from(ValueError, None)
+ except ValueError as exc:
+ self.assertIsNone(exc.__cause__)
+ self.assertTrue(exc.__suppress_context__)
+ exc.__suppress_context__ = False
+ raise exc
+ except ValueError as exc:
+ e = exc
+
+ self.assertIsNone(e.__cause__)
+ self.assertFalse(e.__suppress_context__)
+ self.assertIsInstance(e.__context__, TypeError)
+
+ def test_invalid_cause(self):
+ try:
+ raise_from(IndexError, 5)
+ except TypeError as e:
+ self.assertIn("exception cause", str(e))
+ else:
+ self.fail("No exception raised")
+
+ def test_class_cause(self):
+ try:
+ raise_from(IndexError, KeyError)
+ except IndexError as e:
+ self.assertIsInstance(e.__cause__, KeyError)
+ else:
+ self.fail("No exception raised")
+
+ def test_instance_cause(self):
+ cause = KeyError('blah')
+ try:
+ raise_from(IndexError, cause)
+ except IndexError as e:
+ # FAILS:
+ self.assertTrue(e.__cause__ is cause)
+ # Even this weaker version seems to fail, although repr(cause) looks correct.
+ # Is there something strange about testing exceptions for equality?
+ self.assertEqual(e.__cause__, cause)
+ else:
+ self.fail("No exception raised")
+
+ def test_erroneous_cause(self):
+ class MyException(Exception):
+ def __init__(self):
+ raise RuntimeError()
+
+ try:
+ raise_from(IndexError, MyException)
+ except RuntimeError:
+ pass
+ else:
+ self.fail("No exception raised")
+
+ def test_single_exception_stacktrace(self):
+ expected = '''Traceback (most recent call last):
+ File "/opt/python-future/tests/test_future/test_utils.py", line 328, in test_single_exception_stacktrace
+ raise CustomException('ERROR')
+'''
+ if PY2:
+ expected += 'CustomException: ERROR\n'
+ else:
+ expected += 'test_future.test_utils.CustomException: ERROR\n'
+
+ try:
+ raise CustomException('ERROR')
+ except:
+ ret = re.sub(r'"[^"]*tests/test_future', '"/opt/python-future/tests/test_future', traceback.format_exc())
+ ret = re.sub(r', line \d+,', ', line 328,', ret)
+ self.assertEqual(expected, ret)
+ else:
+ self.fail('No exception raised')
+
+ if PY2:
+ def test_chained_exceptions_stacktrace(self):
+ expected = '''Traceback (most recent call last):
+ File "/opt/python-future/tests/test_future/test_utils.py", line 1, in test_chained_exceptions_stacktrace
+ raise_from(CustomException('ERROR'), val_err)
+ File "/opt/python-future/src/future/utils/__init__.py", line 1, in raise_from
+ raise e
+CustomException: ERROR
+
+The above exception was the direct cause of the following exception:
+
+ File "/opt/python-future/tests/test_future/test_utils.py", line 1, in test_chained_exceptions_stacktrace
+ raise ValueError('Wooops')
+ValueError: Wooops
+'''
+
+ try:
+ try:
+ raise ValueError('Wooops')
+ except ValueError as val_err:
+ raise_from(CustomException('ERROR'), val_err)
+ except Exception as err:
+ ret = re.sub(r'"[^"]*tests/test_future', '"/opt/python-future/tests/test_future', traceback.format_exc())
+ ret = re.sub(r'"[^"]*future/utils/__init__.py', '"/opt/python-future/src/future/utils/__init__.py', ret)
+ ret = re.sub(r', line \d+,', ', line 1,', ret)
+ self.assertEqual(expected.splitlines(), ret.splitlines())
+ else:
+ self.fail('No exception raised')
+
+
+class CustomException(Exception):
+ if PY2:
+ def __str__(self):
+ try:
+ out = Exception.__str__(self)
+ if hasattr(self, '__cause__') and self.__cause__ and hasattr(self.__cause__, '__traceback__') and self.__cause__.__traceback__:
+ out += '\n\nThe above exception was the direct cause of the following exception:\n\n'
+ out += ''.join(traceback.format_tb(self.__cause__.__traceback__) + ['{0}: {1}'.format(self.__cause__.__class__.__name__, self.__cause__)])
+ return out
+ except Exception as e:
+ print(e)
+ else:
+ pass
+
+
+if __name__ == '__main__':
+ unittest.main()