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
toil/__init__.py CHANGED
@@ -16,14 +16,11 @@ import os
16
16
  import re
17
17
  import socket
18
18
  import sys
19
- from datetime import datetime
20
- from typing import TYPE_CHECKING, Optional
21
-
22
- from toil.lib.web import web_session
19
+ from typing import TYPE_CHECKING
23
20
 
24
21
  from docker.errors import ImageNotFound
25
22
  from toil.lib.memoize import memoize
26
- from toil.lib.retry import retry as retry
23
+ from toil.lib.web import web_session
27
24
  from toil.version import currentCommit
28
25
 
29
26
  if TYPE_CHECKING:
@@ -32,7 +29,7 @@ if TYPE_CHECKING:
32
29
  log = logging.getLogger(__name__)
33
30
 
34
31
 
35
- def which(cmd, mode=os.F_OK | os.X_OK, path=None) -> Optional[str]:
32
+ def which(cmd, mode=os.F_OK | os.X_OK, path=None) -> str | None:
36
33
  """
37
34
  Return the path with conforms to the given mode on the Path.
38
35
 
@@ -355,11 +352,11 @@ def parseDockerAppliance(appliance: str) -> tuple[str, str, str]:
355
352
  def checkDockerSchema(appliance):
356
353
  if not appliance:
357
354
  raise ImageNotFound("No docker image specified.")
358
- elif "://" in appliance:
355
+ if "://" in appliance:
359
356
  raise ImageNotFound(
360
357
  "Docker images cannot contain a schema (such as '://'): %s" "" % appliance
361
358
  )
362
- elif len(appliance) > 256:
359
+ if len(appliance) > 256:
363
360
  raise ImageNotFound(
364
361
  "Docker image must be less than 256 chars: %s" "" % appliance
365
362
  )
@@ -479,4 +476,3 @@ def logProcessContext(config: "Config") -> None:
479
476
 
480
477
  log.info("Running Toil version %s on host %s.", version, socket.gethostname())
481
478
  log.debug("Configuration: %s", config.__dict__)
482
-
@@ -11,7 +11,6 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- from dataclasses import dataclass
15
14
  import enum
16
15
  import logging
17
16
  import os
@@ -21,8 +20,9 @@ from abc import ABC, abstractmethod
21
20
  from argparse import ArgumentParser, _ArgumentGroup
22
21
  from collections.abc import Iterator
23
22
  from contextlib import contextmanager
23
+ from dataclasses import dataclass
24
24
  from threading import Condition
25
- from typing import Any, ContextManager, NamedTuple, Optional, Union, cast
25
+ from typing import Any, ContextManager, NamedTuple, cast
26
26
 
27
27
  from toil.batchSystems.options import OptionSetter
28
28
  from toil.bus import MessageBus, MessageOutbox
@@ -73,6 +73,7 @@ class BatchJobExitReason(enum.IntEnum):
73
73
  except ValueError:
74
74
  return str(value)
75
75
 
76
+
76
77
  @dataclass
77
78
  class UpdatedBatchJobInfo:
78
79
  jobID: int
@@ -87,9 +88,9 @@ class UpdatedBatchJobInfo:
87
88
  (e.g. job is lost, or otherwise died but actual exit code was not reported).
88
89
  """
89
90
 
90
- exitReason: Optional[BatchJobExitReason] = None
91
- wallTime: Union[float, int, None] = None
92
- backing_id: Optional[str] = None
91
+ exitReason: BatchJobExitReason | None = None
92
+ wallTime: float | int | None = None
93
+ backing_id: str | None = None
93
94
  """
94
95
  The identifier for the job in the backing scheduler, if available.
95
96
  """
@@ -97,10 +98,10 @@ class UpdatedBatchJobInfo:
97
98
 
98
99
  # Information required for worker cleanup on shutdown of the batch system.
99
100
  class WorkerCleanupInfo(NamedTuple):
100
- work_dir: Optional[str]
101
+ work_dir: str | None
101
102
  """Work directory path (where the cache would go) if specified by user"""
102
103
 
103
- coordination_dir: Optional[str]
104
+ coordination_dir: str | None
104
105
  """Coordination directory path (where lock files would go) if specified by user"""
105
106
 
106
107
  workflow_id: str
@@ -171,7 +172,7 @@ class AbstractBatchSystem(ABC):
171
172
  self,
172
173
  command: str,
173
174
  job_desc: JobDescription,
174
- job_environment: Optional[dict[str, str]] = None,
175
+ job_environment: dict[str, str] | None = None,
175
176
  ) -> int:
