Skip to content

Commit 3ac366a

Browse files
committed
Upgrade to Python3.9 syntax
1 parent 14d8884 commit 3ac366a

File tree

4 files changed

+43
-48
lines changed

4 files changed

+43
-48
lines changed

cwlprov/prov.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424

2525
import datetime
2626
import logging
27+
from collections.abc import Iterable
2728
from pathlib import Path
2829
from typing import (
2930
TYPE_CHECKING,
3031
Any,
3132
Callable,
32-
Iterable,
3333
List,
3434
Optional,
3535
Set,
@@ -159,7 +159,7 @@ def _prov_format(self, media_type: Optional[str]) -> Optional[Path]:
159159
return self.ro.resolve_path(str(prov))
160160
return None
161161

162-
def _load_prov_document(self) -> Union[Tuple[None, None], Tuple[ProvBundle, Path]]:
162+
def _load_prov_document(self) -> Union[tuple[None, None], tuple[ProvBundle, Path]]:
163163
# Preferred order
164164
candidates = ("xml", "json", "nt", "ttl", "rdf")
165165
# Note: Not all of these parse consistently with rdflib in py3
@@ -221,7 +221,7 @@ def label(self) -> Optional[QualifiedName]:
221221
def type(self) -> Optional[QualifiedName]:
222222
return self._prov_attr("prov:type")
223223

224-
def types(self) -> Set[QualifiedName]:
224+
def types(self) -> set[QualifiedName]:
225225
return set(self._prov_attrs("prov:type"))
226226

227227
@property
@@ -238,7 +238,7 @@ def __str__(self) -> str:
238238
def _prov_attr(self, attr: QualifiedNameCandidate) -> Optional[QualifiedName]:
239239
return first(self._prov_attrs(attr))
240240

241-
def _prov_attrs(self, attr: QualifiedNameCandidate) -> Set[QualifiedName]:
241+
def _prov_attrs(self, attr: QualifiedNameCandidate) -> set[QualifiedName]:
242242
return self.record.get_attribute(attr)
243243

244244

@@ -382,7 +382,7 @@ def nameext(self) -> Any:
382382
def derivations(self) -> Iterable["Derivation"]:
383383
return self._records(ProvDerivation, Derivation, PROV_ATTR_USED_ENTITY)
384384

385-
def secondary_files(self) -> List[Any]:
385+
def secondary_files(self) -> list[Any]:
386386
return [
387387
d.generated_entity()
388388
for d in self.derivations()

cwlprov/ro.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@
2727
import logging
2828
import pathlib
2929
import urllib.parse
30+
from collections.abc import Iterable
3031
from contextlib import ExitStack
3132
from functools import partial
32-
from typing import TYPE_CHECKING, Iterable, Optional, Set, Union
33+
from typing import TYPE_CHECKING, Optional, Set, Union
3334

3435
import arcp
3536
from bdbag.bdbagit import BDBag
@@ -181,18 +182,18 @@ def _uriref(
181182
return self.id_uriref
182183

183184
@property
184-
def conformsTo(self) -> Set[str]:
185+
def conformsTo(self) -> set[str]:
185186
resource = self._uriref()
186187
return set(map(str, self.manifest.objects(resource, DCTERMS.conformsTo)))
187188

188189
@property
189-
def createdBy(self) -> Set["Agent"]:
190+
def createdBy(self) -> set["Agent"]:
190191
resource = self._uriref()
191192
new_agent = partial(Agent, self.manifest)
192193
return set(map(new_agent, self.manifest.objects(resource, PAV.createdBy)))
193194

194195
@property
195-
def authoredBy(self) -> Set["Agent"]:
196+
def authoredBy(self) -> set["Agent"]:
196197
resource = self._uriref()
197198
new_agent = partial(Agent, self.manifest)
198199
return set(map(new_agent, self.manifest.objects(resource, PAV.authoredBy)))
@@ -201,7 +202,7 @@ def annotations_about(
201202
self,
202203
path: Optional[Union[str, pathlib.PurePosixPath]] = None,
203204
uri: Optional[str] = None,
204-
) -> Set["Annotation"]:
205+
) -> set["Annotation"]:
205206
resource = self._uriref(path=path, uri=uri)
206207
new_annotation = partial(Annotation, self.manifest)
207208
return set(map(new_annotation, self.manifest.subjects(OA.hasTarget, resource)))
@@ -210,7 +211,7 @@ def annotations_with_content(
210211
self,
211212
path: Optional[Union[str, pathlib.PurePosixPath]] = None,
212213
uri: Optional[Union[str, Identifier]] = None,
213-
) -> Set["Annotation"]:
214+
) -> set["Annotation"]:
214215
resource = self._uriref(path=path, uri=uri)
215216
new_annotation = partial(Annotation, self.manifest)
216217
return set(map(new_annotation, self.manifest.subjects(OA.hasBody, resource)))
@@ -233,7 +234,7 @@ def provenance(
233234
self,
234235
path: Optional[Union[str, pathlib.PurePosixPath]] = None,
235236
uri: Optional[str] = None,
236-
) -> Optional[Set[Node]]:
237+
) -> Optional[set[Node]]:
237238
for a in self.annotations_about(path, uri):
238239
if a.motivatedBy == PROV.has_provenance:
239240
return a.hasBodies
@@ -288,7 +289,7 @@ def hasBody(self) -> Optional[Node]:
288289
return next(self._graph.objects(self._id, OA.hasBody), None)
289290

