diff --git a/adafruit_pioasm.py b/adafruit_pioasm.py index 8ed258a..514d1ba 100644 --- a/adafruit_pioasm.py +++ b/adafruit_pioasm.py @@ -11,6 +11,11 @@ * Author(s): Scott Shawcroft """ +try: + from typing import List, MutableSequence +except ImportError: + pass + import array import re @@ -40,14 +45,14 @@ class Program: # pylint: disable=too-few-public-methods """ - def __init__(self, text_program: str, *, build_debuginfo=False) -> None: + def __init__(self, text_program: str, *, build_debuginfo: bool = False) -> None: """Converts pioasm text to encoded instruction bytes""" # pylint: disable=too-many-branches,too-many-statements,too-many-locals - assembled = [] + assembled: List[int] = [] program_name = None labels = {} linemap = [] - instructions = [] + instructions: List[str] = [] sideset_count = 0 sideset_enable = 0 wrap = None @@ -86,9 +91,8 @@ def __init__(self, text_program: str, *, build_debuginfo=False) -> None: max_delay = 2 ** (5 - sideset_count - sideset_enable) - 1 assembled = [] - for instruction in instructions: - # print(instruction) - instruction = splitter(instruction.strip()) + for line in instructions: + instruction = splitter(line.strip()) delay = 0 if instruction[-1].endswith("]"): # Delay delay = int(instruction[-1].strip("[]"), 0) @@ -253,16 +257,13 @@ def __init__(self, text_program: str, *, build_debuginfo=False) -> None: self.assembled = array.array("H", assembled) - if build_debuginfo: - self.debuginfo = (linemap, text_program) - else: - self.debuginfo = None + self.debuginfo = (linemap, text_program) if build_debuginfo else None - def print_c_program(self, name, qualifier="const"): + def print_c_program(self, name: str, qualifier: str = "const") -> None: """Print the program into a C program snippet""" if self.debuginfo is None: - linemap = None - program_lines = None + linemap = [] + program_lines = [] else: linemap = self.debuginfo[0][:] # Use a copy since we destroy it program_lines = self.debuginfo[1].split("\n") @@ -306,7 +307,7 @@ def print_c_program(self, name, qualifier="const"): print() -def assemble(program_text: str) -> array.array: +def assemble(program_text: str) -> MutableSequence[int]: """Converts pioasm text to encoded instruction bytes In new code, prefer to use the `Program` class so that the extra arguments diff --git a/tests/pytest_helpers.py b/tests/pytest_helpers.py index 678e9b7..72ac7cf 100644 --- a/tests/pytest_helpers.py +++ b/tests/pytest_helpers.py @@ -6,17 +6,22 @@ Pytest helper functions """ +try: + from typing import Any, List, Optional, Type +except ImportError: + pass + import pytest import adafruit_pioasm -def nice_opcode(opcode): - opcode = f"{opcode:016b}" - return opcode[:3] + "_" + opcode[3:8] + "_" + opcode[8:] +def nice_opcode(opcode: int) -> str: + nice = f"{opcode:016b}" + return nice[:3] + "_" + nice[3:8] + "_" + nice[8:] -def assert_assembles_to(source, expected): +def assert_assembles_to(source: str, expected: List[int]) -> None: actual = adafruit_pioasm.assemble(source) expected_bin = [nice_opcode(x) for x in expected] actual_bin = [nice_opcode(x) for x in actual] @@ -25,7 +30,9 @@ def assert_assembles_to(source, expected): ), f"Assembling {source!r}: Expected {expected_bin}, got {actual_bin}" -def assert_assembly_fails(source, match=None, errtype=RuntimeError): +def assert_assembly_fails( + source: str, match: Optional[str] = None, errtype: Type[Exception] = RuntimeError +) -> None: with pytest.raises(errtype, match=match): adafruit_pioasm.assemble(source) # if match: @@ -36,6 +43,6 @@ def assert_assembly_fails(source, match=None, errtype=RuntimeError): # adafruit_pioasm.assemble(source) -def assert_pio_kwargs(source, **kw): +def assert_pio_kwargs(source: str, **kw: Any) -> None: program = adafruit_pioasm.Program(source) assert kw == program.pio_kwargs diff --git a/tests/test_in.py b/tests/test_in.py index d2b76dd..9c7eeb7 100644 --- a/tests/test_in.py +++ b/tests/test_in.py @@ -57,13 +57,13 @@ def test_in_delay_with_sideset() -> None: assert_assembles_to("\n".join(source), [0b010_10_101_000_10001]) -def test_in_bad_source(): +def test_in_bad_source() -> None: assert_assembly_fails( "in bad, 17", match="Invalid in source 'bad'", errtype=ValueError ) -def test_in_bad_bitcount(): +def test_in_bad_bitcount() -> None: assert_assembly_fails( "in pins, 0", match="Count out of range", errtype=RuntimeError ) diff --git a/tests/test_mov.py b/tests/test_mov.py index b6015cb..52492d7 100644 --- a/tests/test_mov.py +++ b/tests/test_mov.py @@ -9,21 +9,21 @@ from pytest_helpers import assert_assembles_to, assert_assembly_fails -def test_mov_non_happy(): +def test_mov_non_happy() -> None: # non happy path assert_assembly_fails( "mov x, blah", match="Invalid mov source 'blah'", errtype=ValueError ) -def test_mov_invert(): +def test_mov_invert() -> None: # test moving and inverting assert_assembles_to("mov x, ~ x", [0b101_00000_001_01_001]) assert_assembles_to("mov x, ~x", [0b101_00000_001_01_001]) assert_assembles_to("mov x, !x", [0b101_00000_001_01_001]) -def test_mov_reverse(): +def test_mov_reverse() -> None: # test moving and reversing bits assert_assembles_to("mov x, :: x", [0b101_00000_001_10_001]) assert_assembles_to("mov x, ::x", [0b101_00000_001_10_001]) diff --git a/tests/test_nop.py b/tests/test_nop.py index 7fd7bca..68bd3c5 100644 --- a/tests/test_nop.py +++ b/tests/test_nop.py @@ -9,11 +9,11 @@ from pytest_helpers import assert_assembles_to, assert_assembly_fails, assert_pio_kwargs -def test_nonsense(): +def test_nonsense() -> None: assert_assembly_fails("nope") -def test_nop(): +def test_nop() -> None: assert_assembles_to("nop", [0b101_00000_010_00_010]) assert_assembles_to("nop\nnop", [0b101_00000_010_00_010, 0b101_00000_010_00_010]) assert_assembles_to("nop [1]", [0b101_00001_010_00_010]) @@ -22,7 +22,7 @@ def test_nop(): assert_assembles_to(".side_set 1\nnop side 1 [15]", [0b101_11111_010_00_010]) -def test_sideset_opt(): +def test_sideset_opt() -> None: assert_assembles_to(".side_set 1 opt\nnop side 1", [0b101_11000_010_00_010]) assert_assembles_to(".side_set 1 opt\nnop side 0", [0b101_10000_010_00_010]) assert_assembles_to(".side_set 1 opt\nnop side 0 [1]", [0b101_10001_010_00_010]) @@ -32,14 +32,14 @@ def test_sideset_opt(): assert_assembles_to(".side_set 1 opt\nnop side 0 [7]", [0b101_10111_010_00_010]) -def test_set(): +def test_set() -> None: # non happy path assert_assembly_fails( "set isr, 1", match="Invalid set destination 'isr'", errtype=ValueError ) -def test_jmp(): +def test_jmp() -> None: assert_assembles_to("l:\njmp l", [0b000_00000_000_00000]) assert_assembles_to("l:\njmp 7", [0b000_00000_000_00111]) assert_assembles_to("jmp l\nl:", [0b000_00000_000_00001]) @@ -56,7 +56,7 @@ def test_jmp(): ) -def test_wait(): +def test_wait() -> None: assert_assembles_to("wait 0 gpio 0", [0b001_00000_0_00_00000]) assert_assembles_to("wait 0 gpio 1", [0b001_00000_0_00_00001]) assert_assembles_to("wait 1 gpio 2", [0b001_00000_1_00_00010]) @@ -69,7 +69,7 @@ def test_wait(): assert_assembles_to("wait 0 irq 1 rel", [0b001_00000_0_10_10001]) -def test_limits(): +def test_limits() -> None: assert_assembly_fails(".side_set 1\nnop side 2") assert_assembly_fails(".side_set 1\nnop side 2 [1]") assert_assembly_fails("nop [32]") @@ -77,7 +77,7 @@ def test_limits(): assert_assembly_fails(".side_set 1 opt\nnop side 0 [8]") -def test_cls(): +def test_cls() -> None: assert_pio_kwargs("", sideset_enable=False) assert_pio_kwargs(".side_set 1", sideset_pin_count=1, sideset_enable=False) assert_pio_kwargs(".side_set 3 opt", sideset_pin_count=3, sideset_enable=True) diff --git a/tests/test_out.py b/tests/test_out.py index 5956fce..67bc978 100644 --- a/tests/test_out.py +++ b/tests/test_out.py @@ -59,13 +59,13 @@ def test_out_delay_with_sideset() -> None: assert_assembles_to("\n".join(source), [0b011_10_101_000_10001]) -def test_out_bad_destination(): +def test_out_bad_destination() -> None: assert_assembly_fails( "out bad, 17", match="Invalid out destination 'bad'", errtype=ValueError ) -def test_out_bad_bitcount(): +def test_out_bad_bitcount() -> None: assert_assembly_fails( "out pins, 0", match="Count out of range", errtype=RuntimeError ) diff --git a/tests/test_pseudo.py b/tests/test_pseudo.py index 72e817c..66d93c2 100644 --- a/tests/test_pseudo.py +++ b/tests/test_pseudo.py @@ -9,5 +9,5 @@ from pytest_helpers import assert_pio_kwargs -def test_offset(): +def test_offset() -> None: assert_pio_kwargs(".origin 7", offset=7, sideset_enable=False) diff --git a/tests/test_radix.py b/tests/test_radix.py index f3cfb9e..19775f4 100644 --- a/tests/test_radix.py +++ b/tests/test_radix.py @@ -9,13 +9,13 @@ from pytest_helpers import assert_assembles_to -def test_octal(): +def test_octal() -> None: assert_assembles_to(".side_set 0o1\nset x, 0o11", [0b111_00000_001_01001]) -def test_binary(): +def test_binary() -> None: assert_assembles_to(".side_set 0b101\nnop side 0b10001", [0b101_10001_010_00_010]) -def test_hex(): +def test_hex() -> None: assert_assembles_to(".side_set 0x0\nnop [0x10]", [0b101_10000_010_00_010]) diff --git a/tests/test_wrap.py b/tests/test_wrap.py index b866a26..05eed73 100644 --- a/tests/test_wrap.py +++ b/tests/test_wrap.py @@ -9,7 +9,7 @@ from pytest_helpers import assert_assembly_fails, assert_pio_kwargs -def test_wrap(): +def test_wrap() -> None: assert_assembly_fails(".wrap") assert_pio_kwargs( "nop\n.wrap_target\nnop\nnop\n.wrap",