Fix
This commit is contained in:
parent
ac8547656f
commit
5673e3556e
|
@ -12,11 +12,14 @@ __all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES',
|
|||
'total_ordering', 'cmp_to_key', 'lru_cache', 'reduce', 'partial']
|
||||
|
||||
from _functools import partial, reduce
|
||||
from collections import OrderedDict, namedtuple
|
||||
from collections import MutableMapping, namedtuple
|
||||
from reprlib32 import recursive_repr as _recursive_repr
|
||||
from weakref import proxy as _proxy
|
||||
import sys as _sys
|
||||
try:
|
||||
from _thread import allocate_lock as Lock
|
||||
except:
|
||||
from _dummy_thread import allocate_lock as Lock
|
||||
from _dummy_thread32 import allocate_lock as Lock
|
||||
|
||||
################################################################################
|
||||
### OrderedDict
|
||||
|
@ -237,7 +240,7 @@ class OrderedDict(dict):
|
|||
# update_wrapper() and wraps() are tools to help write
|
||||
# wrapper functions that can handle naive introspection
|
||||
|
||||
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__', '__annotations__')
|
||||
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
|
||||
WRAPPER_UPDATES = ('__dict__',)
|
||||
def update_wrapper(wrapper,
|
||||
wrapped,
|
||||
|
@ -297,8 +300,7 @@ def total_ordering(cls):
|
|||
('__gt__', lambda self, other: self >= other and not self == other),
|
||||
('__lt__', lambda self, other: not self >= other)]
|
||||
}
|
||||
# Find user-defined comparisons (not those inherited from object).
|
||||
roots = [op for op in convert if getattr(cls, op, None) is not getattr(object, op, None)]
|
||||
roots = set(dir(cls)) & set(convert)
|
||||
if not roots:
|
||||
raise ValueError('must define at least one ordering operation: < > <= >=')
|
||||
root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__
|
||||
|
@ -355,7 +357,7 @@ def lru_cache(maxsize=100):
|
|||
def decorating_function(user_function,
|
||||
tuple=tuple, sorted=sorted, len=len, KeyError=KeyError):
|
||||
|
||||
hits = misses = 0
|
||||
hits, misses = [0], [0]
|
||||
kwd_mark = (object(),) # separates positional and keyword args
|
||||
lock = Lock() # needed because OrderedDict isn't threadsafe
|
||||
|
||||
|
@ -364,19 +366,18 @@ def lru_cache(maxsize=100):
|
|||
|
||||
@wraps(user_function)
|
||||
def wrapper(*args, **kwds):
|
||||
nonlocal hits, misses
|
||||
key = args
|
||||
if kwds:
|
||||
key += kwd_mark + tuple(sorted(kwds.items()))
|
||||
try:
|
||||
result = cache[key]
|
||||
hits += 1
|
||||
hits[0] += 1
|
||||
return result
|
||||
except KeyError:
|
||||
pass
|
||||
result = user_function(*args, **kwds)
|
||||
cache[key] = result
|
||||
misses += 1
|
||||
misses[0] += 1
|
||||
return result
|
||||
else:
|
||||
cache = OrderedDict() # ordered least recent to most recent
|
||||
|
@ -385,7 +386,6 @@ def lru_cache(maxsize=100):
|
|||
|
||||
@wraps(user_function)
|
||||
def wrapper(*args, **kwds):
|
||||
nonlocal hits, misses
|
||||
key = args
|
||||
if kwds:
|
||||
key += kwd_mark + tuple(sorted(kwds.items()))
|
||||
|
@ -393,14 +393,14 @@ def lru_cache(maxsize=100):
|
|||
try:
|
||||
result = cache[key]
|
||||
cache_renew(key) # record recent use of this key
|
||||
hits += 1
|
||||
hits[0] += 1
|
||||
return result
|
||||
except KeyError:
|
||||
pass
|
||||
result = user_function(*args, **kwds)
|
||||
with lock:
|
||||
cache[key] = result # record recent use of this key
|
||||
misses += 1
|
||||
misses[0] += 1
|
||||
if len(cache) > maxsize:
|
||||
cache_popitem(0) # purge least recently used cache entry
|
||||
return result
|
||||
|
@ -408,14 +408,13 @@ def lru_cache(maxsize=100):
|
|||
def cache_info():
|
||||
"""Report cache statistics"""
|
||||
with lock:
|
||||
return _CacheInfo(hits, misses, maxsize, len(cache))
|
||||
return _CacheInfo(hits[0], misses[0], maxsize, len(cache))
|
||||
|
||||
def cache_clear():
|
||||
"""Clear the cache and cache statistics"""
|
||||
nonlocal hits, misses
|
||||
with lock:
|
||||
cache.clear()
|
||||
hits = misses = 0
|
||||
hits[0] = misses[0] = 0
|
||||
|
||||
wrapper.cache_info = cache_info
|
||||
wrapper.cache_clear = cache_clear
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
__all__ = ["Repr", "repr", "recursive_repr"]
|
||||
|
||||
import builtins
|
||||
import __builtin__ as builtins
|
||||
from itertools import islice
|
||||
try:
|
||||
from _thread import get_ident
|
||||
except ImportError:
|
||||
from _dummy_thread import get_ident
|
||||
from _dummy_thread32 import get_ident
|
||||
|
||||
def recursive_repr(fillvalue='...'):
|
||||
'Decorator to make a repr function return fillvalue for a recursive call'
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import functools
|
||||
import functools32 as functools
|
||||
import collections
|
||||
import sys
|
||||
import unittest
|
||||
from test import support
|
||||
import test_support32 as support
|
||||
from weakref import proxy
|
||||
import pickle
|
||||
from random import choice
|
||||
|
@ -48,9 +48,9 @@ class TestPartial(unittest.TestCase):
|
|||
# attributes should not be writable
|
||||
if not isinstance(self.thetype, type):
|
||||
return
|
||||
self.assertRaises(AttributeError, setattr, p, 'func', map)
|
||||
self.assertRaises(AttributeError, setattr, p, 'args', (1, 2))
|
||||
self.assertRaises(AttributeError, setattr, p, 'keywords', dict(a=1, b=2))
|
||||
self.assertRaises(TypeError, setattr, p, 'func', map)
|
||||
self.assertRaises(TypeError, setattr, p, 'args', (1, 2))
|
||||
self.assertRaises(TypeError, setattr, p, 'keywords', dict(a=1, b=2))
|
||||
|
||||
p = self.thetype(hex)
|
||||
try:
|
||||
|
@ -148,32 +148,6 @@ class TestPartial(unittest.TestCase):
|
|||
join = self.thetype(''.join)
|
||||
self.assertEqual(join(data), '0123456789')
|
||||
|
||||
def test_repr(self):
|
||||
args = (object(), object())
|
||||
args_repr = ', '.join(repr(a) for a in args)
|
||||
kwargs = {'a': object(), 'b': object()}
|
||||
kwargs_repr = ', '.join("%s=%r" % (k, v) for k, v in kwargs.items())
|
||||
if self.thetype is functools.partial:
|
||||
name = 'functools.partial'
|
||||
else:
|
||||
name = self.thetype.__name__
|
||||
|
||||
f = self.thetype(capture)
|
||||
self.assertEqual('{}({!r})'.format(name, capture),
|
||||
repr(f))
|
||||
|
||||
f = self.thetype(capture, *args)
|
||||
self.assertEqual('{}({!r}, {})'.format(name, capture, args_repr),
|
||||
repr(f))
|
||||
|
||||
f = self.thetype(capture, **kwargs)
|
||||
self.assertEqual('{}({!r}, {})'.format(name, capture, kwargs_repr),
|
||||
repr(f))
|
||||
|
||||
f = self.thetype(capture, *args, **kwargs)
|
||||
self.assertEqual('{}({!r}, {}, {})'.format(name, capture, args_repr, kwargs_repr),
|
||||
repr(f))
|
||||
|
||||
def test_pickle(self):
|
||||
f = self.thetype(signature, 'asdf', bar=True)
|
||||
f.add_something_to__dict__ = True
|
||||
|
@ -213,11 +187,11 @@ class TestUpdateWrapper(unittest.TestCase):
|
|||
self.assertTrue(wrapped_attr[key] is wrapper_attr[key])
|
||||
|
||||
def _default_update(self):
|
||||
def f(a:'This is a new annotation'):
|
||||
def f(a):
|
||||
"""This is a test"""
|
||||
pass
|
||||
f.attr = 'This is also a test'
|
||||
def wrapper(b:'This is the prior annotation'):
|
||||
def wrapper(b):
|
||||
pass
|
||||
functools.update_wrapper(wrapper, f)
|
||||
return wrapper, f
|
||||
|
@ -228,8 +202,6 @@ class TestUpdateWrapper(unittest.TestCase):
|
|||
self.assertIs(wrapper.__wrapped__, f)
|
||||
self.assertEqual(wrapper.__name__, 'f')
|
||||
self.assertEqual(wrapper.attr, 'This is also a test')
|
||||
self.assertEqual(wrapper.__annotations__['a'], 'This is a new annotation')
|
||||
self.assertNotIn('b', wrapper.__annotations__)
|
||||
|
||||
@unittest.skipIf(sys.flags.optimize >= 2,
|
||||
"Docstrings are omitted with -O2 and above")
|
||||
|
@ -248,7 +220,6 @@ class TestUpdateWrapper(unittest.TestCase):
|
|||
self.check_wrapper(wrapper, f, (), ())
|
||||
self.assertEqual(wrapper.__name__, 'wrapper')
|
||||
self.assertEqual(wrapper.__doc__, None)
|
||||
self.assertEqual(wrapper.__annotations__, {})
|
||||
self.assertFalse(hasattr(wrapper, 'attr'))
|
||||
|
||||
def test_selective_update(self):
|
||||
|
@ -297,7 +268,6 @@ class TestUpdateWrapper(unittest.TestCase):
|
|||
functools.update_wrapper(wrapper, max)
|
||||
self.assertEqual(wrapper.__name__, 'max')
|
||||
self.assertTrue(wrapper.__doc__.startswith('max('))
|
||||
self.assertEqual(wrapper.__annotations__, {})
|
||||
|
||||
class TestWraps(TestUpdateWrapper):
|
||||
|
||||
|
@ -401,11 +371,6 @@ class TestReduce(unittest.TestCase):
|
|||
self.assertRaises(TypeError, self.func, add, ())
|
||||
self.assertRaises(TypeError, self.func, add, object())
|
||||
|
||||
class TestFailingIter:
|
||||
def __iter__(self):
|
||||
raise RuntimeError
|
||||
self.assertRaises(RuntimeError, self.func, add, TestFailingIter())
|
||||
|
||||
self.assertEqual(self.func(add, [], None), None)
|
||||
self.assertEqual(self.func(add, [], 42), 42)
|
||||
|
||||
|
@ -520,14 +485,14 @@ class TestTotalOrdering(unittest.TestCase):
|
|||
def test_total_ordering_no_overwrite(self):
|
||||
# new methods should not overwrite existing
|
||||
@functools.total_ordering
|
||||
class A(int):
|
||||
class A(str):
|
||||
pass
|
||||
self.assertTrue(A(1) < A(2))
|
||||
self.assertTrue(A(2) > A(1))
|
||||
self.assertTrue(A(1) <= A(2))
|
||||
self.assertTrue(A(2) >= A(1))
|
||||
self.assertTrue(A(2) <= A(2))
|
||||
self.assertTrue(A(2) >= A(2))
|
||||
self.assertTrue(A("a") < A("b"))
|
||||
self.assertTrue(A("b") > A("a"))
|
||||
self.assertTrue(A("a") <= A("b"))
|
||||
self.assertTrue(A("b") >= A("a"))
|
||||
self.assertTrue(A("b") <= A("b"))
|
||||
self.assertTrue(A("b") >= A("b"))
|
||||
|
||||
def test_no_operations_defined(self):
|
||||
with self.assertRaises(ValueError):
|
||||
|
@ -596,14 +561,13 @@ class TestLRU(unittest.TestCase):
|
|||
# test size zero (which means "never-cache")
|
||||
@functools.lru_cache(0)
|
||||
def f():
|
||||
nonlocal f_cnt
|
||||
f_cnt += 1
|
||||
f_cnt[0] += 1
|
||||
return 20
|
||||
self.assertEqual(f.cache_info().maxsize, 0)
|
||||
f_cnt = 0
|
||||
f_cnt = [0]
|
||||
for i in range(5):
|
||||
self.assertEqual(f(), 20)
|
||||
self.assertEqual(f_cnt, 5)
|
||||
self.assertEqual(f_cnt[0], 5)
|
||||
hits, misses, maxsize, currsize = f.cache_info()
|
||||
self.assertEqual(hits, 0)
|
||||
self.assertEqual(misses, 5)
|
||||
|
@ -612,14 +576,13 @@ class TestLRU(unittest.TestCase):
|
|||
# test size one
|
||||
@functools.lru_cache(1)
|
||||
def f():
|
||||
nonlocal f_cnt
|
||||
f_cnt += 1
|
||||
f_cnt[0] += 1
|
||||
return 20
|
||||
self.assertEqual(f.cache_info().maxsize, 1)
|
||||
f_cnt = 0
|
||||
f_cnt = [0]
|
||||
for i in range(5):
|
||||
self.assertEqual(f(), 20)
|
||||
self.assertEqual(f_cnt, 1)
|
||||
self.assertEqual(f_cnt[0], 1)
|
||||
hits, misses, maxsize, currsize = f.cache_info()
|
||||
self.assertEqual(hits, 4)
|
||||
self.assertEqual(misses, 1)
|
||||
|
@ -628,15 +591,14 @@ class TestLRU(unittest.TestCase):
|
|||
# test size two
|
||||
@functools.lru_cache(2)
|
||||
def f(x):
|
||||
nonlocal f_cnt
|
||||
f_cnt += 1
|
||||
f_cnt[0] += 1
|
||||
return x*10
|
||||
self.assertEqual(f.cache_info().maxsize, 2)
|
||||
f_cnt = 0
|
||||
f_cnt = [0]
|
||||
for x in 7, 9, 7, 9, 7, 9, 8, 8, 8, 9, 9, 9, 8, 8, 8, 7:
|
||||
# * * * *
|
||||
self.assertEqual(f(x), x*10)
|
||||
self.assertEqual(f_cnt, 4)
|
||||
self.assertEqual(f_cnt[0], 4)
|
||||
hits, misses, maxsize, currsize = f.cache_info()
|
||||
self.assertEqual(hits, 12)
|
||||
self.assertEqual(misses, 4)
|
||||
|
@ -665,9 +627,8 @@ class TestLRU(unittest.TestCase):
|
|||
def func(i):
|
||||
return 'abc'[i]
|
||||
self.assertEqual(func(0), 'a')
|
||||
with self.assertRaises(IndexError) as cm:
|
||||
with self.assertRaises(IndexError):
|
||||
func(15)
|
||||
self.assertIsNone(cm.exception.__context__)
|
||||
# Verify that the previous exception did not result in a cached entry
|
||||
with self.assertRaises(IndexError):
|
||||
func(15)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""Supporting definitions for the Python regression tests."""
|
||||
|
||||
if __name__ != 'test.support':
|
||||
if __name__ != 'test_support32':
|
||||
raise ImportError('support must be imported from the test package')
|
||||
|
||||
import contextlib
|
||||
|
@ -458,7 +458,7 @@ TESTFN = "{}_{}_tmp".format(TESTFN, os.getpid())
|
|||
|
||||
|
||||
# TESTFN_UNICODE is a non-ascii filename
|
||||
TESTFN_UNICODE = TESTFN + "-\xe0\xf2\u0258\u0141\u011f"
|
||||
TESTFN_UNICODE = TESTFN + u"-\xe0\xf2\u0258\u0141\u011f"
|
||||
if sys.platform == 'darwin':
|
||||
# In Mac OS X's VFS API file names are, by definition, canonically
|
||||
# decomposed Unicode, encoded using UTF-8. See QA1173:
|
||||
|
@ -618,7 +618,7 @@ def open_urlresource(url, *args, **kw):
|
|||
# Verify the requirement before downloading the file
|
||||
requires('urlfetch')
|
||||
|
||||
print('\tfetching %s ...' % url, file=get_original_stdout())
|
||||
print >>get_original_stdout(), '\tfetching %s ...' % url
|
||||
f = urllib.request.urlopen(url, timeout=15)
|
||||
try:
|
||||
with open(fn, "wb") as out:
|
||||
|
@ -865,7 +865,7 @@ ioerror_peer_reset = TransientResource(IOError, errno=errno.ECONNRESET)
|
|||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def transient_internet(resource_name, *, timeout=30.0, errnos=()):
|
||||
def transient_internet(resource_name, timeout=30.0, errnos=(), *_argv):
|
||||
"""Return a context manager that raises ResourceDenied when various issues
|
||||
with the Internet connection manifest themselves as exceptions."""
|
||||
default_errnos = [
|
||||
|
@ -900,7 +900,10 @@ def transient_internet(resource_name, *, timeout=30.0, errnos=()):
|
|||
n in captured_errnos):
|
||||
if not verbose:
|
||||
sys.stderr.write(denied.args[0] + "\n")
|
||||
raise denied from err
|
||||
try:
|
||||
raise err
|
||||
except:
|
||||
raise denied
|
||||
|
||||
old_timeout = socket.getdefaulttimeout()
|
||||
try:
|
||||
|
|
Loading…
Reference in New Issue