siliconcompiler 0.35.0__py3-none-any.whl → 0.35.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.
Files changed (49) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/apps/_common.py +3 -2
  3. siliconcompiler/apps/sc_dashboard.py +3 -1
  4. siliconcompiler/apps/sc_install.py +149 -37
  5. siliconcompiler/apps/smake.py +9 -3
  6. siliconcompiler/checklist.py +3 -3
  7. siliconcompiler/data/demo_fpga/z1000_yosys_config.json +24 -0
  8. siliconcompiler/design.py +51 -45
  9. siliconcompiler/flowgraph.py +2 -2
  10. siliconcompiler/library.py +23 -12
  11. siliconcompiler/package/__init__.py +77 -49
  12. siliconcompiler/package/git.py +11 -6
  13. siliconcompiler/package/github.py +11 -6
  14. siliconcompiler/package/https.py +6 -4
  15. siliconcompiler/pdk.py +23 -16
  16. siliconcompiler/scheduler/scheduler.py +30 -22
  17. siliconcompiler/scheduler/schedulernode.py +60 -50
  18. siliconcompiler/scheduler/taskscheduler.py +52 -32
  19. siliconcompiler/schema/baseschema.py +88 -69
  20. siliconcompiler/schema/docs/schemagen.py +4 -3
  21. siliconcompiler/schema/editableschema.py +5 -5
  22. siliconcompiler/schema/journal.py +19 -13
  23. siliconcompiler/schema/namedschema.py +16 -10
  24. siliconcompiler/schema/parameter.py +64 -37
  25. siliconcompiler/schema/parametervalue.py +126 -80
  26. siliconcompiler/schema/safeschema.py +16 -7
  27. siliconcompiler/schema/utils.py +3 -1
  28. siliconcompiler/schema_support/cmdlineschema.py +9 -9
  29. siliconcompiler/schema_support/dependencyschema.py +12 -7
  30. siliconcompiler/schema_support/filesetschema.py +15 -10
  31. siliconcompiler/schema_support/metric.py +29 -17
  32. siliconcompiler/schema_support/packageschema.py +2 -2
  33. siliconcompiler/schema_support/pathschema.py +30 -18
  34. siliconcompiler/schema_support/record.py +30 -23
  35. siliconcompiler/tool.py +265 -210
  36. siliconcompiler/tools/opensta/timing.py +13 -0
  37. siliconcompiler/tools/yosys/syn_fpga.py +3 -2
  38. siliconcompiler/toolscripts/_tools.json +3 -3
  39. siliconcompiler/utils/__init__.py +23 -16
  40. siliconcompiler/utils/curation.py +11 -5
  41. siliconcompiler/utils/multiprocessing.py +16 -14
  42. siliconcompiler/utils/paths.py +24 -12
  43. siliconcompiler/utils/units.py +16 -12
  44. {siliconcompiler-0.35.0.dist-info → siliconcompiler-0.35.1.dist-info}/METADATA +3 -4
  45. {siliconcompiler-0.35.0.dist-info → siliconcompiler-0.35.1.dist-info}/RECORD +49 -48
  46. {siliconcompiler-0.35.0.dist-info → siliconcompiler-0.35.1.dist-info}/entry_points.txt +4 -3
  47. {siliconcompiler-0.35.0.dist-info → siliconcompiler-0.35.1.dist-info}/WHEEL +0 -0
  48. {siliconcompiler-0.35.0.dist-info → siliconcompiler-0.35.1.dist-info}/licenses/LICENSE +0 -0
  49. {siliconcompiler-0.35.0.dist-info → siliconcompiler-0.35.1.dist-info}/top_level.txt +0 -0
siliconcompiler/design.py CHANGED
@@ -3,7 +3,7 @@ import re
3
3
  import os.path
4
4
  from pathlib import Path
5
5
 
6
- from typing import List, Union, Tuple, Dict
6
+ from typing import List, Union, Tuple, Dict, Optional, Iterable, Type
7
7
 
8
8
  from siliconcompiler import utils
9
9
 
@@ -26,7 +26,7 @@ class Design(LibrarySchema, DependencySchema):
26
26
  and compilation settings.
27
27
  '''
28
28
 
29
- def __init__(self, name: str = None):
29
+ def __init__(self, name: Optional[str] = None):
30
30
  '''
31
31
  Initializes a new Design object.
