Exemple #1
0
    def replace_prefix(self, path, property=None):
        if (self.trie is None and self.prefix is None) or (
                property in self.skip_properties or os.path.isabs(path)
                or path.startswith("..") or is_flagged(path, "remote_object")
                or is_callable(path)):
            # no replacement
            return path

        if self.trie is not None:
            prefixes = self.trie.prefix_items(str(path))
            if len(prefixes) > 1:
                # ambiguous prefixes
                raise WorkflowError(
                    "Multiple prefixes ({}) match the path {}. Make sure that the replace_prefix statement "
                    "in your module definition does not yield ambiguous matches."
                    .format(", ".join(prefix[0] for prefix in prefixes), path))
            elif prefixes:
                # replace prefix
                prefix, replacement = prefixes[0]
                return replacement + path[len(prefix):]
            else:
                # no matching prefix
                return path
        else:
            # prefix case
            return self.prefix + path
Exemple #2
0
        def modify_callable(item):
            if is_callable(item):
                # For callables ensure that the rule's original path modifier is applied as well.

                def inner(wildcards):
                    return self.rule.apply_path_modifier(
                        item(wildcards),
                        self.rule.input_modifier,
                        property="input")

                return inner
            else:
                # For strings, the path modifier has been already applied.
                return item
Exemple #3
0
def expand_report_argument(item, wildcards, job):
    if is_callable(item):
        aux_params = get_input_function_aux_params(item,
                                                   {"params": job.params})
        try:
            item = item(wildcards, **aux_params)
        except Exception as e:
            raise InputFunctionException(e, rule=job.rule, wildcards=wildcards)
    if isinstance(item, str):
        try:
            return apply_wildcards(item, wildcards)
        except AttributeError as e:
            raise WorkflowError("Failed to resolve wildcards.",
                                e,
                                rule=job.rule)
    else:
        return item
Exemple #4
0
    def _apply_wildcards(
        self,
        newitems,
        olditems,
        wildcards,
        concretize=None,
        check_return_type=True,
        omit_callable=False,
        mapping=None,
        no_flattening=False,
        aux_params=None,
        apply_path_modifier=True,
        property=None,
        incomplete_checkpoint_func=lambda e: None,
        allow_unpack=True,
    ):
        if aux_params is None:
            aux_params = dict()
        for name, item in olditems._allitems():
            start = len(newitems)
            is_unpack = is_flagged(item, "unpack")
            _is_callable = is_callable(item)

            if _is_callable:
                if omit_callable:
                    continue
                item, incomplete = self.apply_input_function(
                    item,
                    wildcards,
                    incomplete_checkpoint_func=incomplete_checkpoint_func,
                    is_unpack=is_unpack,
                    **aux_params)
                if apply_path_modifier:
                    item = self.apply_path_modifier(item, property=property)

            if is_unpack and not incomplete:
                if not allow_unpack:
                    raise WorkflowError(
                        "unpack() is not allowed with params. "
                        "Simply return a dictionary which can be directly ."
                        "used, e.g. via {params[mykey]}.")
                # Sanity checks before interpreting unpack()
                if not isinstance(item, (list, dict)):
                    raise WorkflowError(
                        "Can only use unpack() on list and dict", rule=self)
                if name:
                    raise WorkflowError(
                        "Cannot combine named input file with unpack()",
                        rule=self)
                # Allow streamlined code with/without unpack
                if isinstance(item, list):
                    pairs = zip([None] * len(item), item)
                else:
                    assert isinstance(item, dict)
                    pairs = item.items()
            else:
                pairs = [(name, item)]

            for name, item in pairs:
                is_iterable = True
                if not_iterable(item) or no_flattening:
                    item = [item]
                    is_iterable = False
                for item_ in item:
                    if (check_return_type and not isinstance(item_, str)
                            and not isinstance(item_, Path)):
                        raise WorkflowError(
                            "Function did not return str or list "
                            "of str.",
                            rule=self)
                    concrete = concretize(item_, wildcards, _is_callable)
                    newitems.append(concrete)
                    if mapping is not None:
                        mapping[concrete] = item_

                if name:
                    newitems._set_name(
                        name,
                        start,
                        end=len(newitems) if is_iterable else None)
                    start = len(newitems)
Exemple #5
0
    def _apply_wildcards(self,
                         newitems,
                         olditems,
                         wildcards,
                         concretize=apply_wildcards,
                         check_return_type=True,
                         omit_callable=False,
                         mapping=None,
                         no_flattening=False,
                         aux_params=None,
                         apply_default_remote=True):
        if aux_params is None:
            aux_params = dict()
        for name, item in olditems.allitems():
            start = len(newitems)
            is_iterable = True
            is_unpack = is_flagged(item, "unpack")

            if is_callable(item):
                if omit_callable:
                    continue
                item = self.apply_input_function(item, wildcards, **aux_params)
                if apply_default_remote:
                    item = self.apply_default_remote(item)

            if is_unpack:
                # Sanity checks before interpreting unpack()
                if not isinstance(item, (list, dict)):
                    raise WorkflowError(
                        "Can only use unpack() on list and dict", rule=self)
                if name:
                    raise WorkflowError(
                        "Cannot combine named input file with unpack()",
                        rule=self)
                # Allow streamlined code with/without unpack
                if isinstance(item, list):
                    pairs = zip([None] * len(item), item)
                else:
                    assert isinstance(item, dict)
                    pairs = item.items()
            else:
                pairs = [(name, item)]

            for name, item in pairs:
                if not_iterable(item) or no_flattening:
                    item = [item]
                    is_iterable = False
                for item_ in item:
                    if check_return_type and not isinstance(item_, str):
                        raise WorkflowError(
                            "Function did not return str or list "
                            "of str.",
                            rule=self)
                    concrete = concretize(item_, wildcards)
                    newitems.append(concrete)
                    if mapping is not None:
                        mapping[concrete] = item_

                if name:
                    newitems.set_name(
                        name,
                        start,
                        end=len(newitems) if is_iterable else None)
                    start = len(newitems)
Exemple #6
0
def render_iofile(iofile):
    if is_callable(iofile):
        return "<function>"
    else:
        return str(iofile)