diff --git a/.github/workflows/action.yaml b/.github/workflows/action.yaml index 3bf8536c..5b39225d 100644 --- a/.github/workflows/action.yaml +++ b/.github/workflows/action.yaml @@ -71,7 +71,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ 3.7, 3.8, 3.9, "3.10", "3.11", "3.12", "3.13" ] + python-version: [ 3.9, "3.10", "3.11", "3.12", "3.13" ] steps: - uses: actions/checkout@v4 @@ -101,7 +101,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ 3.7, 3.8, 3.9, "3.10", "3.11", "3.12", "3.13" ] + python-version: [ 3.9, "3.10", "3.11", "3.12", "3.13" ] steps: - uses: actions/checkout@v4 @@ -150,7 +150,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ 3.7, 3.8, 3.9, "3.10", "3.11", "3.12", "3.13" ] + python-version: [ 3.9, "3.10", "3.11", "3.12", "3.13" ] steps: - uses: actions/checkout@v4 @@ -252,7 +252,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12", "3.13"] + python-version: [3.9, "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -291,9 +291,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - # reduced matrix because the autoformatter was having issues with python 3.8 so we will - # limit this to modern versions of python only - python-version: [3.8, 3.9, "3.10", "3.11", "3.12", "3.13"] + python-version: [3.9, "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 diff --git a/pyproject.toml b/pyproject.toml index a76bc7b4..41b02fce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,11 +5,10 @@ build-backend = "setuptools.build_meta" [project] name = "peakrdl-python" dynamic = ["version"] -requires-python = ">=3.7" +requires-python = ">=3.9" dependencies = [ "systemrdl-compiler>=1.25.0", "jinja2", - "asynctest;python_version<'3.8'", "typing-extensions;python_version<'3.11'" ] @@ -27,8 +26,6 @@ classifiers = [ "Development Status :: 4 - Beta", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", diff --git a/src/peakrdl_python/__about__.py b/src/peakrdl_python/__about__.py index c76b096f..e250d5ae 100644 --- a/src/peakrdl_python/__about__.py +++ b/src/peakrdl_python/__about__.py @@ -17,4 +17,4 @@ Variables that describes the peakrdl-python Package """ -__version__ = "0.9.3" +__version__ = "0.9.4" diff --git a/src/peakrdl_python/lib/async_memory.py b/src/peakrdl_python/lib/async_memory.py index 60954b3c..30cd5479 100644 --- a/src/peakrdl_python/lib/async_memory.py +++ b/src/peakrdl_python/lib/async_memory.py @@ -177,14 +177,12 @@ async def _read(self, start_entry: int, number_entries: int) -> List[int]: read_callback = self._callbacks.read_callback if read_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions addr = self.address_lookup(entry=start_entry) data_read = \ - await read_block_callback(addr=addr, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - length=number_entries) # type: ignore[call-arg] + await read_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + length=number_entries) if isinstance(self._callbacks, AsyncCallbackSet): if not isinstance(data_read, List): @@ -204,11 +202,10 @@ async def _read(self, start_entry: int, number_entries: int) -> List[int]: for entry in range(number_entries): entry_address = self.address_lookup(entry=start_entry+entry) - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - data_entry = await read_callback(addr=entry_address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width) # type: ignore[call-arg] + + data_entry = await read_callback(addr=entry_address, + width=self.width, + accesswidth=self.width) data_read[entry] = data_entry @@ -248,14 +245,12 @@ async def _read_legacy(self, start_entry: int, number_entries: int) -> Array: read_callback = self._callbacks.read_callback if read_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions addr = self.address_lookup(entry=start_entry) data_read = \ - await read_block_callback(addr=addr, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - length=number_entries) # type: ignore[call-arg] + await read_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + length=number_entries) if isinstance(self._callbacks, AsyncCallbackSet): if not isinstance(data_read, List): @@ -275,11 +270,9 @@ async def _read_legacy(self, start_entry: int, number_entries: int) -> Array: for entry in range(number_entries): entry_address = self.address_lookup(entry=start_entry + entry) - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - data_entry = await read_callback(addr=entry_address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width) # type: ignore[call-arg] + data_entry = await read_callback(addr=entry_address, + width=self.width, + accesswidth=self.width) data_read_block[entry] = data_entry @@ -428,53 +421,41 @@ async def _write(self, start_entry: int, data: Union[Array, List[int]]) -> None: f'but got {len(data):d}') if self._callbacks.write_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions + addr = self.address_lookup(entry=start_entry) if isinstance(self._callbacks, AsyncCallbackSet): if isinstance(data, Array): - # pylint: disable=line-too-long - await self._callbacks.write_block_callback(addr=addr, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=data.tolist()) # type: ignore[call-arg] - # pylint: enable=line-too-long + await self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=data.tolist()) else: - # pylint: disable=line-too-long - await self._callbacks.write_block_callback(addr=addr, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=data) # type: ignore[call-arg] - # pylint: enable=line-too-long + await self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=data) if isinstance(self._callbacks, AsyncCallbackSetLegacy): if isinstance(data, list): # need to convert the data to an array before calling - # pylint: disable=line-too-long - await self._callbacks.write_block_callback(addr=addr, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=Array(self.array_typecode, data)) # type: ignore[call-arg] - # pylint: enable=line-too-long + await self._callbacks.write_block_callback( + addr=addr, + width=self.width, + accesswidth=self.width, + data=Array(self.array_typecode, data)) else: - # pylint: disable=line-too-long - await self._callbacks.write_block_callback(addr=addr, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=data) # type: ignore[call-arg] - # pylint: enable=line-too-long + await self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=data) elif self._callbacks.write_callback is not None: # there is not write_block_callback defined so we must used individual write for entry_index, entry_data in enumerate(data): entry_address = self.address_lookup(entry=start_entry+entry_index) - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - # pylint: disable=line-too-long - await self._callbacks.write_callback(addr=entry_address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=entry_data) # type: ignore[call-arg] - # pylint: enable=line-too-long + await self._callbacks.write_callback(addr=entry_address, + width=self.width, + accesswidth=self.width, + data=entry_data) else: raise RuntimeError('No suitable callback') diff --git a/src/peakrdl_python/lib/async_register_and_field.py b/src/peakrdl_python/lib/async_register_and_field.py index be6fe582..c416796e 100644 --- a/src/peakrdl_python/lib/async_register_and_field.py +++ b/src/peakrdl_python/lib/async_register_and_field.py @@ -178,20 +178,17 @@ async def read(self) -> int: # pylint: enable=duplicate-code if read_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - return await read_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth) # type: ignore[call-arg] + + return await read_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth) if read_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions array_read_result = \ - await read_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - length=1) # type: ignore[call-arg] + await read_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + length=1) return array_read_result[0] raise RuntimeError('This function does not have a useable callback') @@ -272,35 +269,26 @@ async def write(self, data: int) -> None: # pylint: enable=duplicate-code if self._callbacks.write_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - # pylint: disable=line-too-long - await self._callbacks.write_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - data=data) # type: ignore[call-arg] - # pylint: enable=line-too-long + + await self._callbacks.write_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + data=data) elif self._callbacks.write_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - # pylint: disable-next=duplicate-code + if isinstance(self._callbacks, AsyncCallbackSetLegacy): data_as_array = Array(get_array_typecode(self.width), [data]) - # pylint: disable=line-too-long - await self._callbacks.write_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - data=data_as_array) # type: ignore[call-arg] - # pylint: enable=line-too-long + await self._callbacks.write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + data=data_as_array) if isinstance(self._callbacks, AsyncCallbackSet): - # pylint: disable=line-too-long - await self._callbacks.write_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - data=[data]) # type: ignore[call-arg] - # pylint: enable=line-too-long + await self._callbacks.write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + data=[data]) else: # pylint: disable-next=duplicate-code @@ -567,15 +555,11 @@ async def __block_read_legacy(self) -> Array: read_callback = self._callbacks.read_callback if read_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - # pylint: disable=line-too-long - data_read = \ - await read_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - length=self.__number_cache_entries) # type: ignore[call-arg] - # pylint: enable=line-too-long + + data_read = await read_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + length=self.__number_cache_entries) if not isinstance(data_read, Array): raise TypeError('The read block callback is expected to return an array') @@ -590,13 +574,9 @@ async def __block_read_legacy(self) -> Array: raise RuntimeError('This address array has not be initialised') for entry, address in enumerate(self.__register_address_array): - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - # pylint: disable=line-too-long - data_entry = await read_callback(addr=address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth) # type: ignore[call-arg] - # pylint: enable=line-too-long + data_entry = await read_callback(addr=address, + width=self.width, + accesswidth=self.accesswidth) data_array[entry] = data_entry @@ -615,12 +595,10 @@ async def __block_write_legacy(self, data: Array, verify: bool) -> None: write_callback = self._callbacks.write_callback if write_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - await write_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=data) # type: ignore[call-arg] + await write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.width, + data=data) elif write_callback is not None: # there is not write_block_callback defined so we must used individual write @@ -630,12 +608,10 @@ async def __block_write_legacy(self, data: Array, verify: bool) -> None: for entry_index, entry_data in enumerate(data): entry_address = self.__register_address_array[entry_index] - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - await write_callback(addr=entry_address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - data=entry_data) # type: ignore[call-arg] + await write_callback(addr=entry_address, + width=self.width, + accesswidth=self.accesswidth, + data=entry_data) else: raise RuntimeError('No suitable callback') @@ -656,15 +632,12 @@ async def __block_read(self) -> List[int]: read_callback = self._callbacks.read_callback if read_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - # pylint: disable=line-too-long data_read = \ - await read_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - length=self.__number_cache_entries) # type: ignore[call-arg] - # pylint: enable=line-too-long + await read_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + length=self.__number_cache_entries) + if not isinstance(data_read, List): raise TypeError('The read block callback is expected to return an array') @@ -679,11 +652,9 @@ async def __block_read(self) -> List[int]: raise RuntimeError('This address array has not be initialised') for entry, address in enumerate(self.__register_address_array): - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - data = await read_callback(addr=address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth) # type: ignore[call-arg] + data = await read_callback(addr=address, + width=self.width, + accesswidth=self.accesswidth) data_list[entry] = data @@ -702,13 +673,10 @@ async def __block_write(self, data: List[int], verify: bool) -> None: write_callback = self._callbacks.write_callback if write_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - await write_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=data) # type: ignore[call-arg] - + await write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.width, + data=data) elif write_callback is not None: # there is not write_block_callback defined so we must used individual write @@ -717,12 +685,10 @@ async def __block_write(self, data: List[int], verify: bool) -> None: for entry_index, entry_data in enumerate(data): entry_address = self.__register_address_array[entry_index] - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - await write_callback(addr=entry_address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - data=entry_data) # type: ignore[call-arg] + await write_callback(addr=entry_address, + width=self.width, + accesswidth=self.accesswidth, + data=entry_data) else: raise RuntimeError('No suitable callback') diff --git a/src/peakrdl_python/lib/callbacks.py b/src/peakrdl_python/lib/callbacks.py index 58b96f6a..4c7b97b3 100644 --- a/src/peakrdl_python/lib/callbacks.py +++ b/src/peakrdl_python/lib/callbacks.py @@ -18,136 +18,115 @@ This module is intended to distributed as part of automatically generated code by the peakrdl-python tool. It provides a set of types used by the autogenerated code to callbacks """ -import sys - from array import array as Array from typing import Optional, Union, List +from typing import Protocol -if sys.version_info >= (3, 8): - # Python 3.8 introduced the Protocol class to the typing module which is more powerful than the - # previous method because it also check the argument names - - from typing import Protocol - class ReadCallback(Protocol): - """ - Callback definition for a single register read operation - """ - # pylint: disable=too-few-public-methods - def __call__(self, addr: int, width: int, accesswidth: int) -> int: - pass +class ReadCallback(Protocol): + """ + Callback definition for a single register read operation + """ + # pylint: disable=too-few-public-methods + def __call__(self, addr: int, width: int, accesswidth: int) -> int: + pass - class WriteCallback(Protocol): - """ - Callback definition for a single register write operation - """ - # pylint: disable=too-few-public-methods - def __call__(self, addr: int, width: int, accesswidth: int, data: int) -> None: - pass +class WriteCallback(Protocol): + """ + Callback definition for a single register write operation + """ + # pylint: disable=too-few-public-methods + def __call__(self, addr: int, width: int, accesswidth: int, data: int) -> None: + pass - class ReadBlockLegacyCallback(Protocol): - """ - Callback definition for a block read operation - """ - # pylint: disable=too-few-public-methods - def __call__(self, addr: int, width: int, accesswidth: int, length: int) -> Array: - pass +class ReadBlockLegacyCallback(Protocol): + """ + Callback definition for a block read operation + """ + # pylint: disable=too-few-public-methods + def __call__(self, addr: int, width: int, accesswidth: int, length: int) -> Array: + pass - class ReadBlockCallback(Protocol): - """ - Callback definition for a block read operation - """ - # pylint: disable=too-few-public-methods - def __call__(self, addr: int, width: int, accesswidth: int, length: int) -> List[int]: - pass +class ReadBlockCallback(Protocol): + """ + Callback definition for a block read operation + """ + # pylint: disable=too-few-public-methods + def __call__(self, addr: int, width: int, accesswidth: int, length: int) -> List[int]: + pass - class WriteBlockCallback(Protocol): - """ - Callback definition for a block write operation - """ - # pylint: disable=too-few-public-methods - def __call__(self, addr: int, width: int, accesswidth: int, data: List[int]) -> None: - pass +class WriteBlockCallback(Protocol): + """ + Callback definition for a block write operation + """ + # pylint: disable=too-few-public-methods + def __call__(self, addr: int, width: int, accesswidth: int, data: List[int]) -> None: + pass - class WriteBlockLegacyCallback(Protocol): - """ - Callback definition for a block write operation - """ - # pylint: disable=too-few-public-methods - def __call__(self, addr: int, width: int, accesswidth: int, data: Array) -> None: - pass +class WriteBlockLegacyCallback(Protocol): + """ + Callback definition for a block write operation + """ + # pylint: disable=too-few-public-methods + def __call__(self, addr: int, width: int, accesswidth: int, data: Array) -> None: + pass - class AsyncReadCallback(Protocol): - """ - Callback definition for a single register async read operation - """ - # pylint: disable=too-few-public-methods,unexpected-special-method-signature - async def __call__(self, addr: int, width: int, accesswidth: int) -> int: - pass +class AsyncReadCallback(Protocol): + """ + Callback definition for a single register async read operation + """ + # pylint: disable=too-few-public-methods,unexpected-special-method-signature + async def __call__(self, addr: int, width: int, accesswidth: int) -> int: + pass - class AsyncWriteCallback(Protocol): - """ - Callback definition for a single register async write operation - """ - # pylint: disable=too-few-public-methods,unexpected-special-method-signature - async def __call__(self, addr: int, width: int, accesswidth: int, data: int) -> None: - pass +class AsyncWriteCallback(Protocol): + """ + Callback definition for a single register async write operation + """ + # pylint: disable=too-few-public-methods,unexpected-special-method-signature + async def __call__(self, addr: int, width: int, accesswidth: int, data: int) -> None: + pass - class AsyncReadBlockCallback(Protocol): - """ - Callback definition for an async block read operation - """ - # pylint: disable=too-few-public-methods,unexpected-special-method-signature - async def __call__(self, addr: int, width: int, accesswidth: int, length: int) -> List[int]: - pass +class AsyncReadBlockCallback(Protocol): + """ + Callback definition for an async block read operation + """ + # pylint: disable=too-few-public-methods,unexpected-special-method-signature + async def __call__(self, addr: int, width: int, accesswidth: int, length: int) -> List[int]: + pass - class AsyncReadBlockLegacyCallback(Protocol): - """ - Callback definition for an async block read operation - """ - # pylint: disable=too-few-public-methods,unexpected-special-method-signature - async def __call__(self, addr: int, width: int, accesswidth: int, length: int) -> Array: - pass +class AsyncReadBlockLegacyCallback(Protocol): + """ + Callback definition for an async block read operation + """ + # pylint: disable=too-few-public-methods,unexpected-special-method-signature + async def __call__(self, addr: int, width: int, accesswidth: int, length: int) -> Array: + pass - class AsyncWriteBlockCallback(Protocol): - """ - Callback definition for an async block write operation - """ - # pylint: disable=too-few-public-methods,unexpected-special-method-signature - async def __call__(self, addr: int, width: int, accesswidth: int, data: List[int]) -> None: - pass +class AsyncWriteBlockCallback(Protocol): + """ + Callback definition for an async block write operation + """ + # pylint: disable=too-few-public-methods,unexpected-special-method-signature + async def __call__(self, addr: int, width: int, accesswidth: int, data: List[int]) -> None: + pass - class AsyncWriteBlockLegacyCallback(Protocol): - """ - Callback definition for an async block write operation - """ - # pylint: disable=too-few-public-methods,unexpected-special-method-signature - async def __call__(self, addr: int, width: int, accesswidth: int, data: Array) -> None: - pass -else: - from typing import Callable, Coroutine - - ReadCallback = Callable[[int, int, int], int] - WriteCallback = Callable[[int, int, int, int], None] - ReadBlockCallback = Callable[[int, int, int, int], List[int]] - WriteBlockCallback = Callable[[int, int, int, List[int]], None] - ReadBlockLegacyCallback = Callable[[int, int, int, int], Array] - WriteBlockLegacyCallback = Callable[[int, int, int, Array], None] - AsyncReadCallback = Callable[[int, int, int], Coroutine[None, None, int]] - AsyncWriteCallback = Callable[[int, int, int, int], Coroutine[None, None, None]] - AsyncReadBlockCallback = Callable[[int, int, int, int], Coroutine[None, None, List[int]]] - AsyncWriteBlockCallback = Callable[[int, int, int, List[int]], Coroutine[None, None, None]] - AsyncReadBlockLegacyCallback = Callable[[int, int, int, int], Coroutine[None, None, Array]] - AsyncWriteBlockLegacyCallback = Callable[[int, int, int, Array], Coroutine[None, None, None]] +class AsyncWriteBlockLegacyCallback(Protocol): + """ + Callback definition for an async block write operation + """ + # pylint: disable=too-few-public-methods,unexpected-special-method-signature + async def __call__(self, addr: int, width: int, accesswidth: int, data: Array) -> None: + pass class _NormalCallbackSetBase: @@ -186,7 +165,6 @@ def write_callback(self) -> Optional[WriteCallback]: return self.__write_callback - class NormalCallbackSet(_NormalCallbackSetBase): """ Class to hold a set of callbacks, this reduces the number of callback that need to be passed @@ -226,6 +204,7 @@ def write_block_callback(self) -> Optional[WriteBlockCallback]: """ return self.__write_block_callback + class NormalCallbackSetLegacy(_NormalCallbackSetBase): """ Class to hold a set of callbacks, this reduces the number of callback that need to be passed diff --git a/src/peakrdl_python/lib/memory.py b/src/peakrdl_python/lib/memory.py index 00a3beb6..4d01c928 100644 --- a/src/peakrdl_python/lib/memory.py +++ b/src/peakrdl_python/lib/memory.py @@ -303,14 +303,12 @@ def _read(self, start_entry: int, number_entries: int) -> List[int]: read_callback = self._callbacks.read_callback if read_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions addr = self.address_lookup(entry=start_entry) data_read = \ - read_block_callback(addr=addr, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - length=number_entries) # type: ignore[call-arg] + read_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + length=number_entries) if isinstance(self._callbacks, NormalCallbackSet): if not isinstance(data_read, List): @@ -335,11 +333,9 @@ def _read(self, start_entry: int, number_entries: int) -> List[int]: for entry in range(number_entries): entry_address = self.address_lookup(entry=start_entry+entry) - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - data_entry = read_callback(addr=entry_address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width) # type: ignore[call-arg] + data_entry = read_callback(addr=entry_address, + width=self.width, + accesswidth=self.width) data_read[entry] = data_entry @@ -379,14 +375,12 @@ def _read_legacy(self, start_entry: int, number_entries: int) -> Array: read_callback = self._callbacks.read_callback if read_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions addr = self.address_lookup(entry=start_entry) data_read = \ - read_block_callback(addr=addr, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - length=number_entries) # type: ignore[call-arg] + read_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + length=number_entries) if isinstance(self._callbacks, NormalCallbackSet): if not isinstance(data_read, List): @@ -411,11 +405,9 @@ def _read_legacy(self, start_entry: int, number_entries: int) -> Array: for entry in range(number_entries): entry_address = self.address_lookup(entry=start_entry+entry) - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - data_entry = read_callback(addr=entry_address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width) # type: ignore[call-arg] + data_entry = read_callback(addr=entry_address, + width=self.width, + accesswidth=self.width) data_read[entry] = data_entry @@ -565,51 +557,39 @@ def _write(self, start_entry: int, data: Union[Array, List[int]]) -> None: f'but got {len(data):d}') if self._callbacks.write_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions addr = self.address_lookup(entry=start_entry) if isinstance(self._callbacks, NormalCallbackSet): if isinstance(data, Array): - # pylint: disable=line-too-long - self._callbacks.write_block_callback(addr=addr, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=data.tolist()) # type: ignore[call-arg] - # pylint: enable=line-too-long + self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=data.tolist()) else: - # pylint: disable=line-too-long - self._callbacks.write_block_callback(addr=addr, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=data) # type: ignore[call-arg] - # pylint: enable=line-too-long + self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=data) if isinstance(self._callbacks, NormalCallbackSetLegacy): if isinstance(data, list): # need to convert the data to an array before calling - # pylint: disable=line-too-long - self._callbacks.write_block_callback(addr=addr, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=Array(self.array_typecode, data)) # type: ignore[call-arg] - # pylint: enable=line-too-long + self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=Array(self.array_typecode, data)) else: - # pylint: disable=line-too-long - self._callbacks.write_block_callback(addr=addr, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=data) # type: ignore[call-arg] - # pylint: enable=line-too-long + self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=data) elif self._callbacks.write_callback is not None: # there is not write_block_callback defined so we must used individual write for entry_index, entry_data in enumerate(data): entry_address = self.address_lookup(entry=start_entry+entry_index) - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - self._callbacks.write_callback(addr=entry_address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=entry_data) # type: ignore[call-arg] + self._callbacks.write_callback(addr=entry_address, + width=self.width, + accesswidth=self.width, + data=entry_data) else: raise RuntimeError('No suitable callback') diff --git a/src/peakrdl_python/lib/register_and_field.py b/src/peakrdl_python/lib/register_and_field.py index 1a092b9d..216a6a28 100644 --- a/src/peakrdl_python/lib/register_and_field.py +++ b/src/peakrdl_python/lib/register_and_field.py @@ -166,13 +166,9 @@ def __block_read_legacy(self) -> Array: read_callback = self._callbacks.read_callback if read_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - data_read = \ - read_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - length=self.__number_cache_entries) # type: ignore[call-arg] + data_read = read_block_callback(addr=self.address, width=self.width, + accesswidth=self.accesswidth, + length=self.__number_cache_entries) if not isinstance(data_read, Array): raise TypeError('The read block callback is expected to return an array') @@ -187,12 +183,9 @@ def __block_read_legacy(self) -> Array: raise RuntimeError('This address array has not be initialised') for entry, address in enumerate(self.__register_address_array): - - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - data_entry = read_callback(addr=address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth) # type: ignore[call-arg] + data_entry = read_callback(addr=address, + width=self.width, + accesswidth=self.accesswidth) data_array[entry] = data_entry @@ -211,12 +204,10 @@ def __block_write_legacy(self, data: Array, verify: bool) -> None: write_callback = self._callbacks.write_callback if write_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - write_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=data) # type: ignore[call-arg] + write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.width, + data=data) elif write_callback is not None: # there is not write_block_callback defined so we must used individual write @@ -226,12 +217,10 @@ def __block_write_legacy(self, data: Array, verify: bool) -> None: for entry_index, entry_data in enumerate(data): entry_address = self.__register_address_array[entry_index] - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - write_callback(addr=entry_address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - data=entry_data) # type: ignore[call-arg] + write_callback(addr=entry_address, + width=self.width, + accesswidth=self.accesswidth, + data=entry_data) else: raise RuntimeError('No suitable callback') @@ -252,13 +241,11 @@ def __block_read(self) -> List[int]: read_callback = self._callbacks.read_callback if read_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions data_read = \ - read_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - length=self.__number_cache_entries) # type: ignore[call-arg] + read_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + length=self.__number_cache_entries) if not isinstance(data_read, List): if isinstance(data_read, Array): @@ -276,11 +263,9 @@ def __block_read(self) -> List[int]: raise RuntimeError('This address array has not be initialised') for entry, address in enumerate(self.__register_address_array): - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - data_entry = read_callback(addr=address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth) # type: ignore[call-arg] + data_entry = read_callback(addr=address, + width=self.width, + accesswidth=self.accesswidth) data_list[entry] = data_entry @@ -299,12 +284,10 @@ def __block_write(self, data: List[int], verify: bool) -> None: write_callback = self._callbacks.write_callback if write_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - write_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.width, # type: ignore[call-arg] - data=data) # type: ignore[call-arg] + write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.width, + data=data) elif write_callback is not None: # there is not write_block_callback defined so we must used individual write @@ -314,12 +297,10 @@ def __block_write(self, data: List[int], verify: bool) -> None: for entry_index, entry_data in enumerate(data): entry_address = self.__register_address_array[entry_index] - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - write_callback(addr=entry_address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - data=entry_data) # type: ignore[call-arg] + write_callback(addr=entry_address, + width=self.width, + accesswidth=self.accesswidth, + data=entry_data) else: raise RuntimeError('No suitable callback') @@ -532,19 +513,15 @@ def read(self) -> int: read_callback = self._callbacks.read_callback if read_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - return read_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth) # type: ignore[call-arg] + return read_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth) if read_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - return read_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - length=1)[0] # type: ignore[call-arg] + return read_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + length=1)[0] raise RuntimeError('This function does not have a useable callback') @@ -620,30 +597,24 @@ def write(self, data: int) -> None: self._logger.info('Writing data:%X to %X', data, self.address) if self._callbacks.write_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - self._callbacks.write_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] - accesswidth=self.accesswidth, # type: ignore[call-arg] - data=data) # type: ignore[call-arg] + self._callbacks.write_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + data=data) # elif self._callbacks.write_block_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions if isinstance(self._callbacks, NormalCallbackSetLegacy): data_as_array = Array(get_array_typecode(self.width), [data]) - self._callbacks.write_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] + self._callbacks.write_block_callback(addr=self.address, + width=self.width, accesswidth=self.accesswidth, - # type: ignore[call-arg] - data=data_as_array) # type: ignore[call-arg] + data=data_as_array) if isinstance(self._callbacks, NormalCallbackSet): - self._callbacks.write_block_callback(addr=self.address, # type: ignore[call-arg] - width=self.width, # type: ignore[call-arg] + self._callbacks.write_block_callback(addr=self.address, + width=self.width, accesswidth=self.accesswidth, - # type: ignore[call-arg] - data=[data]) # type: ignore[call-arg] + data=[data]) else: raise RuntimeError('This function does not have a useable callback') diff --git a/src/peakrdl_python/sim_lib/_callbacks.py b/src/peakrdl_python/sim_lib/_callbacks.py index f76118eb..e2946177 100644 --- a/src/peakrdl_python/sim_lib/_callbacks.py +++ b/src/peakrdl_python/sim_lib/_callbacks.py @@ -18,78 +18,62 @@ This module is intended to distributed as part of automatically generated code by the peakrdl-python tool. It provides a set of types used by the autogenerated code to callbacks """ +from typing import Protocol -import sys -if sys.version_info >= (3, 8): - # Python 3.8 introduced the Protocol class to the typing module which is more powerful than the - # previous method because it also check the argument names +class RegisterReadCallback(Protocol): + """ + Callback definition software read to a field, register or memory + """ - from typing import Protocol + # pylint: disable=too-few-public-methods + def __call__(self, value: int) -> None: + pass - class RegisterReadCallback(Protocol): - """ - Callback definition software read to a field, register or memory - """ - # pylint: disable=too-few-public-methods - def __call__(self, value: int) -> None: - pass +class RegisterWriteCallback(Protocol): + """ + Callback definition software write to a field, register or memory + """ + # pylint: disable=too-few-public-methods + def __call__(self, value: int) -> None: + pass - class RegisterWriteCallback(Protocol): - """ - Callback definition software write to a field, register or memory - """ +class FieldReadCallback(Protocol): + """ + Callback definition software read to a field, register or memory + """ - # pylint: disable=too-few-public-methods - def __call__(self, value: int) -> None: - pass + # pylint: disable=too-few-public-methods + def __call__(self, value: int) -> None: + pass - class FieldReadCallback(Protocol): - """ - Callback definition software read to a field, register or memory - """ - # pylint: disable=too-few-public-methods - def __call__(self, value: int) -> None: - pass +class FieldWriteCallback(Protocol): + """ + Callback definition software write to a field, register or memory + """ + # pylint: disable=too-few-public-methods + def __call__(self, value: int) -> None: + pass - class FieldWriteCallback(Protocol): - """ - Callback definition software write to a field, register or memory - """ +class MemoryReadCallback(Protocol): + """ + Callback definition software read to a field, register or memory + """ - # pylint: disable=too-few-public-methods - def __call__(self, value: int) -> None: - pass + # pylint: disable=too-few-public-methods + def __call__(self, offset: int, value: int) -> None: + pass - class MemoryReadCallback(Protocol): - """ - Callback definition software read to a field, register or memory - """ - # pylint: disable=too-few-public-methods - def __call__(self, offset: int, value: int) -> None: - pass +class MemoryWriteCallback(Protocol): + """ + Callback definition software write to a field, register or memory + """ - - class MemoryWriteCallback(Protocol): - """ - Callback definition software write to a field, register or memory - """ - - # pylint: disable=too-few-public-methods - def __call__(self, offset: int, value: int) -> None: - pass - -else: - from typing import Callable - - RegisterReadCallback = Callable[[int], None] - RegisterWriteCallback = Callable[[int], None] - FieldReadCallback = Callable[[int], None] - FieldWriteCallback = Callable[[int], None] - MemoryReadCallback = Callable[[int], None] - MemoryWriteCallback = Callable[[int], None] + # pylint: disable=too-few-public-methods + def __call__(self, offset: int, value: int) -> None: + pass diff --git a/src/peakrdl_python/sim_lib/memory.py b/src/peakrdl_python/sim_lib/memory.py index 960d81d6..529110db 100644 --- a/src/peakrdl_python/sim_lib/memory.py +++ b/src/peakrdl_python/sim_lib/memory.py @@ -101,13 +101,10 @@ def read(self, offset: int) -> int: self.__offset_range_check(offset) value = self.value[offset] if self.read_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - # pylint does not recognise that the property is returning a callback therefore it # is legal to call it. # pylint: disable-next=not-callable - self.read_callback(offset=offset, value=value) # type: ignore[call-arg] + self.read_callback(offset=offset, value=value) return value def write(self, offset: int, data: int) -> None: @@ -124,13 +121,10 @@ def write(self, offset: int, data: int) -> None: """ self.__offset_range_check(offset) if self.write_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - # pylint does not recognise that the property is returning a callback therefore it # is legal to call it. # pylint: disable-next=not-callable - self.write_callback(offset=offset, value=data) # type: ignore[call-arg] + self.write_callback(offset=offset, value=data) self.value[offset] = data @property diff --git a/src/peakrdl_python/sim_lib/register.py b/src/peakrdl_python/sim_lib/register.py index e4481fc9..7f5d49ed 100644 --- a/src/peakrdl_python/sim_lib/register.py +++ b/src/peakrdl_python/sim_lib/register.py @@ -80,35 +80,25 @@ def write_callback(self, callback: Optional[RegisterWriteCallback]) -> None: def _action_read_callback(self) -> None: if self.read_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - # pylint does not recognise that the property is returning a callback therefore it # is legal to call it. # pylint: disable-next=not-callable - self.read_callback(value=self.value) # type: ignore[call-arg] + self.read_callback(value=self.value) for field in self.fields: if field.read_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - field.read_callback(value=field.value) # type: ignore[call-arg] + field.read_callback(value=field.value) def _action_write_callback(self) -> None: if self.write_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't recognise - # the arguments in the call back functions - # pylint does not recognise that the property is returning a callback therefore it # is legal to call it. # pylint: disable-next=not-callable - self.write_callback(value=self.value) # type: ignore[call-arg] + self.write_callback(value=self.value) for field in self.fields: if field.write_callback is not None: - # python 3.7 doesn't have the callback defined as protocol so mypy doesn't - # recognise the arguments in the call back functions - field.write_callback(value=field.value) # type: ignore[call-arg] + field.write_callback(value=field.value) @abstractmethod def read(self) -> int: diff --git a/src/peakrdl_python/systemrdl_node_utility_functions.py b/src/peakrdl_python/systemrdl_node_utility_functions.py index 6388a868..8322009c 100644 --- a/src/peakrdl_python/systemrdl_node_utility_functions.py +++ b/src/peakrdl_python/systemrdl_node_utility_functions.py @@ -18,8 +18,7 @@ A set of utility functions that perform supplementary processing on a node in a compiled system RDL dataset. """ -from typing import Iterable, Optional, List -import sys +from typing import Iterable, Optional, List, Protocol from itertools import filterfalse import textwrap @@ -36,24 +35,15 @@ from systemrdl.rdltypes.user_enum import UserEnumMeta # type: ignore from systemrdl import RDLListener, WalkerAction, RDLWalker # type: ignore -if sys.version_info >= (3, 8): - # Python 3.8 introduced the Protocol class to the typing module which is more powerful than the - # previous method because it also check the argument names - from typing import Protocol - - class HideNodeCallback(Protocol): - """ - Callback function that determines whether a node should be hidden or not, this is intended - to be used with the RegEX check on the node name - """ - # pylint: disable=too-few-public-methods - def __call__(self, node: Node) -> bool: - pass -else: - from typing import Callable - - HideNodeCallback=Callable[[Node], bool] +class HideNodeCallback(Protocol): + """ + Callback function that determines whether a node should be hidden or not, this is intended + to be used with the RegEX check on the node name + """ + # pylint: disable=too-few-public-methods + def __call__(self, node: Node) -> bool: + pass def get_fully_qualified_type_name(node: Node) -> str: diff --git a/src/peakrdl_python/templates/addrmap_simulation_tb.py.jinja b/src/peakrdl_python/templates/addrmap_simulation_tb.py.jinja index 1be031b2..de03fe3e 100644 --- a/src/peakrdl_python/templates/addrmap_simulation_tb.py.jinja +++ b/src/peakrdl_python/templates/addrmap_simulation_tb.py.jinja @@ -23,12 +23,8 @@ from typing import List, Union, Dict, cast {% if asyncoutput %} import sys import asyncio -if sys.version_info < (3, 8): - import asynctest # type: ignore[import] - from asynctest.mock import Mock # type: ignore[import] -else: - import unittest - from unittest.mock import Mock +import unittest +from unittest.mock import Mock {% else %} import unittest from unittest.mock import Mock diff --git a/src/peakrdl_python/templates/addrmap_tb.py.jinja b/src/peakrdl_python/templates/addrmap_tb.py.jinja index 5eeba7b3..9f1666d0 100644 --- a/src/peakrdl_python/templates/addrmap_tb.py.jinja +++ b/src/peakrdl_python/templates/addrmap_tb.py.jinja @@ -22,12 +22,8 @@ from array import array as Array {% if asyncoutput %} import sys import asyncio -if sys.version_info < (3, 8): - import asynctest # type: ignore[import] - from asynctest.mock import patch, call # type: ignore[import] -else: - import unittest - from unittest.mock import patch, call +import unittest +from unittest.mock import patch, call {% else %} import unittest from unittest.mock import patch, call diff --git a/tests/testcases/name_clash.rdl b/tests/testcases/name_clash.rdl index e1ec7746..3c8b69c4 100644 --- a/tests/testcases/name_clash.rdl +++ b/tests/testcases/name_clash.rdl @@ -23,6 +23,8 @@ addrmap name_clash { field { fieldwidth=1; } yield = 1; field { fieldwidth=1; } in = 1; field { fieldwidth=1; } field_in = 1; + field { fieldwidth=1; } max = 1; + field { fieldwidth=1; } len = 1; } gpio_status; reg {