From 1935c220dc6796bde467b8dbdb7ec759018cb265 Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Thu, 1 Aug 2024 00:24:46 -0700 Subject: [PATCH 1/8] explicit re-exports --- snarled/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/snarled/__init__.py b/snarled/__init__.py index f0baef8..86944c6 100644 --- a/snarled/__init__.py +++ b/snarled/__init__.py @@ -12,7 +12,10 @@ has deprived the man of a schematic and a better connectivity tool. The main functionality is in `trace`. `__main__.py` details the command-line interface. """ -from .trace import trace_layout, TraceAnalysis +from .trace import ( + trace_layout as trace_layout, + TraceAnalysis as TraceAnalysis, + ) __author__ = 'Jan Petykiewicz' __version__ = '1.0' From 2d174f7a1d1567369f605ea7bc421bfbecadf015 Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Thu, 1 Aug 2024 00:33:43 -0700 Subject: [PATCH 2/8] add ruff config --- pyproject.toml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 85c290a..c3e7355 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,3 +54,40 @@ path = "snarled/__init__.py" [project.scripts] snarled = "snarled.main:main" + + +[tool.ruff] +exclude = [ + ".git", + "dist", + ] +line-length = 145 +indent-width = 4 +lint.dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" +lint.select = [ + "NPY", "E", "F", "W", "B", "ANN", "UP", "SLOT", "SIM", "LOG", + "C4", "ISC", "PIE", "PT", "RET", "TCH", "PTH", "INT", + "ARG", "PL", "R", "TRY", + "G010", "G101", "G201", "G202", + "Q002", "Q003", "Q004", + ] +lint.ignore = [ + #"ANN001", # No annotation + "ANN002", # *args + "ANN003", # **kwargs + "ANN401", # Any + "ANN101", # self: Self + "SIM108", # single-line if / else assignment + "RET504", # x=y+z; return x + "PIE790", # unnecessary pass + "ISC003", # non-implicit string concatenation + "C408", # dict(x=y) instead of {'x': y} + "PLR09", # Too many xxx + "PLR2004", # magic number + "PLC0414", # import x as x + "TRY003", # Long exception message + "PTH123", # open() + "UP015", # open(..., 'rt') + "PLW2901", # overwriting loop var + ] + From 012a24237972177e7d6a8433d55db3f475ebb5f8 Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Thu, 1 Aug 2024 00:33:56 -0700 Subject: [PATCH 3/8] bump req versions --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c3e7355..868c432 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,10 +42,10 @@ classifiers = [ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)", ] -requires-python = ">=3.10" +requires-python = ">=3.11" dynamic = ["version"] dependencies = [ - "klayout~=0.28", + "klayout~=0.29", ] From a3978b5f5e4416ef6aa11caa9ae5425f63c35c1d Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Thu, 1 Aug 2024 00:34:31 -0700 Subject: [PATCH 4/8] improve error handling --- snarled/trace.py | 5 +++-- snarled/utils.py | 34 +++++++++++++++++++--------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/snarled/trace.py b/snarled/trace.py index a7d0d9b..ebb8e00 100644 --- a/snarled/trace.py +++ b/snarled/trace.py @@ -5,6 +5,7 @@ from itertools import chain from klayout import db from .types import lnum_t, layer_t +from .utils import SnarledError logger = logging.getLogger(__name__) @@ -165,8 +166,8 @@ def trace_layout( # Merge labels from a separate layout if asked if lfile_path: if not lfile_map: - raise Exception('Asked to load labels from a separate file, but no ' - 'label layers were specified in lfile_map') + raise SnarledError('Asked to load labels from a separate file, but no ' + + 'label layers were specified in lfile_map') if lfile_layer_map is None: lfile_layer_map = layer_map diff --git a/snarled/utils.py b/snarled/utils.py index 3274755..752d61e 100644 --- a/snarled/utils.py +++ b/snarled/utils.py @@ -5,6 +5,10 @@ from .types import layer_t logger = logging.getLogger(__name__) +class SnarledError(Exception): + pass + + def strip_underscored_label(string: str) -> str: """ If the label ends in an underscore followed by an integer, strip @@ -50,18 +54,18 @@ def read_layermap(path: str) -> dict[str, tuple[int, int]]: for cc in '*-()': if cc in line: - raise Exception(f'Failed to read layermap on line {nn} due to special character "{cc}"') + raise SnarledError(f'Failed to read layermap on line {nn} due to special character "{cc}"') for cc in ':/': if cc not in line: - raise Exception(f'Failed to read layermap on line {nn}; missing "{cc}"') + raise SnarledError(f'Failed to read layermap on line {nn}; missing "{cc}"') try: layer_part, name = line.split(':') layer_nums = str2lnum(layer_part) - except Exception as err: - logger.error(f'Layer map read failed on line {nn}') - raise err + except Exception: + logger.exception(f'Layer map read failed on line {nn}') + raise layer_map[name.strip()] = layer_nums @@ -101,7 +105,7 @@ def read_connectivity(path: str) -> list[tuple[layer_t, layer_t | None, layer_t] parts = line.split(',') if len(parts) not in (2, 3): - raise Exception(f'Too many commas in connectivity spec on line {nn}') + raise SnarledError(f'Too many commas in connectivity spec on line {nn}') layers = [] for part in parts: @@ -109,13 +113,13 @@ def read_connectivity(path: str) -> list[tuple[layer_t, layer_t | None, layer_t] if '/' in part: try: layer = str2lnum(part) - except Exception as err: - logger.error(f'Connectivity spec read failed on line {nn}') - raise err + except Exception: + logger.exception(f'Connectivity spec read failed on line {nn}') + raise else: layer = part.strip() if not layer: - raise Exception(f'Empty layer in connectivity spec on line {nn}') + raise SnarledError(f'Empty layer in connectivity spec on line {nn}') layers.append(layer) if len(layers) == 2: @@ -156,7 +160,7 @@ def read_remap(path: str) -> dict[layer_t, layer_t]: parts = line.split(':') if len(parts) != 2: - raise Exception(f'Too many commas in layer remap spec on line {nn}') + raise SnarledError(f'Too many commas in layer remap spec on line {nn}') layers = [] for part in parts: @@ -164,13 +168,13 @@ def read_remap(path: str) -> dict[layer_t, layer_t]: if '/' in part: try: layer = str2lnum(part) - except Exception as err: - logger.error(f'Layer remap spec read failed on line {nn}') - raise err + except Exception: + logger.exception(f'Layer remap spec read failed on line {nn}') + raise else: layer = part.strip() if not layer: - raise Exception(f'Empty layer in layer remap spec on line {nn}') + raise SnarledError(f'Empty layer in layer remap spec on line {nn}') layers.append(layer) remap[layers[0]] = layers[1] From 7c718401d4d8238b4c7e25d5244f2ce977d26e6e Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Thu, 1 Aug 2024 00:34:52 -0700 Subject: [PATCH 5/8] flatten indentation (unnecessary else) --- snarled/trace.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/snarled/trace.py b/snarled/trace.py index ebb8e00..8876623 100644 --- a/snarled/trace.py +++ b/snarled/trace.py @@ -276,9 +276,8 @@ def _get_topcell( """ if name is None: return layout.top_cell() - else: - ind = layout.cell_by_name(name) - return layout.cell(ind) + ind = layout.cell_by_name(name) + return layout.cell(ind) def _write_net_layout( From 22f8015b828224e7b6cd864cb8017e271656cb57 Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Thu, 1 Aug 2024 00:35:03 -0700 Subject: [PATCH 6/8] explicit non-strict zip --- snarled/trace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snarled/trace.py b/snarled/trace.py index 8876623..43da7c0 100644 --- a/snarled/trace.py +++ b/snarled/trace.py @@ -248,7 +248,7 @@ def trace_layout( # # Return merged nets # - top_circuits = [cc for cc, _ in zip(nl.each_circuit_top_down(), range(nl.top_circuit_count()))] + top_circuits = [cc for cc, _ in zip(nl.each_circuit_top_down(), range(nl.top_circuit_count()), strict=False)] # Nets with more than one label get their labels joined with a comma nets = [ From bb9552ce1fbbf60bec5361b6b31504a602f558ea Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Thu, 1 Aug 2024 00:35:41 -0700 Subject: [PATCH 7/8] modernize type imports --- snarled/trace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snarled/trace.py b/snarled/trace.py index 43da7c0..7a436ba 100644 --- a/snarled/trace.py +++ b/snarled/trace.py @@ -1,4 +1,4 @@ -from typing import Sequence, Iterable +from collections.abc import Sequence, Iterable import logging from collections import Counter from itertools import chain From ceaebeb4c719b7c03880b53355b3cd74743c06fb Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Thu, 1 Aug 2024 00:35:48 -0700 Subject: [PATCH 8/8] no need for .keys() --- snarled/trace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snarled/trace.py b/snarled/trace.py index 7a436ba..316f049 100644 --- a/snarled/trace.py +++ b/snarled/trace.py @@ -200,7 +200,7 @@ def trace_layout( # Create l2n text layers layer2texts = {} - for layer in labels_map.keys(): + for layer in labels_map: if isinstance(layer, str): layer = layer_map[layer] klayer = layout.layer(*layer)