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.
- toil/__init__.py +5 -9
- toil/batchSystems/abstractBatchSystem.py +23 -22
- toil/batchSystems/abstractGridEngineBatchSystem.py +17 -12
- toil/batchSystems/awsBatch.py +8 -8
- toil/batchSystems/cleanup_support.py +4 -4
- toil/batchSystems/contained_executor.py +3 -3
- toil/batchSystems/gridengine.py +3 -4
- toil/batchSystems/htcondor.py +5 -5
- toil/batchSystems/kubernetes.py +65 -63
- toil/batchSystems/local_support.py +2 -3
- toil/batchSystems/lsf.py +6 -7
- toil/batchSystems/mesos/batchSystem.py +11 -7
- toil/batchSystems/mesos/test/__init__.py +1 -2
- toil/batchSystems/options.py +9 -10
- toil/batchSystems/registry.py +3 -7
- toil/batchSystems/singleMachine.py +8 -11
- toil/batchSystems/slurm.py +49 -38
- toil/batchSystems/torque.py +3 -4
- toil/bus.py +36 -34
- toil/common.py +129 -89
- toil/cwl/cwltoil.py +857 -729
- toil/cwl/utils.py +44 -35
- toil/fileStores/__init__.py +3 -1
- toil/fileStores/abstractFileStore.py +28 -30
- toil/fileStores/cachingFileStore.py +8 -8
- toil/fileStores/nonCachingFileStore.py +10 -21
- toil/job.py +159 -158
- toil/jobStores/abstractJobStore.py +68 -69
- toil/jobStores/aws/jobStore.py +249 -213
- toil/jobStores/aws/utils.py +13 -24
- toil/jobStores/fileJobStore.py +28 -22
- toil/jobStores/googleJobStore.py +21 -17
- toil/jobStores/utils.py +3 -7
- toil/leader.py +14 -14
- toil/lib/accelerators.py +6 -4
- toil/lib/aws/__init__.py +9 -10
- toil/lib/aws/ami.py +33 -19
- toil/lib/aws/iam.py +6 -6
- toil/lib/aws/s3.py +259 -157
- toil/lib/aws/session.py +76 -76
- toil/lib/aws/utils.py +51 -43
- toil/lib/checksum.py +19 -15
- toil/lib/compatibility.py +3 -2
- toil/lib/conversions.py +45 -18
- toil/lib/directory.py +29 -26
- toil/lib/docker.py +93 -99
- toil/lib/dockstore.py +77 -50
- toil/lib/ec2.py +39 -38
- toil/lib/ec2nodes.py +11 -4
- toil/lib/exceptions.py +8 -5
- toil/lib/ftp_utils.py +9 -14
- toil/lib/generatedEC2Lists.py +161 -20
- toil/lib/history.py +141 -97
- toil/lib/history_submission.py +163 -72
- toil/lib/io.py +27 -17
- toil/lib/memoize.py +2 -1
- toil/lib/misc.py +15 -11
- toil/lib/pipes.py +40 -25
- toil/lib/plugins.py +12 -8
- toil/lib/resources.py +1 -0
- toil/lib/retry.py +32 -38
- toil/lib/threading.py +12 -12
- toil/lib/throttle.py +1 -2
- toil/lib/trs.py +113 -51
- toil/lib/url.py +14 -23
- toil/lib/web.py +7 -2
- toil/options/common.py +18 -15
- toil/options/cwl.py +2 -2
- toil/options/runner.py +9 -5
- toil/options/wdl.py +1 -3
- toil/provisioners/__init__.py +9 -9
- toil/provisioners/abstractProvisioner.py +22 -20
- toil/provisioners/aws/__init__.py +20 -14
- toil/provisioners/aws/awsProvisioner.py +10 -8
- toil/provisioners/clusterScaler.py +19 -18
- toil/provisioners/gceProvisioner.py +2 -3
- toil/provisioners/node.py +11 -13
- toil/realtimeLogger.py +4 -4
- toil/resource.py +5 -5
- toil/server/app.py +2 -2
- toil/server/cli/wes_cwl_runner.py +11 -11
- toil/server/utils.py +18 -21
- toil/server/wes/abstract_backend.py +9 -8
- toil/server/wes/amazon_wes_utils.py +3 -3
- toil/server/wes/tasks.py +3 -5
- toil/server/wes/toil_backend.py +17 -21
- toil/server/wsgi_app.py +3 -3
- toil/serviceManager.py +3 -4
- toil/statsAndLogging.py +12 -13
- toil/test/__init__.py +33 -24
- toil/test/batchSystems/batchSystemTest.py +12 -11
- toil/test/batchSystems/batch_system_plugin_test.py +3 -5
- toil/test/batchSystems/test_slurm.py +38 -24
- toil/test/cwl/conftest.py +5 -6
- toil/test/cwl/cwlTest.py +194 -78
- toil/test/cwl/download_file_uri.json +6 -0
- toil/test/cwl/download_file_uri_no_hostname.json +6 -0
- toil/test/docs/scripts/tutorial_staging.py +1 -0
- toil/test/jobStores/jobStoreTest.py +9 -7
- toil/test/lib/aws/test_iam.py +1 -3
- toil/test/lib/aws/test_s3.py +1 -1
- toil/test/lib/dockerTest.py +9 -9
- toil/test/lib/test_ec2.py +12 -11
- toil/test/lib/test_history.py +4 -4
- toil/test/lib/test_trs.py +16 -14
- toil/test/lib/test_url.py +7 -6
- toil/test/lib/url_plugin_test.py +12 -18
- toil/test/provisioners/aws/awsProvisionerTest.py +10 -8
- toil/test/provisioners/clusterScalerTest.py +2 -5
- toil/test/provisioners/clusterTest.py +1 -3
- toil/test/server/serverTest.py +13 -4
- toil/test/sort/restart_sort.py +2 -6
- toil/test/sort/sort.py +3 -8
- toil/test/src/deferredFunctionTest.py +7 -7
- toil/test/src/environmentTest.py +1 -2
- toil/test/src/fileStoreTest.py +5 -5
- toil/test/src/importExportFileTest.py +5 -6
- toil/test/src/jobServiceTest.py +22 -14
- toil/test/src/jobTest.py +121 -25
- toil/test/src/miscTests.py +5 -7
- toil/test/src/promisedRequirementTest.py +8 -7
- toil/test/src/regularLogTest.py +2 -3
- toil/test/src/resourceTest.py +5 -8
- toil/test/src/restartDAGTest.py +5 -6
- toil/test/src/resumabilityTest.py +2 -2
- toil/test/src/retainTempDirTest.py +3 -3
- toil/test/src/systemTest.py +3 -3
- toil/test/src/threadingTest.py +1 -1
- toil/test/src/workerTest.py +1 -2
- toil/test/utils/toilDebugTest.py +6 -4
- toil/test/utils/toilKillTest.py +1 -1
- toil/test/utils/utilsTest.py +15 -14
- toil/test/wdl/wdltoil_test.py +247 -124
- toil/test/wdl/wdltoil_test_kubernetes.py +2 -2
- toil/toilState.py +2 -3
- toil/utils/toilDebugFile.py +3 -8
- toil/utils/toilDebugJob.py +1 -2
- toil/utils/toilLaunchCluster.py +1 -2
- toil/utils/toilSshCluster.py +2 -0
- toil/utils/toilStats.py +19 -24
- toil/utils/toilStatus.py +11 -14
- toil/version.py +10 -10
- toil/wdl/wdltoil.py +313 -209
- toil/worker.py +18 -12
- {toil-9.1.2.dist-info → toil-9.2.0.dist-info}/METADATA +11 -14
- {toil-9.1.2.dist-info → toil-9.2.0.dist-info}/RECORD +150 -153
- {toil-9.1.2.dist-info → toil-9.2.0.dist-info}/WHEEL +1 -1
- toil/test/cwl/staging_cat.cwl +0 -27
- toil/test/cwl/staging_make_file.cwl +0 -25
- toil/test/cwl/staging_workflow.cwl +0 -43
- toil/test/cwl/zero_default.cwl +0 -61
- toil/test/utils/ABCWorkflowDebug/ABC.txt +0 -1
- {toil-9.1.2.dist-info → toil-9.2.0.dist-info}/entry_points.txt +0 -0
- {toil-9.1.2.dist-info → toil-9.2.0.dist-info}/licenses/LICENSE +0 -0
- {toil-9.1.2.dist-info → toil-9.2.0.dist-info}/top_level.txt +0 -0
|
@@ -17,7 +17,7 @@ import pickle
|
|
|
17
17
|
import re
|
|
18
18
|
import shutil
|
|
19
19
|
from abc import ABC, ABCMeta, abstractmethod
|
|
20
|
-
from collections.abc import Iterator, ValuesView
|
|
20
|
+
from collections.abc import Callable, Iterator, ValuesView
|
|
21
21
|
from contextlib import closing, contextmanager
|
|
22
22
|
from datetime import timedelta
|
|
23
23
|
from http.client import BadStatusLine
|
|
@@ -25,18 +25,15 @@ from typing import (
|
|
|
25
25
|
IO,
|
|
26
26
|
TYPE_CHECKING,
|
|
27
27
|
Any,
|
|
28
|
-
Callable,
|
|
29
28
|
ContextManager,
|
|
30
29
|
Literal,
|
|
31
|
-
Optional,
|
|
32
30
|
Union,
|
|
33
31
|
cast,
|
|
34
32
|
overload,
|
|
35
|
-
Type,
|
|
36
33
|
)
|
|
37
34
|
from urllib.error import HTTPError
|
|
38
35
|
from urllib.parse import ParseResult, urlparse
|
|
39
|
-
from urllib.request import
|
|
36
|
+
from urllib.request import Request, urlopen
|
|
40
37
|
from uuid import uuid4
|
|
41
38
|
|
|
42
39
|
from toil.common import Config, getNodeID, safeUnpickleFromStream
|
|
@@ -47,9 +44,8 @@ from toil.job import (
|
|
|
47
44
|
JobException,
|
|
48
45
|
ServiceJobDescription,
|
|
49
46
|
)
|
|
50
|
-
from toil.lib.ftp_utils import FtpFsAccess
|
|
51
47
|
from toil.lib.compatibility import deprecated
|
|
52
|
-
from toil.lib.
|
|
48
|
+
from toil.lib.ftp_utils import FtpFsAccess
|
|
53
49
|
from toil.lib.io import WriteWatchingStream
|
|
54
50
|
from toil.lib.memoize import memoize
|
|
55
51
|
from toil.lib.retry import ErrorCondition, retry
|
|
@@ -74,7 +70,7 @@ class LocatorException(Exception):
|
|
|
74
70
|
For example, job store/aws bucket exceptions where they already exist
|
|
75
71
|
"""
|
|
76
72
|
|
|
77
|
-
def __init__(self, error_msg: str, locator: str, prefix:
|
|
73
|
+
def __init__(self, error_msg: str, locator: str, prefix: str | None = None):
|
|
78
74
|
full_locator = locator if prefix is None else f"{prefix}:{locator}"
|
|
79
75
|
super().__init__(error_msg % full_locator)
|
|
80
76
|
|
|
@@ -90,7 +86,7 @@ class InvalidImportExportUrlException(Exception):
|
|
|
90
86
|
class NoSuchJobException(Exception):
|
|
91
87
|
"""Indicates that the specified job does not exist."""
|
|
92
88
|
|
|
93
|
-
def __init__(self, jobStoreID:
|
|
89
|
+
def __init__(self, jobStoreID: FileID | str):
|
|
94
90
|
"""
|
|
95
91
|
:param str jobStoreID: the jobStoreID that was mistakenly assumed to exist
|
|
96
92
|
"""
|
|
@@ -100,7 +96,7 @@ class NoSuchJobException(Exception):
|
|
|
100
96
|
class ConcurrentFileModificationException(Exception):
|
|
101
97
|
"""Indicates that the file was attempted to be modified by multiple processes at once."""
|
|
102
98
|
|
|
103
|
-
def __init__(self, jobStoreFileID:
|
|
99
|
+
def __init__(self, jobStoreFileID: FileID | str):
|
|
104
100
|
"""
|
|
105
101
|
:param jobStoreFileID: the ID of the file that was modified by multiple workers
|
|
106
102
|
or processes concurrently
|
|
@@ -112,7 +108,10 @@ class NoSuchFileException(Exception):
|
|
|
112
108
|
"""Indicates that the specified file does not exist."""
|
|
113
109
|
|
|
114
110
|
def __init__(
|
|
115
|
-
self,
|
|
111
|
+
self,
|
|
112
|
+
jobStoreFileID: FileID | str,
|
|
113
|
+
customName: str | None = None,
|
|
114
|
+
*extra: Any,
|
|
116
115
|
):
|
|
117
116
|
"""
|
|
118
117
|
:param jobStoreFileID: the ID of the file that was mistakenly assumed to exist
|
|
@@ -145,7 +144,7 @@ class NoSuchJobStoreException(LocatorException):
|
|
|
145
144
|
super().__init__(
|
|
146
145
|
"The job store '%s' does not exist, so there is nothing to restart.",
|
|
147
146
|
locator,
|
|
148
|
-
prefix
|
|
147
|
+
prefix,
|
|
149
148
|
)
|
|
150
149
|
|
|
151
150
|
|
|
@@ -160,7 +159,7 @@ class JobStoreExistsException(LocatorException):
|
|
|
160
159
|
"The job store '%s' already exists. Use --restart to resume the workflow, or remove "
|
|
161
160
|
"the job store with 'toil clean' to start the workflow from scratch.",
|
|
162
161
|
locator,
|
|
163
|
-
prefix
|
|
162
|
+
prefix,
|
|
164
163
|
)
|
|
165
164
|
|
|
166
165
|
|
|
@@ -362,7 +361,6 @@ class AbstractJobStore(ABC):
|
|
|
362
361
|
jobStoreClasses.append(jobStoreClass)
|
|
363
362
|
return jobStoreClasses
|
|
364
363
|
|
|
365
|
-
|
|
366
364
|
# Importing a file with a shared file name returns None, but without one it
|
|
367
365
|
# returns a file ID. Explain this to MyPy.
|
|
368
366
|
|
|
@@ -388,10 +386,10 @@ class AbstractJobStore(ABC):
|
|
|
388
386
|
def importFile(
|
|
389
387
|
self,
|
|
390
388
|
srcUrl: str,
|
|
391
|
-
sharedFileName:
|
|
389
|
+
sharedFileName: str | None = None,
|
|
392
390
|
hardlink: bool = False,
|
|
393
391
|
symlink: bool = True,
|
|
394
|
-
) ->
|
|
392
|
+
) -> FileID | None:
|
|
395
393
|
return self.import_file(srcUrl, sharedFileName, hardlink, symlink)
|
|
396
394
|
|
|
397
395
|
@overload
|
|
@@ -415,10 +413,10 @@ class AbstractJobStore(ABC):
|
|
|
415
413
|
def import_file(
|
|
416
414
|
self,
|
|
417
415
|
src_uri: str,
|
|
418
|
-
shared_file_name:
|
|
416
|
+
shared_file_name: str | None = None,
|
|
419
417
|
hardlink: bool = False,
|
|
420
418
|
symlink: bool = True,
|
|
421
|
-
) ->
|
|
419
|
+
) -> FileID | None:
|
|
422
420
|
"""
|
|
423
421
|
Imports the file at the given URL into job store. The ID of the newly imported file is
|
|
424
422
|
returned. If the name of a shared file name is provided, the file will be imported as
|
|
@@ -467,12 +465,12 @@ class AbstractJobStore(ABC):
|
|
|
467
465
|
|
|
468
466
|
def _import_file(
|
|
469
467
|
self,
|
|
470
|
-
otherCls:
|
|
468
|
+
otherCls: type["URLAccess"],
|
|
471
469
|
uri: ParseResult,
|
|
472
|
-
shared_file_name:
|
|
470
|
+
shared_file_name: str | None = None,
|
|
473
471
|
hardlink: bool = False,
|
|
474
472
|
symlink: bool = True,
|
|
475
|
-
) ->
|
|
473
|
+
) -> FileID | None:
|
|
476
474
|
"""
|
|
477
475
|
Import the file at the given URL using the given job store class to retrieve that file.
|
|
478
476
|
See also :meth:`.importFile`. This method applies a generic approach to importing: it
|
|
@@ -524,13 +522,14 @@ class AbstractJobStore(ABC):
|
|
|
524
522
|
supported URL scheme e.g. a blob in an AWS s3 bucket. May also be a local path.
|
|
525
523
|
"""
|
|
526
524
|
from toil.common import Toil
|
|
525
|
+
|
|
527
526
|
dst_uri = Toil.normalize_uri(dst_uri)
|
|
528
527
|
parseResult = urlparse(dst_uri)
|
|
529
528
|
otherCls = URLAccess._find_url_implementation(parseResult, export=True)
|
|
530
529
|
self._export_file(otherCls, file_id, parseResult)
|
|
531
530
|
|
|
532
531
|
def _export_file(
|
|
533
|
-
self, otherCls:
|
|
532
|
+
self, otherCls: type["URLAccess"], jobStoreFileID: FileID, url: ParseResult
|
|
534
533
|
) -> None:
|
|
535
534
|
"""
|
|
536
535
|
Refer to exportFile docstring for information about this method.
|
|
@@ -547,7 +546,7 @@ class AbstractJobStore(ABC):
|
|
|
547
546
|
self._default_export_file(otherCls, jobStoreFileID, url)
|
|
548
547
|
|
|
549
548
|
def _default_export_file(
|
|
550
|
-
self, otherCls:
|
|
549
|
+
self, otherCls: type["URLAccess"], jobStoreFileID: FileID, url: ParseResult
|
|
551
550
|
) -> None:
|
|
552
551
|
"""
|
|
553
552
|
Refer to exportFile docstring for information about this method.
|
|
@@ -597,7 +596,7 @@ class AbstractJobStore(ABC):
|
|
|
597
596
|
|
|
598
597
|
# Cleanup functions
|
|
599
598
|
def clean(
|
|
600
|
-
self, jobCache:
|
|
599
|
+
self, jobCache: dict[Union[str, "TemporaryID"], JobDescription] | None = None
|
|
601
600
|
) -> JobDescription:
|
|
602
601
|
"""
|
|
603
602
|
Function to cleanup the state of a job store after a restart.
|
|
@@ -648,7 +647,7 @@ class AbstractJobStore(ABC):
|
|
|
648
647
|
self.update_job(jobDescription)
|
|
649
648
|
|
|
650
649
|
def getJobDescriptions() -> (
|
|
651
|
-
|
|
650
|
+
ValuesView[JobDescription] | Iterator[JobDescription]
|
|
652
651
|
):
|
|
653
652
|
if jobCache is not None:
|
|
654
653
|
return jobCache.values()
|
|
@@ -904,7 +903,7 @@ class AbstractJobStore(ABC):
|
|
|
904
903
|
|
|
905
904
|
# We have to manually discard the stream to avoid getting
|
|
906
905
|
# stuck on a blocking write from the job store.
|
|
907
|
-
def discardStream(stream:
|
|
906
|
+
def discardStream(stream: IO[bytes] | IO[str]) -> None:
|
|
908
907
|
"""Read the stream 4K at a time until EOF, discarding all input."""
|
|
909
908
|
while len(stream.read(4096)) != 0:
|
|
910
909
|
pass
|
|
@@ -1093,14 +1092,14 @@ class AbstractJobStore(ABC):
|
|
|
1093
1092
|
def writeFile(
|
|
1094
1093
|
self,
|
|
1095
1094
|
localFilePath: str,
|
|
1096
|
-
jobStoreID:
|
|
1095
|
+
jobStoreID: str | None = None,
|
|
1097
1096
|
cleanup: bool = False,
|
|
1098
1097
|
) -> str:
|
|
1099
1098
|
return self.write_file(localFilePath, jobStoreID, cleanup)
|
|
1100
1099
|
|
|
1101
1100
|
@abstractmethod
|
|
1102
1101
|
def write_file(
|
|
1103
|
-
self, local_path: str, job_id:
|
|
1102
|
+
self, local_path: str, job_id: str | None = None, cleanup: bool = False
|
|
1104
1103
|
) -> str:
|
|
1105
1104
|
"""
|
|
1106
1105
|
Takes a file (as a path) and places it in this job store. Returns an ID that can be used
|
|
@@ -1135,11 +1134,11 @@ class AbstractJobStore(ABC):
|
|
|
1135
1134
|
@deprecated(new_function_name="write_file_stream")
|
|
1136
1135
|
def writeFileStream(
|
|
1137
1136
|
self,
|
|
1138
|
-
jobStoreID:
|
|
1137
|
+
jobStoreID: str | None = None,
|
|
1139
1138
|
cleanup: bool = False,
|
|
1140
|
-
basename:
|
|
1141
|
-
encoding:
|
|
1142
|
-
errors:
|
|
1139
|
+
basename: str | None = None,
|
|
1140
|
+
encoding: str | None = None,
|
|
1141
|
+
errors: str | None = None,
|
|
1143
1142
|
) -> ContextManager[tuple[IO[bytes], str]]:
|
|
1144
1143
|
return self.write_file_stream(jobStoreID, cleanup, basename, encoding, errors)
|
|
1145
1144
|
|
|
@@ -1147,11 +1146,11 @@ class AbstractJobStore(ABC):
|
|
|
1147
1146
|
@contextmanager
|
|
1148
1147
|
def write_file_stream(
|
|
1149
1148
|
self,
|
|
1150
|
-
job_id:
|
|
1149
|
+
job_id: str | None = None,
|
|
1151
1150
|
cleanup: bool = False,
|
|
1152
|
-
basename:
|
|
1153
|
-
encoding:
|
|
1154
|
-
errors:
|
|
1151
|
+
basename: str | None = None,
|
|
1152
|
+
encoding: str | None = None,
|
|
1153
|
+
errors: str | None = None,
|
|
1155
1154
|
) -> Iterator[tuple[IO[bytes], str]]:
|
|
1156
1155
|
"""
|
|
1157
1156
|
Similar to writeFile, but returns a context manager yielding a tuple of
|
|
@@ -1194,18 +1193,18 @@ class AbstractJobStore(ABC):
|
|
|
1194
1193
|
@deprecated(new_function_name="get_empty_file_store_id")
|
|
1195
1194
|
def getEmptyFileStoreID(
|
|
1196
1195
|
self,
|
|
1197
|
-
jobStoreID:
|
|
1196
|
+
jobStoreID: str | None = None,
|
|
1198
1197
|
cleanup: bool = False,
|
|
1199
|
-
basename:
|
|
1198
|
+
basename: str | None = None,
|
|
1200
1199
|
) -> str:
|
|
1201
1200
|
return self.get_empty_file_store_id(jobStoreID, cleanup, basename)
|
|
1202
1201
|
|
|
1203
1202
|
@abstractmethod
|
|
1204
1203
|
def get_empty_file_store_id(
|
|
1205
1204
|
self,
|
|
1206
|
-
job_id:
|
|
1205
|
+
job_id: str | None = None,
|
|
1207
1206
|
cleanup: bool = False,
|
|
1208
|
-
basename:
|
|
1207
|
+
basename: str | None = None,
|
|
1209
1208
|
) -> str:
|
|
1210
1209
|
"""
|
|
1211
1210
|
Creates an empty file in the job store and returns its ID.
|
|
@@ -1263,31 +1262,31 @@ class AbstractJobStore(ABC):
|
|
|
1263
1262
|
def readFileStream(
|
|
1264
1263
|
self,
|
|
1265
1264
|
jobStoreFileID: str,
|
|
1266
|
-
encoding:
|
|
1267
|
-
errors:
|
|
1268
|
-
) ->
|
|
1265
|
+
encoding: str | None = None,
|
|
1266
|
+
errors: str | None = None,
|
|
1267
|
+
) -> ContextManager[IO[bytes]] | ContextManager[IO[str]]:
|
|
1269
1268
|
return self.read_file_stream(jobStoreFileID, encoding, errors)
|
|
1270
1269
|
|
|
1271
1270
|
@overload
|
|
1272
1271
|
def read_file_stream(
|
|
1273
1272
|
self,
|
|
1274
|
-
file_id:
|
|
1273
|
+
file_id: FileID | str,
|
|
1275
1274
|
encoding: Literal[None] = None,
|
|
1276
|
-
errors:
|
|
1275
|
+
errors: str | None = None,
|
|
1277
1276
|
) -> ContextManager[IO[bytes]]: ...
|
|
1278
1277
|
|
|
1279
1278
|
@overload
|
|
1280
1279
|
def read_file_stream(
|
|
1281
|
-
self, file_id:
|
|
1280
|
+
self, file_id: FileID | str, encoding: str, errors: str | None = None
|
|
1282
1281
|
) -> ContextManager[IO[str]]: ...
|
|
1283
1282
|
|
|
1284
1283
|
@abstractmethod
|
|
1285
1284
|
def read_file_stream(
|
|
1286
1285
|
self,
|
|
1287
|
-
file_id:
|
|
1288
|
-
encoding:
|
|
1289
|
-
errors:
|
|
1290
|
-
) ->
|
|
1286
|
+
file_id: FileID | str,
|
|
1287
|
+
encoding: str | None = None,
|
|
1288
|
+
errors: str | None = None,
|
|
1289
|
+
) -> ContextManager[IO[bytes]] | ContextManager[IO[str]]:
|
|
1291
1290
|
"""
|
|
1292
1291
|
Similar to readFile, but returns a context manager yielding a file handle which can be
|
|
1293
1292
|
read from. The yielded file handle does not need to and should not be closed explicitly.
|
|
@@ -1378,15 +1377,15 @@ class AbstractJobStore(ABC):
|
|
|
1378
1377
|
def updateFileStream(
|
|
1379
1378
|
self,
|
|
1380
1379
|
jobStoreFileID: str,
|
|
1381
|
-
encoding:
|
|
1382
|
-
errors:
|
|
1380
|
+
encoding: str | None = None,
|
|
1381
|
+
errors: str | None = None,
|
|
1383
1382
|
) -> ContextManager[IO[Any]]:
|
|
1384
1383
|
return self.update_file_stream(jobStoreFileID, encoding, errors)
|
|
1385
1384
|
|
|
1386
1385
|
@abstractmethod
|
|
1387
1386
|
@contextmanager
|
|
1388
1387
|
def update_file_stream(
|
|
1389
|
-
self, file_id: str, encoding:
|
|
1388
|
+
self, file_id: str, encoding: str | None = None, errors: str | None = None
|
|
1390
1389
|
) -> Iterator[IO[Any]]:
|
|
1391
1390
|
"""
|
|
1392
1391
|
Replaces the existing version of a file in the job store. Similar to writeFile, but
|
|
@@ -1419,9 +1418,9 @@ class AbstractJobStore(ABC):
|
|
|
1419
1418
|
def writeSharedFileStream(
|
|
1420
1419
|
self,
|
|
1421
1420
|
sharedFileName: str,
|
|
1422
|
-
isProtected:
|
|
1423
|
-
encoding:
|
|
1424
|
-
errors:
|
|
1421
|
+
isProtected: bool | None = None,
|
|
1422
|
+
encoding: str | None = None,
|
|
1423
|
+
errors: str | None = None,
|
|
1425
1424
|
) -> ContextManager[IO[bytes]]:
|
|
1426
1425
|
return self.write_shared_file_stream(
|
|
1427
1426
|
sharedFileName, isProtected, encoding, errors
|
|
@@ -1432,9 +1431,9 @@ class AbstractJobStore(ABC):
|
|
|
1432
1431
|
def write_shared_file_stream(
|
|
1433
1432
|
self,
|
|
1434
1433
|
shared_file_name: str,
|
|
1435
|
-
encrypted:
|
|
1436
|
-
encoding:
|
|
1437
|
-
errors:
|
|
1434
|
+
encrypted: bool | None = None,
|
|
1435
|
+
encoding: str | None = None,
|
|
1436
|
+
errors: str | None = None,
|
|
1438
1437
|
) -> Iterator[IO[bytes]]:
|
|
1439
1438
|
"""
|
|
1440
1439
|
Returns a context manager yielding a writable file handle to the global file referenced
|
|
@@ -1464,9 +1463,9 @@ class AbstractJobStore(ABC):
|
|
|
1464
1463
|
def readSharedFileStream(
|
|
1465
1464
|
self,
|
|
1466
1465
|
sharedFileName: str,
|
|
1467
|
-
encoding:
|
|
1468
|
-
errors:
|
|
1469
|
-
) ->
|
|
1466
|
+
encoding: str | None = None,
|
|
1467
|
+
errors: str | None = None,
|
|
1468
|
+
) -> ContextManager[IO[str]] | ContextManager[IO[bytes]]:
|
|
1470
1469
|
return self.read_shared_file_stream(sharedFileName, encoding, errors)
|
|
1471
1470
|
|
|
1472
1471
|
@overload
|
|
@@ -1476,7 +1475,7 @@ class AbstractJobStore(ABC):
|
|
|
1476
1475
|
self,
|
|
1477
1476
|
shared_file_name: str,
|
|
1478
1477
|
encoding: str,
|
|
1479
|
-
errors:
|
|
1478
|
+
errors: str | None = None,
|
|
1480
1479
|
) -> Iterator[IO[str]]:
|
|
1481
1480
|
"""If encoding is specified, then a text file handle is provided."""
|
|
1482
1481
|
|
|
@@ -1487,7 +1486,7 @@ class AbstractJobStore(ABC):
|
|
|
1487
1486
|
self,
|
|
1488
1487
|
shared_file_name: str,
|
|
1489
1488
|
encoding: Literal[None] = None,
|
|
1490
|
-
errors:
|
|
1489
|
+
errors: str | None = None,
|
|
1491
1490
|
) -> Iterator[IO[bytes]]:
|
|
1492
1491
|
"""If no encoding is provided, then a bytest file handle is provided."""
|
|
1493
1492
|
|
|
@@ -1496,9 +1495,9 @@ class AbstractJobStore(ABC):
|
|
|
1496
1495
|
def read_shared_file_stream(
|
|
1497
1496
|
self,
|
|
1498
1497
|
shared_file_name: str,
|
|
1499
|
-
encoding:
|
|
1500
|
-
errors:
|
|
1501
|
-
) ->
|
|
1498
|
+
encoding: str | None = None,
|
|
1499
|
+
errors: str | None = None,
|
|
1500
|
+
) -> Iterator[IO[str]] | Iterator[IO[bytes]]:
|
|
1502
1501
|
"""
|
|
1503
1502
|
Returns a context manager yielding a readable file handle to the global file referenced
|
|
1504
1503
|
by the given name.
|
|
@@ -1693,7 +1692,7 @@ class JobStoreSupport(AbstractJobStore, URLAccess, metaclass=ABCMeta):
|
|
|
1693
1692
|
ErrorCondition(error=HTTPError, error_codes=[408, 500, 503]),
|
|
1694
1693
|
]
|
|
1695
1694
|
)
|
|
1696
|
-
def _get_size(cls, url: ParseResult) ->
|
|
1695
|
+
def _get_size(cls, url: ParseResult) -> int | None:
|
|
1697
1696
|
if url.scheme.lower() == "ftp":
|
|
1698
1697
|
ftp = cls._setup_ftp()
|
|
1699
1698
|
return ftp.size(url.geturl())
|
|
@@ -1705,7 +1704,7 @@ class JobStoreSupport(AbstractJobStore, URLAccess, metaclass=ABCMeta):
|
|
|
1705
1704
|
|
|
1706
1705
|
@classmethod
|
|
1707
1706
|
def _read_from_url(
|
|
1708
|
-
cls, url: ParseResult, writable:
|
|
1707
|
+
cls, url: ParseResult, writable: IO[bytes] | IO[str]
|
|
1709
1708
|
) -> tuple[int, bool]:
|
|
1710
1709
|
# We can't actually retry after we start writing.
|
|
1711
1710
|
# TODO: Implement retry with byte range requests
|