From 4fd7ed82106d0f7788d13cf59d21d6242e2ba473 Mon Sep 17 00:00:00 2001
From: Samuel Gaist <samuel.gaist@idiap.ch>
Date: Mon, 6 May 2019 12:30:32 +0200
Subject: [PATCH] [algorithm] Pre-commit cleanup

---
 beat/backend/python/algorithm.py | 476 +++++++++++++++++--------------
 1 file changed, 254 insertions(+), 222 deletions(-)

diff --git a/beat/backend/python/algorithm.py b/beat/backend/python/algorithm.py
index 3905f82..3757208 100644
--- a/beat/backend/python/algorithm.py
+++ b/beat/backend/python/algorithm.py
@@ -76,14 +76,14 @@ class Storage(utils.CodeStorage):
 
     def __init__(self, prefix, name, language=None):
 
-        if name.count('/') != 2:
+        if name.count("/") != 2:
             raise RuntimeError("invalid algorithm name: `%s'" % name)
 
-        self.username, self.name, self.version = name.split('/')
+        self.username, self.name, self.version = name.split("/")
         self.fullname = name
         self.prefix = prefix
 
-        path = utils.hashed_or_simple(self.prefix, 'algorithms', name, suffix='.json')
+        path = utils.hashed_or_simple(self.prefix, "algorithms", name, suffix=".json")
         path = path[:-5]
         super(Storage, self).__init__(path, language)
 
@@ -115,30 +115,28 @@ class Runner(object):
 
         try:
             class_ = getattr(module, obj_name)
-        except Exception as e:
+        except Exception:
             if exc is not None:
                 type, value, traceback = sys.exc_info()
                 six.reraise(exc, exc(value), traceback)
             else:
                 raise  # Just re-raise the user exception
 
-        self.obj = loader.run(class_, '__new__', exc)
+        self.obj = loader.run(class_, "__new__", exc)
         self.name = module.__name__
         self.algorithm = algorithm
         self.exc = exc
 
-        self.ready = not hasattr(self.obj, 'setup')
+        self.ready = not hasattr(self.obj, "setup")
 
         has_api_v1 = self.algorithm.api_version == 1
-        has_prepare = hasattr(self.obj, 'prepare')
+        has_prepare = hasattr(self.obj, "prepare")
 
         self.prepared = has_api_v1 or not has_prepare
 
         if has_api_v1 and has_prepare:
             logger.warning("Prepare is a reserved function name starting with API V2")
 
-
-
     def _check_parameters(self, parameters):
         """Checks input parameters from the user and fill defaults"""
 
@@ -149,12 +147,11 @@ class Runner(object):
         # Checks the user is not trying to set an undeclared parameter
         if not user_keys.issubset(valid_keys):
             err_keys = user_keys - valid_keys
-            message = "parameters `%s' are not declared for algorithm `%s' - " \
-                      "valid parameters are `%s'" % (
-                            ','.join(err_keys),
-                            self.name,
-                            ','.join(valid_keys),
-                      )
+            message = (
+                "parameters `%s' are not declared for algorithm `%s' - "
+                "valid parameters are `%s'"
+                % (",".join(err_keys), self.name, ",".join(valid_keys))
+            )
             exc = self.exc or KeyError
             raise exc(message)
 
@@ -166,20 +163,21 @@ class Runner(object):
                 try:
                     value = self.algorithm.clean_parameter(key, parameters[key])
                 except Exception as e:
-                    message = "parameter `%s' cannot be safely cast to the declared " \
-                            "type on algorithm `%s': %s" % (key, self.name, e)
+                    message = (
+                        "parameter `%s' cannot be safely cast to the declared "
+                        "type on algorithm `%s': %s" % (key, self.name, e)
+                    )
                     exc = self.exc or ValueError
                     raise exc(message)
 
             else:  # User has not set a value, use the default
