toil 7.0.0__py3-none-any.whl → 8.0.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 (190) hide show
  1. toil/__init__.py +121 -83
  2. toil/batchSystems/__init__.py +1 -0
  3. toil/batchSystems/abstractBatchSystem.py +137 -77
  4. toil/batchSystems/abstractGridEngineBatchSystem.py +211 -101
  5. toil/batchSystems/awsBatch.py +237 -128
  6. toil/batchSystems/cleanup_support.py +22 -16
  7. toil/batchSystems/contained_executor.py +30 -26
  8. toil/batchSystems/gridengine.py +85 -49
  9. toil/batchSystems/htcondor.py +164 -87
  10. toil/batchSystems/kubernetes.py +622 -386
  11. toil/batchSystems/local_support.py +17 -12
  12. toil/batchSystems/lsf.py +132 -79
  13. toil/batchSystems/lsfHelper.py +13 -11
  14. toil/batchSystems/mesos/__init__.py +41 -29
  15. toil/batchSystems/mesos/batchSystem.py +288 -149
  16. toil/batchSystems/mesos/executor.py +77 -49
  17. toil/batchSystems/mesos/test/__init__.py +31 -23
  18. toil/batchSystems/options.py +38 -29
  19. toil/batchSystems/registry.py +53 -19
  20. toil/batchSystems/singleMachine.py +293 -123
  21. toil/batchSystems/slurm.py +489 -137
  22. toil/batchSystems/torque.py +46 -32
  23. toil/bus.py +141 -73
  24. toil/common.py +630 -359
  25. toil/cwl/__init__.py +1 -1
  26. toil/cwl/cwltoil.py +1114 -532
  27. toil/cwl/utils.py +17 -22
  28. toil/deferred.py +62 -41
  29. toil/exceptions.py +5 -3
  30. toil/fileStores/__init__.py +5 -5
  31. toil/fileStores/abstractFileStore.py +88 -57
  32. toil/fileStores/cachingFileStore.py +711 -247
  33. toil/fileStores/nonCachingFileStore.py +113 -75
  34. toil/job.py +988 -315
  35. toil/jobStores/abstractJobStore.py +387 -243
  36. toil/jobStores/aws/jobStore.py +727 -403
  37. toil/jobStores/aws/utils.py +161 -109
  38. toil/jobStores/conftest.py +1 -0
  39. toil/jobStores/fileJobStore.py +289 -151
  40. toil/jobStores/googleJobStore.py +137 -70
  41. toil/jobStores/utils.py +36 -15
  42. toil/leader.py +614 -269
  43. toil/lib/accelerators.py +115 -18
  44. toil/lib/aws/__init__.py +55 -28
  45. toil/lib/aws/ami.py +122 -87
  46. toil/lib/aws/iam.py +284 -108
  47. toil/lib/aws/s3.py +31 -0
  48. toil/lib/aws/session.py +193 -58
  49. toil/lib/aws/utils.py +238 -218
  50. toil/lib/bioio.py +13 -5
  51. toil/lib/compatibility.py +11 -6
  52. toil/lib/conversions.py +83 -49
  53. toil/lib/docker.py +131 -103
  54. toil/lib/ec2.py +322 -209
  55. toil/lib/ec2nodes.py +174 -106
  56. toil/lib/encryption/_dummy.py +5 -3
  57. toil/lib/encryption/_nacl.py +10 -6
  58. toil/lib/encryption/conftest.py +1 -0
  59. toil/lib/exceptions.py +26 -7
  60. toil/lib/expando.py +4 -2
  61. toil/lib/ftp_utils.py +217 -0
  62. toil/lib/generatedEC2Lists.py +127 -19
  63. toil/lib/humanize.py +6 -2
  64. toil/lib/integration.py +341 -0
  65. toil/lib/io.py +99 -11
  66. toil/lib/iterables.py +4 -2
  67. toil/lib/memoize.py +12 -8
  68. toil/lib/misc.py +65 -18
  69. toil/lib/objects.py +2 -2
  70. toil/lib/resources.py +19 -7
  71. toil/lib/retry.py +115 -77
  72. toil/lib/threading.py +282 -80
  73. toil/lib/throttle.py +15 -14
  74. toil/options/common.py +834 -401
  75. toil/options/cwl.py +175 -90
  76. toil/options/runner.py +50 -0
  77. toil/options/wdl.py +70 -19
  78. toil/provisioners/__init__.py +111 -46
  79. toil/provisioners/abstractProvisioner.py +322 -157
  80. toil/provisioners/aws/__init__.py +62 -30
  81. toil/provisioners/aws/awsProvisioner.py +980 -627
  82. toil/provisioners/clusterScaler.py +541 -279
  83. toil/provisioners/gceProvisioner.py +282 -179
  84. toil/provisioners/node.py +147 -79
  85. toil/realtimeLogger.py +34 -22
  86. toil/resource.py +137 -75
  87. toil/server/app.py +127 -61
  88. toil/server/celery_app.py +3 -1
  89. toil/server/cli/wes_cwl_runner.py +82 -53
  90. toil/server/utils.py +54 -28
  91. toil/server/wes/abstract_backend.py +64 -26
  92. toil/server/wes/amazon_wes_utils.py +21 -15
  93. toil/server/wes/tasks.py +121 -63
  94. toil/server/wes/toil_backend.py +142 -107
  95. toil/server/wsgi_app.py +4 -3
  96. toil/serviceManager.py +58 -22
  97. toil/statsAndLogging.py +148 -64
  98. toil/test/__init__.py +263 -179
  99. toil/test/batchSystems/batchSystemTest.py +438 -195
  100. toil/test/batchSystems/batch_system_plugin_test.py +18 -7
  101. toil/test/batchSystems/test_gridengine.py +173 -0
  102. toil/test/batchSystems/test_lsf_helper.py +67 -58
  103. toil/test/batchSystems/test_slurm.py +93 -47
  104. toil/test/cactus/test_cactus_integration.py +20 -22
  105. toil/test/cwl/cwlTest.py +271 -71
  106. toil/test/cwl/measure_default_memory.cwl +12 -0
  107. toil/test/cwl/not_run_required_input.cwl +29 -0
  108. toil/test/cwl/scatter_duplicate_outputs.cwl +40 -0
  109. toil/test/docs/scriptsTest.py +60 -34
  110. toil/test/jobStores/jobStoreTest.py +412 -235
  111. toil/test/lib/aws/test_iam.py +116 -48
  112. toil/test/lib/aws/test_s3.py +16 -9
  113. toil/test/lib/aws/test_utils.py +5 -6
  114. toil/test/lib/dockerTest.py +118 -141
  115. toil/test/lib/test_conversions.py +113 -115
  116. toil/test/lib/test_ec2.py +57 -49
  117. toil/test/lib/test_integration.py +104 -0
  118. toil/test/lib/test_misc.py +12 -5
  119. toil/test/mesos/MesosDataStructuresTest.py +23 -10
  120. toil/test/mesos/helloWorld.py +7 -6
  121. toil/test/mesos/stress.py +25 -20
  122. toil/test/options/options.py +7 -2
  123. toil/test/provisioners/aws/awsProvisionerTest.py +293 -140
  124. toil/test/provisioners/clusterScalerTest.py +440 -250
  125. toil/test/provisioners/clusterTest.py +81 -42
  126. toil/test/provisioners/gceProvisionerTest.py +174 -100
  127. toil/test/provisioners/provisionerTest.py +25 -13
  128. toil/test/provisioners/restartScript.py +5 -4
  129. toil/test/server/serverTest.py +188 -141
  130. toil/test/sort/restart_sort.py +137 -68
  131. toil/test/sort/sort.py +134 -66
  132. toil/test/sort/sortTest.py +91 -49
  133. toil/test/src/autoDeploymentTest.py +140 -100
  134. toil/test/src/busTest.py +20 -18
  135. toil/test/src/checkpointTest.py +8 -2
  136. toil/test/src/deferredFunctionTest.py +49 -35
  137. toil/test/src/dockerCheckTest.py +33 -26
  138. toil/test/src/environmentTest.py +20 -10
  139. toil/test/src/fileStoreTest.py +538 -271
  140. toil/test/src/helloWorldTest.py +7 -4
  141. toil/test/src/importExportFileTest.py +61 -31
  142. toil/test/src/jobDescriptionTest.py +32 -17
  143. toil/test/src/jobEncapsulationTest.py +2 -0
  144. toil/test/src/jobFileStoreTest.py +74 -50
  145. toil/test/src/jobServiceTest.py +187 -73
  146. toil/test/src/jobTest.py +120 -70
  147. toil/test/src/miscTests.py +19 -18
  148. toil/test/src/promisedRequirementTest.py +82 -36
  149. toil/test/src/promisesTest.py +7 -6
  150. toil/test/src/realtimeLoggerTest.py +6 -6
  151. toil/test/src/regularLogTest.py +71 -37
  152. toil/test/src/resourceTest.py +80 -49
  153. toil/test/src/restartDAGTest.py +36 -22
  154. toil/test/src/resumabilityTest.py +9 -2
  155. toil/test/src/retainTempDirTest.py +45 -14
  156. toil/test/src/systemTest.py +12 -8
  157. toil/test/src/threadingTest.py +44 -25
  158. toil/test/src/toilContextManagerTest.py +10 -7
  159. toil/test/src/userDefinedJobArgTypeTest.py +8 -5
  160. toil/test/src/workerTest.py +33 -16
  161. toil/test/utils/toilDebugTest.py +70 -58
  162. toil/test/utils/toilKillTest.py +4 -5
  163. toil/test/utils/utilsTest.py +239 -102
  164. toil/test/wdl/wdltoil_test.py +789 -148
  165. toil/test/wdl/wdltoil_test_kubernetes.py +37 -23
  166. toil/toilState.py +52 -26
  167. toil/utils/toilConfig.py +13 -4
  168. toil/utils/toilDebugFile.py +44 -27
  169. toil/utils/toilDebugJob.py +85 -25
  170. toil/utils/toilDestroyCluster.py +11 -6
  171. toil/utils/toilKill.py +8 -3
  172. toil/utils/toilLaunchCluster.py +251 -145
  173. toil/utils/toilMain.py +37 -16
  174. toil/utils/toilRsyncCluster.py +27 -14
  175. toil/utils/toilSshCluster.py +45 -22
  176. toil/utils/toilStats.py +75 -36
  177. toil/utils/toilStatus.py +226 -119
  178. toil/utils/toilUpdateEC2Instances.py +3 -1
  179. toil/version.py +11 -11
  180. toil/wdl/utils.py +5 -5
  181. toil/wdl/wdltoil.py +3513 -1052
  182. toil/worker.py +269 -128
  183. toil-8.0.0.dist-info/METADATA +173 -0
  184. toil-8.0.0.dist-info/RECORD +253 -0
  185. {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/WHEEL +1 -1
  186. toil-7.0.0.dist-info/METADATA +0 -158
  187. toil-7.0.0.dist-info/RECORD +0 -244
  188. {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/LICENSE +0 -0
  189. {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/entry_points.txt +0 -0
  190. {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/top_level.txt +0 -0
@@ -14,32 +14,28 @@
14
14
  import logging
15
15
  import os
16
16
  from abc import ABC, abstractmethod
17
+ from collections.abc import Generator, Iterator
17
18
  from contextlib import contextmanager
18
19
  from tempfile import mkstemp
19
20
  from threading import Event, Semaphore
20
- from typing import (IO,
21
- TYPE_CHECKING,
22
- Any,
23
- Callable,
24
- ContextManager,
25
- Dict,
26
- Generator,
27
- Iterator,
28
- List,
29
- Literal,
30
- Optional,
31
- Set,
32
- Tuple,
33
- Type,
34
- Union,
35
- cast,
36
- overload)
21
+ from typing import (
22
+ IO,
23
+ TYPE_CHECKING,
24
+ Any,
25
+ Callable,
26
+ ContextManager,
27
+ Literal,
28
+ Optional,
29
+ Union,
30
+ cast,
31
+ overload,
32
+ )
37
33
 
38
34
  import dill
39
35
 
40
36
  from toil.common import Toil, cacheDirName, getDirSizeRecursively
41
37
  from toil.fileStores import FileID
42
- from toil.job import Job, JobDescription, DebugStoppingPointReached
38
+ from toil.job import DebugStoppingPointReached, Job, JobDescription
43
39
  from toil.jobStores.abstractJobStore import AbstractJobStore
44
40
  from toil.lib.compatibility import deprecated
45
41
  from toil.lib.conversions import bytes2human
@@ -76,9 +72,10 @@ class AbstractFileStore(ABC):
76
72
  Also responsible for committing completed jobs back to the job store with
77
73
  an update operation, and allowing that commit operation to be waited for.
78
74
  """
75
+
79
76
  # Variables used for syncing reads/writes
80
77
  _pendingFileWritesLock = Semaphore()
81
- _pendingFileWrites: Set[str] = set()
78
+ _pendingFileWrites: set[str] = set()
82
79
  _terminateEvent = Event() # Used to signify crashes in threads
83
80
 
84
81
  def __init__(
@@ -111,20 +108,26 @@ class AbstractFileStore(ABC):
111
108
  # This gets replaced with a subdirectory of itself on open()
112
109
  self.localTempDir: str = os.path.abspath(file_store_dir)
113
110
  assert self.jobStore.config.workflowID is not None
114
- self.workflow_dir: str = Toil.getLocalWorkflowDir(self.jobStore.config.workflowID, self.jobStore.config.workDir)
115
- self.coordination_dir: str =Toil.get_local_workflow_coordination_dir(self.jobStore.config.workflowID, self.jobStore.config.workDir, self.jobStore.config.coordination_dir)
111
+ self.workflow_dir: str = Toil.getLocalWorkflowDir(
112
+ self.jobStore.config.workflowID, self.jobStore.config.workDir
113
+ )
114
+ self.coordination_dir: str = Toil.get_local_workflow_coordination_dir(
115
+ self.jobStore.config.workflowID,
116
+ self.jobStore.config.workDir,
117
+ self.jobStore.config.coordination_dir,
118
+ )
116
119
  self.jobName: str = str(self.jobDesc)
117
120
  self.waitForPreviousCommit = waitForPreviousCommit
118
- self.logging_messages: List[Dict[str, Union[int, str]]] = []
119
- self.logging_user_streams: List[dict[str, str]] = []
121
+ self.logging_messages: list[dict[str, Union[int, str]]] = []
122
+ self.logging_user_streams: list[dict[str, str]] = []
120
123
  # Records file IDs of files deleted during the current job. Doesn't get
121
124
  # committed back until the job is completely successful, because if the
122
125
  # job is re-run it will need to be able to re-delete these files.
123
126
  # This is a set of str objects, not FileIDs.
124
- self.filesToDelete: Set[str] = set()
127
+ self.filesToDelete: set[str] = set()
125
128
  # Holds records of file ID, or file ID and local path, for reporting
126
129
  # the accessed files of failed jobs.
127
- self._accessLog: List[Tuple[str, ...]] = []
130
+ self._accessLog: list[tuple[str, ...]] = []
128
131
  # Holds total bytes of observed disk usage for the last job run under open()
129
132
  self._job_disk_used: Optional[int] = None
130
133
 
@@ -141,13 +144,17 @@ class AbstractFileStore(ABC):
141
144
  from toil.fileStores.cachingFileStore import CachingFileStore
142
145
  from toil.fileStores.nonCachingFileStore import NonCachingFileStore
143
146
 
144
- fileStoreCls: Union[Type["CachingFileStore"], Type["NonCachingFileStore"]] = (
147
+ fileStoreCls: Union[type["CachingFileStore"], type["NonCachingFileStore"]] = (
145
148
  CachingFileStore if caching else NonCachingFileStore
146
149
  )
147
150
  return fileStoreCls(jobStore, jobDesc, file_store_dir, waitForPreviousCommit)
148
151
 
149
152
  @staticmethod
150
- def shutdownFileStore(workflowID: str, config_work_dir: Optional[str], config_coordination_dir: Optional[str]) -> None:
153
+ def shutdownFileStore(
154
+ workflowID: str,
155
+ config_work_dir: Optional[str],
156
+ config_coordination_dir: Optional[str],
157
+ ) -> None:
151
158
  """
152
159
  Carry out any necessary filestore-specific cleanup.
153
160
 
@@ -167,7 +174,9 @@ class AbstractFileStore(ABC):
167
174
  from toil.fileStores.nonCachingFileStore import NonCachingFileStore
168
175
 
169
176
  workflowDir = Toil.getLocalWorkflowDir(workflowID, config_work_dir)
170
- coordination_dir = Toil.get_local_workflow_coordination_dir(workflowID, config_work_dir, config_coordination_dir)
177
+ coordination_dir = Toil.get_local_workflow_coordination_dir(
178
+ workflowID, config_work_dir, config_coordination_dir
179
+ )
171
180
  cacheDir = os.path.join(workflowDir, cacheDirName(workflowID))
172
181
  if os.path.exists(cacheDir):
173
182
  # The presence of the cacheDir suggests this was a cached run. We don't need
@@ -208,12 +217,16 @@ class AbstractFileStore(ABC):
208
217
  percent: float = 0.0
209
218
  if job_requested_disk and job_requested_disk > 0:
210
219
  percent = float(self._job_disk_used) / job_requested_disk * 100
211
- disk_usage: str = (f"Job {self.jobName} used {percent:.2f}% disk ({bytes2human(self._job_disk_used)}B [{self._job_disk_used}B] used, "
212
- f"{bytes2human(job_requested_disk)}B [{job_requested_disk}B] requested).")
220
+ disk_usage: str = (
221
+ f"Job {self.jobName} used {percent:.2f}% disk ({bytes2human(self._job_disk_used)}B [{self._job_disk_used}B] used, "
222
+ f"{bytes2human(job_requested_disk)}B [{job_requested_disk}B] requested)."
223
+ )
213
224
  if self._job_disk_used > job_requested_disk:
214
- self.log_to_leader("Job used more disk than requested. For CWL, consider increasing the outdirMin "
215
- f"requirement, otherwise, consider increasing the disk requirement. {disk_usage}",
216
- level=logging.WARNING)
225
+ self.log_to_leader(
226
+ "Job used more disk than requested. For CWL, consider increasing the outdirMin "
227
+ f"requirement, otherwise, consider increasing the disk requirement. {disk_usage}",
228
+ level=logging.WARNING,
229
+ )
217
230
  else:
218
231
  self.log_to_leader(disk_usage, level=logging.DEBUG)
219
232
 
@@ -226,7 +239,6 @@ class AbstractFileStore(ABC):
226
239
  """
227
240
  return self._job_disk_used
228
241
 
229
-
230
242
  # Functions related to temp files and directories
231
243
  def getLocalTempDir(self) -> str:
232
244
  """
@@ -241,7 +253,9 @@ class AbstractFileStore(ABC):
241
253
  """
242
254
  return os.path.abspath(mkdtemp(dir=self.localTempDir))
243
255
 
244
- def getLocalTempFile(self, suffix: Optional[str] = None, prefix: Optional[str] = None) -> str:
256
+ def getLocalTempFile(
257
+ self, suffix: Optional[str] = None, prefix: Optional[str] = None
258
+ ) -> str:
245
259
  """
246
260
  Get a new local temporary file that will persist for the duration of the job.
247
261
 
@@ -258,12 +272,14 @@ class AbstractFileStore(ABC):
258
272
  handle, tmpFile = mkstemp(
259
273
  suffix=".tmp" if suffix is None else suffix,
260
274
  prefix="tmp" if prefix is None else prefix,
261
- dir=self.localTempDir
275
+ dir=self.localTempDir,
262
276
  )
263
277
  os.close(handle)
264
278
  return os.path.abspath(tmpFile)
265
279
 
266
- def getLocalTempFileName(self, suffix: Optional[str] = None, prefix: Optional[str] = None) -> str:
280
+ def getLocalTempFileName(
281
+ self, suffix: Optional[str] = None, prefix: Optional[str] = None
282
+ ) -> str:
267
283
  """
268
284
  Get a valid name for a new local file. Don't actually create a file at the path.
269
285
 
@@ -317,7 +333,7 @@ class AbstractFileStore(ABC):
317
333
  basename: Optional[str] = None,
318
334
  encoding: Optional[str] = None,
319
335
  errors: Optional[str] = None,
320
- ) -> Iterator[Tuple[WriteWatchingStream, FileID]]:
336
+ ) -> Iterator[tuple[WriteWatchingStream, FileID]]:
321
337
  """
322
338
  Similar to writeGlobalFile, but allows the writing of a stream to the job store.
323
339
  The yielded file handle does not need to and should not be closed explicitly.
@@ -357,11 +373,14 @@ class AbstractFileStore(ABC):
357
373
  def handle(numBytes: int) -> None:
358
374
  # No scope problem here, because we don't assign to a fileID local
359
375
  fileID.size += numBytes
376
+
360
377
  wrappedStream.onWrite(handle)
361
378
 
362
379
  yield wrappedStream, fileID
363
380
 
364
- def _dumpAccessLogs(self, job_type: str = "Failed", log_level: int = logging.WARNING) -> None:
381
+ def _dumpAccessLogs(
382
+ self, job_type: str = "Failed", log_level: int = logging.WARNING
383
+ ) -> None:
365
384
  """
366
385
  Log a report of the files accessed.
367
386
 
@@ -370,7 +389,7 @@ class AbstractFileStore(ABC):
370
389
  :param job_type: Adjective to describe the job in the report.
371
390
  """
372
391
  if len(self._accessLog) > 0:
373
- logger.log(log_level, '%s job accessed files:', job_type)
392
+ logger.log(log_level, "%s job accessed files:", job_type)
374
393
 
375
394
  for item in self._accessLog:
376
395
  # For each access record
@@ -379,14 +398,29 @@ class AbstractFileStore(ABC):
379
398
  file_id, dest_path = item
380
399
  if os.path.exists(dest_path):
381
400
  if os.path.islink(dest_path):
382
- logger.log(log_level, 'Symlinked file \'%s\' to path \'%s\'', file_id, dest_path)
401
+ logger.log(
402
+ log_level,
403
+ "Symlinked file '%s' to path '%s'",
404
+ file_id,
405
+ dest_path,
406
+ )
383
407
  else:
384
- logger.log(log_level, 'Downloaded file \'%s\' to path \'%s\'', file_id, dest_path)
408
+ logger.log(
409
+ log_level,
410
+ "Downloaded file '%s' to path '%s'",
411
+ file_id,
412
+ dest_path,
413
+ )
385
414
  else:
386
- logger.log(log_level, 'Downloaded file \'%s\' to path \'%s\' (gone!)', file_id, dest_path)
415
+ logger.log(
416
+ log_level,
417
+ "Downloaded file '%s' to path '%s' (gone!)",
418
+ file_id,
419
+ dest_path,
420
+ )
387
421
  else:
388
422
  # Otherwise dump without the name
389
- logger.log(log_level, 'Streamed file \'%s\'', *item)
423
+ logger.log(log_level, "Streamed file '%s'", *item)
390
424
 
391
425
  def logAccess(
392
426
  self, fileStoreID: Union[FileID, str], destination: Union[str, None] = None
@@ -453,14 +487,12 @@ class AbstractFileStore(ABC):
453
487
  fileStoreID: str,
454
488
  encoding: Literal[None] = None,
455
489
  errors: Optional[str] = None,
456
- ) -> ContextManager[IO[bytes]]:
457
- ...
490
+ ) -> ContextManager[IO[bytes]]: ...
458
491
 
459
492
  @overload
460
493
  def readGlobalFileStream(
461
494
  self, fileStoreID: str, encoding: str, errors: Optional[str] = None
462
- ) -> ContextManager[IO[str]]:
463
- ...
495
+ ) -> ContextManager[IO[str]]: ...
464
496
 
465
497
  @abstractmethod
466
498
  def readGlobalFileStream(
@@ -504,7 +536,7 @@ class AbstractFileStore(ABC):
504
536
  :return: File's size in bytes, as stored in the job store
505
537
  """
506
538
  # First try and see if the size is still attached
507
- size = getattr(fileStoreID, 'size', None)
539
+ size = getattr(fileStoreID, "size", None)
508
540
 
509
541
  if size is None:
510
542
  # It fell off
@@ -557,7 +589,7 @@ class AbstractFileStore(ABC):
557
589
  ) -> Optional[FileID]:
558
590
  return self.jobStore.import_file(src_uri, shared_file_name=shared_file_name)
559
591
 
560
- @deprecated(new_function_name='export_file')
592
+ @deprecated(new_function_name="export_file")
561
593
  def exportFile(self, jobStoreFileID: FileID, dstUrl: str) -> None:
562
594
  return self.export_file(jobStoreFileID, dstUrl)
563
595
 
@@ -586,7 +618,7 @@ class AbstractFileStore(ABC):
586
618
  class _StateFile:
587
619
  """Read and write dill-ed state dictionaries from/to a file into a namespace."""
588
620
 
589
- def __init__(self, stateDict: Dict[str, Any]):
621
+ def __init__(self, stateDict: dict[str, Any]):
590
622
  assert isinstance(stateDict, dict)
591
623
  self.__dict__.update(stateDict)
592
624
 
@@ -614,7 +646,7 @@ class AbstractFileStore(ABC):
614
646
  """
615
647
  # Read the value from the cache state file then initialize and instance of
616
648
  # _CacheState with it.
617
- with open(fileName, 'rb') as fH:
649
+ with open(fileName, "rb") as fH:
618
650
  infoDict = dill.load(fH)
619
651
  return cls(infoDict)
620
652
 
@@ -624,14 +656,14 @@ class AbstractFileStore(ABC):
624
656
 
625
657
  :param fileName: Path to the state file.
626
658
  """
627
- with open(fileName + '.tmp', 'wb') as fH:
659
+ with open(fileName + ".tmp", "wb") as fH:
628
660
  # Based on answer by user "Mark" at:
629
661
  # http://stackoverflow.com/questions/2709800/how-to-pickle-yourself
630
662
  # We can't pickle nested classes. So we have to pickle the variables
631
663
  # of the class.
632
664
  # If we ever change this, we need to ensure it doesn't break FileID
633
665
  dill.dump(self.__dict__, fH)
634
- os.rename(fileName + '.tmp', fileName)
666
+ os.rename(fileName + ".tmp", fileName)
635
667
 
636
668
  # Functions related to logging
637
669
  def log_to_leader(self, text: str, level: int = logging.INFO) -> None:
@@ -645,8 +677,7 @@ class AbstractFileStore(ABC):
645
677
  logger.log(level=level, msg=("LOG-TO-MASTER: " + text))
646
678
  self.logging_messages.append(dict(text=text, level=level))
647
679
 
648
-
649
- @deprecated(new_function_name='export_file')
680
+ @deprecated(new_function_name="export_file")
650
681
  def logToMaster(self, text: str, level: int = logging.INFO) -> None:
651
682
  self.log_to_leader(text, level)
652
683
 
@@ -664,7 +695,7 @@ class AbstractFileStore(ABC):
664
695
  """
665
696
 
666
697
  # Read the whole stream into memory
667
- steam_data = stream.read().decode('utf-8', errors='replace')
698
+ steam_data = stream.read().decode("utf-8", errors="replace")
668
699
  # And remember it for the worker to fish out
669
700
  self.logging_user_streams.append(dict(name=name, text=steam_data))
670
701