|
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