-                value = algo_parameters[key]['default']
+                value = algo_parameters[key]["default"]
 
             # In the end, set the value on the dictionary to be returned
             retval[key] = value
 
         return retval
 
-
     def setup(self, parameters):
         """Sets up the algorithm, only effective on the first call"""
 
@@ -189,10 +187,9 @@ class Runner(object):
 
         completed_parameters = self._check_parameters(parameters)
 
-        self.ready = loader.run(self.obj, 'setup', self.exc, completed_parameters)
+        self.ready = loader.run(self.obj, "setup", self.exc, completed_parameters)
         return self.ready
 
-
     def prepare(self, data_loaders):
         """Let the algorithm process the data on the non-principal channels"""
 
@@ -211,25 +208,33 @@ class Runner(object):
             return True
 
         # The method is optional
-        if hasattr(self.obj, 'prepare'):
+        if hasattr(self.obj, "prepare"):
             if self.algorithm.type in [Algorithm.AUTONOMOUS, Algorithm.LOOP_USER]:
-                self.prepared = loader.run(self.obj, 'prepare', self.exc, data_loaders.secondaries())
+                self.prepared = loader.run(
+                    self.obj, "prepare", self.exc, data_loaders.secondaries()
+                )
             else:
-                self.prepared = loader.run(self.obj, 'prepare', self.exc, data_loaders)
+                self.prepared = loader.run(self.obj, "prepare", self.exc, data_loaders)
         else:
             self.prepared = True
 
         return self.prepared
 
-
-    def process(self, inputs=None, data_loaders=None, outputs=None, output=None, loop_channel=None):
+    def process(
+        self,
+        inputs=None,
+        data_loaders=None,
+        outputs=None,
+        output=None,
+        loop_channel=None,
+    ):
         """Runs through data"""
 
         exc = self.exc or RuntimeError
 
         def _check_argument(argument, name):
             if argument is None:
-                raise exc('Missing argument: %s' % name)
+                raise exc("Missing argument: %s" % name)
 
         # setup() must have run
         if not self.ready:
@@ -241,42 +246,48 @@ class Runner(object):
 
         # Call the correct version of process()
         if self.algorithm.isAnalyzer:
-            _check_argument(output, 'output')
+            _check_argument(output, "output")
             outputs_to_use = output
         else:
-            _check_argument(outputs, 'outputs')
+            _check_argument(outputs, "outputs")
             outputs_to_use = outputs
 
         if self.algorithm.type == Algorithm.LEGACY:
-            _check_argument(inputs, 'inputs')
-            return loader.run(self.obj, 'process', self.exc, inputs, outputs_to_use)
+            _check_argument(inputs, "inputs")
+            return loader.run(self.obj, "process", self.exc, inputs, outputs_to_use)
 
         else:
-            _check_argument(data_loaders, 'data_loaders')
+            _check_argument(data_loaders, "data_loaders")
 
             if self.algorithm.type == Algorithm.SEQUENTIAL:
-                _check_argument(inputs, 'inputs')
+                _check_argument(inputs, "inputs")
 
-                return loader.run(self.obj, 'process', self.exc, inputs, data_loaders,
-                                  outputs_to_use)
+                return loader.run(
+                    self.obj, "process", self.exc, inputs, data_loaders, outputs_to_use
+                )
 
             elif self.algorithm.is_autonomous:
-                run_args = [self.obj, 'process', self.exc, data_loaders, outputs_to_use]
+                run_args = [self.obj, "process", self.exc, data_loaders, outputs_to_use]
 
-                has_loop_arg = utils.has_argument(self.obj.process, 'loop_channel')
+                has_loop_arg = utils.has_argument(self.obj.process, "loop_channel")
                 if loop_channel is not None:
                     if has_loop_arg:
                         run_args.append(loop_channel)
                     else:
