|
3 | 3 | from copy import copy
|
4 | 4 | from .helpers import execute
|
5 | 5 | from pathlib import Path
|
| 6 | +import logging |
6 | 7 | from fileformats.generic import FileSet
|
7 | 8 | from pydra.engine.helpers import list_fields
|
8 | 9 | from pydra.utils.typing import TypeParser
|
9 | 10 |
|
| 11 | +logger = logging.getLogger("pydra") |
10 | 12 |
|
11 | 13 | if ty.TYPE_CHECKING:
|
12 | 14 | from pydra.engine.core import Task
|
@@ -121,34 +123,50 @@ def get_bindings(
|
121 | 123 | fld: shell.arg
|
122 | 124 | for fld in list_fields(task.definition):
|
123 | 125 | if TypeParser.contains_type(FileSet, fld.type):
|
124 |
| - fileset: FileSet | None = task.inputs[fld.name] |
125 |
| - if not fileset: |
| 126 | + value: FileSet | None = task.inputs[fld.name] |
| 127 | + if not value: |
126 | 128 | continue
|
127 |
| - if not isinstance(fileset, (os.PathLike, FileSet)): |
128 |
| - raise NotImplementedError( |
129 |
| - f"No support for generating bindings for {type(fileset)} types " |
130 |
| - f"({fileset})" |
131 |
| - ) |
| 129 | + |
132 | 130 | copy_file = fld.copy_mode == FileSet.CopyMode.copy
|
133 | 131 |
|
134 |
| - host_path, env_path = fileset.parent, Path(f"{root}{fileset.parent}") |
| 132 | + def map_path(fileset: os.PathLike | FileSet) -> Path: |
| 133 | + host_path, env_path = fileset.parent, Path( |
| 134 | + f"{root}{fileset.parent}" |
| 135 | + ) |
135 | 136 |
|
136 |
| - # Default to mounting paths as read-only, but respect existing modes |
137 |
| - bindings[host_path] = ( |
138 |
| - env_path, |
139 |
| - "rw" if copy_file or isinstance(fld, shell.outarg) else "ro", |
140 |
| - ) |
| 137 | + # Default to mounting paths as read-only, but respect existing modes |
| 138 | + bindings[host_path] = ( |
| 139 | + env_path, |
| 140 | + "rw" if copy_file or isinstance(fld, shell.outarg) else "ro", |
| 141 | + ) |
| 142 | + return ( |
| 143 | + env_path / fileset.name |
| 144 | + if isinstance(fileset, os.PathLike) |
| 145 | + else tuple(env_path / rel for rel in fileset.relative_fspaths) |
| 146 | + ) |
141 | 147 |
|
142 | 148 | # Provide updated in-container paths to the command to be run. If a
|
143 | 149 | # fs-object, which resolves to a single path, just pass in the name of
|
144 | 150 | # that path relative to the location in the mount point in the container.
|
145 | 151 | # If it is a more complex file-set with multiple paths, then it is converted
|
146 | 152 | # into a tuple of paths relative to the base of the fileset.
|
147 |
| - value_updates[fld.name] = ( |
148 |
| - env_path / fileset.name |
149 |
| - if isinstance(fileset, os.PathLike) |
150 |
| - else tuple(env_path / rel for rel in fileset.relative_fspaths) |
151 |
| - ) |
| 153 | + if TypeParser.matches(value, os.PathLike | FileSet): |
| 154 | + value_updates[fld.name] = map_path(value) |
| 155 | + elif TypeParser.matches(value, ty.Sequence[FileSet | os.PathLike]): |
| 156 | + mapped_value = [] |
| 157 | + for val in value: |
| 158 | + mapped_val = map_path(val) |
| 159 | + if isinstance(mapped_val, tuple): |
| 160 | + mapped_value.extend(mapped_val) |
| 161 | + else: |
| 162 | + mapped_value.append(mapped_val) |
| 163 | + value_updates[fld.name] = mapped_value |
| 164 | + else: |
| 165 | + logger.debug( |
| 166 | + "No support for generating bindings for %s types " "(%s)", |
| 167 | + type(value), |
| 168 | + value, |
| 169 | + ) |
152 | 170 |
|
153 | 171 | # Add the cache directory to the list of mounts
|
154 | 172 | bindings[task.cache_dir] = (f"{self.root}/{task.cache_dir}", "rw")
|
|
0 commit comments