Skip to content

Commit 7d43802

Browse files
committed
allow executable to be None if environment is a Container
1 parent ec87910 commit 7d43802

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

pydra/compose/shell/builder.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,17 @@ def make(
130130
f"Shell task class {wrapped} must have an `executable` "
131131
"attribute that specifies the command to run"
132132
) from None
133-
if not isinstance(executable, str) and not (
134-
isinstance(executable, ty.Sequence)
135-
and all(isinstance(e, str) for e in executable)
133+
if (
134+
executable is not None
135+
and not isinstance(executable, str)
136+
and not (
137+
isinstance(executable, ty.Sequence)
138+
and all(isinstance(e, str) for e in executable)
139+
)
136140
):
137141
raise ValueError(
138-
"executable must be a string or a sequence of strings"
139-
f", not {executable!r}"
142+
"executable must be a string or a sequence of strings or None if "
143+
f"the command run is the entrypoint of a container, not {executable!r}"
140144
)
141145
class_name = klass.__name__
142146
check_explicit_fields_are_none(klass, inputs, outputs)
@@ -199,7 +203,7 @@ def make(
199203
)
200204
parsed_inputs["executable"] = field.arg(
201205
name="executable",
202-
type=str | ty.Sequence[str],
206+
type=str | ty.Sequence[str] | None,
203207
argstr="",
204208
position=0,
205209
default=executable,

pydra/compose/shell/task.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
)
2727
from pydra.compose import base
2828
from pydra.compose.base.field import RequirementSet
29+
from pydra.environments.base import Container
2930
from pydra.compose.base.helpers import is_set
3031
from . import field
3132
from .templating import (
@@ -254,6 +255,11 @@ class ShellTask(base.Task[ShellOutputsType]):
254255

255256
def _run(self, job: "Job[ShellTask]", rerun: bool = True) -> None:
256257
"""Run the shell command."""
258+
if self.executable is None and not isinstance(job.environment, Container):
259+
raise ValueError(
260+
"executable is not set, and the environment is not a container "
261+
f"({job.environment}) with an entrypoint"
262+
)
257263
job.return_values = job.environment.execute(job)
258264

259265
@property
@@ -291,9 +297,9 @@ def _command_args(self, values: dict[str, ty.Any]) -> list[str]:
291297
del values["executable"]
292298
del values["append_args"]
293299
# Add executable
294-
pos_args = [
295-
self._command_shelltask_executable(fld, self.executable),
296-
] # list for (position, command arg)
300+
pos_args = []
301+
if self.executable is not None:
302+
pos_args.append(self._executable_pos_arg(fld, self.executable))
297303
positions_provided = [0]
298304
fields = {f.name: f for f in get_fields(self)}
299305
for field_name in values:
@@ -312,9 +318,9 @@ def _command_args(self, values: dict[str, ty.Any]) -> list[str]:
312318
command_args += self.append_args
313319
return command_args
314320

315-
def _command_shelltask_executable(
316-
self, fld: field.arg, value: ty.Any
317-
) -> tuple[int, ty.Any]:
321+
def _executable_pos_arg(
322+
self, fld: field.arg, value: str | list[str] | None
323+
) -> tuple[int, str | list[str] | None]:
318324
"""Returning position and value for executable Task input"""
319325
pos = 0 # executable should be the first el. of the command
320326
assert value

0 commit comments

Comments
 (0)