-                        raise exc("Algorithm '%s' is not a valid loop enabled algorithm" % self.name)
+                        raise exc(
+                            "Algorithm '%s' is not a valid loop enabled algorithm"
+                            % self.name
+                        )
                 elif has_loop_arg:
-                    raise exc("Algorithm '%s' is a loop enabled algorithm but no loop_channel given" % self.name)
+                    raise exc(
+                        "Algorithm '%s' is a loop enabled algorithm but no loop_channel given"
+                        % self.name
+                    )
 
                 return loader.run(*run_args)
 
             else:
-                raise exc('Unknown algorithm type: %s' % self.algorithm.type)
-
+                raise exc("Unknown algorithm type: %s" % self.algorithm.type)
 
     def validate(self, result):
         """Validates the given results"""
@@ -284,7 +295,7 @@ class Runner(object):
         exc = self.exc or RuntimeError
 
         if self.algorithm.type != Algorithm.LOOP:
-            raise exc('Wrong algorithm type: %s' % self.algorithm.type)
+            raise exc("Wrong algorithm type: %s" % self.algorithm.type)
 
         # setup() must have run
         if not self.ready:
@@ -294,14 +305,13 @@ class Runner(object):
         if not self.prepared:
             raise exc("Algorithm '%s' is not yet prepared" % self.name)
 
-        answer = loader.run(self.obj, 'validate', self.exc, result)
+        answer = loader.run(self.obj, "validate", self.exc, result)
 
         if not isinstance(answer, tuple):
             raise exc("Improper implementation: validate must return a tuple")
 
         return answer
 
-
     def __getattr__(self, key):
         """Returns an attribute of the algorithm - only called at last resort
         """