32
32
 
@@ -68,7 +68,7 @@ class Design(LibrarySchema, DependencySchema):
68
68
  ############################################
69
69
  def set_topmodule(self,
70
70
  value: str,
71
- fileset: str = None) -> str:
71
+ fileset: Optional[str] = None) -> str:
72
72
  """Sets the topmodule of a fileset.
73
73
 
74
74
  Args:
@@ -91,7 +91,7 @@ class Design(LibrarySchema, DependencySchema):
91
91
 
92
92
  return self.__set_add(fileset, 'topmodule', value, typelist=[str])
93
93
 
94
- def get_topmodule(self, fileset: str = None) -> str:
94
+ def get_topmodule(self, fileset: Optional[str] = None) -> str:
95
95
  """Returns the topmodule of a fileset.
96
96
 
97
97
  Args:
@@ -106,9 +106,9 @@ class Design(LibrarySchema, DependencySchema):
106
106
  ##############################################
107
107
  def add_idir(self,
108
108
  value: str,
109
- fileset: str = None,
109
+ fileset: Optional[str] = None,
110
110
  clobber: bool = False,
111
- dataroot: str = None) -> List[str]:
111
+ dataroot: Optional[str] = None) -> List[str]:
112
112
  """Adds include directories to a fileset.
113
113
 
114
114
  Args:
@@ -125,7 +125,7 @@ class Design(LibrarySchema, DependencySchema):
125
125
  typelist=[str, list, Path],
126
126
  dataroot=dataroot)
127
127
 
128
- def get_idir(self, fileset: str = None) -> List[str]:
128
+ def get_idir(self, fileset: Optional[str] = None) -> List[str]:
129
129
  """Returns include directories for a fileset.
130
130
 
131
131
  Args:
@@ -137,7 +137,7 @@ class Design(LibrarySchema, DependencySchema):
137
137
  """
138
138
  return self.__get(fileset, 'idir', is_file=True)
139
139
 
140
- def has_idir(self, fileset: str = None) -> bool:
140
+ def has_idir(self, fileset: Optional[str] = None) -> bool:
141
141
  """Returns true if idirs are defined for the fileset
142
142
 
143
143
  Args:
@@ -152,7 +152,7 @@ class Design(LibrarySchema, DependencySchema):
152
152
  ##############################################
153
153
  def add_define(self,
154
154
  value: str,
155
- fileset: str = None,
155
+ fileset: Optional[str] = None,
156
156
  clobber: bool = False) -> List[str]:
157
157
  """Adds preprocessor macro definitions to a fileset.
158
158
 
@@ -168,7 +168,7 @@ class Design(LibrarySchema, DependencySchema):
168
168
  """
169
169
  return self.__set_add(fileset, 'define', value, clobber, typelist=[str, list])
170
170
 
171
- def get_define(self, fileset: str = None) -> List[str]:
171
+ def get_define(self, fileset: Optional[str] = None) -> List[str]:
172
172
  """Returns defined macros for a fileset.
173
173
 
174
174
  Args:
@@ -183,7 +183,7 @@ class Design(LibrarySchema, DependencySchema):
183
183
  ##############################################
184
184
  def add_undefine(self,
185
185
  value: str,
186
- fileset: str = None,
186
+ fileset: Optional[str] = None,
187
187
  clobber: bool = False) -> List[str]:
188
188
  """Adds preprocessor macro (un)definitions to a fileset.
189
189
 
@@ -198,7 +198,7 @@ class Design(LibrarySchema, DependencySchema):
198
198
  """
199
199
  return self.__set_add(fileset, 'undefine', value, clobber, typelist=[str, list])
200
200
 
201
- def get_undefine(self, fileset: str = None) -> List[str]:
201
+ def get_undefine(self, fileset: Optional[str] = None) -> List[str]:
202
202
  """Returns undefined macros for a fileset.
203
203
 
204
204
  Args:
@@ -214,9 +214,9 @@ class Design(LibrarySchema, DependencySchema):
214
214
  ###############################################