176
177
  """
177
178
  Issues a job with the specified command to the batch system and returns
@@ -224,7 +225,7 @@ class AbstractBatchSystem(ABC):
224
225
  raise NotImplementedError()
225
226
 
226
227
  @abstractmethod
227
- def getUpdatedBatchJob(self, maxWait: int) -> Optional[UpdatedBatchJobInfo]:
228
+ def getUpdatedBatchJob(self, maxWait: int) -> UpdatedBatchJobInfo | None:
228
229
  """
229
230
  Returns information about job that has updated its status (i.e. ceased
230
231
  running, either successfully or with an error). Each such job will be
@@ -242,7 +243,7 @@ class AbstractBatchSystem(ABC):
242
243
  """
243
244
  raise NotImplementedError()
244
245
 
245
- def getSchedulingStatusMessage(self) -> Optional[str]:
246
+ def getSchedulingStatusMessage(self) -> str | None:
246
247
  """
247
248
  Get a log message fragment for the user about anything that might be
248
249
  going wrong in the batch system, if available.
@@ -269,7 +270,7 @@ class AbstractBatchSystem(ABC):
269
270
  """
270
271
  raise NotImplementedError()
271
272
 
272
- def setEnv(self, name: str, value: Optional[str] = None) -> None:
273
+ def setEnv(self, name: str, value: str | None = None) -> None:
273
274
  """
274
275
  Set an environment variable for the worker process before it is launched.
275
276
 
@@ -286,7 +287,7 @@ class AbstractBatchSystem(ABC):
286
287
  raise NotImplementedError()
287
288
 
288
289
  @classmethod
289
- def add_options(cls, parser: Union[ArgumentParser, _ArgumentGroup]) -> None:
290
+ def add_options(cls, parser: ArgumentParser | _ArgumentGroup) -> None:
290
291
  """
291
292
  If this batch system provides any command line options, add them to the given parser.
292
293
  """
@@ -351,7 +352,7 @@ class BatchSystemSupport(AbstractBatchSystem):
351
352
  workflow_id=config.workflowID,
352
353
  clean_work_dir=config.cleanWorkDir,
353
354
  )
354
- self._outbox: Optional[MessageOutbox] = None
355
+ self._outbox: MessageOutbox | None = None
355
356
 
356
357
  def check_resource_request(self, requirer: Requirer) -> None:
357
358
  """
@@ -400,7 +401,7 @@ class BatchSystemSupport(AbstractBatchSystem):
400
401
  details=["The batch system does not support any accelerators."],
401
402
  )
402
403
 
403
- def setEnv(self, name: str, value: Optional[str] = None) -> None:
404
+ def setEnv(self, name: str, value: str | None = None) -> None:
404
405
  """
405
406
  Set an environment variable for the worker process before it is launched. The worker
406
407
  process will typically inherit the environment of the machine it is running on but this
@@ -572,7 +573,7 @@ class AbstractScalableBatchSystem(AbstractBatchSystem):
572
573
 
573
574
  @abstractmethod
574
575
  def getNodes(
575
- self, preemptible: Optional[bool] = None, timeout: int = 600
576
+ self, preemptible: bool | None = None, timeout: int = 600
576
577
  ) -> dict[str, NodeInfo]:
577
578
  """
578
579
  Returns a dictionary mapping node identifiers of preemptible or non-preemptible nodes to
@@ -622,9 +623,9 @@ class InsufficientSystemResources(Exception):
622
623
  self,
623
624
  requirer: Requirer,
624
625
  resource: str,
625
- available: Optional[ParsedRequirement] = None,
626
- batch_system: Optional[str] = None,
627
- source: Optional[str] = None,
626
+ available: ParsedRequirement | None = None,
627
+ batch_system: str | None = None,
628
+ source: str | None = None,
628
629
  details: list[str] = [],
629
630
  ) -> None:
630
631
  """
@@ -639,7 +640,7 @@ class InsufficientSystemResources(Exception):
639
640
  :param details: Any extra details about the problem that can be attached to the error.
640
641
  """
641
642
 
642
- self.job_name: Optional[str] = str(requirer)
643
+ self.job_name: str | None = str(requirer)
643
644
  self.resource = resource
644
645
  self.requested = cast(ParsedRequirement, getattr(requirer, resource))
645
646
  self.available = available
@@ -655,7 +656,7 @@ class InsufficientSystemResources(Exception):
655
656
  unit = "bytes of " if self.resource in ("disk", "memory") else ""
656
657
  purpose = " for temporary space" if self.resource == "disk" else ""
657
658
  qualifier = (
658
- " free on {self.source}"
659
+ f" free on {self.source}"
659
660
  if self.resource == "disk" and self.source is not None
660
661
  else ""
661
662
  )
@@ -695,8 +696,8 @@ class AcquisitionTimeoutException(Exception):
695
696
  def __init__(
696
697
  self,
697
698
  resource: str,
698
- requested: Union[int, float, set[int]],
699
- available: Union[int, float, set[int]],
699
+ requested: int | float | set[int],
700
+ available: int | float | set[int],
700
701
  ) -> None:
701
702
  """