@@ -385,12 +395,11 @@ class Algorithm(object):
 
     """
 
-    LEGACY     = 'legacy'
-    SEQUENTIAL = 'sequential'
-    AUTONOMOUS = 'autonomous'
-    LOOP = 'loop'
-    LOOP_USER = 'loop_user'
-
+    LEGACY = "legacy"
+    SEQUENTIAL = "sequential"
+    AUTONOMOUS = "autonomous"
+    LOOP = "loop"
+    LOOP_USER = "loop_user"
 
     def __init__(self, prefix, name, dataformat_cache=None, library_cache=None):
 
@@ -407,7 +416,6 @@ class Algorithm(object):
 
         self._load(name, dataformat_cache, library_cache)
 
-
     def _load(self, data, dataformat_cache, library_cache):
         """Loads the algorithm"""
 
@@ -416,67 +424,76 @@ class Algorithm(object):
         self.storage = Storage(self.prefix, data)
         json_path = self.storage.json.path
         if not self.storage.exists():
-            self.errors.append('Algorithm declaration file not found: %s' % json_path)
+            self.errors.append("Algorithm declaration file not found: %s" % json_path)
             return
 
-        with open(json_path, 'rb') as f:
-            self.data = simplejson.loads(f.read().decode('utf-8'))
+        with open(json_path, "rb") as f:
+            self.data = simplejson.loads(f.read().decode("utf-8"))
 
         self.code_path = self.storage.code.path
         self.code = self.storage.code.load()
 
-        self.groups = self.data['groups']
+        self.groups = self.data["groups"]
 
         # create maps for easy access to data
-        self.input_map = dict([(k,v['type']) for g in self.groups \
-                for k,v in g['inputs'].items()])
-        self.output_map = dict([(k,v['type']) for g in self.groups \
-                for k,v in g.get('outputs', {}).items()])
-        self.loop_map = dict([(k,v['type']) for g in self.groups \
-                for k,v in g.get('loop', {}).items()])
+        self.input_map = dict(
+            [(k, v["type"]) for g in self.groups for k, v in g["inputs"].items()]
+        )
+        self.output_map = dict(
+            [
+                (k, v["type"])
+                for g in self.groups
+                for k, v in g.get("outputs", {}).items()
+            ]
+        )
+        self.loop_map = dict(
+            [(k, v["type"]) for g in self.groups for k, v in g.get("loop", {}).items()]
+        )
 
         self._load_dataformats(dataformat_cache)
         self._convert_parameter_types()
         self._load_libraries(library_cache)
 
-
     def _load_dataformats(self, dataformat_cache):
         """Makes sure we can load all requested formats
         """
 
         for group in self.groups:
 
-            for name, input in group['inputs'].items():
-                if input['type'] in self.dataformats: continue
+            for name, input in group["inputs"].items():
+                if input["type"] in self.dataformats:
+                    continue
 
-                if dataformat_cache and input['type'] in dataformat_cache: #reuse
-                    thisformat = dataformat_cache[input['type']]
+                if dataformat_cache and input["type"] in dataformat_cache:  # reuse
+                    thisformat = dataformat_cache[input["type"]]
                 else:  # load it
-                    thisformat = dataformat.DataFormat(self.prefix, input['type'])
+                    thisformat = dataformat.DataFormat(self.prefix, input["type"])
                     if dataformat_cache is not None:  # update it
-                        dataformat_cache[input['type']] = thisformat
+                        dataformat_cache[input["type"]] = thisformat
 
-                self.dataformats[input['type']] = thisformat
+                self.dataformats[input["type"]] = thisformat
 
-            if 'outputs' not in group: continue
+            if "outputs" not in group:
+                continue
 
-            for name, output in group['outputs'].items():
-                if output['type'] in self.dataformats: continue
+            for name, output in group["outputs"].items():
+                if output["type"] in self.dataformats:
+                    continue
 
-                if dataformat_cache and output['type'] in dataformat_cache:  # reuse
-                    thisformat = dataformat_cache[output['type']]
+                if dataformat_cache and output["type"] in dataformat_cache:  # reuse
+                    thisformat = dataformat_cache[output["type"]]
                 else:  # load it
-                    thisformat = dataformat.DataFormat(self.prefix, output['type'])
-                    if dataformat_cache is not None: #update it
-                        dataformat_cache[output['type']] = thisformat
+                    thisformat = dataformat.DataFormat(self.prefix, output["type"])
+                    if dataformat_cache is not None:  # update it
+                        dataformat_cache[output["type"]] = thisformat
 
-                self.dataformats[output['type']] = thisformat
+                self.dataformats[output["type"]] = thisformat
 
-            if 'loop' not in group:
+            if "loop" not in group:
                 continue
 
-            for name, entry in group['loop'].items():
-                entry_format = entry['type']
+            for name, entry in group["loop"].items():
+                entry_format = entry["type"]
                 if entry_format in self.dataformats:
                     continue
 
@@ -489,24 +506,23 @@ class Algorithm(object):
 
                 self.dataformats[entry_format] = thisformat
 
-
         if self.results:
 
             for name, result in self.results.items():
 
-                if result['type'].find('/') != -1:
+                if result["type"].find("/") != -1:
 
-                    if result['type'] in self.dataformats: continue
+                    if result["type"] in self.dataformats:
+                        continue
 
-                    if dataformat_cache and result['type'] in dataformat_cache: #reuse
-                        thisformat = dataformat_cache[result['type']]
+                    if dataformat_cache and result["type"] in dataformat_cache:  # reuse
+                        thisformat = dataformat_cache[result["type"]]
                     else:
-                        thisformat = dataformat.DataFormat(self.prefix, result['type'])
-                        if dataformat_cache is not None: #update it
-                            dataformat_cache[result['type']] = thisformat
-
-                    self.dataformats[result['type']] = thisformat
+                        thisformat = dataformat.DataFormat(self.prefix, result["type"])
+                        if dataformat_cache is not None:  # update it
+                            dataformat_cache[result["type"]] = thisformat
 
+                    self.dataformats[result["type"]] = thisformat
 
     def _convert_parameter_types(self):
         """Converts types to numpy equivalents, checks defaults, ranges and choices