290291
@property
291-
def hasBodies(self) -> Set[Node]:
292+
def hasBodies(self) -> set[Node]:
292293
"""Find the set of body Nodes of this Annotation."""
293294
return set(self._graph.objects(self._id, OA.hasBody))
294295

@@ -298,7 +299,7 @@ def hasTarget(self) -> Optional[Identifier]:
298299
return next(self._graph.objects(self._id, OA.hasTarget), None)
299300

300301
@property
301-
def hasTargets(self) -> Set[Node]:
302+
def hasTargets(self) -> set[Node]:
302303
"""Find which Noes this Annotation targets."""
303304
return set(self._graph.objects(self._id, OA.hasTarget))
304305

@@ -343,10 +344,8 @@ def __repr__(self) -> str:
343344
def __str__(self) -> str:
344345
"""Print the name, identifier, and uri of this Agent."""
345346
s = str(self.name) or "(unknown)"
346-
o = self.orcid
347-
if o:
347+
if o := self.orcid:
348348
s += " <%s>" % o
349-
u = self.uri
350-
if u:
349+
if u := self.uri:
351350
s += " <%s>" % u
352351
return s

cwlprov/tool.py

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import sys
3636
import tempfile
3737
import urllib.parse
38+
from collections.abc import Iterable, MutableMapping, MutableSequence
3839
from enum import IntEnum
3940
from functools import partial
4041
from pathlib import Path
@@ -44,10 +45,7 @@
4445
Callable,
4546
ContextManager,
4647
Dict,
47-
Iterable,
4848
List,
49-
MutableMapping,
50-
MutableSequence,
5149
Optional,
5250
Set,
5351
TextIO,
@@ -131,7 +129,7 @@ class Status(IntEnum):
131129
MISSING_MANIFEST = 171
132130

133131

