diff --git a/masque/file/gdsii.py b/masque/file/gdsii.py index 60755d6..4837765 100644 --- a/masque/file/gdsii.py +++ b/masque/file/gdsii.py @@ -11,7 +11,7 @@ Note that GDSII references follow the same convention as `masque`, Scaling, rotation, and mirroring apply to individual instances, not grid vectors or offsets. """ -from typing import List, Any, Dict, Tuple, Callable, Union, Sequence, Iterable, Optional +from typing import List, Any, Dict, Tuple, Callable, Union, Sequence, Iterable, Optional, Sequence import re import io import copy @@ -482,13 +482,24 @@ def _labels_to_texts(labels: List[Label]) -> List[gdsii.elements.Text]: return texts -def disambiguate_pattern_names(patterns, +def disambiguate_pattern_names(patterns: Sequence[Pattern], max_name_length: int = 32, suffix_length: int = 6, - dup_warn_filter: Callable[[str,], bool] = None, # If returns False, don't warn about this name + dup_warn_filter: Optional[Callable[[str,], bool]] = None, ): + """ + Args: + patterns: List of patterns to disambiguate + max_name_length: Names longer than this will be truncated + suffix_length: Names which get truncated are truncated by this many extra characters. This is to + leave room for a suffix if one is necessary. + dup_warn_filter: (optional) Function for suppressing warnings about cell names changing. Receives + the cell name and returns `False` if the warning should be suppressed and `True` if it should + be displayed. Default displays all warnings. + """ used_names = [] for pat in patterns: + # Shorten names which already exceed max-length if len(pat.name) > max_name_length: shortened_name = pat.name[:max_name_length - suffix_length] logger.warning('Pattern name "{}" is too long ({}/{} chars),\n'.format(pat.name, len(pat.name), max_name_length) + @@ -496,8 +507,10 @@ def disambiguate_pattern_names(patterns, else: shortened_name = pat.name + # Remove invalid characters sanitized_name = re.compile('[^A-Za-z0-9_\?\$]').sub('_', shortened_name) + # Add a suffix that makes the name unique i = 0 suffixed_name = sanitized_name while suffixed_name in used_names or suffixed_name == '': @@ -513,6 +526,7 @@ def disambiguate_pattern_names(patterns, logger.warning('Pattern name "{}" ({}) appears multiple times;\n renaming to "{}"'.format( pat.name, sanitized_name, suffixed_name)) + # Encode into a byte-string and perform some final checks encoded_name = suffixed_name.encode('ASCII') if len(encoded_name) == 0: # Should never happen since zero-length names are replaced