siliconcompiler 0.35.1__py3-none-any.whl → 0.35.3__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.
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/sc_install.py +1 -1
- siliconcompiler/apps/sc_issue.py +8 -16
- siliconcompiler/apps/smake.py +106 -100
- siliconcompiler/checklist.py +349 -91
- siliconcompiler/design.py +8 -1
- siliconcompiler/flowgraph.py +419 -130
- siliconcompiler/flows/showflow.py +1 -2
- siliconcompiler/library.py +6 -5
- siliconcompiler/package/https.py +10 -5
- siliconcompiler/project.py +87 -37
- siliconcompiler/remote/client.py +17 -6
- siliconcompiler/scheduler/scheduler.py +284 -59
- siliconcompiler/scheduler/schedulernode.py +154 -102
- siliconcompiler/schema/__init__.py +3 -2
- siliconcompiler/schema/_metadata.py +1 -1
- siliconcompiler/schema/baseschema.py +210 -93
- siliconcompiler/schema/namedschema.py +21 -13
- siliconcompiler/schema/parameter.py +8 -1
- siliconcompiler/schema/safeschema.py +18 -7
- siliconcompiler/schema_support/dependencyschema.py +23 -3
- siliconcompiler/schema_support/filesetschema.py +10 -4
- siliconcompiler/schema_support/option.py +37 -34
- siliconcompiler/schema_support/pathschema.py +7 -2
- siliconcompiler/schema_support/record.py +5 -4
- siliconcompiler/targets/asap7_demo.py +4 -1
- siliconcompiler/tool.py +100 -8
- siliconcompiler/tools/__init__.py +10 -7
- siliconcompiler/tools/bambu/convert.py +19 -0
- siliconcompiler/tools/builtin/__init__.py +3 -2
- siliconcompiler/tools/builtin/filter.py +108 -0
- siliconcompiler/tools/builtin/importfiles.py +154 -0
- siliconcompiler/tools/execute/exec_input.py +4 -3
- siliconcompiler/tools/gtkwave/show.py +6 -2
- siliconcompiler/tools/icarus/compile.py +1 -0
- siliconcompiler/tools/klayout/scripts/klayout_show.py +1 -1
- siliconcompiler/tools/klayout/show.py +17 -5
- siliconcompiler/tools/openroad/screenshot.py +0 -1
- siliconcompiler/tools/openroad/scripts/common/screenshot.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/common/write_images.tcl +2 -0
- siliconcompiler/tools/openroad/show.py +10 -0
- siliconcompiler/tools/surfer/show.py +7 -2
- siliconcompiler/tools/verilator/compile.py +2 -2
- siliconcompiler/tools/yosys/prepareLib.py +7 -2
- siliconcompiler/tools/yosys/syn_asic.py +20 -2
- siliconcompiler/toolscripts/_tools.json +5 -5
- siliconcompiler/toolscripts/rhel9/{install-yosys-wildebeest.sh → install-wildebeest.sh} +5 -5
- siliconcompiler/toolscripts/ubuntu22/{install-yosys-wildebeest.sh → install-wildebeest.sh} +5 -5
- siliconcompiler/toolscripts/ubuntu24/{install-yosys-wildebeest.sh → install-wildebeest.sh} +5 -5
- siliconcompiler/utils/__init__.py +1 -2
- siliconcompiler/utils/issue.py +38 -45
- {siliconcompiler-0.35.1.dist-info → siliconcompiler-0.35.3.dist-info}/METADATA +4 -4
- {siliconcompiler-0.35.1.dist-info → siliconcompiler-0.35.3.dist-info}/RECORD +57 -55
- {siliconcompiler-0.35.1.dist-info → siliconcompiler-0.35.3.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.35.1.dist-info → siliconcompiler-0.35.3.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.35.1.dist-info → siliconcompiler-0.35.3.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.35.1.dist-info → siliconcompiler-0.35.3.dist-info}/top_level.txt +0 -0
|
@@ -30,10 +30,36 @@ if TYPE_CHECKING:
|
|
|
30
30
|
from siliconcompiler.schema_support.metric import MetricSchema
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
class
|
|
33
|
+
class _SchedulerReset(Exception):
|
|
34
|
+
def __init__(self, msg: str, *args: object) -> None:
|
|
35
|
+
super().__init__(msg, *args)
|
|
36
|
+
self.__msg = msg
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def msg(self) -> str:
|
|
40
|
+
return self.__msg
|
|
41
|
+
|
|
42
|
+
def log(self, logger: logging.Logger) -> None:
|
|
43
|
+
logger.debug(self.msg)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class SchedulerFlowReset(_SchedulerReset):
|
|
34
47
|
pass
|
|
35
48
|
|
|
36
49
|
|
|
50
|
+
class SchedulerNodeReset(_SchedulerReset):
|
|
51
|
+
def log(self, logger: logging.Logger) -> None:
|
|
52
|
+
logger.warning(self.msg)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class SchedulerNodeResetSilent(SchedulerNodeReset):
|
|
56
|
+
def __init__(self, msg: str, *args: object) -> None:
|
|
57
|
+
super().__init__(msg, *args)
|
|
58
|
+
|
|
59
|
+
def log(self, logger: logging.Logger) -> None:
|
|
60
|
+
_SchedulerReset.log(self, logger)
|
|
61
|
+
|
|
62
|
+
|
|
37
63
|
class SchedulerNode:
|
|
38
64
|
"""
|
|
39
65
|
A class for managing and executing a single node in the compilation flow graph.
|
|
@@ -120,10 +146,12 @@ class SchedulerNode:
|
|
|
120
146
|
are directed to the correct task's schema.
|
|
121
147
|
"""
|
|
122
148
|
prev_task = self.__task
|
|
123
|
-
|
|
124
|
-
self.__task
|
|
125
|
-
|
|
126
|
-
|
|
149
|
+
try:
|
|
150
|
+
with self.__task.runtime(self) as runtask:
|
|
151
|
+
self.__task = runtask
|
|
152
|
+
yield
|
|
153
|
+
finally:
|
|
154
|
+
self.__task = prev_task
|
|
127
155
|
|
|
128
156
|
@staticmethod
|
|
129
157
|
def init(project: "Project") -> None:
|
|
@@ -382,7 +410,7 @@ class SchedulerNode:
|
|
|
382
410
|
|
|
383
411
|
return True
|
|
384
412
|
|
|
385
|
-
def check_previous_run_status(self, previous_run: "SchedulerNode") ->
|
|
413
|
+
def check_previous_run_status(self, previous_run: "SchedulerNode") -> None:
|
|
386
414
|
"""
|
|
387
415
|
Determine whether a prior run is compatible and completed successfully for use as
|
|
388
416
|
an incremental build starting point.
|
|
@@ -406,25 +434,19 @@ class SchedulerNode:
|
|
|
406
434
|
|
|
407
435
|
# Tool name
|
|
408
436
|
if self.__task.tool() != previous_run.__task.tool():
|
|
409
|
-
|
|
410
|
-
return False
|
|
437
|
+
raise SchedulerNodeResetSilent("Tool name changed")
|
|
411
438
|
|
|
412
439
|
# Task name
|
|
413
440
|
if self.__task.task() != previous_run.__task.task():
|
|
414
|
-
|
|
415
|
-
return False
|
|
441
|
+
raise SchedulerNodeResetSilent("Task name changed")
|
|
416
442
|
|
|
417
443
|
previous_status = previous_run.__project.get("record", "status",
|
|
418
444
|
step=self.__step, index=self.__index)
|
|
419
445
|
if not NodeStatus.is_done(previous_status):
|
|
420
|
-
|
|
421
|
-
# Not complete
|
|
422
|
-
return False
|
|
446
|
+
raise SchedulerNodeResetSilent("Previous step did not complete")
|
|
423
447
|
|
|
424
448
|
if not NodeStatus.is_success(previous_status):
|
|
425
|
-
|
|
426
|
-
# Not a success
|
|
427
|
-
return False
|
|
449
|
+
raise SchedulerNodeResetSilent("Previous step was not successful")
|
|
428
450
|
|
|
429
451
|
# Check input nodes
|
|
430
452
|
log_level = self.logger.level
|
|
@@ -433,16 +455,11 @@ class SchedulerNode:
|
|
|
433
455
|
self.logger.setLevel(log_level)
|
|
434
456
|
if set(previous_run.__project.get("record", "inputnode",
|
|
435
457
|
step=self.__step, index=self.__index)) != set(sel_inputs):
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
return False
|
|
439
|
-
|
|
440
|
-
# Check that all output files are present?
|
|
441
|
-
|
|
442
|
-
return True
|
|
458
|
+
raise SchedulerNodeReset(f'inputs to {self.__step}/{self.__index} has been '
|
|
459
|
+
'modified from previous run')
|
|
443
460
|
|
|
444
461
|
def check_values_changed(self, previous_run: "SchedulerNode", keys: Set[Tuple[str, ...]]) \
|
|
445
|
-
->
|
|
462
|
+
-> None:
|
|
446
463
|
"""
|
|
447
464
|
Checks if any specified schema parameter values have changed.
|
|
448
465
|
|
|
@@ -453,15 +470,14 @@ class SchedulerNode:
|
|
|
453
470
|
Returns:
|
|
454
471
|
bool: True if any value has changed, False otherwise.
|
|
455
472
|
"""
|
|
456
|
-
def
|
|
457
|
-
|
|
458
|
-
|
|
473
|
+
def gen_reset(key):
|
|
474
|
+
raise SchedulerNodeReset(f'[{",".join(key)}] in {self.__step}/{self.__index} has been '
|
|
475
|
+
'modified from previous run')
|
|
459
476
|
|
|
460
477
|
for key in sorted(keys):
|
|
461
478
|
if not self.__project.valid(*key) or not previous_run.__project.valid(*key):
|
|
462
479
|
# Key is missing in either run
|
|
463
|
-
|
|
464
|
-
return True
|
|
480
|
+
gen_reset(key)
|
|
465
481
|
|
|
466
482
|
param = self.__project.get(*key, field=None)
|
|
467
483
|
step, index = self.__step, self.__index
|
|
@@ -472,13 +488,10 @@ class SchedulerNode:
|
|
|
472
488
|
prev_val = previous_run.__project.get(*key, step=step, index=index)
|
|
473
489
|
|
|
474
490
|
if check_val != prev_val:
|
|
475
|
-
|
|
476
|
-
return True
|
|
477
|
-
|
|
478
|
-
return False
|
|
491
|
+
gen_reset(key)
|
|
479
492
|
|
|
480
493
|
def check_files_changed(self, previous_run: "SchedulerNode",
|
|
481
|
-
previous_time: float, keys: Set[Tuple[str, ...]]) ->
|
|
494
|
+
previous_time: float, keys: Set[Tuple[str, ...]]) -> None:
|
|
482
495
|
"""
|
|
483
496
|
Checks if any specified file-based parameters have changed.
|
|
484
497
|
|
|
@@ -494,9 +507,9 @@ class SchedulerNode:
|
|
|
494
507
|
"""
|
|
495
508
|
use_hash = self.__hash and previous_run.__hash
|
|
496
509
|
|
|
497
|
-
def
|
|
498
|
-
|
|
499
|
-
|
|
510
|
+
def gen_warning(key, reason):
|
|
511
|
+
raise SchedulerNodeReset(f'[{",".join(key)}] ({reason}) in {self.__step}/'
|
|
512
|
+
f'{self.__index} has been modified from previous run')
|
|
500
513
|
|
|
501
514
|
def get_file_time(path):
|
|
502
515
|
times = [os.path.getmtime(path)]
|
|
@@ -521,8 +534,7 @@ class SchedulerNode:
|
|
|
521
534
|
step=step, index=index)
|
|
522
535
|
|
|
523
536
|
if check_hash != prev_hash:
|
|
524
|
-
|
|
525
|
-
return True
|
|
537
|
+
gen_warning(key, "file hash")
|
|
526
538
|
else:
|
|
527
539
|
# check package values
|
|
528
540
|
check_val = self.__project.get(*key, field='dataroot',
|
|
@@ -531,8 +543,7 @@ class SchedulerNode:
|
|
|
531
543
|
step=step, index=index)
|
|
532
544
|
|
|
533
545
|
if check_val != prev_val:
|
|
534
|
-
|
|
535
|
-
return True
|
|
546
|
+
gen_warning(key, "file dataroot")
|
|
536
547
|
|
|
537
548
|
files = self.__project.find_files(*key, step=step, index=index)
|
|
538
549
|
if not isinstance(files, (list, set, tuple)):
|
|
@@ -540,10 +551,7 @@ class SchedulerNode:
|
|
|
540
551
|
|
|
541
552
|
for check_file in files:
|
|
542
553
|
if get_file_time(check_file) > previous_time:
|
|
543
|
-
|
|
544
|
-
return True
|
|
545
|
-
|
|
546
|
-
return False
|
|
554
|
+
gen_warning(key, "timestamp")
|
|
547
555
|
|
|
548
556
|
def get_check_changed_keys(self) -> Tuple[Set[Tuple[str, ...]], Set[Tuple[str, ...]]]:
|
|
549
557
|
"""
|
|
@@ -585,7 +593,7 @@ class SchedulerNode:
|
|
|
585
593
|
|
|
586
594
|
return value_keys, path_keys
|
|
587
595
|
|
|
588
|
-
def requires_run(self) ->
|
|
596
|
+
def requires_run(self) -> None:
|
|
589
597
|
"""
|
|
590
598
|
Determines if the node needs to be re-run.
|
|
591
599
|
|
|
@@ -601,8 +609,7 @@ class SchedulerNode:
|
|
|
601
609
|
|
|
602
610
|
if self.__breakpoint:
|
|
603
611
|
# Breakpoint is set to must run
|
|
604
|
-
|
|
605
|
-
return True
|
|
612
|
+
raise SchedulerNodeResetSilent(f"Breakpoint is set on {self.__step}/{self.__index}")
|
|
606
613
|
|
|
607
614
|
# Load previous manifest
|
|
608
615
|
previous_node = None
|
|
@@ -612,33 +619,27 @@ class SchedulerNode:
|
|
|
612
619
|
try:
|
|
613
620
|
i_project: Project = Project.from_manifest(filepath=self.__manifests["input"])
|
|
614
621
|
except: # noqa E722
|
|
615
|
-
|
|
616
|
-
return True
|
|
622
|
+
raise SchedulerNodeResetSilent("Input manifest failed to load")
|
|
617
623
|
previous_node = SchedulerNode(i_project, self.__step, self.__index)
|
|
618
624
|
else:
|
|
619
625
|
# No manifest found so assume rerun is needed
|
|
620
|
-
|
|
621
|
-
return True
|
|
626
|
+
raise SchedulerNodeResetSilent("Previous run did not generate input manifest")
|
|
622
627
|
|
|
623
628
|
previous_node_end = None
|
|
624
629
|
if os.path.exists(self.__manifests["output"]):
|
|
625
630
|
try:
|
|
626
631
|
o_project = Project.from_manifest(filepath=self.__manifests["output"])
|
|
627
632
|
except: # noqa E722
|
|
628
|
-
|
|
629
|
-
return True
|
|
633
|
+
raise SchedulerNodeResetSilent("Output manifest failed to load")
|
|
630
634
|
previous_node_end = SchedulerNode(o_project, self.__step, self.__index)
|
|
631
635
|
else:
|
|
632
636
|
# No manifest found so assume rerun is needed
|
|
633
|
-
|
|
634
|
-
return True
|
|
637
|
+
raise SchedulerNodeResetSilent("Previous run did not generate output manifest")
|
|
635
638
|
|
|
636
639
|
with self.runtime():
|
|
637
640
|
if previous_node_end:
|
|
638
641
|
with previous_node_end.runtime():
|
|
639
|
-
|
|
640
|
-
self.logger.debug("Previous run state failed")
|
|
641
|
-
return True
|
|
642
|
+
self.check_previous_run_status(previous_node_end)
|
|
642
643
|
|
|
643
644
|
if previous_node:
|
|
644
645
|
with previous_node.runtime():
|
|
@@ -650,18 +651,10 @@ class SchedulerNode:
|
|
|
650
651
|
value_keys.update(previous_value_keys)
|
|
651
652
|
path_keys.update(previous_path_keys)
|
|
652
653
|
except KeyError:
|
|
653
|
-
|
|
654
|
-
return True
|
|
655
|
-
|
|
656
|
-
if self.check_values_changed(previous_node, value_keys.union(path_keys)):
|
|
657
|
-
self.logger.debug("Key values changed")
|
|
658
|
-
return True
|
|
654
|
+
raise SchedulerNodeResetSilent("Failed to acquire keys")
|
|
659
655
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
return True
|
|
663
|
-
|
|
664
|
-
return False
|
|
656
|
+
self.check_values_changed(previous_node, value_keys.union(path_keys))
|
|
657
|
+
self.check_files_changed(previous_node, previous_node_time, path_keys)
|
|
665
658
|
|
|
666
659
|
def setup_input_directory(self) -> None:
|
|
667
660
|
"""
|
|
@@ -869,6 +862,67 @@ class SchedulerNode:
|
|
|
869
862
|
if self.__pipe:
|
|
870
863
|
self.__pipe.send(Resolver.get_cache(self.__project))
|
|
871
864
|
|
|
865
|
+
@contextlib.contextmanager
|
|
866
|
+
def __set_env(self):
|
|
867
|
+
"""Temporarily sets task-specific environment variables.
|
|
868
|
+
|
|
869
|
+
This context manager saves the current `os.environ`, updates it
|
|
870
|
+
with the task's runtime variables, yields control, and then
|
|
871
|
+
restores the original environment upon exiting the context.
|
|
872
|
+
"""
|
|
873
|
+
org_env = os.environ.copy()
|
|
874
|
+
try:
|
|
875
|
+
os.environ.update(self.__task.get_runtime_environmental_variables())
|
|
876
|
+
yield
|
|
877
|
+
finally:
|
|
878
|
+
os.environ.clear()
|
|
879
|
+
os.environ.update(org_env)
|
|
880
|
+
|
|
881
|
+
def get_exe_path(self) -> Optional[str]:
|
|
882
|
+
"""Gets the path to the requested executable for this task.
|
|
883
|
+
|
|
884
|
+
This method retrieves the executable path from the underlying task
|
|
885
|
+
object. It ensures that the task's specific runtime environment
|
|
886
|
+
variables are set before making the call.
|
|
887
|
+
|
|
888
|
+
Returns:
|
|
889
|
+
Optional[str]: The file path to the executable, or None if not found.
|
|
890
|
+
"""
|
|
891
|
+
with self.__set_env():
|
|
892
|
+
return self.__task.get_exe()
|
|
893
|
+
|
|
894
|
+
def check_version(self, version: Optional[str] = None) -> Tuple[Optional[str], bool]:
|
|
895
|
+
"""Checks the version of the tool for this task.
|
|
896
|
+
|
|
897
|
+
Compares a version string against the tool's requirements. This check
|
|
898
|
+
is performed within the task's specific runtime environment.
|
|
899
|
+
|
|
900
|
+
If no `version` is provided, this method will attempt to get the
|
|
901
|
+
version from the task itself. The check can be skipped if the
|
|
902
|
+
project option 'novercheck' is set.
|
|
903
|
+
|
|
904
|
+
Args:
|
|
905
|
+
version: The version string to check. If None, the task's
|
|
906
|
+
configured version is fetched and used.
|
|
907
|
+
|
|
908
|
+
Returns:
|
|
909
|
+
A tuple (version_str, check_passed):
|
|
910
|
+
- version_str (Optional[str]): The version string that was
|
|
911
|
+
evaluated.
|
|
912
|
+
- check_passed (bool): True if the version is compatible or
|
|
913
|
+
if the check was skipped, False otherwise.
|
|
914
|
+
"""
|
|
915
|
+
if self.__project.get('option', 'novercheck', step=self.__step, index=self.__index):
|
|
916
|
+
return version, True
|
|
917
|
+
|
|
918
|
+
with self.__set_env():
|
|
919
|
+
if version is None:
|
|
920
|
+
version = self.__task.get_exe_version()
|
|
921
|
+
|
|
922
|
+
check = self.__task.check_exe_version(version)
|
|
923
|
+
|
|
924
|
+
return version, check
|
|
925
|
+
|
|
872
926
|
def execute(self) -> None:
|
|
873
927
|
"""
|
|
874
928
|
Handles the core tool execution logic.
|
|
@@ -918,38 +972,36 @@ class SchedulerNode:
|
|
|
918
972
|
|
|
919
973
|
send_messages.send(self.__project, "skipped", self.__step, self.__index)
|
|
920
974
|
else:
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
toolpath = self.__task.get_exe()
|
|
925
|
-
version = self.__task.get_exe_version()
|
|
975
|
+
with self.__set_env():
|
|
976
|
+
toolpath = self.__task.get_exe()
|
|
977
|
+
version, version_pass = self.check_version()
|
|
926
978
|
|
|
927
|
-
|
|
928
|
-
if not self.__task.check_exe_version(version):
|
|
979
|
+
if not version_pass:
|
|
929
980
|
self.halt()
|
|
930
981
|
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
self.
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
982
|
+
if version:
|
|
983
|
+
self.__record.record_tool(self.__step, self.__index, version,
|
|
984
|
+
RecordTool.VERSION)
|
|
985
|
+
|
|
986
|
+
if toolpath:
|
|
987
|
+
self.__record.record_tool(self.__step, self.__index, toolpath, RecordTool.PATH)
|
|
988
|
+
|
|
989
|
+
send_messages.send(self.__project, "begin", self.__step, self.__index)
|
|
990
|
+
|
|
991
|
+
try:
|
|
992
|
+
if not self.__replay:
|
|
993
|
+
self.__task.generate_replay_script(self.__replay_script, self.__workdir)
|
|
994
|
+
ret_code = self.__task.run_task(
|
|
995
|
+
self.__workdir,
|
|
996
|
+
self.__project.get('option', 'quiet',
|
|
997
|
+
step=self.__step, index=self.__index),
|
|
998
|
+
self.__breakpoint,
|
|
999
|
+
self.__project.get('option', 'nice',
|
|
1000
|
+
step=self.__step, index=self.__index),
|
|
1001
|
+
self.__project.get('option', 'timeout',
|
|
1002
|
+
step=self.__step, index=self.__index))
|
|
1003
|
+
except Exception as e:
|
|
1004
|
+
raise e
|
|
953
1005
|
|
|
954
1006
|
if ret_code != 0:
|
|
955
1007
|
msg = f'Command failed with code {ret_code}.'
|
|
@@ -1037,15 +1089,15 @@ class SchedulerNode:
|
|
|
1037
1089
|
from siliconcompiler.utils.issue import generate_testcase
|
|
1038
1090
|
import lambdapdk
|
|
1039
1091
|
|
|
1092
|
+
foss_libraries = [*lambdapdk.get_pdk_names(), *lambdapdk.get_lib_names()]
|
|
1093
|
+
|
|
1040
1094
|
generate_testcase(
|
|
1041
1095
|
self.__project,
|
|
1042
1096
|
self.__step,
|
|
1043
1097
|
self.__index,
|
|
1044
1098
|
archive_directory=self.__jobworkdir,
|
|
1045
|
-
include_pdks=False,
|
|
1046
|
-
include_specific_pdks=lambdapdk.get_pdk_names(),
|
|
1047
1099
|
include_libraries=False,
|
|
1048
|
-
include_specific_libraries=
|
|
1100
|
+
include_specific_libraries=foss_libraries,
|
|
1049
1101
|
hash_files=self.__hash,
|
|
1050
1102
|
verbose_collect=False)
|
|
1051
1103
|
|
|
@@ -4,7 +4,7 @@ from .parameter import Parameter, Scope, PerNode
|
|
|
4
4
|
from .journal import Journal
|
|
5
5
|
from .safeschema import SafeSchema
|
|
6
6
|
from .editableschema import EditableSchema
|
|
7
|
-
from .baseschema import BaseSchema
|
|
7
|
+
from .baseschema import BaseSchema, LazyLoad
|
|
8
8
|
from .namedschema import NamedSchema
|
|
9
9
|
from .docschema import DocsSchema
|
|
10
10
|
|
|
@@ -17,7 +17,8 @@ __all__ = [
|
|
|
17
17
|
"Scope",
|
|
18
18
|
"PerNode",
|
|
19
19
|
"Journal",
|
|
20
|
-
"DocsSchema"
|
|
20
|
+
"DocsSchema",
|
|
21
|
+
"LazyLoad"
|
|
21
22
|
]
|
|
22
23
|
|
|
23
24
|
SCHEMA_VERSION = __version__
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# Version number following semver standard.
|
|
2
|
-
version = '0.52.
|
|
2
|
+
version = '0.52.1'
|