@@ -516,49 +532,75 @@ class Algorithm(object):
             try:
                 return tp.type(value)
             except Exception as e:
-                self.errors.append("%s for parameter `%s' cannot be cast to type " \
-                        "`%s': %s" % (desc, name, tp.name, e))
+                self.errors.append(
+                    "%s for parameter `%s' cannot be cast to type "
+                    "`%s': %s" % (desc, name, tp.name, e)
+                )
 
-        if self.parameters is None: return
+        if self.parameters is None:
+            return
 
         for name, parameter in self.parameters.items():
-            if parameter['type'] == 'string':
-                parameter['type'] = numpy.dtype('str')
+            if parameter["type"] == "string":
+                parameter["type"] = numpy.dtype("str")
             else:
-                parameter['type'] = numpy.dtype(parameter['type'])
-
-            if 'range' in parameter:
-                parameter['range'][0] = _try_convert(name, parameter['type'],
-                    parameter['range'][0], 'start of range')
-                parameter['range'][1] = _try_convert(name, parameter['type'],
-                    parameter['range'][1], 'end of range')
-                if parameter['range'][0] >= parameter['range'][1]:
-                    self.errors.append("range for parameter `%s' has a start greater " \
-                            "then the end value (%r >= %r)" % \
-                            (name, parameter['range'][0], parameter['range'][1]))
-
-            if 'choice' in parameter:
-                for i, choice in enumerate(parameter['choice']):
-                    parameter['choice'][i] = _try_convert(name, parameter['type'],
-                        parameter['choice'][i], 'choice[%d]' % i)
-
-            if 'default' in parameter:
-                parameter['default'] = _try_convert(name, parameter['type'],
-                    parameter['default'], 'default')
-
-                if 'range' in parameter: #check range
-                    if parameter['default'] < parameter['range'][0] or \
-                            parameter['default'] > parameter['range'][1]:
-                        self.errors.append("default for parameter `%s' (%r) is not " \
-                          "within parameter range [%r, %r]" % (name, parameter['default'],
-                              parameter['range'][0], parameter['range'][1]))
-
-                if 'choice' in parameter: #check choices
-                    if parameter['default'] not in parameter['choice']:
-                        self.errors.append("default for parameter `%s' (%r) is not " \
-                          "a valid choice `[%s]'" % (name, parameter['default'],
-                              ', '.join(['%r' % k for k in parameter['choice']])))
+                parameter["type"] = numpy.dtype(parameter["type"])
+
+            if "range" in parameter:
+                parameter["range"][0] = _try_convert(
+                    name, parameter["type"], parameter["range"][0], "start of range"
+                )
+                parameter["range"][1] = _try_convert(
+                    name, parameter["type"], parameter["range"][1], "end of range"
+                )
+                if parameter["range"][0] >= parameter["range"][1]:
+                    self.errors.append(
+                        "range for parameter `%s' has a start greater "
+                        "then the end value (%r >= %r)"
+                        % (name, parameter["range"][0], parameter["range"][1])
+                    )
+
+            if "choice" in parameter:
+                for i, choice in enumerate(parameter["choice"]):
+                    parameter["choice"][i] = _try_convert(
+                        name,
+                        parameter["type"],
+                        parameter["choice"][i],
+                        "choice[%d]" % i,
+                    )
+
+            if "default" in parameter:
+                parameter["default"] = _try_convert(
+                    name, parameter["type"], parameter["default"], "default"
+                )
+
+                if "range" in parameter:  # check range
+                    if (
+                        parameter["default"] < parameter["range"][0]
+                        or parameter["default"] > parameter["range"][1]
+                    ):
+                        self.errors.append(
+                            "default for parameter `%s' (%r) is not "
+                            "within parameter range [%r, %r]"
+                            % (
+                                name,
+                                parameter["default"],
+                                parameter["range"][0],
+                                parameter["range"][1],
+                            )
+                        )
 
