Skip to content

Commit fa6fbd5

Browse files
committed
Refuse to write objects with unchecked modifications
This helps users ensure that they don't forget to call `_check()` whenever necessary. The idea is that any external change to the object sets the `_dirty` flag, which can be cleared by calling `_check()`.
1 parent a6b0315 commit fa6fbd5

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

kaitaistruct.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626

2727

2828
class KaitaiStruct(object):
29-
def __init__(self, stream):
30-
self._io = stream
29+
def __init__(self, io):
30+
self._io = io
3131

3232
def __enter__(self):
3333
return self
@@ -58,6 +58,10 @@ def from_io(cls, io):
5858

5959

6060
class ReadWriteKaitaiStruct(KaitaiStruct):
61+
def __init__(self, io):
62+
super(ReadWriteKaitaiStruct, self).__init__(io)
63+
self._dirty = True
64+
6165
def _fetch_instances(self):
6266
raise NotImplementedError()
6367

@@ -69,6 +73,14 @@ def _write(self, io=None):
6973
def _write__seq(self, io):
7074
if io is not None:
7175
self._io = io
76+
if self._dirty:
77+
raise ConsistencyNotCheckedError("consistency not checked: _check() has not been called since the last modification of the object")
78+
79+
def __setattr__(self, key, value):
80+
super_setattr = super(ReadWriteKaitaiStruct, self).__setattr__
81+
if not key.startswith('_') or key in {'_parent', '_root'} or key.startswith('_unnamed'):
82+
super_setattr('_dirty', True)
83+
super_setattr(key, value)
7284

7385

7486
class KaitaiStream(object):
@@ -1001,3 +1013,9 @@ def __init__(self, attr_id, actual, expected):
10011013
self.id = attr_id
10021014
self.actual = actual
10031015
self.expected = expected
1016+
1017+
1018+
class ConsistencyNotCheckedError(Exception):
1019+
"""Thrown when attempting to write an object whose consistency hasn't been
1020+
checked since the last modification."""
1021+
pass

0 commit comments

Comments
 (0)