215
215
  def add_libdir(self,
216
216
  value: str,
217
- fileset: str = None,
217
+ fileset: Optional[str] = None,
218
218
  clobber: bool = False,
219
- dataroot: str = None) -> List[str]:
219
+ dataroot: Optional[str] = None) -> List[str]:
220
220
  """Adds dynamic library directories to a fileset.
221
221
 
222
222
  Args:
@@ -233,7 +233,7 @@ class Design(LibrarySchema, DependencySchema):
233
233
  typelist=[str, list, Path],
234
234
  dataroot=dataroot)
235
235
 
236
- def get_libdir(self, fileset: str = None) -> List[str]:
236
+ def get_libdir(self, fileset: Optional[str] = None) -> List[str]:
237
237
  """Returns dynamic library directories for a fileset.
238
238
 
239
239
  Args:
@@ -245,7 +245,7 @@ class Design(LibrarySchema, DependencySchema):
245
245
  """
246
246
  return self.__get(fileset, 'libdir', is_file=True)
247
247
 
248
- def has_libdir(self, fileset: str = None) -> bool:
248
+ def has_libdir(self, fileset: Optional[str] = None) -> bool:
249
249
  """Returns true if library directories are defined for the fileset
250
250
 
251
251
  Args:
@@ -260,7 +260,7 @@ class Design(LibrarySchema, DependencySchema):
260
260
  ###############################################
261
261
  def add_lib(self,
262
262
  value: str,
263
- fileset: str = None,
263
+ fileset: Optional[str] = None,
264
264
  clobber: bool = False) -> List[str]:
265
265
  """Adds dynamic libraries to a fileset.
266
266
 
@@ -275,7 +275,7 @@ class Design(LibrarySchema, DependencySchema):
275
275
  """
276
276
  return self.__set_add(fileset, 'lib', value, clobber, typelist=[str, list])
277
277
 
278
- def get_lib(self, fileset: str = None) -> List[str]:
278
+ def get_lib(self, fileset: Optional[str] = None) -> List[str]:
279
279
  """Returns list of dynamic libraries for a fileset.
280
280
 
281
281
  Args:
@@ -291,7 +291,7 @@ class Design(LibrarySchema, DependencySchema):
291
291
  def set_param(self,
292
292
  name: str,
293
293
  value: str,
294
- fileset: str = None) -> str:
294
+ fileset: Optional[str] = None) -> str:
295
295
  """Sets a named parameter for a fileset.
296
296
 
297
297
  Args:
@@ -317,7 +317,7 @@ class Design(LibrarySchema, DependencySchema):
317
317
 
318
318
  def get_param(self,
319
319
  name: str,
320
- fileset: str = None) -> str:
320
+ fileset: Optional[str] = None) -> str:
321
321
  """Returns value of a named fileset parameter.
322
322
 
323
323
  Args:
@@ -337,8 +337,8 @@ class Design(LibrarySchema, DependencySchema):
337
337
 
338
338
  ###############################################
339
339
  def add_depfileset(self, dep: Union["Design", str],
340
- depfileset: str = None,
341
- fileset: str = None):
340
+ depfileset: Optional[str] = None,
341
+ fileset: Optional[str] = None):
342
342
  """
343
343
  Record a reference to an imported dependency's fileset.
344
344
 
@@ -388,7 +388,7 @@ class Design(LibrarySchema, DependencySchema):
388
388
 
389
389
  return self.add("fileset", fileset, "depfileset", (dep_name, depfileset))
390
390
 
391
- def get_depfileset(self, fileset: str = None):
391
+ def get_depfileset(self, fileset: Optional[str] = None):
392
392
  """
393
393
  Returns list of dependency filesets.
394
394
 
@@ -409,8 +409,8 @@ class Design(LibrarySchema, DependencySchema):
409
409
 
410
410
  def __write_flist(self,
411
411
  filename: str,
412
- filesets: List[str],
413
- depalias: Dict[str, Tuple[NamedSchema, str]],
412
+ filesets: Union[List[str], str],
413
+ depalias: Optional[Dict[Tuple[str, str], Tuple[NamedSchema, str]]],
414
414
  comments: bool = False):
415
415
  '''
416
416
  Internal helper to write a Verilog-style file list (`.f` file).
@@ -462,7 +462,7 @@ class Design(LibrarySchema, DependencySchema):
462
462
  with open(filename, "w") as f:
463
463
  f.write(content.getvalue())
464
464
 
465
- def __map_fileformat(self, path):
465
+ def __map_fileformat(self, path: str) -> str:
466
466
  '''
467
467
  Internal helper to determine file format from a file extension.
468
468
 
@@ -486,9 +486,9 @@ class Design(LibrarySchema, DependencySchema):
486
486
  ###############################################
487
487
  def write_fileset(self,
488
488
  filename: str,
489
- fileset: str = None,
490
- fileformat: str = None,
491
- depalias: Dict[str, Tuple[NamedSchema, str]] = None,
489
+ fileset: Optional[Union[Iterable[str], str]] = None,
490
+ fileformat: Optional[str] = None,
491
+ depalias: Optional[Dict[Tuple[str, str], Tuple[NamedSchema, str]]] = None,
492
492
  comments: bool = False) -> None:
493
493
  """Exports filesets to a standard formatted text file.