+                if "choice" in parameter:  # check choices
+                    if parameter["default"] not in parameter["choice"]:
+                        self.errors.append(
+                            "default for parameter `%s' (%r) is not "
+                            "a valid choice `[%s]'"
+                            % (
+                                name,
+                                parameter["default"],
+                                ", ".join(["%r" % k for k in parameter["choice"]]),
+                            )
+                        )
 
     def _load_libraries(self, library_cache):
 
@@ -568,16 +610,15 @@ class Algorithm(object):
 
             for name, value in self.uses.items():
 
-                self.libraries[value] = library_cache.setdefault(value,
-                        library.Library(self.prefix, value, library_cache))
-
+                self.libraries[value] = library_cache.setdefault(
+                    value, library.Library(self.prefix, value, library_cache)
+                )
 
     @property
     def name(self):
         """Returns the name of this object
         """
-        return self._name or '__unnamed_algorithm__'
-
+        return self._name or "__unnamed_algorithm__"
 
     @name.setter
     def name(self, value):
@@ -587,30 +628,26 @@ class Algorithm(object):
             name (str): Name of this object
         """
 
-        if self.data['language'] == 'unknown':
+        if self.data["language"] == "unknown":
             raise RuntimeError("algorithm has no programming language set")
 
         self._name = value
-        self.storage = Storage(self.prefix, value, self.data['language'])
-
+        self.storage = Storage(self.prefix, value, self.data["language"])
 
     @property
     def schema_version(self):
         """Returns the schema version"""
-        return self.data.get('schema_version', 1)
-
+        return self.data.get("schema_version", 1)
 
     @property
     def language(self):
         """Returns the current language set for the executable code"""
-        return self.data['language']
-
+        return self.data["language"]
 
     @property
     def api_version(self):
         """Returns the API version"""
-        return self.data.get('api_version', 1)
-
+        return self.data.get("api_version", 1)
 
     @property
     def type(self):
@@ -618,24 +655,19 @@ class Algorithm(object):
         if self.api_version == 1:
             return Algorithm.LEGACY
 
-        return self.data.get('type', Algorithm.SEQUENTIAL)
-
+        return self.data.get("type", Algorithm.SEQUENTIAL)
 
     @property
     def is_autonomous(self):
         """ Returns whether the algorithm is in the autonomous category"""
-        return self.type in [Algorithm.AUTONOMOUS,
-                             Algorithm.LOOP_USER,
-                             Algorithm.LOOP]
-
+        return self.type in [Algorithm.AUTONOMOUS, Algorithm.LOOP_USER, Algorithm.LOOP]
 
     @language.setter
     def language(self, value):
         """Sets the current executable code programming language"""
         if self.storage:
             self.storage.language = value
-        self.data['language'] = value
-
+        self.data["language"] = value
 
     def clean_parameter(self, parameter, value):
         """Checks if a given value against a declared parameter
@@ -672,99 +704,100 @@ class Algorithm(object):
         if (self.parameters is None) or (parameter not in self.parameters):
             raise KeyError(parameter)
 
