Skip to content

Commit e9d29c2

Browse files
devbharataardappel
authored andcommitted
Python: Add forceDefaults opt to python Builder (google#5564)
* Add forceDefaults opt to python Builder * Add test functions for force_default option for python builder * Simplify * Add force default test for UOffsetTFlags
1 parent 8bfafc7 commit e9d29c2

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

python/flatbuffers/builder.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class Builder(object):
103103

104104
## @cond FLATBUFFERS_INTENRAL
105105
__slots__ = ("Bytes", "current_vtable", "head", "minalign", "objectEnd",
106-
"vtables", "nested", "finished")
106+
"vtables", "nested", "forceDefaults", "finished")
107107

108108
"""Maximum buffer size constant, in bytes.
109109
@@ -131,10 +131,10 @@ def __init__(self, initialSize):
131131
self.objectEnd = None
132132
self.vtables = {}
133133
self.nested = False
134+
self.forceDefaults = False
134135
## @endcond
135136
self.finished = False
136137

137-
138138
def Output(self):
139139
"""Return the portion of the buffer that has been used for writing data.
140140
@@ -552,7 +552,7 @@ def Prepend(self, flags, off):
552552
def PrependSlot(self, flags, o, x, d):
553553
N.enforce_number(x, flags)
554554
N.enforce_number(d, flags)
555-
if x != d:
555+
if x != d or self.forceDefaults:
556556
self.Prepend(flags, x)
557557
self.Slot(o)
558558

@@ -589,7 +589,7 @@ def PrependUOffsetTRelativeSlot(self, o, x, d):
589589
be set to zero and no other data will be written.
590590
"""
591591

592-
if x != d:
592+
if x != d or self.forceDefaults:
593593
self.PrependUOffsetTRelative(x)
594594
self.Slot(o)
595595

@@ -691,6 +691,15 @@ def PrependFloat64(self, x):
691691
"""
692692
self.Prepend(N.Float64Flags, x)
693693

694+
def ForceDefaults(self, forceDefaults):
695+
"""
696+
In order to save space, fields that are set to their default value
697+
don't get serialized into the buffer. Forcing defaults provides a
698+
way to manually disable this optimization. When set to `True`, will
699+
always serialize default values.
700+
"""
701+
self.forceDefaults = forceDefaults
702+
694703
##############################################################
695704

696705
## @cond FLATBUFFERS_INTERNAL

tests/py_test.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,41 @@ def make_monster_from_generated_code(sizePrefix = False, file_identifier=None):
11591159
return b.Bytes, b.Head()
11601160

11611161

1162+
class TestBuilderForceDefaults(unittest.TestCase):
1163+
"""Verify that the builder adds default values when forced."""
1164+
1165+
test_flags = [N.BoolFlags(), N.Uint8Flags(), N.Uint16Flags(), \
1166+
N.Uint32Flags(), N.Uint64Flags(), N.Int8Flags(), \
1167+
N.Int16Flags(), N.Int32Flags(), N.Int64Flags(), \
1168+
N.Float32Flags(), N.Float64Flags(), N.UOffsetTFlags()]
1169+
def test_default_force_defaults(self):
1170+
for flag in self.test_flags:
1171+
b = flatbuffers.Builder(0)
1172+
b.StartObject(1)
1173+
stored_offset = b.Offset()
1174+
if flag != N.UOffsetTFlags():
1175+
b.PrependSlot(flag, 0, 0, 0)
1176+
else:
1177+
b.PrependUOffsetTRelativeSlot(0, 0, 0)
1178+
end_offset = b.Offset()
1179+
b.EndObject()
1180+
self.assertEqual(0, end_offset - stored_offset)
1181+
1182+
def test_force_defaults_true(self):
1183+
for flag in self.test_flags:
1184+
b = flatbuffers.Builder(0)
1185+
b.ForceDefaults(True)
1186+
b.StartObject(1)
1187+
stored_offset = b.Offset()
1188+
if flag != N.UOffsetTFlags():
1189+
b.PrependSlot(flag, 0, 0, 0)
1190+
else:
1191+
b.PrependUOffsetTRelativeSlot(0, 0, 0)
1192+
end_offset = b.Offset()
1193+
b.EndObject()
1194+
self.assertEqual(flag.bytewidth, end_offset - stored_offset)
1195+
1196+
11621197
class TestAllCodePathsOfExampleSchema(unittest.TestCase):
11631198
def setUp(self, *args, **kwargs):
11641199
super(TestAllCodePathsOfExampleSchema, self).setUp(*args, **kwargs)

0 commit comments

Comments
 (0)