Merge pull request #9813 from sbidoul/update-vendored-20210417-sbi

Update vendored dependencies
This commit is contained in:
Stéphane Bidoul 2021-04-20 14:46:26 +02:00 committed by GitHub
commit 88eb4f092e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 6115 additions and 6419 deletions

1
news/idna.vendor.rst Normal file
View File

@ -0,0 +1 @@
Upgrade idna to 3.1

1
news/pep517.vendor.rst Normal file
View File

@ -0,0 +1 @@
Upgrade pep517 to 0.10.0

View File

@ -1 +1 @@
Switch from retrying to tenacity Upgrade tenacity to 7.0.0

View File

@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2013-2021, Kim Davies
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,34 +0,0 @@
License
-------
License: bsd-3-clause
Copyright (c) 2013-2020, Kim Davies. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
#. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
#. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided with
the distribution.
#. Neither the name of the copyright holder nor the names of the
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
#. THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

View File

@ -2,14 +2,14 @@ from .core import encode, decode, alabel, ulabel, IDNAError
import codecs import codecs
import re import re
_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') _unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]')
class Codec(codecs.Codec): class Codec(codecs.Codec):
def encode(self, data, errors='strict'): def encode(self, data, errors='strict'):
if errors != 'strict': if errors != 'strict':
raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
if not data: if not data:
return "", 0 return "", 0
@ -19,23 +19,23 @@ class Codec(codecs.Codec):
def decode(self, data, errors='strict'): def decode(self, data, errors='strict'):
if errors != 'strict': if errors != 'strict':
raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
if not data: if not data:
return u"", 0 return '', 0
return decode(data), len(data) return decode(data), len(data)
class IncrementalEncoder(codecs.BufferedIncrementalEncoder): class IncrementalEncoder(codecs.BufferedIncrementalEncoder):
def _buffer_encode(self, data, errors, final): def _buffer_encode(self, data, errors, final):
if errors != 'strict': if errors != 'strict':
raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
if not data: if not data:
return ("", 0) return ('', 0)
labels = _unicode_dots_re.split(data) labels = _unicode_dots_re.split(data)
trailing_dot = u'' trailing_dot = ''
if labels: if labels:
if not labels[-1]: if not labels[-1]:
trailing_dot = '.' trailing_dot = '.'
@ -55,37 +55,29 @@ class IncrementalEncoder(codecs.BufferedIncrementalEncoder):
size += len(label) size += len(label)
# Join with U+002E # Join with U+002E
result = ".".join(result) + trailing_dot result = '.'.join(result) + trailing_dot
size += len(trailing_dot) size += len(trailing_dot)
return (result, size) return (result, size)
class IncrementalDecoder(codecs.BufferedIncrementalDecoder): class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
def _buffer_decode(self, data, errors, final): def _buffer_decode(self, data, errors, final):
if errors != 'strict': if errors != 'strict':
raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
if not data: if not data:
return (u"", 0) return ('', 0)
# IDNA allows decoding to operate on Unicode strings, too. labels = _unicode_dots_re.split(data)
if isinstance(data, unicode): trailing_dot = ''
labels = _unicode_dots_re.split(data)
else:
# Must be ASCII string
data = str(data)
unicode(data, "ascii")
labels = data.split(".")
trailing_dot = u''
if labels: if labels:
if not labels[-1]: if not labels[-1]:
trailing_dot = u'.' trailing_dot = '.'
del labels[-1] del labels[-1]
elif not final: elif not final:
# Keep potentially unfinished label until the next call # Keep potentially unfinished label until the next call
del labels[-1] del labels[-1]
if labels: if labels:
trailing_dot = u'.' trailing_dot = '.'
result = [] result = []
size = 0 size = 0
@ -95,7 +87,7 @@ class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
size += 1 size += 1
size += len(label) size += len(label)
result = u".".join(result) + trailing_dot result = '.'.join(result) + trailing_dot
size += len(trailing_dot) size += len(trailing_dot)
return (result, size) return (result, size)

View File

@ -8,5 +8,5 @@ def ToUnicode(label):
return decode(label) return decode(label)
def nameprep(s): def nameprep(s):
raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") raise NotImplementedError('IDNA 2008 does not utilise nameprep protocol')

View File

