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 - name: Install package
run: uv sync --extra cli run: uv sync --extra cli
- name: Run pyrefly type check - name: Run ty type check
run: uvx pyrefly check src/ run: uvx ty check src/

View File

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

View File

@@ -1,3 +1,5 @@
from __future__ import annotations
import functools import functools
from typing import TYPE_CHECKING, Any from typing import TYPE_CHECKING, Any
@@ -69,7 +71,7 @@ class Exporter(ExporterSubcommandPlugin):
def get_cpuifs(self) -> dict[str, type[BaseCpuif]]: def get_cpuifs(self) -> dict[str, type[BaseCpuif]]:
return get_cpuifs(map(tuple, self.cfg["cpuifs"].items())) 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() cpuifs = self.get_cpuifs()
arg_group.add_argument( 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() cpuifs = self.get_cpuifs()
x = BusDecoderExporter() x = BusDecoderExporter()

View File

@@ -45,7 +45,7 @@ class APB3Cpuif(BaseCpuif):
fanout[self.signal("PADDR", node, "gi")] = self.signal("PADDR") fanout[self.signal("PADDR", node, "gi")] = self.signal("PADDR")
fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data" 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: def fanin(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {} fanin: dict[str, str] = {}
@@ -64,7 +64,7 @@ class APB3Cpuif(BaseCpuif):
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i") fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
fanin["cpuif_rd_err"] = self.signal("PSLVERR", 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: def readback(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {} fanin: dict[str, str] = {}
@@ -80,7 +80,7 @@ class APB3Cpuif(BaseCpuif):
else: else:
fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i") 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( def fanin_intermediate_assignments(
self, node: AddressableNode, inst_name: str, array_idx: str, master_prefix: str, indexed_path: str 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("PADDR", node, "gi")] = f"{{{'-'.join(addr_comp)}}}[{clog2(node.size) - 1}:0]"
fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data" 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: def fanin(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {} fanin: dict[str, str] = {}
@@ -62,7 +62,7 @@ class APB3CpuifFlat(BaseCpuif):
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i") fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
fanin["cpuif_rd_err"] = self.signal("PSLVERR", 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: def readback(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {} fanin: dict[str, str] = {}
@@ -71,4 +71,4 @@ class APB3CpuifFlat(BaseCpuif):
else: else:
fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i") 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("PWDATA", node, "gi")] = "cpuif_wr_data"
fanout[self.signal("PSTRB", node, "gi")] = "cpuif_wr_byte_en" 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: def fanin(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {} fanin: dict[str, str] = {}
@@ -67,7 +67,7 @@ class APB4Cpuif(BaseCpuif):
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i") fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
fanin["cpuif_rd_err"] = self.signal("PSLVERR", 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: def readback(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {} fanin: dict[str, str] = {}
@@ -83,7 +83,7 @@ class APB4Cpuif(BaseCpuif):
else: else:
fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i") 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( def fanin_intermediate_assignments(
self, node: AddressableNode, inst_name: str, array_idx: str, master_prefix: str, indexed_path: str 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("PWDATA", node, "gi")] = "cpuif_wr_data"
fanout[self.signal("PSTRB", node, "gi")] = "cpuif_wr_byte_en" 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: def fanin(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {} fanin: dict[str, str] = {}
@@ -64,7 +64,7 @@ class APB4CpuifFlat(BaseCpuif):
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i") fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
fanin["cpuif_rd_err"] = self.signal("PSLVERR", 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: def readback(self, node: AddressableNode | None = None) -> str:
fanin: dict[str, str] = {} fanin: dict[str, str] = {}
@@ -73,4 +73,4 @@ class APB4CpuifFlat(BaseCpuif):
else: else:
fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i") 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, loader=loader,
undefined=jj.StrictUndefined, undefined=jj.StrictUndefined,
) )
jj_env.tests["array"] = self.check_is_array # type: ignore jj_env.tests["array"] = self.check_is_array
jj_env.filters["clog2"] = clog2 # type: ignore jj_env.filters["clog2"] = clog2
jj_env.filters["is_pow2"] = is_pow2 # type: ignore jj_env.filters["is_pow2"] = is_pow2
jj_env.filters["roundup_pow2"] = roundup_pow2 # type: ignore jj_env.filters["roundup_pow2"] = roundup_pow2
jj_env.filters["address_slice"] = self.get_address_slice # type: ignore 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") # type: ignore jj_env.filters["get_path"] = lambda x: get_indexed_path(self.exp.ds.top_node, x, "i")
jj_env.filters["walk"] = self.exp.walk # type: ignore jj_env.filters["walk"] = self.exp.walk
context = { # type: ignore context = {
"cpuif": self, "cpuif": self,
"ds": self.exp.ds, "ds": self.exp.ds,
"fanout": FanoutGenerator, "fanout": FanoutGenerator,

View File

@@ -78,7 +78,7 @@ class SVInterface(Interface):
# When unrolled, current_idx is set - append it to the name # When unrolled, current_idx is set - append it to the name
if child.current_idx is not None: 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 # Only add array dimensions if this should be treated as an array
if self.cpuif.check_is_array(child): if self.cpuif.check_is_array(child):

View File

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

View File

@@ -62,7 +62,6 @@ def ref_is_internal(top_node: AddrmapNode, ref: Node | PropertyReference) -> boo
else: else:
current_node = ref current_node = ref
# pyrefly: ignore[bad-assignment] - false positive due to circular type checking
while current_node is not None: while current_node is not None:
if current_node == top_node: if current_node == top_node:
# reached top node without finding any external components # 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}", f"instance '{node.inst_name}' must be a multiple of {alignment}",
node.inst.inst_src_ref, 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( self.msg.error(
"Unaligned registers are not supported. Address stride of " "Unaligned registers are not supported. Address stride of "
f"instance array '{node.inst_name}' must be a multiple of {alignment}", 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 = RDLCompiler()
compiler.compile_file(rdl_source) compiler.compile_file(rdl_source)
root = compiler.elaborate(top_name) 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} export_kwargs: dict[str, Any] = {"cpuif_cls": cpuif_cls}
if exporter_kwargs: if exporter_kwargs:

View File

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

870
uv.lock generated

File diff suppressed because it is too large Load Diff