optionally don't sort elements

elements aren't re-ordered that often, sorting them is slow, and the
sort criteria are arbitrary, so we might want to only sort stuff by name
ordering
jan 3 weeks ago
parent 70a9c2a8ef
commit d814f3372d

@ -22,6 +22,7 @@ logger = logging.getLogger(__name__)
def preflight(
lib: Library,
sort: bool = True,
sort_elements: bool = False,
allow_dangling_refs: bool | None = None,
allow_named_layers: bool = True,
prune_empty_patterns: bool = False,
@ -32,8 +33,9 @@ def preflight(
to writing to a file (or immediately after reading).
Args:
sort: Whether to sort the patterns based on their names, and sort the pattern contents.
sort: Whether to sort the patterns based on their names, and optionaly sort the pattern contents.
Default True. Useful for reproducible builds.
sort_elements: Whether to sort the pattern contents. Requires sort=True to run.
allow_dangling_refs: If `None` (default), warns about any refs to patterns that are not
in the provided library. If `True`, no check is performed; if `False`, a `LibraryError`
is raised instead.
@ -48,7 +50,7 @@ def preflight(
"""
if sort:
lib = Library(dict(sorted(
(nn, pp.sort()) for nn, pp in lib.items()
(nn, pp.sort(sort_elements=sort_elements)) for nn, pp in lib.items()
)))
if not allow_dangling_refs:

@ -300,23 +300,33 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable):
return True
def sort(self) -> Self:
def sort(self, sort_elements: bool = True) -> Self:
"""
Sort the element dicts (shapes, labels, refs) and their contained lists.
Sort the element dicts (shapes, labels, refs) and (optionally) their contained lists.
This is primarily useful for making builds more reproducible.
Args:
sort_elements: Whether to sort all the shapes/labels/refs within each layer/target.
Returns:
self
"""
if sort_elements:
def maybe_sort(xx):
return sorted(xx)
else:
def maybe_sort(xx):
return xx
self.refs = defaultdict(list, sorted(
(tgt, sorted(rrs)) for tgt, rrs in self.refs.items()
(tgt, maybe_sort(rrs)) for tgt, rrs in self.refs.items()
))
self.labels = defaultdict(list, sorted(
((layer, sorted(lls)) for layer, lls in self.labels.items()),
((layer, maybe_sort(lls)) for layer, lls in self.labels.items()),
key=lambda tt: layer2key(tt[0]),
))
self.shapes = defaultdict(list, sorted(
((layer, sorted(sss)) for layer, sss in self.shapes.items()),
((layer, maybe_sort(sss)) for layer, sss in self.shapes.items()),
key=lambda tt: layer2key(tt[0]),
))

Loading…
Cancel
Save