Skip to content

Commit 2eaee44

Browse files
committed
Allow empty job array if enabled
1 parent a280db6 commit 2eaee44

File tree

3 files changed

+14
-10
lines changed

3 files changed

+14
-10
lines changed

exca/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
from .task import SubmitInfra as SubmitInfra
1313
from .task import TaskInfra as TaskInfra
1414

15-
__version__ = "0.4.4"
15+
__version__ = "0.4.5"

exca/task.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def compute(self) -> int:
137137
# _method: TaskFunc = pydantic.PrivateAttr()
138138
_cache: tp.Any = pydantic.PrivateAttr(base.Sentinel())
139139

140-
def __getstate__(self) -> tp.Dict[str, tp.Any]:
140+
def __getstate__(self) -> dict[str, tp.Any]:
141141
out = super().__getstate__()
142142
out["__pydantic_private__"]["_cache"] = base.Sentinel()
143143
return out
@@ -180,23 +180,27 @@ def clear_job(self) -> None:
180180
(xpfolder / name).unlink(missing_ok=True)
181181

182182
@contextlib.contextmanager
183-
def job_array(self, max_workers: int = 256) -> tp.Iterator[tp.List[tp.Any]]:
183+
def job_array(
184+
self, max_workers: int = 256, allow_empty: bool = False
185+
) -> tp.Iterator[list[tp.Any]]:
184186
"""Creates a list object to populate
185187
The tasks in the list will be sent as a job array when exiting the context
186188
187189
Parameter
188190
---------
189191
max_workers: int
190192
maximum number of jobs in the array that can be running at a given time
193+
allow_empty: bool
194+
if False, an exeption will be raised at the end of the context if the array is still empty
191195
"""
192196
executor = self.executor()
193-
tasks: tp.List[tp.Any] = []
197+
tasks: list[tp.Any] = []
194198
yield tasks
195-
if not tasks:
199+
if not tasks and not allow_empty:
196200
raise RuntimeError(f"Nothing added to job array for {self.uid()}")
197201
# verify unicity
198202
uid_index: dict[str, int] = {}
199-
infras: tp.List[TaskInfra] = [getattr(t, self._infra_name) for t in tasks]
203+
infras: list[TaskInfra] = [getattr(t, self._infra_name) for t in tasks]
200204
folder = self.uid_folder()
201205
for k, infra in enumerate(infras):
202206
uid = infra.uid()
@@ -216,12 +220,12 @@ def job_array(self, max_workers: int = 256) -> tp.Iterator[tp.List[tp.Any]]:
216220
self._set_permissions(executor.folder)
217221
name = self.uid().split("/", maxsplit=1)[0]
218222
# select jobs to run
219-
statuses: tp.Dict[Status, tp.List[TaskInfra]] = collections.defaultdict(list)
223+
statuses: dict[Status, list[TaskInfra]] = collections.defaultdict(list)
220224
for i in infras:
221225
statuses[i.status()].append(i)
222226
i._computed = True
223227
missing = list(statuses["not submitted"])
224-
to_clear: tp.List[Status] = []
228+
to_clear: list[Status] = []
225229
if self._effective_mode != "cached":
226230
to_clear.append("failed")
227231
if self._effective_mode == "force":
@@ -496,7 +500,7 @@ def compute(self, y: int) -> int:
496500

497501
_array_executor: submitit.Executor | None = pydantic.PrivateAttr(None)
498502

499-
def _exclude_from_cls_uid(self) -> tp.List[str]:
503+
def _exclude_from_cls_uid(self) -> list[str]:
500504
return ["."] # not taken into accound for uid
501505

502506
# pylint: disable=unused-argument

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "exca"
33
readme = "README.md"
44
authors = [{name = "Meta FAIR"}]
55
requires-python = ">=3.10"
6-
version = "0.4.4"
6+
version = "0.4.5"
77
description = "Execution and caching tool for python"
88

99
dependencies = [

0 commit comments

Comments
 (0)