siliconcompiler 0.32.3__py3-none-any.whl → 0.33.1__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/__init__.py +19 -2
- siliconcompiler/_common.py +5 -0
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/sc.py +2 -2
- siliconcompiler/apps/sc_install.py +10 -3
- siliconcompiler/apps/sc_issue.py +1 -1
- siliconcompiler/apps/sc_remote.py +10 -5
- siliconcompiler/apps/sc_show.py +2 -2
- siliconcompiler/apps/utils/replay.py +5 -3
- siliconcompiler/asic.py +120 -0
- siliconcompiler/checklist.py +150 -0
- siliconcompiler/core.py +299 -299
- siliconcompiler/flowgraph.py +803 -515
- siliconcompiler/fpga.py +84 -0
- siliconcompiler/metric.py +479 -0
- siliconcompiler/optimizer/vizier.py +2 -3
- siliconcompiler/package/__init__.py +29 -6
- siliconcompiler/pdk.py +415 -0
- siliconcompiler/record.py +453 -0
- siliconcompiler/remote/client.py +15 -5
- siliconcompiler/remote/schema.py +116 -112
- siliconcompiler/remote/server.py +9 -6
- siliconcompiler/report/dashboard/cli/__init__.py +14 -721
- siliconcompiler/report/dashboard/cli/board.py +899 -0
- siliconcompiler/report/dashboard/web/__init__.py +10 -10
- siliconcompiler/report/dashboard/web/components/__init__.py +5 -4
- siliconcompiler/report/dashboard/web/components/flowgraph.py +3 -3
- siliconcompiler/report/dashboard/web/components/graph.py +6 -3
- siliconcompiler/report/dashboard/web/state.py +1 -1
- siliconcompiler/report/dashboard/web/utils/__init__.py +4 -3
- siliconcompiler/report/html_report.py +2 -3
- siliconcompiler/report/report.py +22 -11
- siliconcompiler/report/summary_image.py +1 -1
- siliconcompiler/report/summary_table.py +3 -3
- siliconcompiler/report/utils.py +21 -14
- siliconcompiler/scheduler/__init__.py +234 -1206
- siliconcompiler/scheduler/run_node.py +2 -1
- siliconcompiler/scheduler/send_messages.py +11 -5
- siliconcompiler/scheduler/slurm.py +11 -44
- siliconcompiler/scheduler/taskscheduler.py +320 -0
- siliconcompiler/schema/__init__.py +19 -2
- siliconcompiler/schema/baseschema.py +493 -0
- siliconcompiler/schema/cmdlineschema.py +250 -0
- siliconcompiler/{sphinx_ext → schema/docs}/__init__.py +3 -1
- siliconcompiler/{sphinx_ext → schema/docs}/dynamicgen.py +63 -81
- siliconcompiler/{sphinx_ext → schema/docs}/schemagen.py +73 -85
- siliconcompiler/{sphinx_ext → schema/docs}/utils.py +12 -13
- siliconcompiler/schema/editableschema.py +136 -0
- siliconcompiler/schema/journalingschema.py +238 -0
- siliconcompiler/schema/namedschema.py +41 -0
- siliconcompiler/schema/packageschema.py +101 -0
- siliconcompiler/schema/parameter.py +791 -0
- siliconcompiler/schema/parametertype.py +323 -0
- siliconcompiler/schema/parametervalue.py +736 -0
- siliconcompiler/schema/safeschema.py +37 -0
- siliconcompiler/schema/schema_cfg.py +109 -1789
- siliconcompiler/schema/utils.py +5 -68
- siliconcompiler/schema_obj.py +119 -0
- siliconcompiler/tool.py +1416 -0
- siliconcompiler/tools/_common/__init__.py +6 -10
- siliconcompiler/tools/_common/asic.py +5 -5
- siliconcompiler/tools/_common/sdc/sc_constraints.sdc +1 -1
- siliconcompiler/tools/bluespec/convert.py +9 -8
- siliconcompiler/tools/builtin/_common.py +9 -2
- siliconcompiler/tools/builtin/concatenate.py +7 -3
- siliconcompiler/tools/builtin/minimum.py +7 -2
- siliconcompiler/tools/builtin/mux.py +8 -2
- siliconcompiler/tools/builtin/nop.py +7 -2
- siliconcompiler/tools/builtin/verify.py +11 -5
- siliconcompiler/tools/chisel/convert.py +10 -10
- siliconcompiler/tools/genfasm/bitstream.py +3 -3
- siliconcompiler/tools/ghdl/convert.py +1 -1
- siliconcompiler/tools/icarus/compile.py +4 -4
- siliconcompiler/tools/icepack/bitstream.py +6 -1
- siliconcompiler/tools/klayout/convert_drc_db.py +5 -0
- siliconcompiler/tools/klayout/drc.py +2 -2
- siliconcompiler/tools/klayout/klayout_export.py +0 -1
- siliconcompiler/tools/klayout/klayout_show.py +6 -6
- siliconcompiler/tools/klayout/klayout_utils.py +15 -22
- siliconcompiler/tools/netgen/count_lvs.py +2 -2
- siliconcompiler/tools/netgen/lvs.py +1 -1
- siliconcompiler/tools/nextpnr/apr.py +6 -1
- siliconcompiler/tools/nextpnr/nextpnr.py +4 -4
- siliconcompiler/tools/openroad/_apr.py +15 -2
- siliconcompiler/tools/openroad/rdlroute.py +3 -3
- siliconcompiler/tools/openroad/scripts/apr/postamble.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +5 -5
- siliconcompiler/tools/openroad/scripts/apr/sc_antenna_repair.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_placement.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_endcap_tapcell_insertion.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_fillercell_insertion.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_fillmetal_insertion.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +3 -9
- siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +3 -3
- siliconcompiler/tools/openroad/scripts/apr/sc_metrics.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_pin_placement.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +75 -1
- siliconcompiler/tools/openroad/scripts/common/read_input_files.tcl +1 -7
- siliconcompiler/tools/openroad/scripts/common/screenshot.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/common/write_images.tcl +28 -3
- siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +3 -3
- siliconcompiler/tools/openroad/scripts/sc_show.tcl +6 -6
- siliconcompiler/tools/opensta/scripts/sc_timing.tcl +10 -0
- siliconcompiler/tools/opensta/timing.py +11 -0
- siliconcompiler/tools/slang/__init__.py +13 -13
- siliconcompiler/tools/slang/elaborate.py +6 -6
- siliconcompiler/tools/slang/lint.py +1 -3
- siliconcompiler/tools/surelog/parse.py +4 -4
- siliconcompiler/tools/sv2v/convert.py +20 -3
- siliconcompiler/tools/verilator/compile.py +2 -2
- siliconcompiler/tools/verilator/verilator.py +3 -3
- siliconcompiler/tools/vpr/_xml_constraint.py +8 -8
- siliconcompiler/tools/vpr/place.py +1 -1
- siliconcompiler/tools/vpr/route.py +4 -4
- siliconcompiler/tools/vpr/screenshot.py +1 -1
- siliconcompiler/tools/vpr/show.py +5 -5
- siliconcompiler/tools/vpr/vpr.py +24 -24
- siliconcompiler/tools/xdm/convert.py +2 -2
- siliconcompiler/tools/xyce/simulate.py +1 -1
- siliconcompiler/tools/yosys/prepareLib.py +2 -2
- siliconcompiler/tools/yosys/sc_synth_asic.tcl +111 -63
- siliconcompiler/tools/yosys/screenshot.py +1 -1
- siliconcompiler/tools/yosys/syn_asic.py +7 -7
- siliconcompiler/toolscripts/_tools.json +12 -10
- siliconcompiler/toolscripts/rhel8/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/rhel8/install-icarus.sh +10 -3
- siliconcompiler/toolscripts/rhel8/install-klayout.sh +8 -1
- siliconcompiler/toolscripts/rhel8/install-magic.sh +9 -2
- siliconcompiler/toolscripts/rhel8/install-montage.sh +1 -1
- siliconcompiler/toolscripts/rhel8/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/rhel8/install-slang.sh +11 -4
- siliconcompiler/toolscripts/rhel8/install-surelog.sh +9 -2
- siliconcompiler/toolscripts/rhel8/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/rhel8/install-verible.sh +11 -3
- siliconcompiler/toolscripts/rhel8/install-verilator.sh +10 -3
- siliconcompiler/toolscripts/rhel8/install-xyce.sh +15 -10
- siliconcompiler/toolscripts/rhel9/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-ghdl.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-gtkwave.sh +10 -3
- siliconcompiler/toolscripts/rhel9/install-icarus.sh +10 -3
- siliconcompiler/toolscripts/rhel9/install-klayout.sh +8 -1
- siliconcompiler/toolscripts/rhel9/install-magic.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-montage.sh +1 -1
- siliconcompiler/toolscripts/rhel9/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-openroad.sh +16 -3
- siliconcompiler/toolscripts/rhel9/install-opensta.sh +17 -5
- siliconcompiler/toolscripts/rhel9/install-slang.sh +11 -4
- siliconcompiler/toolscripts/rhel9/install-surelog.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/rhel9/install-verible.sh +11 -3
- siliconcompiler/toolscripts/rhel9/install-verilator.sh +10 -3
- siliconcompiler/toolscripts/rhel9/install-vpr.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-xdm.sh +10 -2
- siliconcompiler/toolscripts/rhel9/install-xyce.sh +15 -10
- siliconcompiler/toolscripts/rhel9/install-yosys-moosic.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +10 -3
- siliconcompiler/toolscripts/rhel9/install-yosys-slang.sh +10 -2
- siliconcompiler/toolscripts/rhel9/install-yosys.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-bambu.sh +10 -2
- siliconcompiler/toolscripts/ubuntu20/install-bluespec.sh +10 -3
- siliconcompiler/toolscripts/ubuntu20/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-ghdl.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-gtkwave.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-icarus.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-icepack.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-klayout.sh +8 -1
- siliconcompiler/toolscripts/ubuntu20/install-magic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-montage.sh +1 -1
- siliconcompiler/toolscripts/ubuntu20/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-nextpnr.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-openroad.sh +16 -3
- siliconcompiler/toolscripts/ubuntu20/install-opensta.sh +16 -5
- siliconcompiler/toolscripts/ubuntu20/install-slang.sh +11 -4
- siliconcompiler/toolscripts/ubuntu20/install-slurm.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-surelog.sh +10 -2
- siliconcompiler/toolscripts/ubuntu20/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/ubuntu20/install-verible.sh +11 -3
- siliconcompiler/toolscripts/ubuntu20/install-verilator.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-xdm.sh +10 -2
- siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +13 -8
- siliconcompiler/toolscripts/ubuntu20/install-yosys-moosic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-yosys.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-bambu.sh +10 -2
- siliconcompiler/toolscripts/ubuntu22/install-bluespec.sh +10 -3
- siliconcompiler/toolscripts/ubuntu22/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-ghdl.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-gtkwave.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-icarus.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-icepack.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-klayout.sh +8 -1
- siliconcompiler/toolscripts/ubuntu22/install-magic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-montage.sh +1 -1
- siliconcompiler/toolscripts/ubuntu22/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-nextpnr.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-openroad.sh +16 -3
- siliconcompiler/toolscripts/ubuntu22/install-opensta.sh +17 -5
- siliconcompiler/toolscripts/ubuntu22/install-slang.sh +11 -4
- siliconcompiler/toolscripts/ubuntu22/install-slurm.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-surelog.sh +10 -2
- siliconcompiler/toolscripts/ubuntu22/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/ubuntu22/install-verible.sh +11 -3
- siliconcompiler/toolscripts/ubuntu22/install-verilator.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-vpr.sh +9 -4
- siliconcompiler/toolscripts/ubuntu22/install-xdm.sh +10 -2
- siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +13 -8
- siliconcompiler/toolscripts/ubuntu22/install-yosys-moosic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +10 -3
- siliconcompiler/toolscripts/ubuntu22/install-yosys-slang.sh +10 -2
- siliconcompiler/toolscripts/ubuntu22/install-yosys.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-bambu.sh +12 -4
- siliconcompiler/toolscripts/ubuntu24/install-bluespec.sh +10 -3
- siliconcompiler/toolscripts/ubuntu24/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-ghdl.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-gtkwave.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-icarus.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-icepack.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +8 -1
- siliconcompiler/toolscripts/ubuntu24/install-magic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-montage.sh +1 -1
- siliconcompiler/toolscripts/ubuntu24/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-nextpnr.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-openroad.sh +16 -3
- siliconcompiler/toolscripts/ubuntu24/install-opensta.sh +17 -5
- siliconcompiler/toolscripts/ubuntu24/install-slang.sh +11 -4
- siliconcompiler/toolscripts/ubuntu24/install-slurm.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-surelog.sh +10 -2
- siliconcompiler/toolscripts/ubuntu24/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/ubuntu24/install-verible.sh +11 -3
- siliconcompiler/toolscripts/ubuntu24/install-verilator.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-vpr.sh +9 -4
- siliconcompiler/toolscripts/ubuntu24/install-xdm.sh +10 -2
- siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +13 -8
- siliconcompiler/toolscripts/ubuntu24/install-yosys-moosic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +10 -3
- siliconcompiler/toolscripts/ubuntu24/install-yosys-slang.sh +10 -2
- siliconcompiler/toolscripts/ubuntu24/install-yosys.sh +9 -2
- siliconcompiler/utils/__init__.py +19 -112
- siliconcompiler/utils/flowgraph.py +244 -0
- siliconcompiler/{issue.py → utils/issue.py} +18 -25
- siliconcompiler/utils/logging.py +3 -4
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/METADATA +9 -8
- siliconcompiler-0.33.1.dist-info/RECORD +488 -0
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/WHEEL +1 -1
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/entry_points.txt +8 -8
- siliconcompiler/schema/schema_obj.py +0 -1936
- siliconcompiler/toolscripts/ubuntu20/install-vpr.sh +0 -29
- siliconcompiler/toolscripts/ubuntu20/install-yosys-parmys.sh +0 -61
- siliconcompiler-0.32.3.dist-info/RECORD +0 -470
- /siliconcompiler/{templates → data/templates}/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/email/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/email/general.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/email/summary.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/issue/README.txt +0 -0
- /siliconcompiler/{templates → data/templates}/issue/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/issue/run.sh +0 -0
- /siliconcompiler/{templates → data/templates}/replay/replay.py.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/replay/replay.sh.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/replay/requirements.txt +0 -0
- /siliconcompiler/{templates → data/templates}/replay/setup.sh +0 -0
- /siliconcompiler/{templates → data/templates}/report/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/report/bootstrap.min.css +0 -0
- /siliconcompiler/{templates → data/templates}/report/bootstrap.min.js +0 -0
- /siliconcompiler/{templates → data/templates}/report/bootstrap_LICENSE.md +0 -0
- /siliconcompiler/{templates → data/templates}/report/sc_report.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/slurm/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/slurm/run.sh +0 -0
- /siliconcompiler/{templates → data/templates}/tcl/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/tcl/manifest.tcl.j2 +0 -0
- /siliconcompiler/{units.py → utils/units.py} +0 -0
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from collections.abc import Iterable
|
|
3
|
+
from pathlib import Path, PureWindowsPath
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class NodeType:
|
|
7
|
+
"""
|
|
8
|
+
Schema type decoding and encoding class.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
sctype (str or :class:`NodeType`): schema type
|
|
12
|
+
"""
|
|
13
|
+
__list = re.compile(r"^\[(.*)\]$")
|
|
14
|
+
__tuple = re.compile(r"^\((.*)\)$")
|
|
15
|
+
__set = re.compile(r"^\{(.*)\}$")
|
|
16
|
+
__enum = re.compile(r"^<(.*)>$")
|
|
17
|
+
__basetypes = re.compile(r"^(<(.*)>|int|float|str|bool|file|dir)$")
|
|
18
|
+
|
|
19
|
+
def __init__(self, sctype):
|
|
20
|
+
if isinstance(sctype, NodeType):
|
|
21
|
+
self.__type = sctype.type
|
|
22
|
+
elif isinstance(sctype, str):
|
|
23
|
+
self.__type = NodeType.parse(sctype)
|
|
24
|
+
else:
|
|
25
|
+
self.__type = sctype
|
|
26
|
+
|
|
27
|
+
def __str__(self):
|
|
28
|
+
return NodeType.encode(self.__type)
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def type(self):
|
|
32
|
+
return self.__type
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def parse(sctype):
|
|
36
|
+
"""
|
|
37
|
+
Parses a schema type string.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
if isinstance(sctype, NodeType):
|
|
41
|
+
return sctype.type
|
|
42
|
+
|
|
43
|
+
if not isinstance(sctype, str):
|
|
44
|
+
return sctype
|
|
45
|
+
|
|
46
|
+
if NodeType.__basetypes.match(sctype):
|
|
47
|
+
if NodeType.__enum.match(sctype):
|
|
48
|
+
return NodeEnumType(*sctype[1:-1].split(","))
|
|
49
|
+
return sctype
|
|
50
|
+
if NodeType.__list.match(sctype):
|
|
51
|
+
return [NodeType.parse(sctype[1:-1])]
|
|
52
|
+
if NodeType.__set.match(sctype):
|
|
53
|
+
return set([NodeType.parse(sctype[1:-1])])
|
|
54
|
+
if NodeType.__tuple.match(sctype):
|
|
55
|
+
tupletypes = []
|
|
56
|
+
typletype = ""
|
|
57
|
+
for ttype in sctype[1:-1].split(","):
|
|
58
|
+
typletype += ttype
|
|
59
|
+
try:
|
|
60
|
+
tupletypes.append(NodeType.parse(typletype))
|
|
61
|
+
typletype = ""
|
|
62
|
+
except ValueError:
|
|
63
|
+
typletype += ","
|
|
64
|
+
return tuple(tupletypes)
|
|
65
|
+
raise ValueError(sctype)
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def encode(sctype):
|
|
69
|
+
"""
|
|
70
|
+
Encodes a schema type into a string.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
if isinstance(sctype, NodeType):
|
|
74
|
+
sctype = sctype.type
|
|
75
|
+
|
|
76
|
+
if isinstance(sctype, list):
|
|
77
|
+
return f"[{NodeType.encode(sctype[0])}]"
|
|
78
|
+
|
|
79
|
+
if isinstance(sctype, tuple):
|
|
80
|
+
return f"({','.join([NodeType.encode(sct) for sct in sctype])})"
|
|
81
|
+
|
|
82
|
+
if isinstance(sctype, set):
|
|
83
|
+
return f"{{{','.join([NodeType.encode(sct) for sct in sctype])}}}"
|
|
84
|
+
|
|
85
|
+
if isinstance(sctype, NodeEnumType):
|
|
86
|
+
return str(sctype)
|
|
87
|
+
|
|
88
|
+
if isinstance(sctype, str):
|
|
89
|
+
return sctype
|
|
90
|
+
|
|
91
|
+
raise ValueError(f"{sctype} not a recognized type")
|
|
92
|
+
|
|
93
|
+
@staticmethod
|
|
94
|
+
def contains(value, check):
|
|
95
|
+
"""
|
|
96
|
+
Check if the type contains a specific type.
|
|
97
|
+
"""
|
|
98
|
+
if check in (list, tuple, set, NodeEnumType):
|
|
99
|
+
if isinstance(value, check):
|
|
100
|
+
return True
|
|
101
|
+
if isinstance(value, list):
|
|
102
|
+
return NodeType.contains(value[0], check)
|
|
103
|
+
if isinstance(value, tuple):
|
|
104
|
+
return any([NodeType.contains(v, check) for v in value])
|
|
105
|
+
return value == check
|
|
106
|
+
|
|
107
|
+
@staticmethod
|
|
108
|
+
def to_tcl(value, sctype):
|
|
109
|
+
'''
|
|
110
|
+
Recursive helper function for converting Python values to safe TCL
|
|
111
|
+
values, based on the SC type string.
|
|
112
|
+
'''
|
|
113
|
+
|
|
114
|
+
if isinstance(sctype, list):
|
|
115
|
+
if value is None:
|
|
116
|
+
return '[list ]'
|
|
117
|
+
# Recurse into each item of list
|
|
118
|
+
valstr = ' '.join(NodeType.to_tcl(v, sctype[0]) for v in value)
|
|
119
|
+
return f'[list {valstr}]'
|
|
120
|
+
|
|
121
|
+
if isinstance(sctype, set):
|
|
122
|
+
if value is None:
|
|
123
|
+
return '[list ]'
|
|
124
|
+
# Recurse into each item of list
|
|
125
|
+
sctype = list(sctype)[0]
|
|
126
|
+
valstr = ' '.join(NodeType.to_tcl(v, sctype) for v in value)
|
|
127
|
+
return f'[list {valstr}]'
|
|
128
|
+
|
|
129
|
+
if isinstance(sctype, tuple):
|
|
130
|
+
if value is None:
|
|
131
|
+
return '[list ]'
|
|
132
|
+
valstr = ' '.join(NodeType.to_tcl(v, subtype) for v, subtype in zip(value, sctype))
|
|
133
|
+
return f'[list {valstr}]'
|
|
134
|
+
|
|
135
|
+
if value is None:
|
|
136
|
+
return ''
|
|
137
|
+
|
|
138
|
+
if sctype == 'str' or isinstance(sctype, NodeEnumType):
|
|
139
|
+
# Escape string by surrounding it with "" and escaping the few
|
|
140
|
+
# special characters that still get considered inside "". We don't
|
|
141
|
+
# use {}, since this requires adding permanent backslashes to any
|
|
142
|
+
# curly braces inside the string.
|
|
143
|
+
# Source: https://www.tcl.tk/man/tcl8.4/TclCmd/Tcl.html (section [4] on)
|
|
144
|
+
escaped_val = (value.replace('\\', '\\\\') # escape '\' to avoid backslash substitution
|
|
145
|
+
# (do this first, since other replaces
|
|
146
|
+
# insert '\')
|
|
147
|
+
.replace('[', '\\[') # escape '[' to avoid command substitution
|
|
148
|
+
.replace('$', '\\$') # escape '$' to avoid variable substitution
|
|
149
|
+
.replace('"', '\\"')) # escape '"' to avoid string terminating
|
|
150
|
+
return '"' + escaped_val + '"'
|
|
151
|
+
if sctype == 'bool':
|
|
152
|
+
return 'true' if value else 'false'
|
|
153
|
+
|
|
154
|
+
if sctype == 'int':
|
|
155
|
+
return str(value)
|
|
156
|
+
|
|
157
|
+
if sctype == 'float':
|
|
158
|
+
return f"{value:.9g}"
|
|
159
|
+
|
|
160
|
+
if sctype in ('file', 'dir'):
|
|
161
|
+
# Replace $VAR with $env(VAR) for tcl
|
|
162
|
+
value = re.sub(r'\${?(\w+)}?', r'$env(\1)', value)
|
|
163
|
+
# Same escapes as applied to string, minus $ (since we want to resolve env vars).
|
|
164
|
+
escaped_val = (value.replace('\\', '\\\\') # escape '\' to avoid backslash substitution
|
|
165
|
+
# (do this first, since other replaces
|
|
166
|
+
# insert '\')
|
|
167
|
+
.replace('[', '\\[') # escape '[' to avoid command substitution
|
|
168
|
+
.replace('"', '\\"')) # escape '"' to avoid string terminating
|
|
169
|
+
return '"' + escaped_val + '"'
|
|
170
|
+
|
|
171
|
+
raise TypeError(f'{sctype} is not a supported type')
|
|
172
|
+
|
|
173
|
+
@staticmethod
|
|
174
|
+
def normalize(value, sctype):
|
|
175
|
+
"""
|
|
176
|
+
Normalizes a value into the appropriate datatype.
|
|
177
|
+
"""
|
|
178
|
+
|
|
179
|
+
if isinstance(sctype, NodeType):
|
|
180
|
+
return NodeType.normalize(value, sctype.type)
|
|
181
|
+
|
|
182
|
+
if isinstance(sctype, list):
|
|
183
|
+
sctype = sctype[0]
|
|
184
|
+
|
|
185
|
+
# Need to try 2 different recursion strategies - if value is a list already, then we can
|
|
186
|
+
# recurse on it directly. However, if that doesn't work, then it might be a
|
|
187
|
+
# list-of-lists/tuples that needs to be wrapped in an outer list, so we try that.
|
|
188
|
+
if isinstance(value, (list, set, tuple)):
|
|
189
|
+
try:
|
|
190
|
+
return [NodeType.normalize(v, sctype) for v in value]
|
|
191
|
+
except ValueError:
|
|
192
|
+
pass
|
|
193
|
+
|
|
194
|
+
return [NodeType.normalize(v, sctype) for v in [value]]
|
|
195
|
+
|
|
196
|
+
if isinstance(sctype, set):
|
|
197
|
+
sctype = list(sctype)[0]
|
|
198
|
+
|
|
199
|
+
# Need to try 2 different recursion strategies - if value is a list already, then we can
|
|
200
|
+
# recurse on it directly. However, if that doesn't work, then it might be a
|
|
201
|
+
# list-of-lists/tuples that needs to be wrapped in an outer list, so we try that.
|
|
202
|
+
if isinstance(value, (list, set, tuple)):
|
|
203
|
+
try:
|
|
204
|
+
return set([NodeType.normalize(v, sctype) for v in value])
|
|
205
|
+
except ValueError:
|
|
206
|
+
pass
|
|
207
|
+
|
|
208
|
+
return set([NodeType.normalize(v, sctype) for v in [value]])
|
|
209
|
+
|
|
210
|
+
if isinstance(sctype, tuple):
|
|
211
|
+
if value is None:
|
|
212
|
+
return None
|
|
213
|
+
|
|
214
|
+
sctype = [*sctype]
|
|
215
|
+
|
|
216
|
+
if isinstance(value, str):
|
|
217
|
+
if NodeType.__tuple.match(value):
|
|
218
|
+
value = value[1:-1].split(',')
|
|
219
|
+
else:
|
|
220
|
+
value = value.split(',')
|
|
221
|
+
elif not isinstance(value, (list, tuple)):
|
|
222
|
+
valuetype = type(value)
|
|
223
|
+
if isinstance(value, Iterable):
|
|
224
|
+
value = ",".join(value)
|
|
225
|
+
raise ValueError(f"({value}) ({valuetype}) cannot be converted to tuple")
|
|
226
|
+
|
|
227
|
+
if len(value) != len(sctype):
|
|
228
|
+
raise ValueError(f"({','.join(value)}) does not have {len(sctype)} entries")
|
|
229
|
+
return tuple(
|
|
230
|
+
NodeType.normalize(v, base_type)
|
|
231
|
+
for v, base_type in zip(value, sctype))
|
|
232
|
+
|
|
233
|
+
if value is None:
|
|
234
|
+
return None
|
|
235
|
+
|
|
236
|
+
if isinstance(value, (list, tuple, set)):
|
|
237
|
+
if len(value) == 1:
|
|
238
|
+
return NodeType.normalize(list(value)[0], sctype)
|
|
239
|
+
raise ValueError(f"\"{type(value)}\" unable to convert to {sctype}")
|
|
240
|
+
|
|
241
|
+
if sctype == 'bool':
|
|
242
|
+
if isinstance(value, bool):
|
|
243
|
+
return value
|
|
244
|
+
if isinstance(value, str):
|
|
245
|
+
value = value.strip().lower()
|
|
246
|
+
if value == 'true' or value == 't':
|
|
247
|
+
return True
|
|
248
|
+
if value == 'false' or value == 'f':
|
|
249
|
+
return False
|
|
250
|
+
if isinstance(value, (int, float)):
|
|
251
|
+
return value != 0
|
|
252
|
+
raise ValueError(f"\"{value}\" unable to convert to boolean")
|
|
253
|
+
|
|
254
|
+
try:
|
|
255
|
+
if sctype == 'int':
|
|
256
|
+
return int(value)
|
|
257
|
+
|
|
258
|
+
if sctype == 'float':
|
|
259
|
+
return float(value)
|
|
260
|
+
except ValueError:
|
|
261
|
+
raise ValueError(f"\"{value}\" unable to convert to {sctype}")
|
|
262
|
+
|
|
263
|
+
if sctype == 'str':
|
|
264
|
+
if isinstance(value, str):
|
|
265
|
+
return value
|
|
266
|
+
elif isinstance(value, bool):
|
|
267
|
+
return str(value).lower()
|
|
268
|
+
else:
|
|
269
|
+
return str(value)
|
|
270
|
+
|
|
271
|
+
if sctype in ('file', 'dir'):
|
|
272
|
+
if isinstance(value, (str, Path)):
|
|
273
|
+
# Cast everything to a windows path and convert to posix.
|
|
274
|
+
# https://stackoverflow.com/questions/73682260
|
|
275
|
+
return PureWindowsPath(value).as_posix()
|
|
276
|
+
else:
|
|
277
|
+
raise ValueError(f"{sctype} must be a string or Path, not {type(value)}")
|
|
278
|
+
|
|
279
|
+
if isinstance(sctype, NodeEnumType):
|
|
280
|
+
if isinstance(value, str):
|
|
281
|
+
if value in sctype.values:
|
|
282
|
+
return value
|
|
283
|
+
valid = ", ".join(sorted(sctype.values))
|
|
284
|
+
raise ValueError(f'{value} is not a member of: {valid}')
|
|
285
|
+
else:
|
|
286
|
+
raise ValueError(f"enum must be a string, not a {type(value)}")
|
|
287
|
+
|
|
288
|
+
raise ValueError(f'Invalid type specifier: {sctype}')
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
class NodeEnumType:
|
|
292
|
+
"""
|
|
293
|
+
Type for schema data type
|
|
294
|
+
|
|
295
|
+
Args:
|
|
296
|
+
values (list of str): list of legal values for this type.
|
|
297
|
+
"""
|
|
298
|
+
|
|
299
|
+
def __init__(self, *values):
|
|
300
|
+
if not values:
|
|
301
|
+
raise ValueError("enum cannot be empty set")
|
|
302
|
+
self.__values = set(values)
|
|
303
|
+
|
|
304
|
+
def __eq__(self, other):
|
|
305
|
+
if isinstance(other, NodeEnumType):
|
|
306
|
+
return self.__values == other.__values
|
|
307
|
+
return False
|
|
308
|
+
|
|
309
|
+
def __str__(self):
|
|
310
|
+
return f"<{','.join(sorted(self.__values))}>"
|
|
311
|
+
|
|
312
|
+
def __repr__(self):
|
|
313
|
+
return str(self)
|
|
314
|
+
|
|
315
|
+
def __hash__(self):
|
|
316
|
+
return hash(tuple(self.__values))
|
|
317
|
+
|
|
318
|
+
@property
|
|
319
|
+
def values(self):
|
|
320
|
+
'''
|
|
321
|
+
Returns a set of the legal values for this enum.
|
|
322
|
+
'''
|
|
323
|
+
return self.__values
|