@ -7,11 +7,7 @@ from .intranges import intranges_contain
_virama_combining_class = 9 _virama_combining_class = 9
_alabel_prefix = b'xn--' _alabel_prefix = b'xn--'
_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') _unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]')
if sys.version_info[0] >= 3:
unicode = str
unichr = chr
class IDNAError(UnicodeError): class IDNAError(UnicodeError):
""" Base exception for all IDNA-encoding related problems """ """ Base exception for all IDNA-encoding related problems """
@ -34,10 +30,10 @@ class InvalidCodepointContext(IDNAError):
def _combining_class(cp): def _combining_class(cp):
v = unicodedata.combining(unichr(cp)) v = unicodedata.combining(chr(cp))
if v == 0: if v == 0:
if not unicodedata.name(unichr(cp)): if not unicodedata.name(chr(cp)):
raise ValueError("Unknown character in unicodedata") raise ValueError('Unknown character in unicodedata')
return v return v
def _is_script(cp, script): def _is_script(cp, script):
@ -47,7 +43,7 @@ def _punycode(s):
return s.encode('punycode') return s.encode('punycode')
def _unot(s): def _unot(s):
return 'U+{0:04X}'.format(s) return 'U+{:04X}'.format(s)
def valid_label_length(label): def valid_label_length(label):
@ -72,7 +68,7 @@ def check_bidi(label, check_ltr=False):
direction = unicodedata.bidirectional(cp) direction = unicodedata.bidirectional(cp)
if direction == '': if direction == '':
# String likely comes from a newer version of Unicode # String likely comes from a newer version of Unicode
raise IDNABidiError('Unknown directionality in label {0} at position {1}'.format(repr(label), idx)) raise IDNABidiError('Unknown directionality in label {} at position {}'.format(repr(label), idx))
if direction in ['R', 'AL', 'AN']: if direction in ['R', 'AL', 'AN']:
bidi_label = True bidi_label = True
if not bidi_label and not check_ltr: if not bidi_label and not check_ltr:
@ -85,7 +81,7 @@ def check_bidi(label, check_ltr=False):
elif direction == 'L': elif direction == 'L':
rtl = False rtl = False
else: else:
raise IDNABidiError('First codepoint in label {0} must be directionality L, R or AL'.format(repr(label))) raise IDNABidiError('First codepoint in label {} must be directionality L, R or AL'.format(repr(label)))
valid_ending = False valid_ending = False
number_type = False number_type = False
@ -95,7 +91,7 @@ def check_bidi(label, check_ltr=False):
if rtl: if rtl:
# Bidi rule 2 # Bidi rule 2
if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']:
raise IDNABidiError('Invalid direction for codepoint at position {0} in a right-to-left label'.format(idx)) raise IDNABidiError('Invalid direction for codepoint at position {} in a right-to-left label'.format(idx))
# Bidi rule 3 # Bidi rule 3
if direction in ['R', 'AL', 'EN', 'AN']: if direction in ['R', 'AL', 'EN', 'AN']:
valid_ending = True valid_ending = True
@ -111,7 +107,7 @@ def check_bidi(label, check_ltr=False):
else: else:
# Bidi rule 5 # Bidi rule 5
if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']:
raise IDNABidiError('Invalid direction for codepoint at position {0} in a left-to-right label'.format(idx)) raise IDNABidiError('Invalid direction for codepoint at position {} in a left-to-right label'.format(idx))
# Bidi rule 6 # Bidi rule 6
if direction in ['L', 'EN']: if direction in ['L', 'EN']:
valid_ending = True valid_ending = True
@ -212,7 +208,7 @@ def valid_contexto(label, pos, exception=False):
elif cp_value == 0x30fb: elif cp_value == 0x30fb:
for cp in label: for cp in label:
if cp == u'\u30fb': if cp == '\u30fb':
continue continue
if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'): if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'):
return True return True
@ -249,16 +245,16 @@ def check_label(label):
elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']): elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']):
try: try:
if not valid_contextj(label, pos): if not valid_contextj(label, pos):
raise InvalidCodepointContext('Joiner {0} not allowed at position {1} in {2}'.format( raise InvalidCodepointContext('Joiner {} not allowed at position {} in {}'.format(
_unot(cp_value), pos+1, repr(label))) _unot(cp_value), pos+1, repr(label)))
except ValueError: except ValueError:
raise IDNAError('Unknown codepoint adjacent to joiner {0} at position {1} in {2}'.format( raise IDNAError('Unknown codepoint adjacent to joiner {} at position {} in {}'.format(
_unot(cp_value), pos+1, repr(label))) _unot(cp_value), pos+1, repr(label)))
elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']): elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']):
if not valid_contexto(label, pos): if not valid_contexto(label, pos):
raise InvalidCodepointContext('Codepoint {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label))) raise InvalidCodepointContext('Codepoint {} not allowed at position {} in {}'.format(_unot(cp_value), pos+1, repr(label)))
else: else:
raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label))) raise InvalidCodepoint('Codepoint {} at position {} of {} not allowed'.format(_unot(cp_value), pos+1, repr(label)))
check_bidi(label) check_bidi(label)
@ -277,7 +273,7 @@ def alabel(label):
if not label: if not label:
raise IDNAError('No Input') raise IDNAError('No Input')
label = unicode(label) label = str(label)
check_label(label) check_label(label)
label = _punycode(label) label = _punycode(label)
label = _alabel_prefix + label label = _alabel_prefix + label
@ -316,35 +312,35 @@ def ulabel(label):
def uts46_remap(domain, std3_rules=True, transitional=False): def uts46_remap(domain, std3_rules=True, transitional=False):
"""Re-map the characters in the string according to UTS46 processing.""" """Re-map the characters in the string according to UTS46 processing."""
from .uts46data import uts46data from .uts46data import uts46data
output = u"" output = ''
try: try:
for pos, char in enumerate(domain): for pos, char in enumerate(domain):
code_point = ord(char) code_point = ord(char)
uts46row = uts46data[code_point if code_point < 256 else uts46row = uts46data[code_point if code_point < 256 else
bisect.bisect_left(uts46data, (code_point, "Z")) - 1] bisect.bisect_left(uts46data, (code_point, 'Z')) - 1]
status = uts46row[1] status = uts46row[1]
replacement = uts46row[2] if len(uts46row) == 3 else None replacement = uts46row[2] if len(uts46row) == 3 else None
if (status == "V" or if (status == 'V' or
(status == "D" and not transitional) or (status == 'D' and not transitional) or
(status == "3" and not std3_rules and replacement is None)): (status == '3' and not std3_rules and replacement is None)):
output += char output += char
elif replacement is not None and (status == "M" or elif replacement is not None and (status == 'M' or
(status == "3" and not std3_rules) or (status == '3' and not std3_rules) or
(status == "D" and transitional)): (status == 'D' and transitional)):
output += replacement output += replacement
elif status != "I": elif status != 'I':
raise IndexError() raise IndexError()
return unicodedata.normalize("NFC", output) return unicodedata.normalize('NFC', output)
except IndexError: except IndexError:
raise InvalidCodepoint( raise InvalidCodepoint(
"Codepoint {0} not allowed at position {1} in {2}".format( 'Codepoint {} not allowed at position {} in {}'.format(
_unot(code_point), pos + 1, repr(domain))) _unot(code_point), pos + 1, repr(domain)))
def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False): def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False):
if isinstance(s, (bytes, bytearray)): if isinstance(s, (bytes, bytearray)):
s = s.decode("ascii") s = s.decode('ascii')
if uts46: if uts46:
s = uts46_remap(s, std3_rules, transitional) s = uts46_remap(s, std3_rules, transitional)
trailing_dot = False trailing_dot = False
@ -375,7 +371,7 @@ def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False):
def decode(s, strict=False, uts46=False, std3_rules=False): def decode(s, strict=False, uts46=False, std3_rules=False):
if isinstance(s, (bytes, bytearray)): if isinstance(s, (bytes, bytearray)):
s = s.decode("ascii") s = s.decode('ascii')
if uts46: if uts46:
s = uts46_remap(s, std3_rules, False) s = uts46_remap(s, std3_rules, False)
trailing_dot = False trailing_dot = False
@ -383,7 +379,7 @@ def decode(s, strict=False, uts46=False, std3_rules=False):
if not strict: if not strict:
labels = _unicode_dots_re.split(s) labels = _unicode_dots_re.split(s)
else: else:
labels = s.split(u'.') labels = s.split('.')
if not labels or labels == ['']: if not labels or labels == ['']:
raise IDNAError('Empty domain') raise IDNAError('Empty domain')
if not labels[-1]: if not labels[-1]:
@ -396,5 +392,5 @@ def decode(s, strict=False, uts46=False, std3_rules=False):
else: else:
raise IDNAError('Empty label') raise IDNAError('Empty label')
if trailing_dot: if trailing_dot:
result.append(u'') result.append('')
return u'.'.join(result) return '.'.join(result)

View File