494
494
 
@@ -583,7 +583,7 @@ class Design(LibrarySchema, DependencySchema):
583
583
  self.set_dataroot(dataroot_name, path_dir)
584
584
  dataroots[path_dir] = dataroot_name
585
585
 
586
- def get_dataroot(path):
586
+ def get_dataroot(path: str) -> Tuple[Optional[str], Optional[str]]:
587
587
  for pdir, name in dataroots.items():
588
588
  if path.startswith(pdir):
589
589
  return name, pdir
@@ -609,8 +609,8 @@ class Design(LibrarySchema, DependencySchema):
609
609
  ################################################
610
610
  def read_fileset(self,
611
611
  filename: str,
612
- fileset: str = None,
613
- fileformat=None) -> None:
612
+ fileset: Optional[str] = None,
613
+ fileformat: Optional[str] = None) -> None:
614
614
  """Imports filesets from a standard formatted text file.
615
615
 
616
616
  Currently supports Verilog `flist` format only.
@@ -641,7 +641,13 @@ class Design(LibrarySchema, DependencySchema):
641
641
  ################################################
642
642
  # Helper Functions
643
643
  ################################################
644
- def __set_add(self, fileset, option, value, clobber=False, typelist=None, dataroot=...):
644
+ def __set_add(self,
645
+ fileset: str,
646
+ option: str,
647
+ value: Union[List[str], str],
648
+ clobber: bool = False,
649
+ typelist: Optional[List[Union[Type[str], Type[List], Type[Path]]]] = None,
650
+ dataroot: Optional[str] = ...):
645
651
  '''
646
652
  Internal helper to set or add a parameter value in the schema.
647
653
 
@@ -693,7 +699,7 @@ class Design(LibrarySchema, DependencySchema):
693
699
 
694
700
  return params
695
701
 
696
- def __get(self, fileset: str, option: str, is_file: bool = False) -> List[str]:
702
+ def __get(self, fileset: Optional[str], option: str, is_file: bool = False) -> List[str]:
697
703
  '''
698
704
  Internal helper to get a parameter value from the schema.
699
705
 
@@ -785,7 +791,7 @@ class Design(LibrarySchema, DependencySchema):
785
791
 
786
792
  def get_fileset(self,
787
793
  filesets: Union[List[str], str],
788
- alias: Dict[Tuple[str, str], Tuple[NamedSchema, str]] = None) -> \
794
+ alias: Optional[Dict[Tuple[str, str], Tuple[NamedSchema, str]]] = None) -> \
789
795
  List[Tuple[NamedSchema, str]]:
790
796
  """
791
797
  Computes the full, recursive list of (design, fileset) tuples
@@ -817,7 +823,7 @@ class Design(LibrarySchema, DependencySchema):
817
823
  ###########################################################################
818
824
  # Schema
819
825
  ###########################################################################
820
- def schema_design(schema):
826
+ def schema_design(schema: Design):
821
827
  '''
822
828
  Defines the schema parameters specific to a design.
823
829
 
@@ -829,7 +835,7 @@ def schema_design(schema):
829
835
  schema (Design): The schema object to configure.
830
836
  '''
831
837
 
832
- schema = EditableSchema(schema)
838
+ edit = EditableSchema(schema)
833
839
 
834
840
  fileset = 'default'
835
841
 
@@ -837,7 +843,7 @@ def schema_design(schema):
837
843
  # Options
838
844
  ###########################
839
845
 
