Skip to content

Commit ec2a99a

Browse files
authored
Merge pull request #97 from ArcanaFramework/pydra-syntax-changes
Cleaned up converter
2 parents 69f6d78 + 754f858 commit ec2a99a

File tree

5 files changed

+37
-41
lines changed

5 files changed

+37
-41
lines changed

fileformats/core/converter_helpers.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def unzip(in_file: Zip[AnyFileFormat], out_file: AnyFileFormat):
2828
...
2929
"""
3030

31-
converters: ty.Dict[ty.Type["fileformats.core.FileSet"], "Converter[ty.Any]"] = {}
31+
converters: ty.Dict[ty.Type["fileformats.core.FileSet"], "Converter"] = {}
3232

3333
@classmethod
3434
def new(cls, name: str, klass: type) -> "SubtypeVar":
@@ -57,10 +57,10 @@ def __subclasshook__(cls, subclass: type) -> bool:
5757
@classmethod
5858
def get_converter_defs(
5959
cls, source_format: ty.Type["mixin.WithClassifiers"], target_format: type
60-
) -> ty.List["Converter[T]"]:
60+
) -> ty.List["Converter"]:
6161
# check to see whether there are converters from a base class of the source
6262
# format
63-
available_converters: ty.List[Converter[T]] = []
63+
available_converters: ty.List[Converter] = []
6464
# assert isinstance(source_format, WithClassifiers)
6565
if source_format.is_classified:
6666
for template_source_format, converter in cls.converters.items():
@@ -83,7 +83,7 @@ def get_converter_defs(
8383
def register_converter(
8484
cls,
8585
source_format: ty.Type["mixin.WithClassifiers"],
86-
converter: "Converter[T]",
86+
converter: "Converter",
8787
) -> None:
8888
"""Registers a converter task within a class attribute. Called by the
8989
@fileformats.core.converter decorator.
@@ -138,11 +138,11 @@ def register_converter(
138138
cls.converters[source_format] = converter # type: ignore
139139

140140

141-
class Converter(ty.Generic[T]):
141+
class Converter:
142142
"""Specification of a converter task, including the task callable, its arguments and
143143
the classifiers"""
144144

145-
task_def: "TaskDef[T]"
145+
task_def: "TaskDef[ty.Any]"
146146
classifiers: ty.Tuple[ty.Type[Classifier], ...]
147147
in_file: str
148148
out_file: str

fileformats/core/datatype.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
)
2424
from .classifier import Classifier
2525

26+
if ty.TYPE_CHECKING:
27+
from .converter_helpers import Converter
28+
2629

