More annotation added to the program

This commit is contained in:
2026-05-30 12:44:44 +08:00
parent b3f29398f0
commit bf223b52ac
22 changed files with 729 additions and 353 deletions
+15
View File
@@ -13,6 +13,7 @@ import yaml
@dataclass
class PdkAsset:
"""Container describing the YAML and GDS assets resolved for a PDK component."""
component: str
yaml_path: Optional[str] = None
gds_path: Optional[str] = None
@@ -23,11 +24,13 @@ class PdkRegistry:
"""Resolve public PDK component names to metadata and public GDS assets."""
def __init__(self, public_root: str, prefer_full_gds: bool = False):
"""Store the active PDK root and cache resolved component assets."""
self.public_root = os.path.abspath(public_root)
self.prefer_full_gds = prefer_full_gds
self._asset_cache = {}
def resolve(self, component: str) -> PdkAsset:
"""Resolve YAML and GDS assets for a requested component key."""
key = (component or "").strip().replace("\\", "/").strip("/")
if not key:
return PdkAsset(component=component)
@@ -42,6 +45,9 @@ class PdkRegistry:
return asset
def _find_yaml(self, key: str) -> Optional[str]:
"""Locate the component YAML description file in the active PDK tree."""
# Try direct component paths first so saved YAML component references
# resolve without scanning the whole PDK tree.
direct = os.path.join(self.public_root, *key.split("/"))
candidates = []
if direct.lower().endswith((".yml", ".yaml")):
@@ -56,6 +62,8 @@ class PdkRegistry:
return os.path.abspath(candidate)
name = key.split("/")[-1]
# Fall back to a tree scan for older saved references that only stored
# the component folder name.
for root, dirs, files in os.walk(self.public_root):
if os.path.basename(root) == name:
for filename in files:
@@ -65,8 +73,11 @@ class PdkRegistry:
return None
def _find_gds(self, key: str, yaml_path: Optional[str]) -> Optional[str]:
"""Locate the best matching GDS asset for a component YAML or key."""
search_dir = os.path.dirname(yaml_path) if yaml_path else os.path.join(self.public_root, *key.split("/"))
name = key.split("/")[-1]
# Normal users prefer black-box GDS for fast previews; manager sessions
# can prefer full layout geometry for complete export.
if self.prefer_full_gds:
candidates = [
os.path.join(search_dir, f"{name}.gds"),
@@ -80,6 +91,8 @@ class PdkRegistry:
for candidate in candidates:
if self._inside_root(candidate) and os.path.exists(candidate):
return os.path.abspath(candidate)
# If the expected filename is missing, choose the first available GDS in
# the component folder while respecting the full-vs-BB preference.
if os.path.isdir(search_dir):
gds_files = sorted(filename for filename in os.listdir(search_dir) if filename.lower().endswith(".gds"))
full_files = [filename for filename in gds_files if not filename.lower().endswith("_bb.gds")]
@@ -90,11 +103,13 @@ class PdkRegistry:
return None
def _load_yaml(self, yaml_path: Optional[str]) -> Optional[dict]:
"""Read a YAML component metadata file into a dictionary."""
if not yaml_path:
return None
with open(yaml_path, "r", encoding="utf-8") as file:
return yaml.safe_load(file) or {}
def _inside_root(self, path: str) -> bool:
"""Check that a candidate asset path remains inside the permitted PDK root."""
target = os.path.abspath(path)
return target == self.public_root or target.startswith(self.public_root + os.sep)