840
- schema.insert(
846
+ edit.insert(
841
847
  'fileset', fileset, 'topmodule',
842
848
  Parameter(
843
849
  'str',
@@ -849,7 +855,7 @@ def schema_design(schema):
849
855
  help=trim("""
850
856
  Name of top module specified on a per fileset basis.""")))
851
857
 
852
- schema.insert(
858
+ edit.insert(
853
859
  'fileset', fileset, 'idir',
854
860
  Parameter(
855
861
  ['dir'],
@@ -863,7 +869,7 @@ def schema_design(schema):
863
869
  compilation. If multiple paths are provided, they are searched
864
870
  in the order given.""")))
865
871
 
866
- schema.insert(
872
+ edit.insert(
867
873
  'fileset', fileset, 'define',
868
874
  Parameter(
869
875
  ['str'],
@@ -876,7 +882,7 @@ def schema_design(schema):
876
882
  preprocessing, such as Verilog, C, and C++. The macro format is
877
883
  is `MACRONAME[=value]`, where [=value] is optional.""")))
878
884
 
879
- schema.insert(
885
+ edit.insert(
880
886
  'fileset', fileset, 'undefine',
881
887
  Parameter(
882
888
  ['str'],
@@ -888,7 +894,7 @@ def schema_design(schema):
888
894
  Undefines a macro that may have been previously defined via the
889
895
  compiler, options, or header files.""")))
890
896
 
891
- schema.insert(
897
+ edit.insert(
892
898
  'fileset', fileset, 'libdir',
893
899
  Parameter(
894
900
  ['dir'],
@@ -901,7 +907,7 @@ def schema_design(schema):
901
907
  :keypath:`Design,fileset,<fileset>,lib` parameter. If multiple paths are provided,
902
908
  they are searched based on the order of the libdir list.""")))
903
909
 
904
- schema.insert(
910
+ edit.insert(
905
911
  'fileset', fileset, 'lib',
906
912
  Parameter(
907
913
  ['str'],
@@ -915,7 +921,7 @@ def schema_design(schema):
915
921
  paths specified by :keypath:`Design,fileset,<fileset>,libdir` parameter.""")))
916
922
 
917
923
  name = 'default'
918
- schema.insert(
924
+ edit.insert(
919
925
  'fileset', fileset, 'param', name,
920
926
  Parameter(
921
927
  'str',
@@ -929,7 +935,7 @@ def schema_design(schema):
929
935
  coupled to tools being used. For example, in Verilog only integer
930
936
  literals (64'h4, 2'b0, 4) and strings are supported.""")))
931
937
 
932
- schema.insert(
938
+ edit.insert(
933
939
  'fileset', fileset, 'depfileset',
934
940
  Parameter(
935
941
  '[(str,str)]',
@@ -856,12 +856,12 @@ class Flowgraph(NamedSchema, DocsSchema):
856
856
 
857
857
  def _generate_doc(self, doc,
858
858
  ref_root: str = "",
859
- key_offset: Tuple[str] = None,
859
+ key_offset: Optional[Tuple[str, ...]] = None,
860
860
  detailed: bool = True):
861
861
  from .schema.docs.utils import image, build_section
862
862
 
863
863
  if not key_offset:
864
- key_offset = []
864
+ key_offset = tuple()
865
865
 
866
866
  docs = []
867
867
  image_sec = build_section("Graph", f"{ref_root}-flow-{self.name}-graph")
@@ -1,4 +1,4 @@
1
- from typing import final, Union, List, Tuple
1
+ from typing import final, Union, List, Tuple, Optional, Dict, Set, TYPE_CHECKING
2
2
 
3
3
  from siliconcompiler.schema_support.packageschema import PackageSchema
4
4
 
@@ -11,11 +11,15 @@ from siliconcompiler.schema import EditableSchema, Parameter, Scope, PerNode
11
11
  from siliconcompiler.schema.utils import trim
12
12
 
13
13
 
14
+ if TYPE_CHECKING:
15
+ from siliconcompiler import PDK
16
+
17
+
14
18
  class LibrarySchema(FileSetSchema, NamedSchema):
15
19
  """
16
20
  A class for managing library schemas.
17
21
  """
18
- def __init__(self, name: str = None):
22
+ def __init__(self, name: Optional[str] = None):
19
23
  """
20
24
  Initializes a LibrarySchema object.
21
25
 
@@ -93,7 +97,10 @@ class ToolLibrarySchema(LibrarySchema):
93
97
 
94
98
  return ToolLibrarySchema.__name__
95
99
 
96
- def _from_dict(self, manifest, keypath, version=None):
100
+ def _from_dict(self, manifest: Dict,
101
+ keypath: Union[List[str], Tuple[str, ...]],
102
+ version: Optional[Tuple[int, ...]] = None) \
103
+ -> Tuple[Set[Tuple[str, ...]], Set[Tuple[str, ...]]]:
97
104
  """
98
105
  Constructs a schema from a dictionary.
99
106
 
@@ -120,7 +127,7 @@ class ToolLibrarySchema(LibrarySchema):
120
127
  edit.insert("tool", tool, var,
121
128
  Parameter.from_dict(
122
129
  manifest["tool"][tool][var],
123
- keypath=keypath + [tool, var],
130
+ keypath=list(keypath) + [tool, var],
124
131
  version=version))
125
132
  del manifest["tool"][tool][var]
126
133
  if not manifest["tool"][tool]:
@@ -133,13 +140,13 @@ class ToolLibrarySchema(LibrarySchema):
133
140
 
134
141
  def _generate_doc(self, doc,
135
142
  ref_root: str = "",
136
- key_offset: Tuple[str] = None,
143
+ key_offset: Optional[Tuple[str, ...]] = None,
137
144
  detailed: bool = True):
138
145
  from .schema.docs.utils import build_section, strong, KeyPath, code, para, build_table
139
146
  from docutils import nodes
140
147
 
141
148
  if not key_offset:
142
- key_offset = []
149
+ key_offset = tuple()
143
150
 
144
151
  tools_added = False
145
152
  if "tool" in self.getkeys():
@@ -193,7 +200,7 @@ class StdCellLibrary(ToolLibrarySchema, DependencySchema):
193
200
  """
194
201
  A class for managing standard cell library schemas.
195
202
  """
196
- def __init__(self, name: str = None):
203
+ def __init__(self, name: Optional[str] = None):
197
204
  """
198
205
  Initializes a StdCellLibrary object.
199
206
 
@@ -291,7 +298,7 @@ class StdCellLibrary(ToolLibrarySchema, DependencySchema):
291
298
  example=["api: schema.set('asic', 'site', 'Site_12T')"],
292
299
  help="Site names for a given library architecture."))
293
300
 
294
- def add_asic_pdk(self, pdk, default: bool = True):
301
+ def add_asic_pdk(self, pdk: Union[str, "PDK"], default: bool = True):
295
302
  """
296
303
  Adds the PDK associated with this library.
297
304
 
@@ -327,7 +334,10 @@ class StdCellLibrary(ToolLibrarySchema, DependencySchema):
327
334
  """
328
335
  return self.add("asic", "stackup", stackup)
329
336
 
330
- def add_asic_libcornerfileset(self, corner: str, model: str, fileset: str = None):
337
+ def add_asic_libcornerfileset(self,
338
+ corner: str,
339
+ model: str,
340
+ fileset: Optional[Union[List[str], str]] = None):
331
341
  """
332
342
  Adds a mapping between filesets a corners defined in the library.
333
343
 
@@ -346,7 +356,8 @@ class StdCellLibrary(ToolLibrarySchema, DependencySchema):
346
356
 
347
357
  return self.add("asic", "libcornerfileset", corner, model, fileset)
348
358
 
349
- def add_asic_pexcornerfileset(self, corner: str, fileset: str = None):
359
+ def add_asic_pexcornerfileset(self, corner: str,
360
+ fileset: Optional[Union[List[str], str]] = None):
350
361
  """
351
362
  Adds a mapping between filesets a corners defined in the library.
352
363
 
@@ -404,13 +415,13 @@ class StdCellLibrary(ToolLibrarySchema, DependencySchema):
404
415
 
405
416
  def _generate_doc(self, doc,
406
417
  ref_root: str = "",
407
- key_offset: Tuple[str] = None,
418
+ key_offset: Optional[Tuple[str, ...]] = None,
408
419
  detailed: bool = True):
409
420
  from .schema.docs.utils import build_section
410
421
  docs = []
411
422
 
412
423
  if not key_offset:
413
- key_offset = ["StdCellLibrary"]
424
+ key_offset = ("StdCellLibrary",)
414
425
 
415
426
  # Show dataroot
416
427
  dataroot = PathSchema._generate_doc(self, doc, ref_root=ref_root, key_offset=key_offset)