Migrated from Pyrefly to ty (#33)

This commit is contained in:
Arnav Sacheti
2026-01-05 23:03:24 -08:00
committed by GitHub
parent 8cc4b838a3
commit 4a327a0290
15 changed files with 528 additions and 430 deletions

View File

@@ -22,5 +22,5 @@ jobs:
- name: Install package
run: uv sync --extra cli
- name: Run pyrefly type check
run: uvx pyrefly check src/
- name: Run ty type check
run: uvx ty check src/

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "peakrdl-busdecoder"
version = "0.6.4"
version = "0.6.5"
requires-python = ">=3.10"
dependencies = [
"jinja2~=3.1",
@@ -65,7 +65,7 @@ test = [
"cocotb>=1.8.0",
"cocotb-bus>=0.2.1",
]
tools = ["pyrefly>=0.37.0", "ruff>=0.14.0"]
tools = ["ty>=0.0.7", "ruff>=0.14.0"]
[project.entry-points."peakrdl.exporters"]
busdecoder = "peakrdl_busdecoder.__peakrdl__:Exporter"
@@ -100,15 +100,12 @@ ignore = [
quote-style = "double"
indent-style = "space"
# ---------------------- PYREFLY ----------------------
[tool.pyrefly]
# ---------------------- TY ----------------------
[tool.ty.environment]
python-version = "3.10"
# Default behavior: check bodies of untyped defs & infer return types.
untyped-def-behavior = "check-and-infer-return-type"
project-includes = ["src/**/*"]
project-excludes = ["**/__pycache__", "**/*venv/**/*"]
[tool.ty.src]
include = ["src"]
# ---------------------- PYTEST ----------------------
[tool.pytest.ini_options]

View File

@@ -1,3 +1,5 @@
from __future__ import annotations
import functools
from typing import TYPE_CHECKING, Any
@@ -69,7 +71,7 @@ class Exporter(ExporterSubcommandPlugin):
def get_cpuifs(self) -> dict[str, type[BaseCpuif]]:
return get_cpuifs(map(tuple, self.cfg["cpuifs"].items()))
def add_exporter_arguments(self, arg_group: "argparse.ArgumentParser") -> None: # type: ignore
def add_exporter_arguments(self, arg_group: argparse._ActionsContainer) -> None:
cpuifs = self.get_cpuifs()
arg_group.add_argument(
@@ -122,7 +124,7 @@ class Exporter(ExporterSubcommandPlugin):
""",
)
def do_export(self, top_node: "AddrmapNode", options: "argparse.Namespace") -> None:
def do_export(self, top_node: AddrmapNode, options: argparse.Namespace) -> None:
cpuifs = self.get_cpuifs()
x = BusDecoderExporter()

View File

@@ -45,7 +45,7 @@ class APB3Cpuif(BaseCpuif):
fanout[self.signal("PADDR", node, "gi")] = self.signal("PADDR")
fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data"
return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items()))
return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
def fanin(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {}
@@ -64,7 +64,7 @@ class APB3Cpuif(BaseCpuif):
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
def readback(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {}
@@ -80,7 +80,7 @@ class APB3Cpuif(BaseCpuif):
else:
fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
def fanin_intermediate_assignments(
self, node: AddressableNode, inst_name: str, array_idx: str, master_prefix: str, indexed_path: str

View File

@@ -51,7 +51,7 @@ class APB3CpuifFlat(BaseCpuif):
fanout[self.signal("PADDR", node, "gi")] = f"{{{'-'.join(addr_comp)}}}[{clog2(node.size) - 1}:0]"
fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data"
return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items()))
return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
def fanin(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {}
@@ -62,7 +62,7 @@ class APB3CpuifFlat(BaseCpuif):
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
def readback(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {}
@@ -71,4 +71,4 @@ class APB3CpuifFlat(BaseCpuif):
else:
fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())

View File

@@ -48,7 +48,7 @@ class APB4Cpuif(BaseCpuif):
fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data"
fanout[self.signal("PSTRB", node, "gi")] = "cpuif_wr_byte_en"
return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items()))
return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
def fanin(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {}
@@ -67,7 +67,7 @@ class APB4Cpuif(BaseCpuif):
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
def readback(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {}
@@ -83,7 +83,7 @@ class APB4Cpuif(BaseCpuif):
else:
fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
def fanin_intermediate_assignments(
self, node: AddressableNode, inst_name: str, array_idx: str, master_prefix: str, indexed_path: str

View File

@@ -53,7 +53,7 @@ class APB4CpuifFlat(BaseCpuif):
fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data"
fanout[self.signal("PSTRB", node, "gi")] = "cpuif_wr_byte_en"
return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items()))
return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
def fanin(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {}
@@ -64,7 +64,7 @@ class APB4CpuifFlat(BaseCpuif):
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
def readback(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {}
@@ -73,4 +73,4 @@ class APB4CpuifFlat(BaseCpuif):
else:
fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())

View File

@@ -82,15 +82,15 @@ class BaseCpuif:
loader=loader,
undefined=jj.StrictUndefined,
)
jj_env.tests["array"] = self.check_is_array # type: ignore
jj_env.filters["clog2"] = clog2 # type: ignore
jj_env.filters["is_pow2"] = is_pow2 # type: ignore
jj_env.filters["roundup_pow2"] = roundup_pow2 # type: ignore
jj_env.filters["address_slice"] = self.get_address_slice # type: ignore
jj_env.filters["get_path"] = lambda x: get_indexed_path(self.exp.ds.top_node, x, "i") # type: ignore
jj_env.filters["walk"] = self.exp.walk # type: ignore
jj_env.tests["array"] = self.check_is_array
jj_env.filters["clog2"] = clog2
jj_env.filters["is_pow2"] = is_pow2
jj_env.filters["roundup_pow2"] = roundup_pow2
jj_env.filters["address_slice"] = self.get_address_slice
jj_env.filters["get_path"] = lambda x: get_indexed_path(self.exp.ds.top_node, x, "i")
jj_env.filters["walk"] = self.exp.walk
context = { # type: ignore
context = {
"cpuif": self,
"ds": self.exp.ds,
"fanout": FanoutGenerator,

View File

@@ -78,7 +78,7 @@ class SVInterface(Interface):
# When unrolled, current_idx is set - append it to the name
if child.current_idx is not None:
base = f"{base}_{'_'.join(map(str, child.current_idx))}"
base = f"{base}_{'_'.join(map(str, child.current_idx))}" # ty: ignore
# Only add array dimensions if this should be treated as an array
if self.cpuif.check_is_array(child):

View File

@@ -58,9 +58,9 @@ class BusDecoderExporter:
loader=c_loader,
undefined=jj.StrictUndefined,
)
self.jj_env.filters["kwf"] = kwf # type: ignore
self.jj_env.filters["walk"] = self.walk # type: ignore
self.jj_env.filters["clog2"] = clog2 # type: ignore
self.jj_env.filters["kwf"] = kwf
self.jj_env.filters["walk"] = self.walk
self.jj_env.filters["clog2"] = clog2
def export(self, node: RootNode | AddrmapNode, output_dir: str, **kwargs: Unpack[ExporterKwargs]) -> None:
"""
@@ -98,7 +98,7 @@ class BusDecoderExporter:
else:
top_node = node
self.ds = DesignState(top_node, kwargs)
self.ds = DesignState(top_node, kwargs) # ty: ignore
cpuif_cls: type[BaseCpuif] = kwargs.pop("cpuif_cls", None) or APB4Cpuif
@@ -113,7 +113,7 @@ class BusDecoderExporter:
DesignValidator(self).do_validate()
# Build Jinja template context
context = { # type: ignore
context = {
"version": version("peakrdl-busdecoder"),
"cpuif": self.cpuif,
"cpuif_decode": DecodeLogicGenerator,

View File

@@ -62,7 +62,6 @@ def ref_is_internal(top_node: AddrmapNode, ref: Node | PropertyReference) -> boo
else:
current_node = ref
# pyrefly: ignore[bad-assignment] - false positive due to circular type checking
while current_node is not None:
if current_node == top_node:
# reached top node without finding any external components

View File

@@ -74,7 +74,9 @@ class DesignValidator(RDLListener):
f"instance '{node.inst_name}' must be a multiple of {alignment}",
node.inst.inst_src_ref,
)
if node.is_array and (node.array_stride % alignment) != 0: # type: ignore # is_array implies stride is not none
if node.is_array and (
node.array_stride is not None and (node.array_stride % alignment) != 0
): # is_array implies stride is not none
self.msg.error(
"Unaligned registers are not supported. Address stride of "
f"instance array '{node.inst_name}' must be a multiple of {alignment}",

View File

@@ -170,7 +170,7 @@ def prepare_cpuif_case(
compiler = RDLCompiler()
compiler.compile_file(rdl_source)
root = compiler.elaborate(top_name)
top_node = root.top # type: ignore[assignment]
top_node = root.top
export_kwargs: dict[str, Any] = {"cpuif_cls": cpuif_cls}
if exporter_kwargs:

View File

@@ -28,7 +28,7 @@ class TestDecodeLogicGenerator:
# Basic sanity check - it should initialize
assert gen is not None
assert gen._flavor == DecodeLogicFlavor.READ # type: ignore
assert gen._flavor == DecodeLogicFlavor.READ
def test_decode_logic_write(self, compile_rdl: Callable[..., AddrmapNode]) -> None:
"""Test decode logic generation for write operations."""
@@ -48,7 +48,7 @@ class TestDecodeLogicGenerator:
gen = DecodeLogicGenerator(ds, DecodeLogicFlavor.WRITE)
assert gen is not None
assert gen._flavor == DecodeLogicFlavor.WRITE # type: ignore
assert gen._flavor == DecodeLogicFlavor.WRITE
def test_cpuif_addr_predicate(self, compile_rdl: Callable[..., AddrmapNode]) -> None:
"""Test address predicate generation."""

870
uv.lock generated

File diff suppressed because it is too large Load Diff