summaryrefslogtreecommitdiff
path: root/src/silx/utils
diff options
context:
space:
mode:
authorPicca Frédéric-Emmanuel <picca@debian.org>2022-11-03 10:02:44 +0100
committerPicca Frédéric-Emmanuel <picca@debian.org>2022-11-03 10:02:44 +0100
commit1c380bfeff1e13a9f7d506460336659502ca052d (patch)
tree48081d47748d4563eeaa76662287eb19638c8591 /src/silx/utils
parent4e774db12d5ebe7a20eded6dd434a289e27999e5 (diff)
New upstream version 1.1.0+dfsg
Diffstat (limited to 'src/silx/utils')
-rw-r--r--src/silx/utils/ExternalResources.py80
-rw-r--r--src/silx/utils/__init__.py1
-rw-r--r--src/silx/utils/_have_openmp.pxd1
-rw-r--r--src/silx/utils/array_like.py3
-rw-r--r--src/silx/utils/debug.py1
-rw-r--r--src/silx/utils/deprecation.py3
-rw-r--r--src/silx/utils/enum.py3
-rw-r--r--src/silx/utils/exceptions.py1
-rw-r--r--src/silx/utils/files.py1
-rw-r--r--src/silx/utils/html.py1
-rw-r--r--src/silx/utils/launcher.py1
-rwxr-xr-xsrc/silx/utils/number.py1
-rw-r--r--src/silx/utils/property.py3
-rw-r--r--src/silx/utils/proxy.py3
-rw-r--r--src/silx/utils/retry.py96
-rw-r--r--src/silx/utils/setup.py43
-rwxr-xr-xsrc/silx/utils/test/__init__.py1
-rw-r--r--src/silx/utils/test/test_array_like.py1
-rw-r--r--src/silx/utils/test/test_debug.py1
-rw-r--r--src/silx/utils/test/test_deprecation.py1
-rw-r--r--src/silx/utils/test/test_enum.py3
-rw-r--r--src/silx/utils/test/test_external_resources.py5
-rw-r--r--src/silx/utils/test/test_launcher.py1
-rw-r--r--src/silx/utils/test/test_launcher_command.py1
-rw-r--r--src/silx/utils/test/test_number.py1
-rw-r--r--src/silx/utils/test/test_proxy.py1
-rw-r--r--src/silx/utils/test/test_retry.py45
-rwxr-xr-xsrc/silx/utils/test/test_testutils.py1
-rw-r--r--src/silx/utils/test/test_weakref.py1
-rwxr-xr-xsrc/silx/utils/testutils.py1
-rw-r--r--src/silx/utils/weakref.py2
31 files changed, 169 insertions, 139 deletions
diff --git a/src/silx/utils/ExternalResources.py b/src/silx/utils/ExternalResources.py
index b79d6ff..429314e 100644
--- a/src/silx/utils/ExternalResources.py
+++ b/src/silx/utils/ExternalResources.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2021 European Synchrotron Radiation Facility
@@ -27,7 +26,7 @@
__authors__ = ["Thomas Vincent", "J. Kieffer"]
__license__ = "MIT"
-__date__ = "08/03/2019"
+__date__ = "21/12/2021"
import os
@@ -38,7 +37,8 @@ import tempfile
import unittest
import urllib.request
import urllib.error
-
+import hashlib
+from collections import OrderedDict
logger = logging.getLogger(__name__)
@@ -68,10 +68,10 @@ class ExternalResources(object):
self.project = project
self._initialized = False
self.sem = threading.Semaphore()
-
+ self.hash = hashlib.sha256
self.env_key = env_key or (self.project.upper() + "_TESTDATA")
self.url_base = url_base
- self.all_data = set()
+ self.all_data = {}
self.timeout = timeout
self._data_home = None
@@ -104,6 +104,21 @@ class ExternalResources(object):
self._data_home = data_home
return data_home
+ def get_hash(self, filename=None, data=None):
+ "Calculate and return the hash of a file or a bunch of data"
+ if data is None and filename is None:
+ return
+ h = self.hash()
+ if filename is not None:
+ fullfilename = os.path.join(self.data_home, filename)
+ if os.path.exists(fullfilename):
+ with open(fullfilename, "rb") as fd:
+ data = fd.read()
+ else:
+ raise RuntimeError(f"Filename {fullfilename} does not exist !")
+ h.update(data)
+ return h.hexdigest()
+
def _initialize_data(self):
"""Initialize for downloading test data"""
if not self._initialized:
@@ -112,7 +127,13 @@ class ExternalResources(object):
self.testdata = os.path.join(self.data_home, "all_testdata.json")
if os.path.exists(self.testdata):
with open(self.testdata) as f:
- self.all_data = set(json.load(f))
+ jdata = json.load(f)
+ if isinstance(jdata, dict):
+ self.all_data = jdata
+ else:
+ #recalculate the hash only if the data was stored as a list
+ self.all_data = {k: self.get_hash(k) for k in jdata}
+ self.save_json()
self._initialized = True
def clean_up(self):
@@ -160,7 +181,7 @@ class ExternalResources(object):
os.makedirs(os.path.dirname(fullfilename))
try:
- with open(fullfilename, "wb") as outfile:
+ with open(fullfilename, mode="wb") as outfile:
outfile.write(data)
except IOError:
raise IOError("unable to write downloaded \
@@ -173,19 +194,32 @@ class ExternalResources(object):
This even works under windows !
Otherwise please try to download the images manually from
%s/%s""" % (filename, self.url_base, filename))
+ else:
+ self.all_data[filename] = self.get_hash(data=data)
+ self.save_json()
- if filename not in self.all_data:
- self.all_data.add(filename)
- image_list = list(self.all_data)
- image_list.sort()
- try:
- with open(self.testdata, "w") as fp:
- json.dump(image_list, fp, indent=4)
- except IOError:
- logger.debug("Unable to save JSON list")
-
+ else:
+ h = self.hash()
+ with open(fullfilename, mode="rb") as fd:
+ h.update(fd.read())
+ if h.hexdigest() != self.all_data[filename]:
+ logger.warning(f"Detected corruped file {fullfilename}")
+ self.all_data.pop(filename)
+ os.unlink(fullfilename)
+ return self.getfile(filename)
+
return fullfilename
+ def save_json(self):
+ image_list = list(self.all_data.keys())
+ image_list.sort()
+ dico = OrderedDict([(i, self.all_data[i]) for i in image_list])
+ try:
+ with open(self.testdata, "w") as fp:
+ json.dump(dico, fp, indent=4)
+ except IOError:
+ logger.info("Unable to save JSON dict")
+
def getdir(self, dirname):
"""Downloads the requested tarball from the server
https://www.silx.org/pub/silx/
@@ -227,14 +261,8 @@ class ExternalResources(object):
if not self._initialized:
self._initialize_data()
if filename not in self.all_data:
- self.all_data.add(filename)
- image_list = list(self.all_data)
- image_list.sort()
- try:
- with open(self.testdata, "w") as fp:
- json.dump(image_list, fp, indent=4)
- except IOError:
- logger.debug("Unable to save JSON list")
+ self.all_data[filename] = self.get_hash(filename)
+ seld.save_json()
baseimage = os.path.basename(filename)
logger.info("UtilsTest.getimage('%s')" % baseimage)
@@ -313,7 +341,7 @@ class ExternalResources(object):
if not self._initialized:
self._initialize_data()
if not imgs:
- imgs = self.all_data
+ imgs = self.all_data.keys()
res = []
for fn in imgs:
logger.info("Downloading from silx.org: %s", fn)
diff --git a/src/silx/utils/__init__.py b/src/silx/utils/__init__.py
index f803a5f..6505e84 100644
--- a/src/silx/utils/__init__.py
+++ b/src/silx/utils/__init__.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2018 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/_have_openmp.pxd b/src/silx/utils/_have_openmp.pxd
index 89a385c..7302956 100644
--- a/src/silx/utils/_have_openmp.pxd
+++ b/src/silx/utils/_have_openmp.pxd
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2018 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/array_like.py b/src/silx/utils/array_like.py
index 0cf4857..d9c7b73 100644
--- a/src/silx/utils/array_like.py
+++ b/src/silx/utils/array_like.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2021 European Synchrotron Radiation Facility
@@ -47,8 +46,6 @@ Functions:
"""
-from __future__ import absolute_import, print_function, division
-
import sys
import numpy
diff --git a/src/silx/utils/debug.py b/src/silx/utils/debug.py
index 3d50fc9..ec361ac 100644
--- a/src/silx/utils/debug.py
+++ b/src/silx/utils/debug.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2021 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/deprecation.py b/src/silx/utils/deprecation.py
index 7b19ee5..81d7ed1 100644
--- a/src/silx/utils/deprecation.py
+++ b/src/silx/utils/deprecation.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
@@ -24,8 +23,6 @@
# ###########################################################################*/
"""Bunch of useful decorators"""
-from __future__ import absolute_import, print_function, division
-
__authors__ = ["Jerome Kieffer", "H. Payno", "P. Knobel"]
__license__ = "MIT"
__date__ = "26/02/2018"
diff --git a/src/silx/utils/enum.py b/src/silx/utils/enum.py
index fece575..176d429 100644
--- a/src/silx/utils/enum.py
+++ b/src/silx/utils/enum.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2019 European Synchrotron Radiation Facility
@@ -24,8 +23,6 @@
# ###########################################################################*/
"""An :class:`.Enum` class with additional features."""
-from __future__ import absolute_import
-
__authors__ = ["T. Vincent"]
__license__ = "MIT"
__date__ = "29/04/2019"
diff --git a/src/silx/utils/exceptions.py b/src/silx/utils/exceptions.py
index addba89..d7e5533 100644
--- a/src/silx/utils/exceptions.py
+++ b/src/silx/utils/exceptions.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/files.py b/src/silx/utils/files.py
index 1982c0d..ab8d417 100644
--- a/src/silx/utils/files.py
+++ b/src/silx/utils/files.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2019 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/html.py b/src/silx/utils/html.py
index 9b39b95..654c780 100644
--- a/src/silx/utils/html.py
+++ b/src/silx/utils/html.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2021 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/launcher.py b/src/silx/utils/launcher.py
index c46256a..20752b3 100644
--- a/src/silx/utils/launcher.py
+++ b/src/silx/utils/launcher.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2004-2017 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/number.py b/src/silx/utils/number.py
index f852a39..72106e7 100755
--- a/src/silx/utils/number.py
+++ b/src/silx/utils/number.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2018 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/property.py b/src/silx/utils/property.py
index 10d5d98..029f28e 100644
--- a/src/silx/utils/property.py
+++ b/src/silx/utils/property.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
@@ -24,8 +23,6 @@
# ###########################################################################*/
"""Bunch of useful decorators"""
-from __future__ import absolute_import, print_function, division
-
__authors__ = ["V. Valls"]
__license__ = "MIT"
__date__ = "22/02/2018"
diff --git a/src/silx/utils/proxy.py b/src/silx/utils/proxy.py
index d8821c2..7801b4b 100644
--- a/src/silx/utils/proxy.py
+++ b/src/silx/utils/proxy.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2021 European Synchrotron Radiation Facility
@@ -24,8 +23,6 @@
# ###########################################################################*/
"""Module containing proxy objects"""
-from __future__ import absolute_import, print_function, division
-
__authors__ = ["V. Valls"]
__license__ = "MIT"
__date__ = "02/10/2017"
diff --git a/src/silx/utils/retry.py b/src/silx/utils/retry.py
index adc43bc..804bcb6 100644
--- a/src/silx/utils/retry.py
+++ b/src/silx/utils/retry.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
#
@@ -32,6 +31,7 @@ __date__ = "05/02/2020"
import time
+import inspect
from functools import wraps
from contextlib import contextmanager
import multiprocessing
@@ -58,13 +58,13 @@ def _default_retry_on_error(e):
@contextmanager
-def _handle_exception(options):
+def _handle_exception(retry_state):
try:
yield
except BaseException as e:
- retry_on_error = options.get("retry_on_error")
+ retry_on_error = retry_state.get("retry_on_error")
if retry_on_error is not None and retry_on_error(e):
- options["exception"] = e
+ retry_state["exception"] = e
else:
raise
@@ -79,15 +79,19 @@ def _retry_loop(retry_timeout=None, retry_period=None, retry_on_error=None):
eligible for retry
"""
has_timeout = retry_timeout is not None
- options = {"exception": None, "retry_on_error": retry_on_error}
if has_timeout:
t0 = time.time()
+ else:
+ t0 = None
+ retry_state = {"t0": t0, "exception": None, "retry_on_error": retry_on_error}
while True:
- yield options
+ yield retry_state
if retry_period is not None:
time.sleep(retry_period)
if has_timeout and (time.time() - t0) > retry_timeout:
- raise RetryTimeoutError from options.get("exception")
+ err_msg = "%s seconds" % retry_timeout
+ cause = retry_state.get("exception")
+ raise RetryTimeoutError(err_msg) from cause
def retry(
@@ -99,6 +103,9 @@ def retry(
The decorator arguments can be overriden by using them when calling the
decorated method.
+ Generator functions are required to have a `start_index` argument which allows
+ the method to start iterating from the last failure when called on retry.
+
:param num retry_timeout:
:param num retry_period: sleep before retry
:param callable or None retry_on_error: checks whether an exception is
@@ -109,18 +116,53 @@ def retry(
retry_period = RETRY_PERIOD
def decorator(method):
- @wraps(method)
- def wrapper(*args, **kw):
- _retry_timeout = kw.pop("retry_timeout", retry_timeout)
- _retry_period = kw.pop("retry_period", retry_period)
- _retry_on_error = kw.pop("retry_on_error", retry_on_error)
- for options in _retry_loop(
- retry_timeout=_retry_timeout,
- retry_period=_retry_period,
- retry_on_error=_retry_on_error,
- ):
- with _handle_exception(options):
- return method(*args, **kw)
+ if inspect.isgeneratorfunction(method):
+ if "start_index" not in inspect.signature(method).parameters:
+ raise TypeError(
+ "The generator function '%s' needs a `start_index` named argument because it is wrapped with the `retry` decorator."
+ % method.__name__
+ )
+
+ @wraps(method)
+ def wrapper(*args, **kw):
+ _retry_timeout = kw.pop("retry_timeout", retry_timeout)
+ _retry_period = kw.pop("retry_period", retry_period)
+ _retry_on_error = kw.pop("retry_on_error", retry_on_error)
+ start_index = kw.pop("start_index", 0)
+ if start_index is None:
+ start_index = 0
+ for retry_state in _retry_loop(
+ retry_timeout=_retry_timeout,
+ retry_period=_retry_period,
+ retry_on_error=_retry_on_error,
+ ):
+ with _handle_exception(retry_state):
+ oretry_on_error = retry_state["retry_on_error"]
+ for result in method(*args, start_index=start_index, **kw):
+ start_index += 1
+ retry_state["retry_on_error"] = None
+ # any exception here will NOT cause a retry
+ yield result
+ # restart the retry loop
+ if retry_state["t0"] is not None:
+ retry_state["t0"] = time.time()
+ retry_state["retry_on_error"] = oretry_on_error
+ return
+
+ else:
+
+ @wraps(method)
+ def wrapper(*args, **kw):
+ _retry_timeout = kw.pop("retry_timeout", retry_timeout)
+ _retry_period = kw.pop("retry_period", retry_period)
+ _retry_on_error = kw.pop("retry_on_error", retry_on_error)
+ for retry_state in _retry_loop(
+ retry_timeout=_retry_timeout,
+ retry_period=_retry_period,
+ retry_on_error=_retry_on_error,
+ ):
+ with _handle_exception(retry_state):
+ return method(*args, **kw)
return wrapper
@@ -151,18 +193,18 @@ def retry_contextmanager(
_retry_timeout = kw.pop("retry_timeout", retry_timeout)
_retry_period = kw.pop("retry_period", retry_period)
_retry_on_error = kw.pop("retry_on_error", retry_on_error)
- for options in _retry_loop(
+ for retry_state in _retry_loop(
retry_timeout=_retry_timeout,
retry_period=_retry_period,
retry_on_error=_retry_on_error,
):
- with _handle_exception(options):
- gen = method(*args, **kw)
- result = next(gen)
- options["retry_on_error"] = None
+ with _handle_exception(retry_state):
+ ctx = method(*args, **kw)
+ result = next(ctx)
+ retry_state["retry_on_error"] = None
yield result
try:
- next(gen)
+ next(ctx)
except StopIteration:
return
else:
@@ -238,10 +280,10 @@ def retry_in_subprocess(
p, queue = start_subprocess()
try:
- for options in _retry_loop(
+ for retry_state in _retry_loop(
retry_timeout=_retry_timeout, retry_on_error=_retry_on_error
):
- with _handle_exception(options):
+ with _handle_exception(retry_state):
if not p.is_alive():
p, queue = start_subprocess()
try:
diff --git a/src/silx/utils/setup.py b/src/silx/utils/setup.py
deleted file mode 100644
index 1f3e09a..0000000
--- a/src/silx/utils/setup.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# coding: utf-8
-# /*##########################################################################
-#
-# Copyright (c) 2016 European Synchrotron Radiation Facility
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#
-# ###########################################################################*/
-__authors__ = ["V. Valls"]
-__license__ = "MIT"
-__date__ = "24/08/2016"
-
-
-from numpy.distutils.misc_util import Configuration
-
-
-def configuration(parent_package='', top_path=None):
- config = Configuration('utils', parent_package, top_path)
- config.add_subpackage('test')
-
- return config
-
-
-if __name__ == "__main__":
- from numpy.distutils.core import setup
-
- setup(configuration=configuration)
diff --git a/src/silx/utils/test/__init__.py b/src/silx/utils/test/__init__.py
index 14fd940..88135c3 100755
--- a/src/silx/utils/test/__init__.py
+++ b/src/silx/utils/test/__init__.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2021 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/test/test_array_like.py b/src/silx/utils/test/test_array_like.py
index a0b4b7b..309b9ff 100644
--- a/src/silx/utils/test/test_array_like.py
+++ b/src/silx/utils/test/test_array_like.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/test/test_debug.py b/src/silx/utils/test/test_debug.py
index 09f4b01..6b7b5d6 100644
--- a/src/silx/utils/test/test_debug.py
+++ b/src/silx/utils/test/test_debug.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2021 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/test/test_deprecation.py b/src/silx/utils/test/test_deprecation.py
index d52cb26..798221a 100644
--- a/src/silx/utils/test/test_deprecation.py
+++ b/src/silx/utils/test/test_deprecation.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2021 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/test/test_enum.py b/src/silx/utils/test/test_enum.py
index 808304a..df6b266 100644
--- a/src/silx/utils/test/test_enum.py
+++ b/src/silx/utils/test/test_enum.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2019 European Synchrotron Radiation Facility
@@ -24,8 +23,6 @@
# ###########################################################################*/
"""Tests of Enum class with extra class methods"""
-from __future__ import absolute_import
-
__authors__ = ["T. Vincent"]
__license__ = "MIT"
__date__ = "29/04/2019"
diff --git a/src/silx/utils/test/test_external_resources.py b/src/silx/utils/test/test_external_resources.py
index 1fedda3..6279460 100644
--- a/src/silx/utils/test/test_external_resources.py
+++ b/src/silx/utils/test/test_external_resources.py
@@ -1,7 +1,6 @@
-# coding: utf-8
# /*##########################################################################
#
-# Copyright (c) 2016-2021 European Synchrotron Radiation Facility
+# Copyright (c) 2016-2022 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -59,7 +58,7 @@ class TestExternalResources(unittest.TestCase):
raise unittest.SkipTest("Network or silx website not available")
def setUp(self):
- self.resources = ExternalResources("toto", "http://www.silx.org/pub/silx/")
+ self.resources = ExternalResources("toto%d" % os.getpid(), "http://www.silx.org/pub/silx/")
def tearDown(self):
if self.resources.data_home:
diff --git a/src/silx/utils/test/test_launcher.py b/src/silx/utils/test/test_launcher.py
index 9e9024c..3261df5 100644
--- a/src/silx/utils/test/test_launcher.py
+++ b/src/silx/utils/test/test_launcher.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/test/test_launcher_command.py b/src/silx/utils/test/test_launcher_command.py
index ccf4601..ff9f336 100644
--- a/src/silx/utils/test/test_launcher_command.py
+++ b/src/silx/utils/test/test_launcher_command.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/test/test_number.py b/src/silx/utils/test/test_number.py
index 3eb8e91..8c6d1a2 100644
--- a/src/silx/utils/test/test_number.py
+++ b/src/silx/utils/test/test_number.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
# Copyright (C) 2016-2021 European Synchrotron Radiation Facility
#
diff --git a/src/silx/utils/test/test_proxy.py b/src/silx/utils/test/test_proxy.py
index e165267..7af4d1f 100644
--- a/src/silx/utils/test/test_proxy.py
+++ b/src/silx/utils/test/test_proxy.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2019 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/test/test_retry.py b/src/silx/utils/test/test_retry.py
index 39bfdcf..7e06e65 100644
--- a/src/silx/utils/test/test_retry.py
+++ b/src/silx/utils/test/test_retry.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
#
@@ -167,3 +166,47 @@ class TestRetry(unittest.TestCase):
f.write("0")
with self.assertRaises(retry.RetryTimeoutError):
_wsubmain(self.ctr_file, **kw)
+
+ def test_retry_generator(self):
+ ncausefailure = 3
+ faildelay = 0.1
+ sufficient_timeout = ncausefailure * (faildelay + 10)
+ insufficient_timeout = ncausefailure * faildelay * 0.5
+
+ @retry.retry()
+ def method(check, kwcheck=None, start_index=0):
+ if start_index <= 0:
+ yield 0
+ assert check
+ assert kwcheck
+ nonlocal failcounter
+ if failcounter < ncausefailure:
+ time.sleep(faildelay)
+ failcounter += 1
+ if start_index <= 1:
+ yield 1
+ raise retry.RetryError
+ else:
+ if start_index <= 1:
+ yield 1
+ if start_index <= 2:
+ yield 2
+
+ failcounter = 0
+ kw = {"kwcheck": True, "retry_timeout": sufficient_timeout}
+ self.assertEqual(list(method(True, **kw)), [0, 1, 2])
+
+ failcounter = 0
+ kw = {
+ "kwcheck": True,
+ "retry_timeout": insufficient_timeout,
+ }
+ with self.assertRaises(retry.RetryTimeoutError):
+ list(method(True, **kw))
+
+ def test_retry_wrong_generator(self):
+ with self.assertRaises(TypeError):
+
+ @retry.retry()
+ def method():
+ yield from range(3)
diff --git a/src/silx/utils/test/test_testutils.py b/src/silx/utils/test/test_testutils.py
index 4f07c4e..a0624b1 100755
--- a/src/silx/utils/test/test_testutils.py
+++ b/src/silx/utils/test/test_testutils.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2021 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/test/test_weakref.py b/src/silx/utils/test/test_weakref.py
index 06f3adf..4e3bf21 100644
--- a/src/silx/utils/test/test_weakref.py
+++ b/src/silx/utils/test/test_weakref.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2019 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/testutils.py b/src/silx/utils/testutils.py
index 4177e33..b331829 100755
--- a/src/silx/utils/testutils.py
+++ b/src/silx/utils/testutils.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2021 European Synchrotron Radiation Facility
diff --git a/src/silx/utils/weakref.py b/src/silx/utils/weakref.py
index 06646e8..62a9232 100644
--- a/src/silx/utils/weakref.py
+++ b/src/silx/utils/weakref.py
@@ -1,4 +1,3 @@
-# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2018 European Synchrotron Radiation Facility
@@ -25,7 +24,6 @@
"""Weakref utils for compatibility between Python 2 and Python 3 or for
extended features.
"""
-from __future__ import absolute_import
__authors__ = ["V. Valls"]
__license__ = "MIT"