702
703
  Creates an instance of this exception that indicates which resource is insufficient for
@@ -17,7 +17,6 @@ from abc import ABCMeta, abstractmethod
17
17
  from datetime import datetime
18
18
  from queue import Empty, Queue
19
19
  from threading import Lock, Thread
20
- from typing import Optional, Union
21
20
 
22
21
  from toil.batchSystems.abstractBatchSystem import (
23
22
  BatchJobExitReason,
@@ -27,9 +26,9 @@ from toil.batchSystems.cleanup_support import BatchSystemCleanupSupport
27
26
  from toil.bus import ExternalBatchIdMessage, get_job_kind
28
27
  from toil.common import Config
29
28
  from toil.job import AcceleratorRequirement, JobDescription
30
- from toil.statsAndLogging import TRACE
31
29
  from toil.lib.misc import CalledProcessErrorStderr
32
30
  from toil.lib.retry import DEFAULT_DELAYS, old_retry
31
+ from toil.statsAndLogging import TRACE
33
32
 
34
33
  logger = logging.getLogger(__name__)
35
34
 
@@ -172,7 +171,7 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
172
171
  "Job %s with batch system ID %s queued as job %s",
173
172
  jobName,
174
173
  jobID,
175
- str(batchJobID)
174
+ str(batchJobID),
176
175
  )
177
176
 
178
177
  # Store dict for mapping Toil job ID to batch job ID
@@ -258,8 +257,12 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
258
257
  self.coalesce_job_exit_codes, batch_job_id_list
259
258
  )
260
259
  # We got the statuses as a batch
261
- for running_job_id, status, backing_id in zip(running_job_list, statuses, batch_job_id_list):
262
- activity = self._handle_job_status(running_job_id, status, activity, backing_id)
260
+ for running_job_id, status, backing_id in zip(
261
+ running_job_list, statuses, batch_job_id_list
262
+ ):
263
+ activity = self._handle_job_status(
264
+ running_job_id, status, activity, backing_id
265
+ )
263
266
 
264
267
  self._checkOnJobsCache = activity
265
268
  self._checkOnJobsTimestamp = datetime.now()
@@ -268,7 +271,7 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
268
271
  def _handle_job_status(
269
272
  self,
270
273
  job_id: int,
271
- status: Union[int, tuple[int, Optional[BatchJobExitReason]], None],
274
+ status: int | tuple[int, BatchJobExitReason | None] | None,
272
275
  activity: bool,
273
276
  backing_id: str,
274
277
  ) -> bool:
@@ -313,7 +316,9 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
313
316
  if self.checkOnJobs():
314
317
  activity = True
315
318
  if not activity:
316
- logger.log(TRACE, "No activity, sleeping for %is", self.boss.sleepSeconds())
319
+ logger.log(
320
+ TRACE, "No activity, sleeping for %is", self.boss.sleepSeconds()
321
+ )
317
322
  return True
318
323
 
319
324
  def run(self):
@@ -332,7 +337,7 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
332
337
 
333
338
  def coalesce_job_exit_codes(
334
339
  self, batch_job_id_list: list
335
- ) -> list[Union[int, tuple[int, Optional[BatchJobExitReason]], None]]:
340
+ ) -> list[int | tuple[int, BatchJobExitReason | None] | None]:
336
341
  """
337
342
  Returns exit codes and possibly exit reasons for a list of jobs, or None if they are running.
338
343
 
@@ -362,8 +367,8 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
362
367
  jobID: int,
363
368
  command: str,
364
369
  jobName: str,
365
- job_environment: Optional[dict[str, str]] = None,
366
- gpus: Optional[int] = None,
370
+ job_environment: dict[str, str] | None = None,
371
+ gpus: int | None = None,
367
372
  ) -> list[str]:
368
373
  """
369
374
  Preparation in putting together a command-line string
@@ -416,7 +421,7 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
416
421
  @abstractmethod
