toil 9.1.2__py3-none-any.whl → 9.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. toil/__init__.py +5 -9
  2. toil/batchSystems/abstractBatchSystem.py +23 -22
  3. toil/batchSystems/abstractGridEngineBatchSystem.py +17 -12
  4. toil/batchSystems/awsBatch.py +8 -8
  5. toil/batchSystems/cleanup_support.py +4 -4
  6. toil/batchSystems/contained_executor.py +3 -3
  7. toil/batchSystems/gridengine.py +3 -4
  8. toil/batchSystems/htcondor.py +5 -5
  9. toil/batchSystems/kubernetes.py +65 -63
  10. toil/batchSystems/local_support.py +2 -3
  11. toil/batchSystems/lsf.py +6 -7
  12. toil/batchSystems/mesos/batchSystem.py +11 -7
  13. toil/batchSystems/mesos/test/__init__.py +1 -2
  14. toil/batchSystems/options.py +9 -10
  15. toil/batchSystems/registry.py +3 -7
  16. toil/batchSystems/singleMachine.py +8 -11
  17. toil/batchSystems/slurm.py +49 -38
  18. toil/batchSystems/torque.py +3 -4
  19. toil/bus.py +36 -34
  20. toil/common.py +129 -89
  21. toil/cwl/cwltoil.py +857 -729
  22. toil/cwl/utils.py +44 -35
  23. toil/fileStores/__init__.py +3 -1
  24. toil/fileStores/abstractFileStore.py +28 -30
  25. toil/fileStores/cachingFileStore.py +8 -8
  26. toil/fileStores/nonCachingFileStore.py +10 -21
  27. toil/job.py +159 -158
  28. toil/jobStores/abstractJobStore.py +68 -69
  29. toil/jobStores/aws/jobStore.py +249 -213
  30. toil/jobStores/aws/utils.py +13 -24
  31. toil/jobStores/fileJobStore.py +28 -22
  32. toil/jobStores/googleJobStore.py +21 -17
  33. toil/jobStores/utils.py +3 -7
  34. toil/leader.py +14 -14
  35. toil/lib/accelerators.py +6 -4
  36. toil/lib/aws/__init__.py +9 -10
  37. toil/lib/aws/ami.py +33 -19
  38. toil/lib/aws/iam.py +6 -6
  39. toil/lib/aws/s3.py +259 -157
  40. toil/lib/aws/session.py +76 -76
  41. toil/lib/aws/utils.py +51 -43
  42. toil/lib/checksum.py +19 -15
  43. toil/lib/compatibility.py +3 -2
  44. toil/lib/conversions.py +45 -18
  45. toil/lib/directory.py +29 -26
  46. toil/lib/docker.py +93 -99
  47. toil/lib/dockstore.py +77 -50
  48. toil/lib/ec2.py +39 -38
  49. toil/lib/ec2nodes.py +11 -4
  50. toil/lib/exceptions.py +8 -5
  51. toil/lib/ftp_utils.py +9 -14
  52. toil/lib/generatedEC2Lists.py +161 -20
  53. toil/lib/history.py +141 -97
  54. toil/lib/history_submission.py +163 -72
  55. toil/lib/io.py +27 -17
  56. toil/lib/memoize.py +2 -1
  57. toil/lib/misc.py +15 -11
  58. toil/lib/pipes.py +40 -25
  59. toil/lib/plugins.py +12 -8
  60. toil/lib/resources.py +1 -0
  61. toil/lib/retry.py +32 -38
  62. toil/lib/threading.py +12 -12
  63. toil/lib/throttle.py +1 -2
  64. toil/lib/trs.py +113 -51
  65. toil/lib/url.py +14 -23
  66. toil/lib/web.py +7 -2
  67. toil/options/common.py +18 -15
  68. toil/options/cwl.py +2 -2
  69. toil/options/runner.py +9 -5
  70. toil/options/wdl.py +1 -3
  71. toil/provisioners/__init__.py +9 -9
  72. toil/provisioners/abstractProvisioner.py +22 -20
  73. toil/provisioners/aws/__init__.py +20 -14
  74. toil/provisioners/aws/awsProvisioner.py +10 -8
  75. toil/provisioners/clusterScaler.py +19 -18
  76. toil/provisioners/gceProvisioner.py +2 -3
  77. toil/provisioners/node.py +11 -13
  78. toil/realtimeLogger.py +4 -4
  79. toil/resource.py +5 -5
  80. toil/server/app.py +2 -2
  81. toil/server/cli/wes_cwl_runner.py +11 -11
  82. toil/server/utils.py +18 -21
  83. toil/server/wes/abstract_backend.py +9 -8
  84. toil/server/wes/amazon_wes_utils.py +3 -3
  85. toil/server/wes/tasks.py +3 -5
  86. toil/server/wes/toil_backend.py +17 -21
  87. toil/server/wsgi_app.py +3 -3
  88. toil/serviceManager.py +3 -4
  89. toil/statsAndLogging.py +12 -13
  90. toil/test/__init__.py +33 -24
  91. toil/test/batchSystems/batchSystemTest.py +12 -11
  92. toil/test/batchSystems/batch_system_plugin_test.py +3 -5
  93. toil/test/batchSystems/test_slurm.py +38 -24
  94. toil/test/cwl/conftest.py +5 -6
  95. toil/test/cwl/cwlTest.py +194 -78
  96. toil/test/cwl/download_file_uri.json +6 -0
  97. toil/test/cwl/download_file_uri_no_hostname.json +6 -0
  98. toil/test/docs/scripts/tutorial_staging.py +1 -0
  99. toil/test/jobStores/jobStoreTest.py +9 -7
  100. toil/test/lib/aws/test_iam.py +1 -3
  101. toil/test/lib/aws/test_s3.py +1 -1
  102. toil/test/lib/dockerTest.py +9 -9
  103. toil/test/lib/test_ec2.py +12 -11
  104. toil/test/lib/test_history.py +4 -4
  105. toil/test/lib/test_trs.py +16 -14
  106. toil/test/lib/test_url.py +7 -6
  107. toil/test/lib/url_plugin_test.py +12 -18
  108. toil/test/provisioners/aws/awsProvisionerTest.py +10 -8
  109. toil/test/provisioners/clusterScalerTest.py +2 -5
  110. toil/test/provisioners/clusterTest.py +1 -3
  111. toil/test/server/serverTest.py +13 -4
  112. toil/test/sort/restart_sort.py +2 -6
  113. toil/test/sort/sort.py +3 -8
  114. toil/test/src/deferredFunctionTest.py +7 -7
  115. toil/test/src/environmentTest.py +1 -2
  116. toil/test/src/fileStoreTest.py +5 -5
  117. toil/test/src/importExportFileTest.py +5 -6
  118. toil/test/src/jobServiceTest.py +22 -14
  119. toil/test/src/jobTest.py +121 -25
  120. toil/test/src/miscTests.py +5 -7
  121. toil/test/src/promisedRequirementTest.py +8 -7
  122. toil/test/src/regularLogTest.py +2 -3
  123. toil/test/src/resourceTest.py +5 -8
  124. toil/test/src/restartDAGTest.py +5 -6
  125. toil/test/src/resumabilityTest.py +2 -2
  126. toil/test/src/retainTempDirTest.py +3 -3
  127. toil/test/src/systemTest.py +3 -3
  128. toil/test/src/threadingTest.py +1 -1
  129. toil/test/src/workerTest.py +1 -2
  130. toil/test/utils/toilDebugTest.py +6 -4
  131. toil/test/utils/toilKillTest.py +1 -1
  132. toil/test/utils/utilsTest.py +15 -14
  133. toil/test/wdl/wdltoil_test.py +247 -124
  134. toil/test/wdl/wdltoil_test_kubernetes.py +2 -2
  135. toil/toilState.py +2 -3
  136. toil/utils/toilDebugFile.py +3 -8
  137. toil/utils/toilDebugJob.py +1 -2
  138. toil/utils/toilLaunchCluster.py +1 -2
  139. toil/utils/toilSshCluster.py +2 -0
  140. toil/utils/toilStats.py +19 -24
  141. toil/utils/toilStatus.py +11 -14
  142. toil/version.py +10 -10
  143. toil/wdl/wdltoil.py +313 -209
  144. toil/worker.py +18 -12
  145. {toil-9.1.2.dist-info → toil-9.2.0.dist-info}/METADATA +11 -14
  146. {toil-9.1.2.dist-info → toil-9.2.0.dist-info}/RECORD +150 -153
  147. {toil-9.1.2.dist-info → toil-9.2.0.dist-info}/WHEEL +1 -1
  148. toil/test/cwl/staging_cat.cwl +0 -27
  149. toil/test/cwl/staging_make_file.cwl +0 -25
  150. toil/test/cwl/staging_workflow.cwl +0 -43
  151. toil/test/cwl/zero_default.cwl +0 -61
  152. toil/test/utils/ABCWorkflowDebug/ABC.txt +0 -1
  153. {toil-9.1.2.dist-info → toil-9.2.0.dist-info}/entry_points.txt +0 -0
  154. {toil-9.1.2.dist-info → toil-9.2.0.dist-info}/licenses/LICENSE +0 -0
  155. {toil-9.1.2.dist-info → toil-9.2.0.dist-info}/top_level.txt +0 -0
