diff --git a/pyproject.toml b/pyproject.toml index 87fe377..61351fd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,6 @@ classifiers = [ ] requires-python = ">=3.10" dependencies = [ - "setuptools_scm[toml]>=6.2", "lxml~=5.3", "numpy~=2.1", "typing_extensions>=4.4.0", @@ -24,17 +23,17 @@ homepage = "https://github.com/nordicsemiconductor/svada" repository = "https://github.com/nordicsemiconductor/svada.git" [build-system] -requires = ["setuptools>=61", "setuptools_scm[toml]>=6.2"] -build-backend = "setuptools.build_meta" +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" -[tool.setuptools] -package-dir = { svd = "src/svd" } -include-package-data = true +[tool.hatch.version] +source = "vcs" -[tool.setuptools.package-data] -svd = ["py.typed"] +[tool.hatch.build.targets.sdist] +packages = ["src/svd"] -[tool.setuptools_scm] +[tool.hatch.build.targets.wheel] +packages = ["src/svd"] [tool.mypy] disallow_untyped_defs = true diff --git a/src/svd/__init__.py b/src/svd/__init__.py index 8d0ddd3..a49928a 100644 --- a/src/svd/__init__.py +++ b/src/svd/__init__.py @@ -4,6 +4,8 @@ # SPDX-License-Identifier: Apache-2.0 # +import importlib.metadata + from .bindings import ( Access, ReadAction, @@ -49,11 +51,46 @@ Struct, ) -import importlib.metadata +__version__ = importlib.metadata.version("svada") + +__all__ = [ + "Access", + "ReadAction", + "Endian", + "SauAccess", + "AddressBlockUsage", + "Protection", + "EnumUsage", + "WriteAction", + "DataType", + "CpuName", + "Cpu", + "AddressBlock", + "SauRegion", + "SvdError", + "SvdParseError", + "SvdDefinitionError", + "SvdMemoryError", + "SvdPathError", + "SvdIndexError", + "SvdKeyError", + "parse", + "Options", + "FEPath", + "EPath", + "Array", + "Field", + "FlatRegister", + "FlatRegisterUnion", + "FlatRegisterType", + "FlatStruct", + "FlatField", + "Device", + "Peripheral", + "Register", + "RegisterUnion", + "RegisterType", + "Struct", +] -try: - __version__ = importlib.metadata.version("svada") -except importlib.metadata.PackageNotFoundError: - # Package is not installed - import setuptools_scm - __version__ = setuptools_scm.get_version(root="../..", relative_to=__file__) +del importlib.metadata diff --git a/src/svd/_bindings.py b/src/svd/_bindings.py index a48c1c0..9dcfd27 100644 --- a/src/svd/_bindings.py +++ b/src/svd/_bindings.py @@ -20,7 +20,6 @@ Dict, Generic, Iterable, - Iterator, List, Literal, Mapping, diff --git a/src/svd/bindings.py b/src/svd/bindings.py index 32097bb..a662477 100644 --- a/src/svd/bindings.py +++ b/src/svd/bindings.py @@ -15,7 +15,6 @@ from __future__ import annotations -import dataclasses as dc import enum import typing from dataclasses import dataclass @@ -23,7 +22,7 @@ from lxml import objectify from lxml.objectify import BoolElement, StringElement -from typing_extensions import TypeGuard, override +from typing_extensions import TypeGuard from ._bindings import ( SELF_CLASS, diff --git a/src/svd/device.py b/src/svd/device.py index 8bc3bbf..03c03c4 100644 --- a/src/svd/device.py +++ b/src/svd/device.py @@ -15,13 +15,9 @@ from __future__ import annotations -import dataclasses as dc import math -import re import typing from abc import ABC, abstractmethod -from collections import defaultdict -from dataclasses import dataclass from functools import cached_property from types import MappingProxyType from typing import ( @@ -37,7 +33,6 @@ Literal, Mapping, NamedTuple, - NoReturn, Optional, Protocol, Reversible, @@ -70,7 +65,6 @@ ReadAction, RegisterProperties, WriteAction, - WriteConstraint, ) from .errors import ( SvdDefinitionError, @@ -1421,21 +1415,17 @@ def content(self, new_content: Union[int, str]) -> None: write to the field. """ if isinstance(new_content, int): - val = self._trailing_zero_adjusted(new_content) - - if val not in self.allowed_values: + if new_content not in self.allowed_values: raise ValueError( f"{self!r} does not accept" - f" the bit value '{val}' ({hex(val)})." - " Are you sure you have an up to date .svd file?" + f" the bit value '{new_content}' ({hex(new_content)})." ) - resolved_value = val + resolved_value = new_content elif isinstance(new_content, str): if new_content not in self.enums: raise ValueError( f"{self!r} does not accept" f" the enum '{new_content}'." - " Are you sure you have an up to date .svd file?" ) resolved_value = self.enums[new_content] else: @@ -1446,6 +1436,16 @@ def content(self, new_content: Union[int, str]) -> None: self._register.set_content(resolved_value << self.bit_offset, self.mask) + @property + def content_enum(self) -> str: + """The name of the enum corresponding to the field value.""" + content = self.content + for enum_str, value in self.enums.items(): + if content == value: + return enum_str + + raise LookupError(f"{self!r} content {content} does not correspond to an enum.") + @property def modified(self) -> bool: """True if the field contains a different value now than at reset.""" @@ -1458,36 +1458,6 @@ def unconstrain(self) -> None: """ self._allowed_values = range(2**self.bit_width) - def _trailing_zero_adjusted(self, content: int) -> int: - """ - Internal method that checks and adjusts a given value for trailing zeroes if it exceeds - the bit width of its field. Some values are simplest to encode as a full 32-bit value even - though their field is comprised of less than 32 bits, such as an address. - - :param value: A numeric value to check against the field bits - - :return: Field value without any trailing zeroes - """ - - width_max = 2**self.bit_width - - if content > width_max: - max_val = width_max - 1 - max_val_hex_len = len(f"{max_val:x}") - hex_val = f"{content:0{8}x}" # leading zeros, 8-byte max, in hex - trailing = hex_val[max_val_hex_len:] # Trailing zeros - - if int(trailing, 16) != 0: - raise SvdMemoryError(f"Unexpected trailing value: {trailing}") - - cropped = hex_val[:max_val_hex_len] # value w/o trailing - adjusted = int(cropped, 16) - - if adjusted <= max_val: - return adjusted - - return content - def __repr__(self) -> str: """Short field description.""" bool_props = ("modified",) if self.modified else () diff --git a/src/svd/errors.py b/src/svd/errors.py index 9c51a54..11c205c 100644 --- a/src/svd/errors.py +++ b/src/svd/errors.py @@ -4,10 +4,9 @@ # SPDX-License-Identifier: Apache-2.0 # -from abc import ABC from typing import Any, Iterable, Union -from .path import EPath, EPathType, EPathUnion +from .path import EPathUnion class SvdError(Exception): diff --git a/src/svd/memory_block.py b/src/svd/memory_block.py index aa2e1d8..cda4e14 100644 --- a/src/svd/memory_block.py +++ b/src/svd/memory_block.py @@ -8,15 +8,12 @@ from functools import partial from typing import ( - Any, Callable, - Dict, Iterator, List, Mapping, Optional, Tuple, - Type, TypeVar, Union, overload, @@ -24,7 +21,7 @@ import numpy as np import numpy.ma as ma -from numpy.typing import ArrayLike, NDArray +from numpy.typing import ArrayLike from typing_extensions import Self from .errors import SvdMemoryError diff --git a/src/svd/parsing.py b/src/svd/parsing.py index 2a5a008..934d6cc 100644 --- a/src/svd/parsing.py +++ b/src/svd/parsing.py @@ -46,7 +46,7 @@ class Options: # Make the addressOffset in cluster elements be relative to the immediate parent # element instead of relative to the containing peripheral. - parent_relative_cluster_address: bool = False + parent_relative_cluster_address: bool = True # Cluster/register/field elements to remove from the XML document prior to parsing. # This can be used to remove outdated/deprecated elements from the device if they cause diff --git a/src/svd/path.py b/src/svd/path.py index ea3fa54..ed8a8a8 100644 --- a/src/svd/path.py +++ b/src/svd/path.py @@ -12,11 +12,9 @@ import re from abc import ABC, abstractmethod -from functools import singledispatch from itertools import chain from typing import ( Any, - Generic, Iterable, List, Optional,