417
422
  def getJobExitCode(
418
423
  self, batchJobID
419
- ) -> Union[int, tuple[int, Optional[BatchJobExitReason]], None]:
424
+ ) -> int | tuple[int, BatchJobExitReason | None] | None:
420
425
  """
421
426
  Returns job exit code and possibly an instance of abstractBatchSystem.BatchJobExitReason.
422
427
 
@@ -478,7 +483,7 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
478
483
  self,
479
484
  command: str,
480
485
  job_desc: JobDescription,
481
- job_environment: Optional[dict[str, str]] = None,
486
+ job_environment: dict[str, str] | None = None,
482
487
  ):
483
488
  # Avoid submitting internal jobs to the batch queue, handle locally
484
489
  local_id = self.handleLocalJob(command, job_desc)
@@ -35,7 +35,7 @@ import time
35
35
  import uuid
36
36
  from argparse import ArgumentParser, _ArgumentGroup
37
37
  from collections.abc import Iterator
38
- from typing import Any, Optional, Union
38
+ from typing import Any
39
39
 
40
40
  from botocore.exceptions import ClientError
41
41
 
@@ -137,7 +137,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
137
137
  # is managed by the BatchSystemLocalSupport.
138
138
 
139
139
  # Here is where we will store the user script resource object if we get one.
140
- self.user_script: Optional[Resource] = None
140
+ self.user_script: Resource | None = None
141
141
 
142
142
  # Get the image to deploy from Toil's configuration
143
143
  self.docker_image = applianceSelf()
@@ -145,7 +145,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
145
145
  # We can't use AWS Batch without a job definition. But we can use one
146
146
  # of them for all the jobs. We want to lazily initialize it. This will
147
147
  # be an ARN.
148
- self.job_definition: Optional[str] = None
148
+ self.job_definition: str | None = None
149
149
 
150
150
  # We need a way to map between our batch system ID numbers, and AWS Batch job IDs from the server.
151
151
  self.bs_id_to_aws_id: dict[int, str] = {}
@@ -179,7 +179,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
179
179
  self,
180
180
  command: str,
181
181
  job_desc: JobDescription,
182
- job_environment: Optional[dict[str, str]] = None,
182
+ job_environment: dict[str, str] | None = None,
183
183
  ) -> int:
184
184
  # Try the job as local
185
185
  local_id = self.handleLocalJob(command, job_desc)
@@ -298,7 +298,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
298
298
  # And re-compose them into a string
299
299
  return "".join(kept_chars)
300
300
 
301
- def _get_runtime(self, job_detail: dict[str, Any]) -> Optional[float]:
301
+ def _get_runtime(self, job_detail: dict[str, Any]) -> float | None:
302
302
  """
303
303
  Internal function. Should not be called outside this class.
304
304
 
@@ -349,7 +349,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
349
349
  )
350
350
  )
351
351
 
352
- def getUpdatedBatchJob(self, maxWait: int) -> Optional[UpdatedBatchJobInfo]:
352
+ def getUpdatedBatchJob(self, maxWait: int) -> UpdatedBatchJobInfo | None:
353
353
  # Remember when we started, for respecting the timeout
354
354
  entry = datetime.datetime.now()
