lib.data: make Field() immutable.

Mutability of Field isn't specified by the RFC and can cause issues
if the objects stored in Layout subclasses are mutated. There isn't
any reason to do that (the subclasses themselves are mutable and
handle that correctly), so disallow it.
This commit is contained in:
Catherine 2023-02-21 17:58:28 +00:00
parent e2f0519774
commit fcc4f54367
2 changed files with 15 additions and 17 deletions

View file

@ -13,33 +13,25 @@ __all__ = [
class Field:
def __init__(self, shape, offset):
self.shape = shape
self.offset = offset
@property
def shape(self):
return self._shape
@shape.setter
def shape(self, shape):
try:
Shape.cast(shape)
except TypeError as e:
raise TypeError("Field shape must be a shape-castable object, not {!r}"
.format(shape)) from e
self._shape = shape
if not isinstance(offset, int) or offset < 0:
raise TypeError("Field offset must be a non-negative integer, not {!r}"
.format(offset))
self._shape = shape
self._offset = offset
@property
def shape(self):
return self._shape
@property
def offset(self):
return self._offset
@offset.setter
def offset(self, offset):
if not isinstance(offset, int) or offset < 0:
raise TypeError("Field offset must be a non-negative integer, not {!r}"
.format(offset))
self._offset = offset
@property
def width(self):
return Shape.cast(self.shape).width

View file

@ -59,6 +59,12 @@ class FieldTestCase(TestCase):
r"^Field offset must be a non-negative integer, not -1$"):
Field(unsigned(2), -1)
def test_immutable(self):
with self.assertRaises(AttributeError):
Field(1, 0).shape = unsigned(2)
with self.assertRaises(AttributeError):
Field(1, 0).offset = 1
class StructLayoutTestCase(TestCase):
def test_construct(self):