Skip to content

Commit 936a6b3

Browse files
committed
fields: Make ConditionalField.getval return None when condition is not met
1 parent 5692fb5 commit 936a6b3

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

suitcase/fields.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,9 @@ def unpack(self, data, **kwargs):
617617
return self.field.unpack(data, **kwargs)
618618

619619
def getval(self):
620+
if not self.condition(self._parent):
621+
return None
622+
620623
return self.field.getval()
621624

622625
def setval(self, value):

suitcase/test/test_fields.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,14 @@ class ConditionalDispatch(Structure):
668668
condition=lambda m: m.f2 == 255)
669669

670670

671+
class ConditionalSubstructures(Structure):
672+
f1 = UBInt8()
673+
f2 = ConditionalField(SubstructureField(BasicMessage),
674+
condition=lambda m: m.f1 < 10)
675+
f3 = ConditionalField(SubstructureField(BasicMessage),
676+
condition=lambda m: m.f1 < 20)
677+
678+
671679
class TestConditionalField(unittest.TestCase):
672680
def test_conditional_pack(self):
673681
m1 = Conditional()
@@ -732,6 +740,62 @@ def test_conditional_dispatch(self):
732740
self.assertEqual(m2.f3.b1, 0x11)
733741
self.assertEqual(m2.f3.b2, 0x22)
734742

743+
def test_conditional_substructure_pack(self):
744+
m = ConditionalSubstructures()
745+
m.f1 = 9
746+
747+
f2 = BasicMessage()
748+
f2.b1 = 0x55
749+
f2.b2 = 0x66
750+
m.f2 = f2
751+
752+
f3 = BasicMessage()
753+
f3.b1 = 0x77
754+
f3.b2 = 0x88
755+
m.f3 = f3
756+
757+
self.assertEqual(m.pack(), b"\x09\x55\x66\x77\x88")
758+
759+
# Remove f2
760+
m.f1 = 10
761+
m.f2 = None
762+
self.assertEqual(m.pack(), b"\x0a\x77\x88")
763+
764+
# Remove f3
765+
m.f1 = 20
766+
m.f3 = None
767+
self.assertEqual(m.pack(), b"\x14")
768+
769+
def test_conditional_substructure_unpack(self):
770+
# Neither substructure is present
771+
m1 = ConditionalSubstructures.from_data(b"\x20")
772+
self.assertEqual(m1.f1, 0x20)
773+
self.assertEqual(m1.f2, None)
774+
self.assertEqual(m1.f3, None)
775+
776+
# Include f3 but not f2
777+
m2 = ConditionalSubstructures()
778+
m2.unpack(b"\x10" +
779+
b"\x11\x22")
780+
self.assertEqual(m2.f1, 0x10)
781+
self.assertEqual(m2.f2, None)
782+
self.assertIsInstance(m2.f3, BasicMessage)
783+
self.assertEqual(m2.f3.b1, 0x11)
784+
self.assertEqual(m2.f3.b2, 0x22)
785+
786+
# Include both substructures
787+
m3 = ConditionalSubstructures()
788+
m3.unpack(b"\x00" +
789+
b"\x11\x22" +
790+
b"\x33\x44")
791+
self.assertEqual(m3.f1, 0x00)
792+
self.assertIsInstance(m3.f2, BasicMessage)
793+
self.assertEqual(m3.f2.b1, 0x11)
794+
self.assertEqual(m3.f2.b2, 0x22)
795+
self.assertIsInstance(m3.f3, BasicMessage)
796+
self.assertEqual(m3.f3.b1, 0x33)
797+
self.assertEqual(m3.f3.b2, 0x44)
798+
735799

736800
class TestStructure(unittest.TestCase):
737801
def test_unpack_fewer_bytes_than_required(self):

0 commit comments

Comments
 (0)