355
355
  while (
@@ -494,7 +494,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
494
494
  if self.job_definition is None:
495
495
  # First work out what volume mounts to make, because the type
496
496
  # system is happiest this way
497
- volumes: list[dict[str, Union[str, dict[str, str]]]] = []
497
+ volumes: list[dict[str, str | dict[str, str]]] = []
498
498
  mount_points: list[dict[str, str]] = []
499
499
  for i, shared_path in enumerate(
500
500
  {
@@ -650,7 +650,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
650
650
  self._wait_until_stopped(self.bs_id_to_aws_id[bs_id])
651
651
 
652
652
  @classmethod
653
- def add_options(cls, parser: Union[ArgumentParser, _ArgumentGroup]) -> None:
653
+ def add_options(cls, parser: ArgumentParser | _ArgumentGroup) -> None:
654
654
  parser.add_argument(
655
655
  "--awsBatchRegion",
656
656
  dest="aws_batch_region",
@@ -13,7 +13,7 @@
13
13
  # limitations under the License.
14
14
  import logging
15
15
  from types import TracebackType
16
- from typing import Any, ContextManager, Optional
16
+ from typing import Any, ContextManager
17
17
 
18
18
  from toil.batchSystems.abstractBatchSystem import BatchSystemSupport, WorkerCleanupInfo
19
19
  from toil.batchSystems.local_support import BatchSystemLocalSupport
@@ -89,9 +89,9 @@ class WorkerCleanupContext:
89
89
  # that is always falsey but claims to return a bool is an error.
90
90
  def __exit__(
91
91
  self,
92
- type: Optional[type[BaseException]],
93
- value: Optional[BaseException],
94
- traceback: Optional[TracebackType],
92
+ type: type[BaseException] | None,
93
+ value: BaseException | None,
94
+ traceback: TracebackType | None,
95
95
  ) -> None:
96
96
  logger.debug("Leaving cleanup arena")
97
97
  for _ in self.arena.leave():
@@ -22,7 +22,7 @@ import os
22
22
  import pickle
23
23
  import subprocess
24
24
  import sys
25
- from typing import Any, Optional
25
+ from typing import Any
26
26
 
27
27
  from toil.batchSystems.abstractBatchSystem import EXIT_STATUS_UNAVAILABLE_VALUE
28
28
  from toil.resource import Resource
@@ -33,8 +33,8 @@ logger = logging.getLogger(__name__)
33
33
 
34
34
  def pack_job(
35
35
  command: str,
36
- user_script: Optional[Resource] = None,
37
- environment: Optional[dict[str, str]] = None,
36
+ user_script: Resource | None = None,
37
+ environment: dict[str, str] | None = None,
38
38
  ) -> list[str]:
39
39
  """
40
40
  Create a command that runs the given command in an environment.
@@ -17,7 +17,6 @@ import os
17
17
  import shlex
18
18
  import time
19
19
  from shlex import quote
20
- from typing import Optional
21
20
 
22
21
  from toil.batchSystems.abstractGridEngineBatchSystem import (
23
22
  AbstractGridEngineBatchSystem,
@@ -62,8 +61,8 @@ class GridEngineBatchSystem(AbstractGridEngineBatchSystem):
62
61
  jobID: int,
63
62
  command: str,
64
63
  jobName: str,
65
- job_environment: Optional[dict[str, str]] = None,
66
- gpus: Optional[int] = None,
64
+ job_environment: dict[str, str] | None = None,
65
+ gpus: int | None = None,
67
66
  ):
68
67
  # POSIX qsub
69
68
  # <https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/qsub.html>
@@ -126,7 +125,7 @@ class GridEngineBatchSystem(AbstractGridEngineBatchSystem):
126
125
  cpu: int,
127
126
  mem: int,
128
127
  jobID: int,
129
- job_environment: Optional[dict[str, str]] = None,
128
+ job_environment: dict[str, str] | None = None,
130
129
  ) -> list[str]:
131
130
  qsubline = [
132
131
  "qsub",
@@ -18,7 +18,7 @@ import os
18
18
  import time
19
19
  from contextlib import contextmanager
20
20
  from threading import Lock
21
- from typing import Any, Optional
21
+ from typing import Any
22
22
 
23
23
  import htcondor
24
24
 
@@ -355,7 +355,7 @@ class HTCondorBatchSystem(AbstractGridEngineBatchSystem):
355
355
  schedd.xquery(limit=0)
356
356
 
357
357
  @retry(errors=[htcondor.HTCondorIOError])
358
- def _get_schedd_address(self) -> Optional[str]:
358
+ def _get_schedd_address(self) -> str | None:
359
359
  """
360
360
  Get the HTCondor scheduler to connect to, or None for the local machine.
361
361
 
@@ -367,7 +367,7 @@ class HTCondorBatchSystem(AbstractGridEngineBatchSystem):
367
367
  schedd_name = os.getenv("TOIL_HTCONDOR_SCHEDD")
368
368
 
369
369
  # Get the scheduler's address, if not local
370
- schedd_ad: Optional[str] = None
370
+ schedd_ad: str | None = None
371
371
 
372
372
  # If TOIL_HTCONDOR_ variables are set, use them to find the Schedd
373
373
  if condor_host and schedd_name:
@@ -397,7 +397,7 @@ class HTCondorBatchSystem(AbstractGridEngineBatchSystem):
397
397
  return schedd_ad
398
398
 
399
399
  @retry(errors=[htcondor.HTCondorIOError])
400
- def _open_schedd_connection(self, schedd_ad: Optional[str] = None) -> Any:
400
+ def _open_schedd_connection(self, schedd_ad: str | None = None) -> Any:
401
401
  """
402
402
  Open a connection to the htcondor schedd.
403
403
 
@@ -451,7 +451,7 @@ class HTCondorBatchSystem(AbstractGridEngineBatchSystem):
451
451
 
452
452
  # Override the issueBatchJob method so HTCondor can be given the disk request
453
453
  def issueBatchJob(
454
- self, command: str, jobNode, job_environment: Optional[dict[str, str]] = None
454
+ self, command: str, jobNode, job_environment: dict[str, str] | None = None
455
455
  ):
456
456
  # Avoid submitting internal jobs to the batch queue, handle locally
457
457
  localID = self.handleLocalJob(command, jobNode)