-        retval = self.parameters[parameter]['type'].type(value)
-
-        if 'choice' in self.parameters[parameter] and \
-                retval not in self.parameters[parameter]['choice']:
-            raise ValueError("value for `%s' (%r) must be one of `[%s]'" % \
-                    (parameter, value, ', '.join(['%r' % k for k in \
-                    self.parameters[parameter]['choice']])))
-
-        if 'range' in self.parameters[parameter] and \
-                (retval < self.parameters[parameter]['range'][0] or \
-                retval > self.parameters[parameter]['range'][1]):
-            raise ValueError("value for `%s' (%r) must be picked within " \
-                    "interval `[%r, %r]'" % (parameter, value,
-                        self.parameters[parameter]['range'][0],
-                        self.parameters[parameter]['range'][1]))
+        retval = self.parameters[parameter]["type"].type(value)
+
+        if (
+            "choice" in self.parameters[parameter]
+            and retval not in self.parameters[parameter]["choice"]
+        ):
+            raise ValueError(
+                "value for `%s' (%r) must be one of `[%s]'"
+                % (
+                    parameter,
+                    value,
+                    ", ".join(["%r" % k for k in self.parameters[parameter]["choice"]]),
+                )
+            )
+
+        if "range" in self.parameters[parameter] and (
+            retval < self.parameters[parameter]["range"][0]
+            or retval > self.parameters[parameter]["range"][1]
+        ):
+            raise ValueError(
+                "value for `%s' (%r) must be picked within "
+                "interval `[%r, %r]'"
+                % (
+                    parameter,
+                    value,
+                    self.parameters[parameter]["range"][0],
+                    self.parameters[parameter]["range"][1],
+                )
+            )
 
         return retval
 
-
     @property
     def valid(self):
         """A boolean that indicates if this algorithm is valid or not"""
 
         return not bool(self.errors)
 
-
     @property
     def uses(self):
-        return self.data.get('uses')
-
+        return self.data.get("uses")
 
     @uses.setter
     def uses(self, value):
-        self.data['uses'] = value
+        self.data["uses"] = value
         return value
 
-
     @property
     def isAnalyzer(self):
         """Returns whether this algorithms is an analyzer"""
 
-        return (self.results is not None)
-
+        return self.results is not None
 
     @property
     def results(self):
         """The results of this algorithm"""
 
-        return self.data.get('results')
-
+        return self.data.get("results")
 
     @results.setter
     def results(self, value):
-        self.data['results'] = value
+        self.data["results"] = value
         return value
 
-
     @property
     def parameters(self):
         """The parameters of this algorithm"""
 
-        return self.data.get('parameters')
-
+        return self.data.get("parameters")
 
     @parameters.setter
     def parameters(self, value):
-        self.data['parameters'] = value
+        self.data["parameters"] = value
         return value
 
-
     @property
     def splittable(self):
         """Whether this algorithm can be split between several processes"""
-        return self.data.get('splittable', False)
-
+        return self.data.get("splittable", False)
 
     @splittable.setter
     def splittable(self, value):
-        self.data['splittable'] = value
+        self.data["splittable"] = value
         return value
 
-
     @property
     def description(self):
         """The short description for this object"""
-        return self.data.get('description', None)
-
+        return self.data.get("description", None)
 
     @description.setter
     def description(self, value):
         """Sets the short description for this object"""
-        self.data['description'] = value
-
+        self.data["description"] = value
 
     @property
     def documentation(self):
@@ -777,7 +810,6 @@ class Algorithm(object):
             return self.storage.doc.load()
         return None
 
-
     @documentation.setter
     def documentation(self, value):
         """Sets the full-length description for this object"""
@@ -785,12 +817,11 @@ class Algorithm(object):
         if not self._name:
             raise RuntimeError("algorithm has no name")
 
-        if hasattr(value, 'read'):
+        if hasattr(value, "read"):
             self.storage.doc.save(value.read())
         else:
             self.storage.doc.save(value)
 
-
     def hash(self):
         """Returns the hexadecimal hash for the current algorithm"""
 
@@ -799,26 +830,26 @@ class Algorithm(object):
 
         return self.storage.hash()
 
-
     def result_dataformat(self):
         """Generates, on-the-fly, the dataformat for the result readout"""
 
         if not self.results:
-            raise TypeError("algorithm `%s' is a block algorithm, not an analyzer" \
-                    % (self.name))
+            raise TypeError(
+                "algorithm `%s' is a block algorithm, not an analyzer" % (self.name)
+            )
 