134-
def parse_args(args: Optional[List[str]] = None) -> argparse.Namespace:
132+
def parse_args(args: Optional[list[str]] = None) -> argparse.Namespace:
135133
parser = argparse.ArgumentParser(
136134
description="cwlprov explores Research Objects containing provenance of "
137135
"Common Workflow Language executions. <https://w3id.org/cwl/prov/>"
@@ -400,8 +398,8 @@ def _find_bagit_folder(folder: Optional[str] = None) -> Optional[pathlib.Path]:
400398
pfolder = pfolder.parent
401399

402400

403-
def _info_set(bag: BDBag, key: str) -> Set[Any]:
404-
v: Union[str, List[Any]] = bag.info.get(key, [])
401+
def _info_set(bag: BDBag, key: str) -> set[Any]:
402+
v: Union[str, list[Any]] = bag.info.get(key, [])
405403
if isinstance(v, list):
406404
return set(v)
407405
else:
@@ -412,7 +410,7 @@ def _simpler_uuid(uri: Any) -> str:
412410
return str(uri).replace("urn:uuid:", "")
413411

414412

415-
def _as_uuid(w: str) -> Tuple[str, Optional[UUID], str]:
413+
def _as_uuid(w: str) -> tuple[str, Optional[UUID], str]:
416414
try:
417415
uuid = UUID(w.replace("urn:uuid:", ""))
418416
return (uuid.urn, uuid, str(uuid))
@@ -487,7 +485,7 @@ def _set_log_level(quiet: Optional[bool] = None, verbose: int = 0) -> None:
487485

488486

489487
class Tool(ContextManager["Tool"]):
490-
def __init__(self, args: Optional[List[str]] = None) -> None:
488+
def __init__(self, args: Optional[list[str]] = None) -> None:
491489
"""Create a Tool and open the output stream."""
492490
self.args = parse_args(args)
493491
if self.args.output != "-":
@@ -509,7 +507,7 @@ def __enter__(self) -> "Tool":
509507

510508
def __exit__(
511509
self,
512-
exc_type: Optional[Type[BaseException]],
510+
exc_type: Optional[type[BaseException]],
513511
exc_value: Optional[BaseException],
514512
traceback: Optional[TracebackType],
515513
) -> Optional[bool]:
@@ -666,7 +664,7 @@ def main(self) -> int:
666664
return Status.OK
667665

668666
# Else, find the other commands
669-
COMMANDS: Dict[str, Callable[[], int]] = {
667+
COMMANDS: dict[str, Callable[[], int]] = {
670668
"info": self.info,
671669
"who": self.who,
672670
"prov": self.prov,
@@ -702,7 +700,7 @@ def _absolute_or_relative_path(self, path: Any, absolute: bool = False) -> Path:
702700
else:
703701
return Path(p).absolute()
704702

705-
def _wf_id(self, run: Optional[str] = None) -> Tuple[str, Optional[UUID], str]:
703+
def _wf_id(self, run: Optional[str] = None) -> tuple[str, Optional[UUID], str]:
706704
w = run or self.args.id or self.ro.workflow_id
707705
# ensure consistent UUID URIs
708706
return _as_uuid(str(w))
@@ -775,11 +773,9 @@ def info(self) -> int:
775773
}
776774
if cwlprov:
777775
self.print("Profile: %s" % many(cwlprov))
778-
w = ro.workflow_id
779-
if w:
776+
if w := ro.workflow_id:
780777
self.print("Workflow run ID: %s" % w)
781-
when = ro.bag.info.get("Bagging-Date")
782-
if when:
778+
if when := ro.bag.info.get("Bagging-Date"):
783779
self.print("Packaged: %s" % when)
784780
return Status.OK
785781

@@ -923,15 +919,14 @@ def _load_provenance(self, wf_uri: str) -> int:
923919

924920
def _load_activity_from_provenance(
925921
self,
926-
) -> Union[Tuple[Literal[Status.OK], Activity], Tuple[int, None]]:
922+
) -> Union[tuple[Literal[Status.OK], Activity], tuple[int, None]]:
927923
wf_uri, wf_uuid, wf_name = self._wf_id(self.args.run)
928924
a_uri, a_uuid, a_name = self._wf_id()
929925
error = self._load_provenance(wf_uri)
930926
if error != Status.OK:
931927
return (error, None)
932928

933-
activity = self.provenance.activity(a_uri)
934-
if activity:
929+
if activity := self.provenance.activity(a_uri):
935930
return (Status.OK, activity)
936931
else:
937932
_logger.error("Provenance does not describe step %s: %s", wf_name, a_uri)
@@ -986,7 +981,7 @@ def _inputs_or_outputs(self, is_inputs: bool) -> int:
986981
else:
987982
_logger.info("%ss for workflow %s", put_s, wf_name)
988983

989-
job: Dict[str, Dict[str, str]] = {}
984+
job: dict[str, dict[str, str]] = {}
990985

991986
if is_inputs:
992987
records: Iterable[Union[Generation, Usage]] = activity.usage()
@@ -1070,7 +1065,7 @@ def _entity_as_json(self, entity: Entity, absolute: bool = True) -> Any:
10701065
continue
10711066
_logger.debug("entity %s bundledAs %s", file_candidate.uri, bundled)
10721067
bundled_path = self._resource_path(bundled, absolute=absolute)
1073-
json: Dict[str, Any] = {
1068+
json: dict[str, Any] = {
10741069
"class": "File",
10751070
"path": str(bundled_path),
10761071
}
@@ -1106,8 +1101,8 @@ def _entity_as_json(self, entity: Entity, absolute: bool = True) -> Any:
11061101

11071102
def _inputs_or_outputs_job(
11081103
self, activity: Activity, is_inputs: bool, absolute: bool
1109-
) -> Dict[str, Any]:
1110-
job: Dict[str, Any] = {}
1104+
) -> dict[str, Any]:
1105+
job: dict[str, Any] = {}
11111106

11121107
if is_inputs:
11131108
records: Iterable[Union[Usage, Generation]] = activity.usage()
@@ -1228,19 +1223,19 @@ def rerun(self) -> int:
12281223

12291224
return self._exec_cwlrunner(wf_arg, job_file)
12301225

1231-
def _load_cwl(self, wf_file: Union[str, Path]) -> Optional[Dict[str, Any]]:
1226+
def _load_cwl(self, wf_file: Union[str, Path]) -> Optional[dict[str, Any]]:
12321227
_logger.debug("Loading CWL as JSON: %s", wf_file)
12331228
with open(wf_file) as f:
12341229
# FIXME: Load as yaml in case it is not JSON?
1235-
cwl = cast(Dict[str, Any], json.load(f))
1230+
cwl = cast(dict[str, Any], json.load(f))
12361231
ver = cwl["cwlVersion"]
12371232
_logger.debug("Loaded CWL version: %s", ver)
12381233
if not ver.startswith("v1."):
12391234
_logger.fatal("Unsupported cwlVersion %s in %s", ver, wf_file)
12401235
return None
12411236
return cwl
12421237

1243-
def _find_step_run(self, cwl: Dict[str, Any], step_id: str) -> Any:
1238+
def _find_step_run(self, cwl: dict[str, Any], step_id: str) -> Any:
12441239
step = find_dict_with_item(cwl, step_id)
12451240
if not step:
12461241
_logger.error("Could not find step for ")
@@ -1288,13 +1283,13 @@ def _find_primary_job(self) -> Path:
12881283
p = self.ro.resolve_path(str(path))
12891284
return p
12901285

1291-
def _recreate_job(self, activity: Activity, absolute: bool) -> Dict[str, Any]:
1286+
def _recreate_job(self, activity: Activity, absolute: bool) -> dict[str, Any]:
12921287
# TODO: Actually do it
12931288
job = self._inputs_or_outputs_job(activity, is_inputs=True, absolute=absolute)
12941289
_logger.debug("Recreated job: %s", job)
12951290
return job
12961291

1297-
def _temporary_job(self, job: Dict[str, Any]) -> str:
1292+
def _temporary_job(self, job: dict[str, Any]) -> str:
12981293
with tempfile.NamedTemporaryFile(
12991294
mode="w", prefix="rerun-", suffix=".json", delete=False, encoding="UTF-8"
13001295
) as f:
@@ -1509,7 +1504,7 @@ def run(self) -> int:
15091504
return Status.OK
15101505

15111506

1512-
def main(args: Optional[List[str]] = None) -> int:
1507+
def main(args: Optional[list[str]] = None) -> int:
15131508
with Tool(args) as tool:
15141509
try:
15151510
return tool.main()

cwlprov/utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323
)
2424

2525
import datetime
26+
from collections.abc import Iterable, Sequence
2627
from functools import partial
27-
from typing import Any, Iterable, Optional, Sequence, Set, Tuple, TypeVar, Union
28+
from typing import Any, Optional, Set, Tuple, TypeVar, Union
2829

2930
prov_type = Union[type, tuple[type]]
3031

@@ -36,7 +37,7 @@ def first(iterable: Union[Iterable[_T], Sequence[_T]]) -> Optional[_T]:
3637
return next(iter(iterable), None)
3738

3839

39-
def many(s: Set[Any]) -> str:
40+
def many(s: set[Any]) -> str:
4041
"""Convert a set of strings into a comma separated string."""
4142
return ", ".join(map(str, s))
4243

0 commit comments

Comments
 (0)