|
5 | 5 | from importlib.resources import files |
6 | 6 | from io import StringIO |
7 | 7 | from types import ModuleType |
8 | | -from typing import Final, Any, IO |
| 8 | +from typing import Final, Any, IO, cast |
9 | 9 |
|
10 | 10 | try: |
11 | 11 | black: ModuleType | None |
@@ -95,15 +95,14 @@ def __init__( |
95 | 95 | super().__init__() |
96 | 96 | self.out: Final = out |
97 | 97 | self.current_class_is_abstract = False |
98 | | - self.current_class_is_inherited = False |
99 | | - self.current_field_loaders: dict[str, str] = {} |
100 | 98 | self.serializer = StringIO() |
101 | 99 | self.idfield = "" |
102 | 100 | self.copyright: Final = copyright |
103 | 101 | self.parents_map: Final = parents_map or {} |
104 | 102 | self.parser_info: Final = parser_info |
105 | 103 | self.salad_version: Final = salad_version |
106 | 104 | self.inherited_classes: dict[str, str] = {} |
| 105 | + self.dynamic_loaders: set[str] = set() |
107 | 106 |
|
108 | 107 | @staticmethod |
109 | 108 | def safe_name(name: str) -> str: |
@@ -189,12 +188,9 @@ def begin_class( |
189 | 188 | idfield: str, |
190 | 189 | optional_fields: set[str], |
191 | 190 | ) -> None: |
192 | | - self.current_field_loaders = {} |
193 | 191 | if (classname := self.safe_name(classname)) in self.inherited_classes: |
194 | | - self.current_class_is_inherited = True |
| 192 | + self.current_class_is_abstract = True |
195 | 193 | return |
196 | | - else: |
197 | | - self.current_class_is_inherited = False |
198 | 194 | self.current_class_is_abstract = abstract |
199 | 195 |
|
200 | 196 | if extends: |
@@ -304,8 +300,7 @@ def fromDoc( |
304 | 300 | doc: Any, |
305 | 301 | baseuri: str, |
306 | 302 | loadingOptions: LoadingOptions, |
307 | | - loaders: Mapping[str, Loader], |
308 | | - docRoot: str | None = None |
| 303 | + docRoot: str | None = None, |
309 | 304 | ) -> Self: |
310 | 305 | _doc = copy.copy(doc) |
311 | 306 |
|
@@ -336,19 +331,6 @@ def end_class(self, classname: str, field_names: list[str]) -> None: |
336 | 331 | if self.current_class_is_abstract: |
337 | 332 | return |
338 | 333 |
|
339 | | - self.add_lazy_init( |
340 | | - LazyInitDef( |
341 | | - self.safe_name(classname) + "FieldLoaders", |
342 | | - "{}.update({{{}}})".format( |
343 | | - self.safe_name(classname) + "FieldLoaders", |
344 | | - ", ".join(f'"{k}": {v}' for k, v in self.current_field_loaders.items()), |
345 | | - ), |
346 | | - ) |
347 | | - ) |
348 | | - |
349 | | - if self.current_class_is_inherited: |
350 | | - return |
351 | | - |
352 | 334 | self.out.write( |
353 | 335 | fmt( |
354 | 336 | """ |
@@ -444,28 +426,77 @@ def type_loader( |
444 | 426 | "_UnionLoader(({},))".format(", ".join(sub_names1)), |
445 | 427 | ) |
446 | 428 | ) |
447 | | - case {"type": "array" | "https://w3id.org/cwl/salad#array", "items": items}: |
| 429 | + case {"type": "array" | "https://w3id.org/cwl/salad#array", "items": items, **rest}: |
448 | 430 | i1: Final = self.type_loader(items) |
449 | | - return self.declare_type( |
450 | | - TypeDef( |
451 | | - f"array_of_{i1.name}", |
452 | | - f"_ArrayLoader({i1.name})", |
| 431 | + if "original_items" in rest: |
| 432 | + original_type = self.safe_name(shortname(cast(str, rest["original_items"]))) |
| 433 | + self.declare_type( |
| 434 | + TypeDef( |
| 435 | + f"{original_type}Loader", |
| 436 | + i1.name, |
| 437 | + abstract=True, |
| 438 | + ) |
| 439 | + ) |
| 440 | + self.declare_type( |
| 441 | + TypeDef( |
| 442 | + f"{original_type}ProxyLoader", |
| 443 | + '_ProxyLoader("{}")'.format(original_type + "Loader"), |
| 444 | + ) |
| 445 | + ) |
| 446 | + return self.declare_type( |
| 447 | + TypeDef( |
| 448 | + f"array_of_{original_type}", |
| 449 | + f"_ArrayLoader({original_type}ProxyLoader)", |
| 450 | + ) |
| 451 | + ) |
| 452 | + else: |
| 453 | + return self.declare_type( |
| 454 | + TypeDef( |
| 455 | + f"array_of_{i1.name}", |
| 456 | + f"_ArrayLoader({i1.name})", |
| 457 | + ) |
453 | 458 | ) |
454 | | - ) |
455 | 459 | case {"type": "map" | "https://w3id.org/cwl/salad#map", "values": values, **rest}: |
456 | 460 | i2: Final = self.type_loader(values) |
457 | 461 | name = self.safe_name(str(rest["name"])) if "name" in rest else None |
458 | | - anon_type = self.declare_type( |
459 | | - TypeDef( |
460 | | - f"map_of_{i2.name}", |
461 | | - "_MapLoader({}, {}, {}, {})".format( |
| 462 | + if "original_values" in rest: |
| 463 | + original_type = self.safe_name(shortname(cast(str, rest["original_values"]))) |
| 464 | + self.declare_type( |
| 465 | + TypeDef( |
| 466 | + original_type + "Loader", |
462 | 467 | i2.name, |
463 | | - f"'{name}'", # noqa: B907 |
464 | | - f"'{container}'" if container is not None else None, # noqa: B907 |
465 | | - no_link_check, |
466 | | - ), |
| 468 | + abstract=True, |
| 469 | + ) |
| 470 | + ) |
| 471 | + self.declare_type( |
| 472 | + TypeDef( |
| 473 | + f"{original_type}ProxyLoader", |
| 474 | + '_ProxyLoader("{}")'.format(original_type + "Loader"), |
| 475 | + ) |
| 476 | + ) |
| 477 | + anon_type = self.declare_type( |
| 478 | + TypeDef( |
| 479 | + f"map_of_{original_type}", |
| 480 | + "_MapLoader({}, {}, {}, {})".format( |
| 481 | + f"{original_type}ProxyLoader", |
| 482 | + f"'{name}'", # noqa: B907 |
| 483 | + f"'{container}'" if container is not None else None, # noqa: B907 |
| 484 | + no_link_check, |
| 485 | + ), |
| 486 | + ) |
| 487 | + ) |
| 488 | + else: |
| 489 | + anon_type = self.declare_type( |
| 490 | + TypeDef( |
| 491 | + f"map_of_{i2.name}", |
| 492 | + "_MapLoader({}, {}, {}, {})".format( |
| 493 | + i2.name, |
| 494 | + f"'{name}'", # noqa: B907 |
| 495 | + f"'{container}'" if container is not None else None, # noqa: B907 |
| 496 | + no_link_check, |
| 497 | + ), |
| 498 | + ) |
467 | 499 | ) |
468 | | - ) |
469 | 500 | if "name" in rest: |
470 | 501 | return self.declare_type( |
471 | 502 | TypeDef(self.safe_name(str(rest["name"])) + "Loader", anon_type.name) |
@@ -504,25 +535,31 @@ def type_loader( |
504 | 535 | classname = self.safe_name(name) |
505 | 536 | if (prefix := name.split("#")[0]) in self.parents_map: |
506 | 537 | self.inherited_classes[classname] = f"{self.parents_map[prefix]}.{classname}" |
507 | | - self.declare_type( |
508 | | - TypeDef( |
509 | | - classname + "FieldLoaders", |
510 | | - "{}", |
511 | | - instance_type="MutableMapping[str, Loader]", |
| 538 | + if rest.get("abstract", False): |
| 539 | + self.declare_type( |
| 540 | + TypeDef( |
| 541 | + classname + "Loader", |
| 542 | + "None", |
| 543 | + abstract=True, |
| 544 | + ) |
512 | 545 | ) |
513 | | - ) |
514 | | - return self.declare_type( |
515 | | - TypeDef( |
516 | | - classname + "Loader", |
517 | | - "_RecordLoader({}, {}, {}, {})".format( |
518 | | - self.inherited_classes.get(classname, classname), |
519 | | - classname + "FieldLoaders", |
520 | | - f"'{container}'" if container is not None else None, # noqa: B907 |
521 | | - no_link_check, |
522 | | - ), |
523 | | - abstract=bool(rest.get("abstract", False)), |
| 546 | + return self.declare_type( |
| 547 | + TypeDef( |
| 548 | + classname + "ProxyLoader", |
| 549 | + '_ProxyLoader("{}")'.format(classname + "Loader"), |
| 550 | + ) |
| 551 | + ) |
| 552 | + else: |
| 553 | + return self.declare_type( |
| 554 | + TypeDef( |
| 555 | + classname + "Loader", |
| 556 | + "_RecordLoader({}, {}, {})".format( |
| 557 | + self.inherited_classes.get(classname, classname), |
| 558 | + f"'{container}'" if container is not None else None, # noqa: B907 |
| 559 | + no_link_check, |
| 560 | + ), |
| 561 | + ) |
524 | 562 | ) |
525 | | - ) |
526 | 563 |
|
527 | 564 | case { |
528 | 565 | "type": "union" | "https://w3id.org/cwl/salad#union", |
@@ -573,9 +610,6 @@ def declare_id_field( |
573 | 610 |
|
574 | 611 | self.declare_field(name, fieldtype, doc, True, "") |
575 | 612 |
|
576 | | - if self.current_class_is_inherited: |
577 | | - return |
578 | | - |
579 | 613 | if optional: |
580 | 614 | opt = """{safename} = "_:" + str(_uuid__.uuid4())""".format( |
581 | 615 | safename=self.safe_name(name) |
@@ -607,11 +641,6 @@ def declare_field( |
607 | 641 | if self.current_class_is_abstract: |
608 | 642 | return |
609 | 643 |
|
610 | | - self.current_field_loaders[shortname(name)] = fieldtype.name |
611 | | - |
612 | | - if self.current_class_is_inherited: |
613 | | - return |
614 | | - |
615 | 644 | if optional: |
616 | 645 | self.out.write(f""" {self.safe_name(name)} = None\n""") |
617 | 646 | self.out.write(f""" if "{shortname(name)}" in _doc:\n""") # noqa: B907 |
@@ -644,14 +673,15 @@ def declare_field( |
644 | 673 | self.out.write( |
645 | 674 | """{spc} {safename} = _load_field( |
646 | 675 | {spc} _doc.get("{fieldname}"), |
647 | | -{spc} loaders["{fieldname}"], |
| 676 | +{spc} {fieldtype}, |
648 | 677 | {spc} {baseurivar}, |
649 | 678 | {spc} loadingOptions, |
650 | 679 | {spc} lc=_doc.get("{fieldname}") |
651 | 680 | {spc} ) |
652 | 681 | """.format( |
653 | 682 | safename=self.safe_name(name), |
654 | 683 | fieldname=shortname(name), |
| 684 | + fieldtype=fieldtype.name, |
655 | 685 | baseurivar=baseurivar, |
656 | 686 | spc=spc, |
657 | 687 | ) |
@@ -851,6 +881,12 @@ def epilogue(self, root_loader: TypeDef) -> None: |
851 | 881 | self.out.write(fmt(f"{collected_type.name}: {type_} = {collected_type.init}\n", 0)) |
852 | 882 | self.out.write("\n") |
853 | 883 |
|
| 884 | + self.out.write("_loaders.update({\n") |
| 885 | + for _, collected_type in self.collected_types.items(): |
| 886 | + if collected_type.abstract: |
| 887 | + self.out.write(f' "{collected_type.name}": {collected_type.init},\n') |
| 888 | + self.out.write("})\n\n") |
| 889 | + |
854 | 890 | if self.lazy_inits: |
855 | 891 | for lazy_init in self.lazy_inits.values(): |
856 | 892 | self.out.write(fmt(f"{lazy_init.init}\n", 0)) |
|
0 commit comments