-        format = dataformat.DataFormat(self.prefix,
-                dict([(k, v['type']) for k,v in self.results.items()]))
+        format = dataformat.DataFormat(
+            self.prefix, dict([(k, v["type"]) for k, v in self.results.items()])
+        )
 
-        format.name = 'analysis:' + self.name
+        format.name = "analysis:" + self.name
 
         return format
 
-
     def uses_dict(self):
         """Returns the usage dictionary for all dependent modules"""
 
-        if self.data['language'] == 'unknown':
+        if self.data["language"] == "unknown":
             raise RuntimeError("algorithm has no programming language set")
 
         if not self._name:
@@ -829,14 +860,13 @@ class Algorithm(object):
         if self.uses is not None:
             for name, value in self.uses.items():
                 retval[name] = dict(
-                        path=self.libraries[value].storage.code.path,
-                        uses=self.libraries[value].uses_dict(),
-                        )
+                    path=self.libraries[value].storage.code.path,
+                    uses=self.libraries[value].uses_dict(),
+                )
 
         return retval
 
-
-    def runner(self, klass='Algorithm', exc=None):
+    def runner(self, klass="Algorithm", exc=None):
         """Returns a runnable algorithm object.
 
         Parameters:
@@ -857,7 +887,7 @@ class Algorithm(object):
             exc = exc or RuntimeError
             raise exc("algorithm has no name")
 
-        if self.data['language'] == 'unknown':
+        if self.data["language"] == "unknown":
             exc = exc or RuntimeError
             raise exc("algorithm has no programming language set")
 
@@ -868,19 +898,24 @@ class Algorithm(object):
 
         # loads the module only once through the lifetime of the algorithm object
         try:
-            self.__module = getattr(self, 'module',
-                    loader.load_module(self.name.replace(os.sep, '_'),
-                        self.storage.code.path, self.uses_dict()))
-        except Exception as e:
+            self.__module = getattr(
+                self,
+                "module",
+                loader.load_module(
+                    self.name.replace(os.sep, "_"),
+                    self.storage.code.path,
+                    self.uses_dict(),
+                ),
+            )
+        except Exception:
             if exc is not None:
                 type, value, traceback = sys.exc_info()
                 six.reraise(exc, exc(value), traceback)
             else:
-                raise #just re-raise the user exception
+                raise  # just re-raise the user exception
 
         return Runner(self.__module, klass, self, exc)
 
-
     def json_dumps(self, indent=4):
         """Dumps the JSON declaration of this object in a string
 
@@ -896,14 +931,11 @@ class Algorithm(object):
 
         """
 
-        return simplejson.dumps(self.data, indent=indent,
-            cls=utils.NumpyJSONEncoder)
-
+        return simplejson.dumps(self.data, indent=indent, cls=utils.NumpyJSONEncoder)
 
     def __str__(self):
         return self.json_dumps()
 
-
     def write(self, storage=None):
         """Writes contents to prefix location
 
@@ -915,17 +947,16 @@ class Algorithm(object):
 
         """
 
-        if self.data['language'] == 'unknown':
+        if self.data["language"] == "unknown":
             raise RuntimeError("algorithm has no programming language set")
 
         if storage is None:
             if not self._name:
                 raise RuntimeError("algorithm has no name")
-            storage = self.storage #overwrite
+            storage = self.storage  # overwrite
 
         storage.save(str(self), self.code, self.description)
 
-
     def export(self, prefix):
         """Recursively exports itself into another prefix
 
@@ -955,8 +986,9 @@ class Algorithm(object):
             raise RuntimeError("algorithm is not valid:\n%s" % "\n".join(self.errors))
 
         if prefix == self.prefix:
-            raise RuntimeError("Cannot export algorithm to the same prefix ("
-                               "%s)" % prefix)
+            raise RuntimeError(
+                "Cannot export algorithm to the same prefix (" "%s)" % prefix
+            )
 
         for k in self.libraries.values():
             k.export(prefix)
-- 
GitLab