@ -1,6 +1,6 @@
# This file is automatically generated by tools/idna-data # This file is automatically generated by tools/idna-data
__version__ = "13.0.0" __version__ = '13.0.0'
scripts = { scripts = {
'Greek': ( 'Greek': (
0x37000000374, 0x37000000374,

View File

@ -1,2 +1,2 @@
__version__ = '2.10' __version__ = '3.1'

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
"""Wrappers to build Python packages using PEP 517 hooks """Wrappers to build Python packages using PEP 517 hooks
""" """
__version__ = '0.9.1' __version__ = '0.10.0'
from .wrappers import * # noqa: F401, F403 from .wrappers import * # noqa: F401, F403

View File

@ -110,6 +110,9 @@ parser.add_argument(
def main(args): def main(args):
log.warning('pep517.build is deprecated. '
'Consider switching to https://pypi.org/project/build/')
# determine which dists to build # determine which dists to build
dists = list(filter(None, ( dists = list(filter(None, (
'sdist' if args.source or not args.binary else None, 'sdist' if args.source or not args.binary else None,

View File

@ -167,6 +167,9 @@ def check(source_dir):
def main(argv=None): def main(argv=None):
log.warning('pep517.check is deprecated. '
'Consider switching to https://pypi.org/project/build/')
ap = argparse.ArgumentParser() ap = argparse.ArgumentParser()
ap.add_argument( ap.add_argument(
'source_dir', 'source_dir',

View File

@ -0,0 +1,17 @@
"""This is a subpackage because the directory is on sys.path for _in_process.py
The subpackage should stay as empty as possible to avoid shadowing modules that
the backend might import.
"""
from os.path import dirname, abspath, join as pjoin
from contextlib import contextmanager
try:
import importlib.resources as resources
def _in_proc_script_path():
return resources.path(__package__, '_in_process.py')
except ImportError:
@contextmanager
def _in_proc_script_path():
yield pjoin(dirname(abspath(__file__)), '_in_process.py')

View File

@ -1,13 +1,14 @@
import threading import threading
from contextlib import contextmanager from contextlib import contextmanager
import os import os
from os.path import dirname, abspath, join as pjoin from os.path import abspath, join as pjoin
import shutil import shutil
from subprocess import check_call, check_output, STDOUT from subprocess import check_call, check_output, STDOUT
import sys import sys
from tempfile import mkdtemp from tempfile import mkdtemp
from . import compat from . import compat
from .in_process import _in_proc_script_path
__all__ = [ __all__ = [
'BackendUnavailable', 'BackendUnavailable',
@ -19,16 +20,6 @@ __all__ = [
'Pep517HookCaller', 'Pep517HookCaller',
] ]
try:
import importlib.resources as resources
def _in_proc_script_path():
return resources.path(__package__, '_in_process.py')
except ImportError:
@contextmanager
def _in_proc_script_path():
yield pjoin(dirname(abspath(__file__)), '_in_process.py')
@contextmanager @contextmanager
def tempdir(): def tempdir():

View File

@ -0,0 +1 @@
from resolvelib import *

View File

@ -38,9 +38,9 @@ from concurrent import futures
from pip._vendor import six from pip._vendor import six
from pip._vendor.tenacity import _utils from pip._vendor.tenacity import _utils
from pip._vendor.tenacity import compat as _compat
# Import all built-in retry strategies for easier usage. # Import all built-in retry strategies for easier usage.
from .retry import retry_base # noqa
from .retry import retry_all # noqa from .retry import retry_all # noqa
from .retry import retry_always # noqa from .retry import retry_always # noqa
from .retry import retry_any # noqa from .retry import retry_any # noqa
@ -116,11 +116,23 @@ def retry(*dargs, **dkw): # noqa
if len(dargs) == 1 and callable(dargs[0]): if len(dargs) == 1 and callable(dargs[0]):
return retry()(dargs[0]) return retry()(dargs[0])
else: else:
def wrap(f): def wrap(f):
if isinstance(f, retry_base):
warnings.warn(
(
"Got retry_base instance ({cls}) as callable argument, "
+ "this will probably hang indefinitely (did you mean "
+ "retry={cls}(...)?)"
).format(cls=f.__class__.__name__)
)
if iscoroutinefunction is not None and iscoroutinefunction(f): if iscoroutinefunction is not None and iscoroutinefunction(f):
r = AsyncRetrying(*dargs, **dkw) r = AsyncRetrying(*dargs, **dkw)
elif tornado and hasattr(tornado.gen, 'is_coroutine_function') \ elif (
and tornado.gen.is_coroutine_function(f): tornado
and hasattr(tornado.gen, "is_coroutine_function")
and tornado.gen.is_coroutine_function(f)
):
r = TornadoRetrying(*dargs, **dkw) r = TornadoRetrying(*dargs, **dkw)
else: else:
r = Retrying(*dargs, **dkw) r = Retrying(*dargs, **dkw)
@ -158,17 +170,18 @@ class BaseAction(object):
NAME = None NAME = None
def __repr__(self): def __repr__(self):
state_str = ', '.join('%s=%r' % (field, getattr(self, field)) state_str = ", ".join(
for field in self.REPR_FIELDS) "%s=%r" % (field, getattr(self, field)) for field in self.REPR_FIELDS
return '%s(%s)' % (type(self).__name__, state_str) )
return "%s(%s)" % (type(self).__name__, state_str)
def __str__(self): def __str__(self):
return repr(self) return repr(self)
class RetryAction(BaseAction): class RetryAction(BaseAction):
REPR_FIELDS = ('sleep',) REPR_FIELDS = ("sleep",)
NAME = 'retry' NAME = "retry"
def __init__(self, sleep): def __init__(self, sleep):
self.sleep = float(sleep) self.sleep = float(sleep)
@ -177,6 +190,10 @@ class RetryAction(BaseAction):
_unset = object() _unset = object()
def _first_set(first, second):
return second if first is _unset else first
class RetryError(Exception): class RetryError(Exception):
"""Encapsulates the last attempt instance right before giving up.""" """Encapsulates the last attempt instance right before giving up."""
@ -214,86 +231,74 @@ class AttemptManager(object):
class BaseRetrying(object): class BaseRetrying(object):
__metaclass__ = ABCMeta __metaclass__ = ABCMeta
def __init__(self, def __init__(
sleep=sleep, self,
stop=stop_never, wait=wait_none(), sleep=sleep,
retry=retry_if_exception_type(), stop=stop_never,
before=before_nothing, wait=wait_none(),
after=after_nothing, retry=retry_if_exception_type(),
before_sleep=None, before=before_nothing,
reraise=False, after=after_nothing,
retry_error_cls=RetryError, before_sleep=None,
retry_error_callback=None): reraise=False,
retry_error_cls=RetryError,
retry_error_callback=None,
):
self.sleep = sleep self.sleep = sleep
self._stop = stop self.stop = stop
self._wait = wait self.wait = wait
self._retry = retry self.retry = retry
self._before = before self.before = before
self._after = after self.after = after
self._before_sleep = before_sleep self.before_sleep = before_sleep
self.reraise = reraise self.reraise = reraise
self._local = threading.local() self._local = threading.local()
self.retry_error_cls = retry_error_cls self.retry_error_cls = retry_error_cls
self._retry_error_callback = retry_error_callback self.retry_error_callback = retry_error_callback
# This attribute was moved to RetryCallState and is deprecated on # This attribute was moved to RetryCallState and is deprecated on
# Retrying objects but kept for backward compatibility. # Retrying objects but kept for backward compatibility.
self.fn = None self.fn = None
@_utils.cached_property def copy(
def stop(self): self,
return _compat.stop_func_accept_retry_state(self._stop) sleep=_unset,
stop=_unset,
@_utils.cached_property wait=_unset,
def wait(self): retry=_unset,
return _compat.wait_func_accept_retry_state(self._wait) before=_unset,
after=_unset,
@_utils.cached_property before_sleep=_unset,
def retry(self): reraise=_unset,
return _compat.retry_func_accept_retry_state(self._retry) retry_error_cls=_unset,
retry_error_callback=_unset,
@_utils.cached_property ):
def before(self):
return _compat.before_func_accept_retry_state(self._before)
@_utils.cached_property
def after(self):
return _compat.after_func_accept_retry_state(self._after)
@_utils.cached_property
def before_sleep(self):
return _compat.before_sleep_func_accept_retry_state(self._before_sleep)
@_utils.cached_property
def retry_error_callback(self):
return _compat.retry_error_callback_accept_retry_state(
self._retry_error_callback)
def copy(self, sleep=_unset, stop=_unset, wait=_unset,
retry=_unset, before=_unset, after=_unset, before_sleep=_unset,
reraise=_unset):
"""Copy this object with some parameters changed if needed.""" """Copy this object with some parameters changed if needed."""
if before_sleep is _unset:
before_sleep = self.before_sleep
return self.__class__( return self.__class__(
sleep=self.sleep if sleep is _unset else sleep, sleep=_first_set(sleep, self.sleep),
stop=self.stop if stop is _unset else stop, stop=_first_set(stop, self.stop),
wait=self.wait if wait is _unset else wait, wait=_first_set(wait, self.wait),
retry=self.retry if retry is _unset else retry, retry=_first_set(retry, self.retry),
before=self.before if before is _unset else before, before=_first_set(before, self.before),
after=self.after if after is _unset else after, after=_first_set(after, self.after),
before_sleep=before_sleep, before_sleep=_first_set(before_sleep, self.before_sleep),
reraise=self.reraise if after is _unset else reraise, reraise=_first_set(reraise, self.reraise),
retry_error_cls=_first_set(retry_error_cls, self.retry_error_cls),
retry_error_callback=_first_set(
retry_error_callback, self.retry_error_callback
),
) )
def __repr__(self): def __repr__(self):
attrs = dict( attrs = dict(
_utils.visible_attrs(self, attrs={'me': id(self)}), _utils.visible_attrs(self, attrs={"me": id(self)}),
__class__=self.__class__.__name__, __class__=self.__class__.__name__,
) )
return ("<%(__class__)s object at 0x%(me)x (stop=%(stop)s, " return (
"wait=%(wait)s, sleep=%(sleep)s, retry=%(retry)s, " "<%(__class__)s object at 0x%(me)x (stop=%(stop)s, "
"before=%(before)s, after=%(after)s)>") % (attrs) "wait=%(wait)s, sleep=%(sleep)s, retry=%(retry)s, "
"before=%(before)s, after=%(after)s)>"
) % (attrs)
@property @property
def statistics(self): def statistics(self):
@ -328,6 +333,7 @@ class BaseRetrying(object):
:param f: A function to wraps for retrying. :param f: A function to wraps for retrying.
""" """
@_utils.wraps(f) @_utils.wraps(f)
def wrapped_f(*args, **kw): def wrapped_f(*args, **kw):
return self(f, *args, **kw) return self(f, *args, **kw)
@ -342,9 +348,9 @@ class BaseRetrying(object):
def begin(self, fn): def begin(self, fn):
self.statistics.clear() self.statistics.clear()
self.statistics['start_time'] = _utils.now() self.statistics["start_time"] = _utils.now()
self.statistics['attempt_number'] = 1 self.statistics["attempt_number"] = 1
self.statistics['idle_for'] = 0 self.statistics["idle_for"] = 0
self.fn = fn self.fn = fn
def iter(self, retry_state): # noqa def iter(self, retry_state): # noqa
@ -354,16 +360,16 @@ class BaseRetrying(object):
self.before(retry_state) self.before(retry_state)
return DoAttempt() return DoAttempt()
is_explicit_retry = retry_state.outcome.failed \ is_explicit_retry = retry_state.outcome.failed and isinstance(
and isinstance(retry_state.outcome.exception(), TryAgain) retry_state.outcome.exception(), TryAgain
)
if not (is_explicit_retry or self.retry(retry_state=retry_state)): if not (is_explicit_retry or self.retry(retry_state=retry_state)):
return fut.result() return fut.result()
if self.after is not None: if self.after is not None:
self.after(retry_state=retry_state) self.after(retry_state=retry_state)
self.statistics['delay_since_first_attempt'] = \ self.statistics["delay_since_first_attempt"] = retry_state.seconds_since_start
retry_state.seconds_since_start
if self.stop(retry_state=retry_state): if self.stop(retry_state=retry_state):
if self.retry_error_callback: if self.retry_error_callback:
return self.retry_error_callback(retry_state=retry_state) return self.retry_error_callback(retry_state=retry_state)
@ -378,8 +384,8 @@ class BaseRetrying(object):
sleep = 0.0 sleep = 0.0
retry_state.next_action = RetryAction(sleep) retry_state.next_action = RetryAction(sleep)
retry_state.idle_for += sleep retry_state.idle_for += sleep
self.statistics['idle_for'] += sleep self.statistics["idle_for"] += sleep
self.statistics['attempt_number'] += 1 self.statistics["attempt_number"] += 1
if self.before_sleep is not None: if self.before_sleep is not None:
self.before_sleep(retry_state=retry_state) self.before_sleep(retry_state=retry_state)
@ -406,8 +412,10 @@ class BaseRetrying(object):
def call(self, *args, **kwargs): def call(self, *args, **kwargs):
"""Use ``__call__`` instead because this method is deprecated.""" """Use ``__call__`` instead because this method is deprecated."""
warnings.warn("'call()' method is deprecated. " + warnings.warn(
"Use '__call__()' instead", DeprecationWarning) "'call()' method is deprecated. " + "Use '__call__()' instead",
DeprecationWarning,
)
return self.__call__(*args, **kwargs) return self.__call__(*args, **kwargs)
@ -417,14 +425,13 @@ class Retrying(BaseRetrying):
def __call__(self, fn, *args, **kwargs): def __call__(self, fn, *args, **kwargs):
self.begin(fn) self.begin(fn)
retry_state = RetryCallState( retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs)
retry_object=self, fn=fn, args=args, kwargs=kwargs)
while True: while True:
do = self.iter(retry_state=retry_state) do = self.iter(retry_state=retry_state)
if isinstance(do, DoAttempt): if isinstance(do, DoAttempt):
try: try:
result = fn(*args, **kwargs) result = fn(*args, **kwargs)
except BaseException: except BaseException: # noqa: B902
retry_state.set_exception(sys.exc_info()) retry_state.set_exception(sys.exc_info())
else: else:
retry_state.set_result(result) retry_state.set_result(result)

View File

@ -26,24 +26,20 @@ from pip._vendor.tenacity import RetryCallState
class AsyncRetrying(BaseRetrying): class AsyncRetrying(BaseRetrying):
def __init__(self, sleep=sleep, **kwargs):
def __init__(self,
sleep=sleep,
**kwargs):
super(AsyncRetrying, self).__init__(**kwargs) super(AsyncRetrying, self).__init__(**kwargs)
self.sleep = sleep self.sleep = sleep
async def __call__(self, fn, *args, **kwargs): async def __call__(self, fn, *args, **kwargs):
self.begin(fn) self.begin(fn)
retry_state = RetryCallState( retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs)
retry_object=self, fn=fn, args=args, kwargs=kwargs)
while True: while True:
do = self.iter(retry_state=retry_state) do = self.iter(retry_state=retry_state)
if isinstance(do, DoAttempt): if isinstance(do, DoAttempt):
try: try:
result = await fn(*args, **kwargs) result = await fn(*args, **kwargs)
except BaseException: except BaseException: # noqa: B902
retry_state.set_exception(sys.exc_info()) retry_state.set_exception(sys.exc_info())
else: else:
retry_state.set_result(result) retry_state.set_result(result)

View File

@ -40,12 +40,15 @@ if six.PY2:
Also, see https://github.com/benjaminp/six/issues/250. Also, see https://github.com/benjaminp/six/issues/250.
""" """
def filter_hasattr(obj, attrs): def filter_hasattr(obj, attrs):
return tuple(a for a in attrs if hasattr(obj, a)) return tuple(a for a in attrs if hasattr(obj, a))
return six.wraps( return six.wraps(
fn, fn,
assigned=filter_hasattr(fn, WRAPPER_ASSIGNMENTS), assigned=filter_hasattr(fn, WRAPPER_ASSIGNMENTS),
updated=filter_hasattr(fn, WRAPPER_UPDATES)) updated=filter_hasattr(fn, WRAPPER_UPDATES),
)
def capture(fut, tb): def capture(fut, tb):
# TODO(harlowja): delete this in future, since its # TODO(harlowja): delete this in future, since its
@ -55,6 +58,8 @@ if six.PY2:
def getargspec(func): def getargspec(func):
# This was deprecated in Python 3. # This was deprecated in Python 3.
return inspect.getargspec(func) return inspect.getargspec(func)
else: else:
from functools import wraps # noqa from functools import wraps # noqa
@ -80,13 +85,13 @@ def find_ordinal(pos_num):
if pos_num == 0: if pos_num == 0:
return "th" return "th"
elif pos_num == 1: elif pos_num == 1:
return 'st' return "st"
elif pos_num == 2: elif pos_num == 2:
return 'nd' return "nd"
elif pos_num == 3: elif pos_num == 3:
return 'rd' return "rd"
elif pos_num >= 4 and pos_num <= 20: elif pos_num >= 4 and pos_num <= 20:
return 'th' return "th"
else: else:
return find_ordinal(pos_num % 10) return find_ordinal(pos_num % 10)

View File

@ -23,13 +23,18 @@ def after_nothing(retry_state):
def after_log(logger, log_level, sec_format="%0.3f"): def after_log(logger, log_level, sec_format="%0.3f"):
"""After call strategy that logs to some logger the finished attempt.""" """After call strategy that logs to some logger the finished attempt."""
log_tpl = ("Finished call to '%s' after " + str(sec_format) + "(s), " log_tpl = (
"this was the %s time calling it.") "Finished call to '%s' after " + str(sec_format) + "(s), "
"this was the %s time calling it."
)
def log_it(retry_state): def log_it(retry_state):
logger.log(log_level, log_tpl, logger.log(
_utils.get_callback_name(retry_state.fn), log_level,
retry_state.seconds_since_start, log_tpl,
_utils.to_ordinal(retry_state.attempt_number)) _utils.get_callback_name(retry_state.fn),
retry_state.seconds_since_start,
_utils.to_ordinal(retry_state.attempt_number),
)
return log_it return log_it

View File

@ -23,10 +23,13 @@ def before_nothing(retry_state):
def before_log(logger, log_level): def before_log(logger, log_level):
"""Before call strategy that logs to some logger the attempt.""" """Before call strategy that logs to some logger the attempt."""
def log_it(retry_state): def log_it(retry_state):
logger.log(log_level, logger.log(
"Starting call to '%s', this is the %s time calling it.", log_level,
_utils.get_callback_name(retry_state.fn), "Starting call to '%s', this is the %s time calling it.",
_utils.to_ordinal(retry_state.attempt_number)) _utils.get_callback_name(retry_state.fn),
_utils.to_ordinal(retry_state.attempt_number),
)
return log_it return log_it

View File

@ -24,23 +24,28 @@ def before_sleep_nothing(retry_state):
def before_sleep_log(logger, log_level, exc_info=False): def before_sleep_log(logger, log_level, exc_info=False):
"""Before call strategy that logs to some logger the attempt.""" """Before call strategy that logs to some logger the attempt."""
def log_it(retry_state): def log_it(retry_state):
if retry_state.outcome.failed: if retry_state.outcome.failed:
ex = retry_state.outcome.exception() ex = retry_state.outcome.exception()
verb, value = 'raised', '%s: %s' % (type(ex).__name__, ex) verb, value = "raised", "%s: %s" % (type(ex).__name__, ex)
if exc_info: if exc_info:
local_exc_info = get_exc_info_from_future(retry_state.outcome) local_exc_info = get_exc_info_from_future(retry_state.outcome)
else: else:
local_exc_info = False local_exc_info = False
else: else:
verb, value = 'returned', retry_state.outcome.result() verb, value = "returned", retry_state.outcome.result()
local_exc_info = False # exc_info does not apply when no exception local_exc_info = False # exc_info does not apply when no exception
logger.log(log_level, logger.log(
"Retrying %s in %s seconds as it %s %s.", log_level,
_utils.get_callback_name(retry_state.fn), "Retrying %s in %s seconds as it %s %s.",
getattr(retry_state.next_action, 'sleep'), _utils.get_callback_name(retry_state.fn),
verb, value, getattr(retry_state.next_action, "sleep"),
exc_info=local_exc_info) verb,
value,
exc_info=local_exc_info,
)
return log_it return log_it

View File

@ -1,305 +1,6 @@
"""Utilities for providing backward compatibility.""" """Utilities for providing backward compatibility."""
import inspect
from fractions import Fraction
from warnings import warn
from pip._vendor import six from pip._vendor import six
from pip._vendor.tenacity import _utils
def warn_about_non_retry_state_deprecation(cbname, func, stacklevel):
msg = (
'"%s" function must accept single "retry_state" parameter,'
' please update %s' % (cbname, _utils.get_callback_name(func)))
warn(msg, DeprecationWarning, stacklevel=stacklevel + 1)
def warn_about_dunder_non_retry_state_deprecation(fn, stacklevel):
msg = (
'"%s" method must be called with'
' single "retry_state" parameter' % (_utils.get_callback_name(fn)))
warn(msg, DeprecationWarning, stacklevel=stacklevel + 1)
def func_takes_retry_state(func):
if not six.callable(func):
raise Exception(func)
return False
if not inspect.isfunction(func) and not inspect.ismethod(func):
# func is a callable object rather than a function/method
func = func.__call__
func_spec = _utils.getargspec(func)
return 'retry_state' in func_spec.args
_unset = object()
def _make_unset_exception(func_name, **kwargs):
missing = []
for k, v in six.iteritems(kwargs):
if v is _unset:
missing.append(k)
missing_str = ', '.join(repr(s) for s in missing)
return TypeError(func_name + ' func missing parameters: ' + missing_str)
def _set_delay_since_start(retry_state, delay):
# Ensure outcome_timestamp - start_time is *exactly* equal to the delay to
# avoid complexity in test code.
retry_state.start_time = Fraction(retry_state.start_time)
retry_state.outcome_timestamp = (retry_state.start_time + Fraction(delay))
assert retry_state.seconds_since_start == delay
def make_retry_state(previous_attempt_number, delay_since_first_attempt,
last_result=None):
"""Construct RetryCallState for given attempt number & delay.
Only used in testing and thus is extra careful about timestamp arithmetics.
"""
required_parameter_unset = (previous_attempt_number is _unset or
delay_since_first_attempt is _unset)
if required_parameter_unset:
raise _make_unset_exception(
'wait/stop',
previous_attempt_number=previous_attempt_number,
delay_since_first_attempt=delay_since_first_attempt)
from pip._vendor.tenacity import RetryCallState
retry_state = RetryCallState(None, None, (), {})
retry_state.attempt_number = previous_attempt_number
if last_result is not None:
retry_state.outcome = last_result
else:
retry_state.set_result(None)
_set_delay_since_start(retry_state, delay_since_first_attempt)
return retry_state
def func_takes_last_result(waiter):
"""Check if function has a "last_result" parameter.
Needed to provide backward compatibility for wait functions that didn't
take "last_result" in the beginning.
"""
if not six.callable(waiter):
return False
if not inspect.isfunction(waiter) and not inspect.ismethod(waiter):
# waiter is a class, check dunder-call rather than dunder-init.
waiter = waiter.__call__
waiter_spec = _utils.getargspec(waiter)
return 'last_result' in waiter_spec.args
def stop_dunder_call_accept_old_params(fn):
"""Decorate cls.__call__ method to accept old "stop" signature."""
@_utils.wraps(fn)
def new_fn(self,
previous_attempt_number=_unset,
delay_since_first_attempt=_unset,
retry_state=None):
if retry_state is None:
from pip._vendor.tenacity import RetryCallState
retry_state_passed_as_non_kwarg = (
previous_attempt_number is not _unset and
isinstance(previous_attempt_number, RetryCallState))
if retry_state_passed_as_non_kwarg:
retry_state = previous_attempt_number
else:
warn_about_dunder_non_retry_state_deprecation(fn, stacklevel=2)
retry_state = make_retry_state(
previous_attempt_number=previous_attempt_number,
delay_since_first_attempt=delay_since_first_attempt)
return fn(self, retry_state=retry_state)
return new_fn
def stop_func_accept_retry_state(stop_func):
"""Wrap "stop" function to accept "retry_state" parameter."""
if not six.callable(stop_func):
return stop_func
if func_takes_retry_state(stop_func):
return stop_func
@_utils.wraps(stop_func)
def wrapped_stop_func(retry_state):
warn_about_non_retry_state_deprecation(
'stop', stop_func, stacklevel=4)
return stop_func(
retry_state.attempt_number,
retry_state.seconds_since_start,
)
return wrapped_stop_func
def wait_dunder_call_accept_old_params(fn):
"""Decorate cls.__call__ method to accept old "wait" signature."""
@_utils.wraps(fn)
def new_fn(self,
previous_attempt_number=_unset,
delay_since_first_attempt=_unset,
last_result=None,
retry_state=None):
if retry_state is None:
from pip._vendor.tenacity import RetryCallState
retry_state_passed_as_non_kwarg = (
previous_attempt_number is not _unset and
isinstance(previous_attempt_number, RetryCallState))
if retry_state_passed_as_non_kwarg:
retry_state = previous_attempt_number
else:
warn_about_dunder_non_retry_state_deprecation(fn, stacklevel=2)
retry_state = make_retry_state(
previous_attempt_number=previous_attempt_number,
delay_since_first_attempt=delay_since_first_attempt,
last_result=last_result)
return fn(self, retry_state=retry_state)
return new_fn
def wait_func_accept_retry_state(wait_func):
"""Wrap wait function to accept "retry_state" parameter."""
if not six.callable(wait_func):
return wait_func
if func_takes_retry_state(wait_func):
return wait_func
if func_takes_last_result(wait_func):
@_utils.wraps(wait_func)
def wrapped_wait_func(retry_state):
warn_about_non_retry_state_deprecation(
'wait', wait_func, stacklevel=4)
return wait_func(
retry_state.attempt_number,
retry_state.seconds_since_start,
last_result=retry_state.outcome,
)
else:
@_utils.wraps(wait_func)
def wrapped_wait_func(retry_state):
warn_about_non_retry_state_deprecation(
'wait', wait_func, stacklevel=4)
return wait_func(
retry_state.attempt_number,
retry_state.seconds_since_start,
)
return wrapped_wait_func
def retry_dunder_call_accept_old_params(fn):
"""Decorate cls.__call__ method to accept old "retry" signature."""
@_utils.wraps(fn)
def new_fn(self, attempt=_unset, retry_state=None):
if retry_state is None:
from pip._vendor.tenacity import RetryCallState
if attempt is _unset:
raise _make_unset_exception('retry', attempt=attempt)
retry_state_passed_as_non_kwarg = (
attempt is not _unset and
isinstance(attempt, RetryCallState))
if retry_state_passed_as_non_kwarg:
retry_state = attempt
else:
warn_about_dunder_non_retry_state_deprecation(fn, stacklevel=2)
retry_state = RetryCallState(None, None, (), {})
retry_state.outcome = attempt
return fn(self, retry_state=retry_state)
return new_fn
def retry_func_accept_retry_state(retry_func):
"""Wrap "retry" function to accept "retry_state" parameter."""
if not six.callable(retry_func):
return retry_func
if func_takes_retry_state(retry_func):
return retry_func
@_utils.wraps(retry_func)
def wrapped_retry_func(retry_state):
warn_about_non_retry_state_deprecation(
'retry', retry_func, stacklevel=4)
return retry_func(retry_state.outcome)
return wrapped_retry_func
def before_func_accept_retry_state(fn):
"""Wrap "before" function to accept "retry_state"."""
if not six.callable(fn):
return fn
if func_takes_retry_state(fn):
return fn
@_utils.wraps(fn)
def wrapped_before_func(retry_state):
# func, trial_number, trial_time_taken
warn_about_non_retry_state_deprecation('before', fn, stacklevel=4)
return fn(
retry_state.fn,
retry_state.attempt_number,
)
return wrapped_before_func
def after_func_accept_retry_state(fn):
"""Wrap "after" function to accept "retry_state"."""
if not six.callable(fn):
return fn
if func_takes_retry_state(fn):
return fn
@_utils.wraps(fn)
def wrapped_after_sleep_func(retry_state):
# func, trial_number, trial_time_taken
warn_about_non_retry_state_deprecation('after', fn, stacklevel=4)
return fn(
retry_state.fn,
retry_state.attempt_number,
retry_state.seconds_since_start)
return wrapped_after_sleep_func
def before_sleep_func_accept_retry_state(fn):
"""Wrap "before_sleep" function to accept "retry_state"."""
if not six.callable(fn):
return fn
if func_takes_retry_state(fn):
return fn
@_utils.wraps(fn)
def wrapped_before_sleep_func(retry_state):
# retry_object, sleep, last_result
warn_about_non_retry_state_deprecation(
'before_sleep', fn, stacklevel=4)
return fn(
retry_state.retry_object,
sleep=getattr(retry_state.next_action, 'sleep'),
last_result=retry_state.outcome)
return wrapped_before_sleep_func
def retry_error_callback_accept_retry_state(fn):
if not six.callable(fn):
return fn
if func_takes_retry_state(fn):
return fn
@_utils.wraps(fn)
def wrapped_retry_error_callback(retry_state):
warn_about_non_retry_state_deprecation(
'retry_error_callback', fn, stacklevel=4)
return fn(retry_state.outcome)
return wrapped_retry_error_callback
def get_exc_info_from_future(future): def get_exc_info_from_future(future):
""" """

View File

@ -1,4 +1,6 @@
# Copyright 2016 Julien Danjou # -*- encoding: utf-8 -*-
#
# Copyright 20162021 Julien Danjou
# Copyright 2016 Joshua Harlow # Copyright 2016 Joshua Harlow
# Copyright 2013-2014 Ray Holder # Copyright 2013-2014 Ray Holder
# #
@ -19,8 +21,6 @@ import re
from pip._vendor import six from pip._vendor import six
from pip._vendor.tenacity import compat as _compat
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class retry_base(object): class retry_base(object):
@ -63,7 +63,6 @@ class retry_if_exception(retry_base):
def __init__(self, predicate): def __init__(self, predicate):
self.predicate = predicate self.predicate = predicate
@_compat.retry_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
if retry_state.outcome.failed: if retry_state.outcome.failed:
return self.predicate(retry_state.outcome.exception()) return self.predicate(retry_state.outcome.exception())
@ -77,7 +76,8 @@ class retry_if_exception_type(retry_if_exception):
def __init__(self, exception_types=Exception): def __init__(self, exception_types=Exception):
self.exception_types = exception_types self.exception_types = exception_types
super(retry_if_exception_type, self).__init__( super(retry_if_exception_type, self).__init__(
lambda e: isinstance(e, exception_types)) lambda e: isinstance(e, exception_types)
)
class retry_unless_exception_type(retry_if_exception): class retry_unless_exception_type(retry_if_exception):
@ -86,9 +86,9 @@ class retry_unless_exception_type(retry_if_exception):
def __init__(self, exception_types=Exception): def __init__(self, exception_types=Exception):
self.exception_types = exception_types self.exception_types = exception_types
super(retry_unless_exception_type, self).__init__( super(retry_unless_exception_type, self).__init__(
lambda e: not isinstance(e, exception_types)) lambda e: not isinstance(e, exception_types)
)
@_compat.retry_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
# always retry if no exception was raised # always retry if no exception was raised
if not retry_state.outcome.failed: if not retry_state.outcome.failed:
@ -102,7 +102,6 @@ class retry_if_result(retry_base):
def __init__(self, predicate): def __init__(self, predicate):
self.predicate = predicate self.predicate = predicate
@_compat.retry_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
if not retry_state.outcome.failed: if not retry_state.outcome.failed:
return self.predicate(retry_state.outcome.result()) return self.predicate(retry_state.outcome.result())
@ -116,7 +115,6 @@ class retry_if_not_result(retry_base):
def __init__(self, predicate): def __init__(self, predicate):
self.predicate = predicate self.predicate = predicate
@_compat.retry_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
if not retry_state.outcome.failed: if not retry_state.outcome.failed:
return not self.predicate(retry_state.outcome.result()) return not self.predicate(retry_state.outcome.result())
@ -131,23 +129,30 @@ class retry_if_exception_message(retry_if_exception):
if message and match: if message and match:
raise TypeError( raise TypeError(
"{}() takes either 'message' or 'match', not both".format( "{}() takes either 'message' or 'match', not both".format(
self.__class__.__name__)) self.__class__.__name__
)
)
# set predicate # set predicate
if message: if message:
def message_fnc(exception): def message_fnc(exception):
return message == str(exception) return message == str(exception)
predicate = message_fnc predicate = message_fnc
elif match: elif match:
prog = re.compile(match) prog = re.compile(match)
def match_fnc(exception): def match_fnc(exception):
return prog.match(str(exception)) return prog.match(str(exception))
predicate = match_fnc predicate = match_fnc
else: else:
raise TypeError( raise TypeError(
"{}() missing 1 required argument 'message' or 'match'". "{}() missing 1 required argument 'message' or 'match'".format(
format(self.__class__.__name__)) self.__class__.__name__
)
)
super(retry_if_exception_message, self).__init__(predicate) super(retry_if_exception_message, self).__init__(predicate)
@ -159,10 +164,8 @@ class retry_if_not_exception_message(retry_if_exception_message):
super(retry_if_not_exception_message, self).__init__(*args, **kwargs) super(retry_if_not_exception_message, self).__init__(*args, **kwargs)
# invert predicate # invert predicate
if_predicate = self.predicate if_predicate = self.predicate
self.predicate = lambda *args_, **kwargs_: not if_predicate( self.predicate = lambda *args_, **kwargs_: not if_predicate(*args_, **kwargs_)
*args_, **kwargs_)
@_compat.retry_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
if not retry_state.outcome.failed: if not retry_state.outcome.failed:
return True return True
@ -173,10 +176,8 @@ class retry_any(retry_base):
"""Retries if any of the retries condition is valid.""" """Retries if any of the retries condition is valid."""
def __init__(self, *retries): def __init__(self, *retries):
self.retries = tuple(_compat.retry_func_accept_retry_state(r) self.retries = retries
for r in retries)
@_compat.retry_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
return any(r(retry_state) for r in self.retries) return any(r(retry_state) for r in self.retries)
@ -185,9 +186,7 @@ class retry_all(retry_base):
"""Retries if all the retries condition are valid.""" """Retries if all the retries condition are valid."""
def __init__(self, *retries): def __init__(self, *retries):
self.retries = tuple(_compat.retry_func_accept_retry_state(r) self.retries = retries
for r in retries)
@_compat.retry_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
return all(r(retry_state) for r in self.retries) return all(r(retry_state) for r in self.retries)

View File

@ -1,4 +1,6 @@
# Copyright 2016 Julien Danjou # -*- encoding: utf-8 -*-
#
# Copyright 20162021 Julien Danjou
# Copyright 2016 Joshua Harlow # Copyright 2016 Joshua Harlow
# Copyright 2013-2014 Ray Holder # Copyright 2013-2014 Ray Holder
# #
@ -17,8 +19,6 @@ import abc
from pip._vendor import six from pip._vendor import six
from pip._vendor.tenacity import compat as _compat
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class stop_base(object): class stop_base(object):
@ -39,10 +39,8 @@ class stop_any(stop_base):
"""Stop if any of the stop condition is valid.""" """Stop if any of the stop condition is valid."""
def __init__(self, *stops): def __init__(self, *stops):
self.stops = tuple(_compat.stop_func_accept_retry_state(stop_func) self.stops = stops
for stop_func in stops)
@_compat.stop_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
return any(x(retry_state) for x in self.stops) return any(x(retry_state) for x in self.stops)
@ -51,10 +49,8 @@ class stop_all(stop_base):
"""Stop if all the stop conditions are valid.""" """Stop if all the stop conditions are valid."""
def __init__(self, *stops): def __init__(self, *stops):
self.stops = tuple(_compat.stop_func_accept_retry_state(stop_func) self.stops = stops
for stop_func in stops)
@_compat.stop_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
return all(x(retry_state) for x in self.stops) return all(x(retry_state) for x in self.stops)
@ -62,7 +58,6 @@ class stop_all(stop_base):
class _stop_never(stop_base): class _stop_never(stop_base):
"""Never stop.""" """Never stop."""
@_compat.stop_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
return False return False
@ -76,7 +71,6 @@ class stop_when_event_set(stop_base):
def __init__(self, event): def __init__(self, event):
self.event = event self.event = event
@_compat.stop_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
return self.event.is_set() return self.event.is_set()
@ -87,7 +81,6 @@ class stop_after_attempt(stop_base):
def __init__(self, max_attempt_number): def __init__(self, max_attempt_number):
self.max_attempt_number = max_attempt_number self.max_attempt_number = max_attempt_number
@_compat.stop_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
return retry_state.attempt_number >= self.max_attempt_number return retry_state.attempt_number >= self.max_attempt_number
@ -98,6 +91,5 @@ class stop_after_delay(stop_base):
def __init__(self, max_delay): def __init__(self, max_delay):
self.max_delay = max_delay self.max_delay = max_delay
@_compat.stop_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
return retry_state.seconds_since_start >= self.max_delay return retry_state.seconds_since_start >= self.max_delay

View File

@ -24,10 +24,7 @@ from tornado import gen
class TornadoRetrying(BaseRetrying): class TornadoRetrying(BaseRetrying):
def __init__(self, sleep=gen.sleep, **kwargs):
def __init__(self,
sleep=gen.sleep,
**kwargs):
super(TornadoRetrying, self).__init__(**kwargs) super(TornadoRetrying, self).__init__(**kwargs)
self.sleep = sleep self.sleep = sleep
@ -35,14 +32,13 @@ class TornadoRetrying(BaseRetrying):
def __call__(self, fn, *args, **kwargs): def __call__(self, fn, *args, **kwargs):
self.begin(fn) self.begin(fn)
retry_state = RetryCallState( retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs)
retry_object=self, fn=fn, args=args, kwargs=kwargs)
while True: while True:
do = self.iter(retry_state=retry_state) do = self.iter(retry_state=retry_state)
if isinstance(do, DoAttempt): if isinstance(do, DoAttempt):
try: try:
result = yield fn(*args, **kwargs) result = yield fn(*args, **kwargs)
except BaseException: except BaseException: # noqa: B902
retry_state.set_exception(sys.exc_info()) retry_state.set_exception(sys.exc_info())
else: else:
retry_state.set_result(result) retry_state.set_result(result)

View File

@ -1,4 +1,6 @@
# Copyright 2016 Julien Danjou # -*- encoding: utf-8 -*-
#
# Copyright 20162021 Julien Danjou
# Copyright 2016 Joshua Harlow # Copyright 2016 Joshua Harlow
# Copyright 2013-2014 Ray Holder # Copyright 2013-2014 Ray Holder
# #
@ -20,7 +22,6 @@ import random
from pip._vendor import six from pip._vendor import six
from pip._vendor.tenacity import _utils from pip._vendor.tenacity import _utils
from pip._vendor.tenacity import compat as _compat
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
@ -47,7 +48,6 @@ class wait_fixed(wait_base):
def __init__(self, wait): def __init__(self, wait):
self.wait_fixed = wait self.wait_fixed = wait
@_compat.wait_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
return self.wait_fixed return self.wait_fixed
@ -66,21 +66,18 @@ class wait_random(wait_base):
self.wait_random_min = min self.wait_random_min = min
self.wait_random_max = max self.wait_random_max = max
@_compat.wait_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
return (self.wait_random_min + return self.wait_random_min + (
(random.random() * random.random() * (self.wait_random_max - self.wait_random_min)
(self.wait_random_max - self.wait_random_min))) )
class wait_combine(wait_base): class wait_combine(wait_base):
"""Combine several waiting strategies.""" """Combine several waiting strategies."""
def __init__(self, *strategies): def __init__(self, *strategies):
self.wait_funcs = tuple(_compat.wait_func_accept_retry_state(strategy) self.wait_funcs = strategies
for strategy in strategies)
@_compat.wait_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
return sum(x(retry_state=retry_state) for x in self.wait_funcs) return sum(x(retry_state=retry_state) for x in self.wait_funcs)
@ -102,13 +99,10 @@ class wait_chain(wait_base):
""" """
def __init__(self, *strategies): def __init__(self, *strategies):
self.strategies = [_compat.wait_func_accept_retry_state(strategy) self.strategies = strategies
for strategy in strategies]
@_compat.wait_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
wait_func_no = min(max(retry_state.attempt_number, 1), wait_func_no = min(max(retry_state.attempt_number, 1), len(self.strategies))
len(self.strategies))
wait_func = self.strategies[wait_func_no - 1] wait_func = self.strategies[wait_func_no - 1]
return wait_func(retry_state=retry_state) return wait_func(retry_state=retry_state)
@ -125,11 +119,8 @@ class wait_incrementing(wait_base):
self.increment = increment self.increment = increment
self.max = max self.max = max
@_compat.wait_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
result = self.start + ( result = self.start + (self.increment * (retry_state.attempt_number - 1))
self.increment * (retry_state.attempt_number - 1)
)
return max(0, min(result, self.max)) return max(0, min(result, self.max))
@ -152,7 +143,6 @@ class wait_exponential(wait_base):
self.max = max self.max = max
self.exp_base = exp_base self.exp_base = exp_base
@_compat.wait_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
try: try:
exp = self.exp_base ** (retry_state.attempt_number - 1) exp = self.exp_base ** (retry_state.attempt_number - 1)
@ -188,8 +178,6 @@ class wait_random_exponential(wait_exponential):
""" """
@_compat.wait_dunder_call_accept_old_params
def __call__(self, retry_state): def __call__(self, retry_state):
high = super(wait_random_exponential, self).__call__( high = super(wait_random_exponential, self).__call__(retry_state=retry_state)
retry_state=retry_state)
return random.uniform(0, high) return random.uniform(0, high)

View File

@ -6,17 +6,17 @@ distro==1.5.0
html5lib==1.1 html5lib==1.1
msgpack==1.0.2 msgpack==1.0.2
packaging==20.9 packaging==20.9
pep517==0.9.1 pep517==0.10.0
progress==1.5 progress==1.5
pyparsing==2.4.7 pyparsing==2.4.7
requests==2.25.1 requests==2.25.1
certifi==2020.12.05 certifi==2020.12.05
chardet==4.0.0 chardet==4.0.0
idna==2.10 idna==3.1
urllib3==1.26.4 urllib3==1.26.4
resolvelib==0.7.0 resolvelib==0.7.0
setuptools==44.0.0 setuptools==44.0.0
six==1.15.0 six==1.15.0
tenacity==6.3.1 tenacity==7.0.0
toml==0.10.2 toml==0.10.2
webencodings==0.5.1 webencodings==0.5.1