2730
class DataType(Classifier, metaclass=ABCMeta):
2831
"""
@@ -39,7 +42,7 @@ def nested_types(cls) -> ty.Tuple[ty.Type[Classifier], ...]:
3942
# Store converters registered by @converter decorator that convert to FileSet
4043
# NB: each class will have its own version of this dictionary
4144
converters: ty.Dict[
42-
ty.Type["DataType"], "fileformats.core.converter_helpers.Converter[ty.Any]" # type: ignore[type-arg]
45+
ty.Type["DataType"], "fileformats.core.converter_helpers.Converter" # type: ignore[type-arg]
4346
] = {}
4447

4548
@classmethod
@@ -92,8 +95,7 @@ def subclasses(cls) -> ty.Generator[ty.Type[Self], None, None]:
9295
def get_converter(
9396
cls,
9497
source_format: ty.Type[DataType],
95-
**kwargs: ty.Any,
96-
) -> ty.Union[None]:
98+
) -> "Converter | None":
9799
if issubclass(source_format, cls):
98100
return None
99101
else:

fileformats/core/extras.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,10 @@ def converter(
229229
"installed, this should be installed with Pydra by default",
230230
)
231231
raise e
232+
if "out_file_" in converter_kwargs:
233+
converter_kwargs["out_file"] = converter_kwargs.pop("out_file_")
234+
if "in_file_" in converter_kwargs:
235+
converter_kwargs["in_file"] = converter_kwargs.pop("in_file_")
232236

233237
def decorator(
234238
task_type: ty.Type["TaskDef[T]"],
@@ -268,6 +272,7 @@ def decorator(
268272
f"Target file format '{target.__name__}' is not of subtype of "
269273
"fileformats.core.FileSet"
270274
)
275+
271276
target.register_converter(
272277
source_format=source,
273278
converter=Converter(

fileformats/core/fileset.py

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
from .mock import MockMixin
4444

4545
if ty.TYPE_CHECKING:
46-
from pydra.engine.specs import TaskDef, OutputsType
4746
from .converter_helpers import Converter
4847

4948

@@ -501,7 +500,6 @@ def matching_exts(
501500
def convert(
502501
cls,
503502
fileset: "FileSet",
504-
worker: ty.Optional[str] = None,
505503
**kwargs: ty.Any,
506504
) -> Self:
507505
"""Convert a given file-set into the format specified by the class
@@ -510,12 +508,8 @@ def convert(
510508
----------
511509
fileset : FileSet
512510
the file-set object to convert
513-
plugin : str
514-
the "execution plugin" used to run the conversion task
515-
task_name : str
516-
the name given to the converter task
517511
**kwargs
518-
args to pass to the conversion process
512+
args to pass to customise the converter task definition
519513
520514
Returns
521515
-------
@@ -525,12 +519,14 @@ def convert(
525519
import attrs
526520

527521
# Make unique, yet somewhat recognisable task name
528-
task = cls.get_converter(source_format=type(fileset), **kwargs)
529-
if task is None:
530-
return copy(fileset) # type: ignore[return-value]
531-
task = attrs.evolve(task, in_file=fileset)
532-
outputs = task(worker=worker)
533-
out_file = outputs.out_file
522+
converter = cls.get_converter(source_format=type(fileset))
523+
if converter is None:
524+
assert isinstance(fileset, cls)
525+
return copy(fileset)
526+
kwargs[converter.in_file] = fileset
527+
task_def = attrs.evolve(converter.task_def, **kwargs)
528+
outputs = task_def()
529+
out_file = getattr(outputs, converter.out_file)
534530
if not isinstance(out_file, cls):
535531
out_file = cls(out_file)
536532
return out_file # type: ignore
@@ -539,8 +535,7 @@ def convert(
539535
def get_converter(
540536
cls,
541537
source_format: ty.Type[DataType],
542-
**kwargs: ty.Any,
543-
) -> "TaskDef[OutputsType] | None":
538+
) -> "Converter | None":
544539
"""Get a converter that converts from the source format type
545540
into the format specified by the class
546541
@@ -577,7 +572,7 @@ def get_converter(
577572
else:
578573
import_extras_module(unclassified)
579574
try:
580-
converter_def = converters[source_format]
575+
converter = converters[source_format]
581576
except KeyError:
582577
# If no direct mapping check for mapping from source super types and wildcard
583578
# matches
@@ -608,36 +603,30 @@ def get_converter(
608603
f"from PyPI (e.g. pip install {extras_mod.pypi}) or check it isn't broken"
609604
)
610605
raise FormatConversionError(msg) from None
611-
converter_def = available_converters[0]
606+
converter = available_converters[0]
612607
# Store mapping for future reference
613-
converters[source_format] = converter_def
614-
if kwargs:
615-
task_def = copy(converter_def.task_def)
616-
for key, val in kwargs.items():
617-
setattr(task_def, key, val)
618-
else:
619-
task_def = converter_def.task_def
620-
return task_def
608+
converters[source_format] = converter
609+
return converter
621610

622611
@classmethod
623612
def get_converters_dict(
624613
cls, klass: ty.Optional[ty.Type[DataType]] = None
625-
) -> ty.Dict[ty.Type[DataType], "Converter[ty.Any]"]:
614+
) -> ty.Dict[ty.Type[DataType], "Converter"]:
626615
# Only access converters to the specific class, not superclasses (which may not
627616
# be able to convert to the specific type)
628617
if klass is None:
629618
klass = cls
630619
# import related extras module for the target class
631620
import_extras_module(klass)
632-
converters_dict: ty.Dict[ty.Type[DataType], "Converter[ty.Any]"]
621+
converters_dict: ty.Dict[ty.Type[DataType], "Converter"]
633622
try:
634623
converters_dict = klass.__dict__["converters"]
635624
except KeyError:
636625
converters_dict = klass.converters = {}
637626
return converters_dict
638627

639628
@classmethod
640-
def get_converter_defs(cls, source_format: type) -> ty.List["Converter[ty.Any]"]:
629+
def get_converter_defs(cls, source_format: type) -> ty.List["Converter"]:
641630
"""Search the registered converters to find any matches and return list of
642631
task and associated key-word args to perform the conversion between source and
643632
target formats
@@ -669,7 +658,7 @@ def get_converter_defs(cls, source_format: type) -> ty.List["Converter[ty.Any]"]
669658
def register_converter(
670659
cls,
671660
source_format: ty.Type["FileSet"],
672-
converter: "Converter[T]",
661+
converter: "Converter",
673662
) -> None:
674663
"""Registers a converter task within a class attribute. Called by the
675664
@fileformats.core.converter decorator.

fileformats/core/mixin.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ def __class_getitem__(
458458
return classified
459459

460460
@classmethod
461-
def get_converter_defs(cls, source_format: type) -> ty.List[Converter[ty.Any]]:
461+
def get_converter_defs(cls, source_format: type) -> ty.List[Converter]:
462462
"""Search the registered converters to find an appropriate task and associated
463463
key-word args to perform the conversion between source and target formats
464464
@@ -470,7 +470,7 @@ def get_converter_defs(cls, source_format: type) -> ty.List[Converter[ty.Any]]:
470470
from fileformats.core import FileSet
471471

472472
# Try to see if a converter has been defined to the exact type
473-
available_converters: ty.List[Converter[ty.Any]] = super().get_converter_defs( # type: ignore[misc, type-arg]
473+
available_converters: ty.List[Converter] = super().get_converter_defs( # type: ignore[misc, type-arg]
474474
source_format
475475
)
476476
# Failing that, see if there is a generic conversion between the container type
@@ -603,7 +603,7 @@ def __subclasshook__(cls, subclass: type) -> bool:
603603
def register_converter(
604604
cls,
605605
source_format: ty.Type["fileformats.core.FileSet"],
606-
converter: Converter[T],
606+
converter: Converter,
607607
) -> None:
608608
"""Registers a converter task within a class attribute. Called by the @fileformats.converter
609609
decorator.

0 commit comments

Comments
 (0)