Skip to content

Commit

Permalink
Fix type hinting
Browse files Browse the repository at this point in the history
  • Loading branch information
amykyta3 committed Jan 3, 2025
1 parent d4411a5 commit cffc9dc
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 55 deletions.
6 changes: 3 additions & 3 deletions src/peakrdl_cheader/__peakrdl__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Union

from peakrdl.plugins.exporter import ExporterSubcommandPlugin #pylint: disable=import-error
from peakrdl.config import schema #pylint: disable=import-error
Expand Down Expand Up @@ -76,8 +76,8 @@ def add_exporter_arguments(self, arg_group: 'argparse._ActionsContainer') -> Non
)

# Wrap constructor to allow hex strings
def integer(n):
return int(n, 0)
def integer(n: Union[int, str]) -> int:
return int(n, 0) # type: ignore # bogus error

arg_group.add_argument(
"--inst-offset",
Expand Down
4 changes: 2 additions & 2 deletions src/peakrdl_cheader/design_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def __init__(self, ds: DesignState) -> None:
self.ds = ds
self.msg = ds.top_node.env.msg

self.prev_reg_stack: List[RegNode]
self.prev_reg_stack: List[Optional[RegNode]]
self.prev_reg_stack = []

@property
Expand Down Expand Up @@ -83,7 +83,7 @@ def enter_Reg(self, node: RegNode) -> Optional[WalkerAction]:
self.ds.overlapping_reg_pairs[prev_reg.get_path()] = node.inst_name

# Check for sparse register arrays
if node.is_array and node.array_stride > node.size:
if node.is_array and node.array_stride > node.size: # type: ignore # is_array implies array_stride is not none
self.msg.error(
"C header export does not support sparse arrays of registers. "
f"See register: '{node.inst_name}.'",
Expand Down
31 changes: 16 additions & 15 deletions src/peakrdl_cheader/header_generator.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
from typing import TextIO, Set, Optional, List
from typing import TextIO, Set, Optional, List, Union
import os
import re

from systemrdl.walker import RDLListener, RDLWalker, WalkerAction
from systemrdl.node import AddrmapNode, AddressableNode, RegNode, FieldNode, Node, MemNode
from systemrdl.node import AddrmapNode, AddressableNode, RegNode, FieldNode, Node, MemNode, RegfileNode

from .design_state import DesignState
from .identifier_filter import kw_filter as kwf
from . import utils

class HeaderGenerator(RDLListener):
root_node: Union[AddrmapNode, MemNode, RegfileNode]
f: TextIO

def __init__(self, ds: DesignState) -> None:
self.ds = ds

self.defined_namespace: Set[str]
self.defined_namespace = set()
self.indent_level = 0

self.root_node: AddrmapNode
self.root_node = None

self.f: TextIO
self.f = None # type: ignore

def run(self, path: str, top_nodes: List[AddrmapNode]) -> None:
def run(self, path: str, top_nodes: List[Union[AddrmapNode, MemNode, RegfileNode]]) -> None:
with open(path, "w", encoding='utf-8') as f:
self.f = f

Expand All @@ -36,7 +33,7 @@ def run(self, path: str, top_nodes: List[AddrmapNode]) -> None:

# Stream header via jinja
template = self.ds.jj_env.get_template("header.h")
template.stream(context).dump(f)
template.stream(context).dump(f) # type: ignore # jinja incorrectly typed
f.write("\n")

# Generate definitions
Expand All @@ -50,7 +47,7 @@ def run(self, path: str, top_nodes: List[AddrmapNode]) -> None:
for node in top_nodes:
addr = node.raw_absolute_address + self.ds.inst_offset
type_name = utils.get_struct_name(self.ds, node, node)
if node.is_array:
if node.array_dimensions:
if len(node.array_dimensions) > 1:
node.env.msg.fatal(
f"C header generator does not support instance defines for multi-dimensional arrays: {node.inst_name}{node.array_dimensions}",
Expand All @@ -62,7 +59,7 @@ def run(self, path: str, top_nodes: List[AddrmapNode]) -> None:

# Stream footer via jinja
template = self.ds.jj_env.get_template("footer.h")
template.stream(context).dump(f)
template.stream(context).dump(f) # type: ignore # jinja incorrectly typed

# Ensure newline before EOF
f.write("\n")
Expand Down Expand Up @@ -281,11 +278,14 @@ def write_block(self, node: AddressableNode) -> None:
# Check if register is overlapping first
partner_reg_name = self.ds.overlapping_reg_pairs.get(child.get_path(), None)
if partner_reg_name:
partner_reg = node.get_child_by_name(partner_reg_name)
assert isinstance(partner_reg, RegNode)

# Two registers occupy the same space
self.write("union {\n")
self.push_indent()
self.write_reg_struct_member(child)
self.write_reg_struct_member(node.get_child_by_name(partner_reg_name))
self.write_reg_struct_member(partner_reg)
self.pop_indent()
if self.ds.std.anon_unions:
self.write("};\n")
Expand All @@ -301,6 +301,7 @@ def write_block(self, node: AddressableNode) -> None:

# Write end padding as needed
if node.is_array:
assert node.array_stride is not None
padding = node.array_stride - current_offset
else:
padding = node.size - current_offset
Expand All @@ -316,7 +317,7 @@ def write_byte_padding(self, start_offset: int, size: int) -> None:


def write_reg_struct_member(self, node: RegNode) -> None:
if node.is_array:
if node.array_dimensions:
array_suffix = "".join(f"[{dim}]" for dim in node.array_dimensions)
else:
array_suffix = ""
Expand All @@ -336,7 +337,7 @@ def write_reg_struct_member(self, node: RegNode) -> None:


def write_group_struct_member(self, node: AddressableNode) -> None:
if node.is_array:
if node.array_dimensions:
array_suffix = "".join(f"[{dim}]" for dim in node.array_dimensions)
else:
array_suffix = ""
Expand Down
29 changes: 12 additions & 17 deletions src/peakrdl_cheader/testcase_generator.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import List, TextIO, Set, Match
from typing import List, TextIO, Set, Match, Union
import os
import re

from systemrdl.walker import RDLListener, RDLWalker
from systemrdl.node import AddrmapNode, RegNode, AddressableNode
from systemrdl.node import AddrmapNode, RegNode, AddressableNode, MemNode, RegfileNode

from .design_state import DesignState
from . import utils
Expand All @@ -13,7 +13,7 @@ class TestcaseGenerator:
def __init__(self, ds: DesignState) -> None:
self.ds = ds

def run(self, header_path: str, top_nodes: List[AddrmapNode]) -> None:
def run(self, header_path: str, top_nodes: List[Union[AddrmapNode, MemNode, RegfileNode]]) -> None:
testcase_path = header_path + ".test.c"
with open(testcase_path, "w", encoding='utf-8') as f:

Expand All @@ -24,7 +24,7 @@ def run(self, header_path: str, top_nodes: List[AddrmapNode]) -> None:

# Stream header via jinja
template = self.ds.jj_env.get_template("test_header.c")
template.stream(context).dump(f)
template.stream(context).dump(f) # type: ignore # jinja incorrectly typed
f.write("\n\n")

OffsetTestsGenerator(self.ds).run(f, top_nodes)
Expand All @@ -36,24 +36,21 @@ def run(self, header_path: str, top_nodes: List[AddrmapNode]) -> None:


class OffsetTestsGenerator(RDLListener):
root_node: Union[AddrmapNode, MemNode, RegfileNode]
f: TextIO

def __init__(self, ds: DesignState) -> None:
self.ds = ds

self.indent_level = 0

self.root_node: AddrmapNode
self.root_node = None

self.root_struct_name: str
self.root_struct_name = ""

self.f: TextIO
self.f = None # type: ignore

self.overlap_pair_stack: List[List[str]]
self.overlap_pair_stack = []

def run(self, f: TextIO, top_nodes: List[AddrmapNode]) -> None:
def run(self, f: TextIO, top_nodes: List[Union[AddrmapNode, MemNode, RegfileNode]]) -> None:
self.f = f

f.write("static void test_offsets(void){\n")
Expand Down Expand Up @@ -138,6 +135,9 @@ def kwrepl(m: Match) -> str:


class BitfieldTestsGenerator(RDLListener):
root_node: Union[AddrmapNode, MemNode, RegfileNode]
f: TextIO

def __init__(self, ds: DesignState) -> None:
self.ds = ds

Expand All @@ -146,13 +146,8 @@ def __init__(self, ds: DesignState) -> None:
self.defined_namespace: Set[str]
self.defined_namespace = set()

self.root_node: AddrmapNode
self.root_node = None

self.f: TextIO
self.f = None # type: ignore

def run(self, f: TextIO, top_nodes: List[AddrmapNode]) -> None:
def run(self, f: TextIO, top_nodes: List[Union[AddrmapNode, MemNode, RegfileNode]]) -> None:
self.f = f

f.write("static void test_bitfields(void){\n")
Expand Down
12 changes: 7 additions & 5 deletions src/peakrdl_cheader/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from systemrdl.node import AddressableNode, AddrmapNode, Node
from typing import Union

from systemrdl.node import AddressableNode, AddrmapNode, Node, MemNode, RegfileNode
from .design_state import DesignState

def get_node_prefix(ds: DesignState, root_node: AddrmapNode, node: AddressableNode) -> str:
def get_node_prefix(ds: DesignState, root_node: Union[AddrmapNode, MemNode, RegfileNode], node: AddressableNode) -> str:
if ds.reuse_typedefs:
prefix = node.get_global_type_name("__")
if prefix is None:
Expand All @@ -23,8 +25,8 @@ def get_node_prefix(ds: DesignState, root_node: AddrmapNode, node: AddressableNo
return prefix


def get_struct_name(ds: DesignState, root_node: AddrmapNode, node: AddressableNode) -> str:
if node.is_array and node.array_stride > node.size:
def get_struct_name(ds: DesignState, root_node: Union[AddrmapNode, MemNode, RegfileNode], node: AddressableNode) -> str:
if node.is_array and node.array_stride > node.size: # type: ignore # is_array implies array_stride is not none
# Stride is larger than size of actual element.
# Struct will be padded up, and therefore needs a unique name
pad_suffix = f"__stride{node.array_stride:x}"
Expand All @@ -34,7 +36,7 @@ def get_struct_name(ds: DesignState, root_node: AddrmapNode, node: AddressableNo
return get_node_prefix(ds, root_node, node) + pad_suffix + "_t"


def get_friendly_name(ds: DesignState, root_node: AddrmapNode, node: Node) -> str:
def get_friendly_name(ds: DesignState, root_node: Union[AddrmapNode, MemNode, RegfileNode], node: Node) -> str:
"""
Returns a useful string that helps identify the typedef in
a comment
Expand Down
16 changes: 6 additions & 10 deletions tests/mypy.ini
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
[mypy]
namespace_packages = True
explicit_package_bases = True

[mypy-systemrdl.*]
# Ignore missing py.typed in release
ignore_missing_imports = True

[mypy-peakrdl.*]
# Ignore missing py.typed in release
ignore_missing_imports = True
disallow_incomplete_defs = True
disallow_untyped_defs = True
warn_unused_configs = True
warn_unused_ignores = True
warn_unreachable = True
disallow_untyped_calls = True
3 changes: 0 additions & 3 deletions tests/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ pip install -r requirements.txt
pip install -U ../

# Run unit tests
export SKIP_SYNTH_TESTS=1
#export STUB_SIMULATOR=1
export NO_XSIM=1
pytest -n auto --cov=peakrdl_cheader

# Generate coverage report
Expand Down

0 comments on commit cffc9dc

Please sign in to comment.