@@ -17,12 +17,12 @@ import errno
17
17
  import logging
18
18
  import math
19
19
  import os
20
- import sys
21
20
  import shlex
22
-
21
+ import sys
23
22
  from argparse import SUPPRESS, ArgumentParser, _ArgumentGroup
24
- from datetime import datetime, timedelta, timezone
25
- from typing import Callable, NamedTuple, Optional, TypeVar
23
+ from collections.abc import Callable
24
+ from datetime import datetime, timedelta
25
+ from typing import NamedTuple, TypeVar
26
26
 
27
27
  from toil.batchSystems.abstractBatchSystem import (
28
28
  EXIT_STATUS_UNAVAILABLE_VALUE,
@@ -103,6 +103,7 @@ def parse_slurm_time(slurm_time: str) -> int:
103
103
  total_seconds += multiplier * int(elapsed_split[index])
104
104
  return total_seconds
105
105
 
106
+
106
107
  # For parsing user-provided option overrides (or self-generated
107
108
  # options) for sbatch, we need a way to recognize long, long-with-equals, and
108
109
  # short forms.
@@ -111,23 +112,34 @@ def option_detector(long: str, short: str | None = None) -> Callable[[str], bool
111
112
  Get a function that returns true if it sees the long or short
112
113
  option.
113
114
  """
115
+
114
116
  def is_match(option: str) -> bool:
115
- return option == f"--{long}" or option.startswith(f"--{long}=") or (short is not None and option == f"-{short}")
117
+ return (
118
+ option == f"--{long}"
119
+ or option.startswith(f"--{long}=")
120
+ or (short is not None and option == f"-{short}")
121
+ )
122
+
116
123
  return is_match
117
124
 
125
+
118
126
  def any_option_detector(options: list[str | tuple[str, str]]) -> Callable[[str], bool]:
119
127
  """
120
128
  Get a function that returns true if it sees any of the long
121
129
  options or long or short option pairs.
122
130
  """
123
- detectors = [option_detector(o) if isinstance(o, str) else option_detector(*o) for o in options]
131
+ detectors = [
132
+ option_detector(o) if isinstance(o, str) else option_detector(*o)
133
+ for o in options
134
+ ]
135
+
124
136
  def is_match(option: str) -> bool:
125
137
  for detector in detectors:
126
138
  if detector(option):
127
139
  return True
128
140
  return False
129
- return is_match
130
141
 
142
+ return is_match
131
143
 
132
144
 
133
145
  class SlurmBatchSystem(AbstractGridEngineBatchSystem):
@@ -352,17 +364,17 @@ class SlurmBatchSystem(AbstractGridEngineBatchSystem):
352
364
  ) -> list[int | tuple[int, BatchJobExitReason | None] | None]:
353
365
  """
354
366
  Collect all job exit codes in a single call.
355
-
367
+
356
368
  :param batch_job_id_list: list of Job ID strings, where each string
357
369
  has the form ``<job>[.<task>]``.
358
-
370
+
359
371
  :return: list of job exit codes or exit code, exit reason pairs
360
372
  associated with the list of job IDs.
361
-
373
+
362
374
  :raises CalledProcessErrorStderr: if communicating with Slurm went
363
375
  wrong.
364
-
365
- :raises OSError: if job details are not available becasue a Slurm
376
+
377
+ :raises OSError: if job details are not available because a Slurm
366
378
  command could not start.
367
379
  """
368
380
  logger.log(
@@ -402,12 +414,12 @@ class SlurmBatchSystem(AbstractGridEngineBatchSystem):
402
414
  value is a tuple containing the job's state and exit code.
403
415
  :raises CalledProcessErrorStderr: if communicating with Slurm went
404
416
  wrong.
405
- :raises OSError: if job details are not available becasue a Slurm
417
+ :raises OSError: if job details are not available because a Slurm
406
418
  command could not start.
407
419
  """
408
420
 
409
421
  status_dict = {}
410
- scontrol_problem: Optional[Exception] = None
422
+ scontrol_problem: Exception | None = None
411
423
 
412
424
  try:
413
425
  # Get all the job details we can from scontrol, which we think
@@ -445,7 +457,6 @@ class SlurmBatchSystem(AbstractGridEngineBatchSystem):
445
457
  # values filled in for all jobs.
446
458
  assert len(status_dict) == len(job_id_list)
447
459
 
448
-
449
460
  return status_dict
450
461
 
451
462
  def _get_job_return_code(
@@ -516,7 +527,11 @@ class SlurmBatchSystem(AbstractGridEngineBatchSystem):
516
527
 
517
528
  return state_token
518
529
 
519
- def _remaining_jobs(self, job_id_list: list[int], job_details: dict[int, tuple[str | None, int | None]]) -> list[int]:
530
+ def _remaining_jobs(
531
+ self,
532
+ job_id_list: list[int],
533
+ job_details: dict[int, tuple[str | None, int | None]],
534
+ ) -> list[int]:
520
535
  """
521
536
  Given a list of job IDs and a list of job details (state and exit
522
537
  code), get the list of job IDs where the details are (None, None)
@@ -550,13 +565,7 @@ class SlurmBatchSystem(AbstractGridEngineBatchSystem):
550
565
  # Pick a now
551
566
  now = datetime.now().astimezone(None)
552
567
  # Decide when to start the search (first copy of past midnight)
553
- begin_time = now.replace(
554
- hour=0,
555
- minute=0,
556
- second=0,
557
- microsecond=0,
558
- fold=0
559
- )
568
+ begin_time = now.replace(hour=0, minute=0, second=0, microsecond=0, fold=0)
560
569
  # And when to end (a day after that)
561
570
  end_time = begin_time + timedelta(days=1)
562
571
  while end_time < now:
@@ -575,9 +584,7 @@ class SlurmBatchSystem(AbstractGridEngineBatchSystem):
575
584
  # started.
576
585
  results.update(
577
586
  self._get_job_details_from_sacct_for_range(
578
- job_id_list,
579
- begin_time,
580
- end_time
587
+ job_id_list, begin_time, end_time
581
588
  )
582
589
  )
583
590
  job_id_list = self._remaining_jobs(job_id_list, results)
@@ -588,14 +595,13 @@ class SlurmBatchSystem(AbstractGridEngineBatchSystem):
588
595
  end_time = begin_time + timedelta(seconds=1)
589
596
  begin_time = end_time - timedelta(days=1, seconds=1)
590
597
 
591
-
592
598
  if end_time < self.boss.start_time and len(job_id_list) > 0:
593
599
  # This is suspicious.
594
600
  logger.warning(
595
601
  "Could not find any information from sacct after "
596
602
  "workflow start at %s about jobs: %s",
597
603
  self.boss.start_time.isoformat(),
598
- job_id_list
604
+ job_id_list,
599
605
  )
600
606
 
601
607
  return results
@@ -622,6 +628,7 @@ class SlurmBatchSystem(AbstractGridEngineBatchSystem):
622
628
 
623
629
  assert begin_time.tzinfo is not None, "begin_time must be aware"
624
630
  assert end_time.tzinfo is not None, "end_time must be aware"
631
+
625
632
  def stringify(t: datetime) -> str:
626
633
  """
627
634
  Convert an aware time local time, and format it *without* a
@@ -662,14 +669,14 @@ class SlurmBatchSystem(AbstractGridEngineBatchSystem):
662
669
  raise
663
670
  job_statuses.update(
664
671
  self._get_job_details_from_sacct_for_range(
665
- job_id_list[:len(job_id_list)//2],
672
+ job_id_list[: len(job_id_list) // 2],
666
673
  begin_time,
667
674
  end_time,
668
675
  )
669
676
  )
670
677
  job_statuses.update(
671
678
  self._get_job_details_from_sacct_for_range(
672
- job_id_list[len(job_id_list)//2:],
679
+ job_id_list[len(job_id_list) // 2 :],
673
680
  begin_time,
674
681
  end_time,
675
682
  )
@@ -845,8 +852,12 @@ class SlurmBatchSystem(AbstractGridEngineBatchSystem):
845
852
  # Also any extra arguments from --slurmArgs or TOIL_SLURM_ARGS
846
853
  nativeConfig: str = self.boss.config.slurm_args # type: ignore[attr-defined]
847
854
 
848
- is_any_mem_option = any_option_detector(["mem", "mem-per-cpu", "mem-per-gpu"])
849
- is_any_cpus_option = any_option_detector([("cpus-per-task", "c"), "cpus-per-gpu"])
855
+ is_any_mem_option = any_option_detector(
856
+ ["mem", "mem-per-cpu", "mem-per-gpu"]
857
+ )
858
+ is_any_cpus_option = any_option_detector(
859
+ [("cpus-per-task", "c"), "cpus-per-gpu"]
860
+ )
850
861
  is_export_option = option_detector("export")
851
862
  is_export_file_option = option_detector("export-file")
852
863
  is_time_option = option_detector("time", "t")
@@ -857,7 +868,7 @@ class SlurmBatchSystem(AbstractGridEngineBatchSystem):
857
868
 
858
869
  # --export=[ALL,]<environment_toil_variables>
859
870
  export_all = True
860
- export_list = [] # Some items here may be multiple comma-separated values
871
+ export_list = [] # Some items here may be multiple comma-separated values
861
872
  time_limit: int | None = self.boss.config.slurm_time # type: ignore[attr-defined]
862
873
  partition: str | None = None
863
874
 
@@ -967,10 +978,7 @@ class SlurmBatchSystem(AbstractGridEngineBatchSystem):
967
978
  raise RuntimeError(
968
979
  f"The job {jobName} is requesting GPUs, but the Slurm cluster does not appear to have an accessible partition with GPUs"
969
980
  )
970
- if (
971
- time_limit is not None
972
- and gpu_partition.time_limit < time_limit
973
- ):
981
+ if time_limit is not None and gpu_partition.time_limit < time_limit:
974
982
  # TODO: find the lowest-priority GPU partition that has at least each job's time limit!
975
983
  logger.warning(
976
984
  "Trying to submit a job that needs %s seconds to partition %s that has a limit of %s seconds",
@@ -993,7 +1001,10 @@ class SlurmBatchSystem(AbstractGridEngineBatchSystem):
993
1001
  if gpus:
994
1002
  # Generate GPU assignment argument
995
1003
  sbatch_line.append(f"--gres=gpu:{gpus}")
996
- if partition is not None and partition not in self.boss.partitions.gpu_partitions:
1004
+ if (
1005
+ partition is not None
1006
+ and partition not in self.boss.partitions.gpu_partitions
1007
+ ):
997
1008
  # the specified partition is not compatible, so warn the user that the job may not work
998
1009
  logger.warning(
999
1010
  f"Job {jobName} needs GPUs, but specified partition {partition} does not have them. This job may not work."
@@ -18,7 +18,6 @@ import shlex
18
18
  import tempfile
19
19
  from queue import Empty
20
20
  from shlex import quote
21
- from typing import Optional
22
21
 
23
22
  from toil.batchSystems.abstractGridEngineBatchSystem import (
24
23
  AbstractGridEngineBatchSystem,
@@ -137,8 +136,8 @@ class TorqueBatchSystem(AbstractGridEngineBatchSystem):
137
136
  jobID: int,
138
137
  command: str,
139
138
  jobName: str,
140
- job_environment: Optional[dict[str, str]] = None,
141
- gpus: Optional[int] = None,
139
+ job_environment: dict[str, str] | None = None,
140
+ gpus: int | None = None,
142
141
  ) -> list[str]:
143
142
  return self.prepareQsub(cpu, memory, jobID, job_environment) + [
144
143
  self.generateTorqueWrapper(command, jobID)
@@ -186,7 +185,7 @@ class TorqueBatchSystem(AbstractGridEngineBatchSystem):
186
185
  cpu: int,
187
186
  mem: int,
188
187
  jobID: int,
189
- job_environment: Optional[dict[str, str]],
188
+ job_environment: dict[str, str] | None,
190
189
  ) -> list[str]:
191
190
 
192
191
  # TODO: passing $PWD on command line not working for -d, resorting to
toil/bus.py CHANGED
@@ -67,9 +67,9 @@ import os
67
67
  import queue
68
68
  import tempfile
69
69
  import threading
70
- from collections.abc import Iterator
70
+ from collections.abc import Callable, Iterator
71
71
  from dataclasses import dataclass
72
- from typing import IO, Any, Callable, NamedTuple, Optional, TypeVar, TYPE_CHECKING, cast
72
+ from typing import IO, Any, NamedTuple, Optional, TypeVar, cast
73
73
 
74
74
  from pubsub.core import Publisher
75
75
  from pubsub.core.listener import Listener
@@ -282,7 +282,7 @@ def bytes_to_message(message_type: type[MessageType], data: bytes) -> MessageTyp
282
282
  # Get a mapping from field name to type in the named tuple.
283
283
  # We need to check a couple different fields because this moved in a recent
284
284
  # Python 3 release.
285
- field_to_type: Optional[dict[str, type]] = cast(
285
+ field_to_type: dict[str, type] | None = cast(
286
286
  Optional[dict[str, type]],
287
287
  getattr(
288
288
  message_type, "__annotations__", getattr(message_type, "_field_types", None)
@@ -369,7 +369,7 @@ class MessageBus:
369
369
  # We are supposed to receive messages
370
370
  while True:
371
371
  # Until we can't get a message, get one
372
- message: Optional[Any] = None
372
+ message: Any | None = None
373
373
  try:
374
374
  message = self._queue.get_nowait()
375
375
  except queue.Empty:
@@ -528,7 +528,7 @@ class MessageBusClient:
528
528
  """
529
529
 
530
530
  # We might be given a reference to the message bus
531
- self._bus: Optional[MessageBus] = None
531
+ self._bus: MessageBus | None = None
532
532
 
533
533
  def _set_bus(self, bus: MessageBus) -> None:
534
534
  """
@@ -775,43 +775,45 @@ def replay_message_bus(path: FileDescriptorOrPath) -> dict[str, JobStatus]:
775
775
  # And for each of them
776
776
  logger.debug("Got message from workflow: %s", event)
777
777
 
778
- if isinstance(event, JobUpdatedMessage):
779
- # Apply the latest return code from the job with this ID.
780
- job_statuses[event.job_id].exit_code = event.result_status
781
- elif isinstance(event, JobIssuedMessage):
782
- job_statuses[event.job_id].job_store_id = event.job_id
783
- job_statuses[event.job_id].name = event.job_type
784
- job_statuses[event.job_id].toil_batch_id = event.toil_batch_id
785
- job_statuses[event.job_id].exit_code = -1
786
- batch_to_job_id[event.toil_batch_id] = event.job_id
787
- elif isinstance(event, JobCompletedMessage):
788
- job_statuses[event.job_id].name = event.job_type
789
- job_statuses[event.job_id].exit_code = event.exit_code
790
- elif isinstance(event, JobFailedMessage):
791
- job_statuses[event.job_id].name = event.job_type
792
- if job_statuses[event.job_id].exit_code == 0:
793
- # Record the failure if we never got a failed exit code.
794
- job_statuses[event.job_id].exit_code = 1
795
- elif isinstance(event, JobAnnotationMessage):
796
- # Remember the last value of any annotation that is set
797
- job_statuses[event.job_id].annotations[
798
- event.annotation_name
799
- ] = event.annotation_value
800
- elif isinstance(event, ExternalBatchIdMessage):
801
- if event.toil_batch_id in batch_to_job_id:
778
+ match event:
779
+ case JobUpdatedMessage():
780
+ # Apply the latest return code from the job with this ID.
781
+ job_statuses[event.job_id].exit_code = event.result_status
782
+ case JobIssuedMessage():
783
+ job_statuses[event.job_id].job_store_id = event.job_id
784
+ job_statuses[event.job_id].name = event.job_type
785
+ job_statuses[event.job_id].toil_batch_id = event.toil_batch_id
786
+ job_statuses[event.job_id].exit_code = -1
787
+ batch_to_job_id[event.toil_batch_id] = event.job_id
788
+ case JobCompletedMessage():
789
+ job_statuses[event.job_id].name = event.job_type
790
+ job_statuses[event.job_id].exit_code = event.exit_code
791
+ case JobFailedMessage():
792
+ job_statuses[event.job_id].name = event.job_type
793
+ if job_statuses[event.job_id].exit_code == 0:
794
+ # Record the failure if we never got a failed exit code.
795
+ job_statuses[event.job_id].exit_code = 1
796
+ case JobAnnotationMessage():
797
+ # Remember the last value of any annotation that is set
798
+ job_statuses[event.job_id].annotations[
799
+ event.annotation_name
800
+ ] = event.annotation_value
801
+ case ExternalBatchIdMessage() as ebim if (
802
+ ebim.toil_batch_id in batch_to_job_id
803
+ ):
802
804
  job_statuses[
803
- batch_to_job_id[event.toil_batch_id]
804
- ].external_batch_id = event.external_batch_id
805
+ batch_to_job_id[ebim.toil_batch_id]
806
+ ].external_batch_id = ebim.external_batch_id
805
807
  job_statuses[
806
- batch_to_job_id[event.toil_batch_id]
807
- ].batch_system = event.batch_system
808
+ batch_to_job_id[ebim.toil_batch_id]
809
+ ].batch_system = ebim.batch_system
808
810
  except FileNotFoundError:
809
811
  logger.warning("We were unable to access the file")
810
812
 
811
813
  return job_statuses
812
814
 
813
815
 
814
- def gen_message_bus_path(tmpdir: Optional[str] = None) -> str:
816
+ def gen_message_bus_path(tmpdir: str | None = None) -> str:
815
817
  """
816
818
  Return a file path in tmp to store the message bus at.
817
819
  Calling function is responsible for cleaning the generated file.