blob: 752f2f5d90cb6a750c9cd27cb0153d7db9165252 [file] [log] [blame]
Tamir Duberstein9d9d0b72015-04-11 20:23:45 -07001#! /usr/bin/env python
kenton@google.coma41a9dd2008-10-03 17:27:48 +00002# -*- coding: utf-8 -*-
kenton@google.com26bd9ee2008-11-21 00:06:27 +00003#
temporal40ee5512008-07-10 02:12:20 +00004# Protocol Buffers - Google's data interchange format
kenton@google.com24bf56f2008-09-24 20:31:01 +00005# Copyright 2008 Google Inc. All rights reserved.
Feng Xiaoe4288622014-10-01 16:26:23 -07006# https://developers.google.com/protocol-buffers/
temporal40ee5512008-07-10 02:12:20 +00007#
kenton@google.com24bf56f2008-09-24 20:31:01 +00008# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions are
10# met:
temporal40ee5512008-07-10 02:12:20 +000011#
kenton@google.com24bf56f2008-09-24 20:31:01 +000012# * Redistributions of source code must retain the above copyright
13# notice, this list of conditions and the following disclaimer.
14# * Redistributions in binary form must reproduce the above
15# copyright notice, this list of conditions and the following disclaimer
16# in the documentation and/or other materials provided with the
17# distribution.
18# * Neither the name of Google Inc. nor the names of its
19# contributors may be used to endorse or promote products derived from
20# this software without specific prior written permission.
temporal40ee5512008-07-10 02:12:20 +000021#
kenton@google.com24bf56f2008-09-24 20:31:01 +000022# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
temporal40ee5512008-07-10 02:12:20 +000034"""Unittest for reflection.py, which also indirectly tests the output of the
35pure-Python protocol compiler.
36"""
37
jieluo@google.combde4a322014-08-12 21:10:30 +000038import copy
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000039import gc
temporal40ee5512008-07-10 02:12:20 +000040import operator
Tres Seaverf336d4b2015-01-13 14:21:29 -050041import six
Jisi Liu46e8ff62015-10-05 11:59:43 -070042import struct
Tres Seaverf336d4b2015-01-13 14:21:29 -050043
Jisi Liudbea00a2015-10-05 16:08:22 -070044try:
45 import unittest2 as unittest
46except ImportError:
47 import unittest
temporal40ee5512008-07-10 02:12:20 +000048from google.protobuf import unittest_import_pb2
49from google.protobuf import unittest_mset_pb2
50from google.protobuf import unittest_pb2
51from google.protobuf import descriptor_pb2
52from google.protobuf import descriptor
53from google.protobuf import message
54from google.protobuf import reflection
jieluo@google.combde4a322014-08-12 21:10:30 +000055from google.protobuf import text_format
liujisi@google.com33165fe2010-11-02 13:14:58 +000056from google.protobuf.internal import api_implementation
temporal40ee5512008-07-10 02:12:20 +000057from google.protobuf.internal import more_extensions_pb2
58from google.protobuf.internal import more_messages_pb2
Feng Xiaoeee38b02015-08-22 18:25:48 -070059from google.protobuf.internal import message_set_extensions_pb2
temporal40ee5512008-07-10 02:12:20 +000060from google.protobuf.internal import wire_format
61from google.protobuf.internal import test_util
62from google.protobuf.internal import decoder
63
64
kenton@google.comfccb1462009-12-18 02:11:36 +000065class _MiniDecoder(object):
66 """Decodes a stream of values from a string.
67
68 Once upon a time we actually had a class called decoder.Decoder. Then we
69 got rid of it during a redesign that made decoding much, much faster overall.
70 But a couple tests in this file used it to check that the serialized form of
71 a message was correct. So, this class implements just the methods that were
72 used by said tests, so that we don't have to rewrite the tests.
73 """
74
75 def __init__(self, bytes):
76 self._bytes = bytes
77 self._pos = 0
78
79 def ReadVarint(self):
80 result, self._pos = decoder._DecodeVarint(self._bytes, self._pos)
81 return result
82
83 ReadInt32 = ReadVarint
84 ReadInt64 = ReadVarint
85 ReadUInt32 = ReadVarint
86 ReadUInt64 = ReadVarint
87
88 def ReadSInt64(self):
89 return wire_format.ZigZagDecode(self.ReadVarint())
90
91 ReadSInt32 = ReadSInt64
92
93 def ReadFieldNumberAndWireType(self):
94 return wire_format.UnpackTag(self.ReadVarint())
95
96 def ReadFloat(self):
97 result = struct.unpack("<f", self._bytes[self._pos:self._pos+4])[0]
98 self._pos += 4
99 return result
100
101 def ReadDouble(self):
102 result = struct.unpack("<d", self._bytes[self._pos:self._pos+8])[0]
103 self._pos += 8
104 return result
105
106 def EndOfStream(self):
107 return self._pos == len(self._bytes)
108
109
Tamir Duberstein9f42f5f2015-01-13 14:47:32 -0500110class ReflectionTest(unittest.TestCase):
pesho.petrov87e64e12008-12-24 01:07:22 +0000111
liujisi@google.com33165fe2010-11-02 13:14:58 +0000112 def assertListsEqual(self, values, others):
pesho.petrov87e64e12008-12-24 01:07:22 +0000113 self.assertEqual(len(values), len(others))
114 for i in range(len(values)):
liujisi@google.com33165fe2010-11-02 13:14:58 +0000115 self.assertEqual(values[i], others[i])
temporal40ee5512008-07-10 02:12:20 +0000116
kenton@google.comfccb1462009-12-18 02:11:36 +0000117 def testScalarConstructor(self):
118 # Constructor with only scalar types should succeed.
119 proto = unittest_pb2.TestAllTypes(
120 optional_int32=24,
121 optional_double=54.321,
122 optional_string='optional_string')
123
124 self.assertEqual(24, proto.optional_int32)
125 self.assertEqual(54.321, proto.optional_double)
126 self.assertEqual('optional_string', proto.optional_string)
127
128 def testRepeatedScalarConstructor(self):
129 # Constructor with only repeated scalar types should succeed.
130 proto = unittest_pb2.TestAllTypes(
131 repeated_int32=[1, 2, 3, 4],
132 repeated_double=[1.23, 54.321],
133 repeated_bool=[True, False, False],
134 repeated_string=["optional_string"])
135
Tres Seavera2abc942015-01-13 15:47:55 -0500136 self.assertEqual([1, 2, 3, 4], list(proto.repeated_int32))
137 self.assertEqual([1.23, 54.321], list(proto.repeated_double))
138 self.assertEqual([True, False, False], list(proto.repeated_bool))
139 self.assertEqual(["optional_string"], list(proto.repeated_string))
kenton@google.comfccb1462009-12-18 02:11:36 +0000140
141 def testRepeatedCompositeConstructor(self):
142 # Constructor with only repeated composite types should succeed.
143 proto = unittest_pb2.TestAllTypes(
144 repeated_nested_message=[
145 unittest_pb2.TestAllTypes.NestedMessage(
146 bb=unittest_pb2.TestAllTypes.FOO),
147 unittest_pb2.TestAllTypes.NestedMessage(
148 bb=unittest_pb2.TestAllTypes.BAR)],
149 repeated_foreign_message=[
150 unittest_pb2.ForeignMessage(c=-43),
151 unittest_pb2.ForeignMessage(c=45324),
152 unittest_pb2.ForeignMessage(c=12)],
153 repeatedgroup=[
154 unittest_pb2.TestAllTypes.RepeatedGroup(),
155 unittest_pb2.TestAllTypes.RepeatedGroup(a=1),
156 unittest_pb2.TestAllTypes.RepeatedGroup(a=2)])
157
Tres Seavera2abc942015-01-13 15:47:55 -0500158 self.assertEqual(
kenton@google.comfccb1462009-12-18 02:11:36 +0000159 [unittest_pb2.TestAllTypes.NestedMessage(
160 bb=unittest_pb2.TestAllTypes.FOO),
161 unittest_pb2.TestAllTypes.NestedMessage(
162 bb=unittest_pb2.TestAllTypes.BAR)],
163 list(proto.repeated_nested_message))
Tres Seavera2abc942015-01-13 15:47:55 -0500164 self.assertEqual(
kenton@google.comfccb1462009-12-18 02:11:36 +0000165 [unittest_pb2.ForeignMessage(c=-43),
166 unittest_pb2.ForeignMessage(c=45324),
167 unittest_pb2.ForeignMessage(c=12)],
168 list(proto.repeated_foreign_message))
Tres Seavera2abc942015-01-13 15:47:55 -0500169 self.assertEqual(
kenton@google.comfccb1462009-12-18 02:11:36 +0000170 [unittest_pb2.TestAllTypes.RepeatedGroup(),
171 unittest_pb2.TestAllTypes.RepeatedGroup(a=1),
172 unittest_pb2.TestAllTypes.RepeatedGroup(a=2)],
173 list(proto.repeatedgroup))
174
175 def testMixedConstructor(self):
176 # Constructor with only mixed types should succeed.
177 proto = unittest_pb2.TestAllTypes(
178 optional_int32=24,
179 optional_string='optional_string',
180 repeated_double=[1.23, 54.321],
181 repeated_bool=[True, False, False],
182 repeated_nested_message=[
183 unittest_pb2.TestAllTypes.NestedMessage(
184 bb=unittest_pb2.TestAllTypes.FOO),
185 unittest_pb2.TestAllTypes.NestedMessage(
186 bb=unittest_pb2.TestAllTypes.BAR)],
187 repeated_foreign_message=[
188 unittest_pb2.ForeignMessage(c=-43),
189 unittest_pb2.ForeignMessage(c=45324),
190 unittest_pb2.ForeignMessage(c=12)])
191
192 self.assertEqual(24, proto.optional_int32)
193 self.assertEqual('optional_string', proto.optional_string)
Tres Seavera2abc942015-01-13 15:47:55 -0500194 self.assertEqual([1.23, 54.321], list(proto.repeated_double))
195 self.assertEqual([True, False, False], list(proto.repeated_bool))
196 self.assertEqual(
kenton@google.comfccb1462009-12-18 02:11:36 +0000197 [unittest_pb2.TestAllTypes.NestedMessage(
198 bb=unittest_pb2.TestAllTypes.FOO),
199 unittest_pb2.TestAllTypes.NestedMessage(
200 bb=unittest_pb2.TestAllTypes.BAR)],
201 list(proto.repeated_nested_message))
Tres Seavera2abc942015-01-13 15:47:55 -0500202 self.assertEqual(
kenton@google.comfccb1462009-12-18 02:11:36 +0000203 [unittest_pb2.ForeignMessage(c=-43),
204 unittest_pb2.ForeignMessage(c=45324),
205 unittest_pb2.ForeignMessage(c=12)],
206 list(proto.repeated_foreign_message))
207
kenton@google.com27028bc2010-07-27 21:19:59 +0000208 def testConstructorTypeError(self):
liujisi@google.com33165fe2010-11-02 13:14:58 +0000209 self.assertRaises(
210 TypeError, unittest_pb2.TestAllTypes, optional_int32="foo")
211 self.assertRaises(
212 TypeError, unittest_pb2.TestAllTypes, optional_string=1234)
213 self.assertRaises(
214 TypeError, unittest_pb2.TestAllTypes, optional_nested_message=1234)
215 self.assertRaises(
216 TypeError, unittest_pb2.TestAllTypes, repeated_int32=1234)
217 self.assertRaises(
218 TypeError, unittest_pb2.TestAllTypes, repeated_int32=["foo"])
219 self.assertRaises(
220 TypeError, unittest_pb2.TestAllTypes, repeated_string=1234)
221 self.assertRaises(
222 TypeError, unittest_pb2.TestAllTypes, repeated_string=[1234])
223 self.assertRaises(
224 TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=1234)
225 self.assertRaises(
226 TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=[1234])
kenton@google.com27028bc2010-07-27 21:19:59 +0000227
228 def testConstructorInvalidatesCachedByteSize(self):
229 message = unittest_pb2.TestAllTypes(optional_int32 = 12)
Tres Seavera2abc942015-01-13 15:47:55 -0500230 self.assertEqual(2, message.ByteSize())
kenton@google.com27028bc2010-07-27 21:19:59 +0000231
232 message = unittest_pb2.TestAllTypes(
233 optional_nested_message = unittest_pb2.TestAllTypes.NestedMessage())
Tres Seavera2abc942015-01-13 15:47:55 -0500234 self.assertEqual(3, message.ByteSize())
kenton@google.com27028bc2010-07-27 21:19:59 +0000235
236 message = unittest_pb2.TestAllTypes(repeated_int32 = [12])
Tres Seavera2abc942015-01-13 15:47:55 -0500237 self.assertEqual(3, message.ByteSize())
kenton@google.com27028bc2010-07-27 21:19:59 +0000238
239 message = unittest_pb2.TestAllTypes(
240 repeated_nested_message = [unittest_pb2.TestAllTypes.NestedMessage()])
Tres Seavera2abc942015-01-13 15:47:55 -0500241 self.assertEqual(3, message.ByteSize())
kenton@google.com27028bc2010-07-27 21:19:59 +0000242
temporal40ee5512008-07-10 02:12:20 +0000243 def testSimpleHasBits(self):
244 # Test a scalar.
245 proto = unittest_pb2.TestAllTypes()
246 self.assertTrue(not proto.HasField('optional_int32'))
247 self.assertEqual(0, proto.optional_int32)
248 # HasField() shouldn't be true if all we've done is
249 # read the default value.
250 self.assertTrue(not proto.HasField('optional_int32'))
251 proto.optional_int32 = 1
252 # Setting a value however *should* set the "has" bit.
253 self.assertTrue(proto.HasField('optional_int32'))
254 proto.ClearField('optional_int32')
255 # And clearing that value should unset the "has" bit.
256 self.assertTrue(not proto.HasField('optional_int32'))
257
258 def testHasBitsWithSinglyNestedScalar(self):
259 # Helper used to test foreign messages and groups.
260 #
261 # composite_field_name should be the name of a non-repeated
262 # composite (i.e., foreign or group) field in TestAllTypes,
263 # and scalar_field_name should be the name of an integer-valued
264 # scalar field within that composite.
265 #
266 # I never thought I'd miss C++ macros and templates so much. :(
267 # This helper is semantically just:
268 #
269 # assert proto.composite_field.scalar_field == 0
270 # assert not proto.composite_field.HasField('scalar_field')
271 # assert not proto.HasField('composite_field')
272 #
273 # proto.composite_field.scalar_field = 10
274 # old_composite_field = proto.composite_field
275 #
276 # assert proto.composite_field.scalar_field == 10
277 # assert proto.composite_field.HasField('scalar_field')
278 # assert proto.HasField('composite_field')
279 #
280 # proto.ClearField('composite_field')
281 #
282 # assert not proto.composite_field.HasField('scalar_field')
283 # assert not proto.HasField('composite_field')
284 # assert proto.composite_field.scalar_field == 0
285 #
286 # # Now ensure that ClearField('composite_field') disconnected
287 # # the old field object from the object tree...
288 # assert old_composite_field is not proto.composite_field
289 # old_composite_field.scalar_field = 20
290 # assert not proto.composite_field.HasField('scalar_field')
291 # assert not proto.HasField('composite_field')
292 def TestCompositeHasBits(composite_field_name, scalar_field_name):
293 proto = unittest_pb2.TestAllTypes()
294 # First, check that we can get the scalar value, and see that it's the
295 # default (0), but that proto.HasField('omposite') and
296 # proto.composite.HasField('scalar') will still return False.
297 composite_field = getattr(proto, composite_field_name)
298 original_scalar_value = getattr(composite_field, scalar_field_name)
299 self.assertEqual(0, original_scalar_value)
300 # Assert that the composite object does not "have" the scalar.
301 self.assertTrue(not composite_field.HasField(scalar_field_name))
302 # Assert that proto does not "have" the composite field.
303 self.assertTrue(not proto.HasField(composite_field_name))
304
305 # Now set the scalar within the composite field. Ensure that the setting
306 # is reflected, and that proto.HasField('composite') and
307 # proto.composite.HasField('scalar') now both return True.
308 new_val = 20
309 setattr(composite_field, scalar_field_name, new_val)
310 self.assertEqual(new_val, getattr(composite_field, scalar_field_name))
311 # Hold on to a reference to the current composite_field object.
312 old_composite_field = composite_field
313 # Assert that the has methods now return true.
314 self.assertTrue(composite_field.HasField(scalar_field_name))
315 self.assertTrue(proto.HasField(composite_field_name))
316
317 # Now call the clear method...
318 proto.ClearField(composite_field_name)
319
320 # ...and ensure that the "has" bits are all back to False...
321 composite_field = getattr(proto, composite_field_name)
322 self.assertTrue(not composite_field.HasField(scalar_field_name))
323 self.assertTrue(not proto.HasField(composite_field_name))
324 # ...and ensure that the scalar field has returned to its default.
325 self.assertEqual(0, getattr(composite_field, scalar_field_name))
326
temporal40ee5512008-07-10 02:12:20 +0000327 self.assertTrue(old_composite_field is not composite_field)
328 setattr(old_composite_field, scalar_field_name, new_val)
329 self.assertTrue(not composite_field.HasField(scalar_field_name))
330 self.assertTrue(not proto.HasField(composite_field_name))
331 self.assertEqual(0, getattr(composite_field, scalar_field_name))
332
333 # Test simple, single-level nesting when we set a scalar.
334 TestCompositeHasBits('optionalgroup', 'a')
335 TestCompositeHasBits('optional_nested_message', 'bb')
336 TestCompositeHasBits('optional_foreign_message', 'c')
337 TestCompositeHasBits('optional_import_message', 'd')
338
339 def testReferencesToNestedMessage(self):
340 proto = unittest_pb2.TestAllTypes()
341 nested = proto.optional_nested_message
342 del proto
343 # A previous version had a bug where this would raise an exception when
344 # hitting a now-dead weak reference.
345 nested.bb = 23
346
347 def testDisconnectingNestedMessageBeforeSettingField(self):
348 proto = unittest_pb2.TestAllTypes()
349 nested = proto.optional_nested_message
350 proto.ClearField('optional_nested_message') # Should disconnect from parent
351 self.assertTrue(nested is not proto.optional_nested_message)
352 nested.bb = 23
353 self.assertTrue(not proto.HasField('optional_nested_message'))
354 self.assertEqual(0, proto.optional_nested_message.bb)
355
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000356 def testGetDefaultMessageAfterDisconnectingDefaultMessage(self):
357 proto = unittest_pb2.TestAllTypes()
358 nested = proto.optional_nested_message
359 proto.ClearField('optional_nested_message')
360 del proto
361 del nested
362 # Force a garbage collect so that the underlying CMessages are freed along
363 # with the Messages they point to. This is to make sure we're not deleting
364 # default message instances.
365 gc.collect()
366 proto = unittest_pb2.TestAllTypes()
367 nested = proto.optional_nested_message
368
369 def testDisconnectingNestedMessageAfterSettingField(self):
370 proto = unittest_pb2.TestAllTypes()
371 nested = proto.optional_nested_message
372 nested.bb = 5
373 self.assertTrue(proto.HasField('optional_nested_message'))
374 proto.ClearField('optional_nested_message') # Should disconnect from parent
375 self.assertEqual(5, nested.bb)
376 self.assertEqual(0, proto.optional_nested_message.bb)
377 self.assertTrue(nested is not proto.optional_nested_message)
378 nested.bb = 23
379 self.assertTrue(not proto.HasField('optional_nested_message'))
380 self.assertEqual(0, proto.optional_nested_message.bb)
381
382 def testDisconnectingNestedMessageBeforeGettingField(self):
383 proto = unittest_pb2.TestAllTypes()
384 self.assertTrue(not proto.HasField('optional_nested_message'))
385 proto.ClearField('optional_nested_message')
386 self.assertTrue(not proto.HasField('optional_nested_message'))
387
388 def testDisconnectingNestedMessageAfterMerge(self):
389 # This test exercises the code path that does not use ReleaseMessage().
390 # The underlying fear is that if we use ReleaseMessage() incorrectly,
391 # we will have memory leaks. It's hard to check that that doesn't happen,
392 # but at least we can exercise that code path to make sure it works.
393 proto1 = unittest_pb2.TestAllTypes()
394 proto2 = unittest_pb2.TestAllTypes()
395 proto2.optional_nested_message.bb = 5
396 proto1.MergeFrom(proto2)
397 self.assertTrue(proto1.HasField('optional_nested_message'))
398 proto1.ClearField('optional_nested_message')
399 self.assertTrue(not proto1.HasField('optional_nested_message'))
400
401 def testDisconnectingLazyNestedMessage(self):
402 # This test exercises releasing a nested message that is lazy. This test
403 # only exercises real code in the C++ implementation as Python does not
404 # support lazy parsing, but the current C++ implementation results in
405 # memory corruption and a crash.
406 if api_implementation.Type() != 'python':
407 return
408 proto = unittest_pb2.TestAllTypes()
409 proto.optional_lazy_message.bb = 5
410 proto.ClearField('optional_lazy_message')
411 del proto
412 gc.collect()
413
temporal40ee5512008-07-10 02:12:20 +0000414 def testHasBitsWhenModifyingRepeatedFields(self):
415 # Test nesting when we add an element to a repeated field in a submessage.
416 proto = unittest_pb2.TestNestedMessageHasBits()
417 proto.optional_nested_message.nestedmessage_repeated_int32.append(5)
418 self.assertEqual(
419 [5], proto.optional_nested_message.nestedmessage_repeated_int32)
420 self.assertTrue(proto.HasField('optional_nested_message'))
421
422 # Do the same test, but with a repeated composite field within the
423 # submessage.
424 proto.ClearField('optional_nested_message')
425 self.assertTrue(not proto.HasField('optional_nested_message'))
426 proto.optional_nested_message.nestedmessage_repeated_foreignmessage.add()
427 self.assertTrue(proto.HasField('optional_nested_message'))
428
429 def testHasBitsForManyLevelsOfNesting(self):
430 # Test nesting many levels deep.
431 recursive_proto = unittest_pb2.TestMutualRecursionA()
432 self.assertTrue(not recursive_proto.HasField('bb'))
433 self.assertEqual(0, recursive_proto.bb.a.bb.a.bb.optional_int32)
434 self.assertTrue(not recursive_proto.HasField('bb'))
435 recursive_proto.bb.a.bb.a.bb.optional_int32 = 5
436 self.assertEqual(5, recursive_proto.bb.a.bb.a.bb.optional_int32)
437 self.assertTrue(recursive_proto.HasField('bb'))
438 self.assertTrue(recursive_proto.bb.HasField('a'))
439 self.assertTrue(recursive_proto.bb.a.HasField('bb'))
440 self.assertTrue(recursive_proto.bb.a.bb.HasField('a'))
441 self.assertTrue(recursive_proto.bb.a.bb.a.HasField('bb'))
442 self.assertTrue(not recursive_proto.bb.a.bb.a.bb.HasField('a'))
443 self.assertTrue(recursive_proto.bb.a.bb.a.bb.HasField('optional_int32'))
444
445 def testSingularListFields(self):
446 proto = unittest_pb2.TestAllTypes()
447 proto.optional_fixed32 = 1
448 proto.optional_int32 = 5
449 proto.optional_string = 'foo'
kenton@google.comfccb1462009-12-18 02:11:36 +0000450 # Access sub-message but don't set it yet.
451 nested_message = proto.optional_nested_message
temporal40ee5512008-07-10 02:12:20 +0000452 self.assertEqual(
453 [ (proto.DESCRIPTOR.fields_by_name['optional_int32' ], 5),
454 (proto.DESCRIPTOR.fields_by_name['optional_fixed32'], 1),
455 (proto.DESCRIPTOR.fields_by_name['optional_string' ], 'foo') ],
456 proto.ListFields())
457
kenton@google.comfccb1462009-12-18 02:11:36 +0000458 proto.optional_nested_message.bb = 123
459 self.assertEqual(
460 [ (proto.DESCRIPTOR.fields_by_name['optional_int32' ], 5),
461 (proto.DESCRIPTOR.fields_by_name['optional_fixed32'], 1),
462 (proto.DESCRIPTOR.fields_by_name['optional_string' ], 'foo'),
463 (proto.DESCRIPTOR.fields_by_name['optional_nested_message' ],
464 nested_message) ],
465 proto.ListFields())
466
temporal40ee5512008-07-10 02:12:20 +0000467 def testRepeatedListFields(self):
468 proto = unittest_pb2.TestAllTypes()
469 proto.repeated_fixed32.append(1)
470 proto.repeated_int32.append(5)
471 proto.repeated_int32.append(11)
kenton@google.com2d6daa72009-01-22 01:27:00 +0000472 proto.repeated_string.extend(['foo', 'bar'])
473 proto.repeated_string.extend([])
temporal40ee5512008-07-10 02:12:20 +0000474 proto.repeated_string.append('baz')
Tres Seaverf336d4b2015-01-13 14:21:29 -0500475 proto.repeated_string.extend(str(x) for x in range(2))
temporal40ee5512008-07-10 02:12:20 +0000476 proto.optional_int32 = 21
kenton@google.comfccb1462009-12-18 02:11:36 +0000477 proto.repeated_bool # Access but don't set anything; should not be listed.
temporal40ee5512008-07-10 02:12:20 +0000478 self.assertEqual(
479 [ (proto.DESCRIPTOR.fields_by_name['optional_int32' ], 21),
480 (proto.DESCRIPTOR.fields_by_name['repeated_int32' ], [5, 11]),
481 (proto.DESCRIPTOR.fields_by_name['repeated_fixed32'], [1]),
482 (proto.DESCRIPTOR.fields_by_name['repeated_string' ],
kenton@google.com80b1d622009-07-29 01:13:20 +0000483 ['foo', 'bar', 'baz', '0', '1']) ],
temporal40ee5512008-07-10 02:12:20 +0000484 proto.ListFields())
485
486 def testSingularListExtensions(self):
487 proto = unittest_pb2.TestAllExtensions()
488 proto.Extensions[unittest_pb2.optional_fixed32_extension] = 1
489 proto.Extensions[unittest_pb2.optional_int32_extension ] = 5
490 proto.Extensions[unittest_pb2.optional_string_extension ] = 'foo'
491 self.assertEqual(
492 [ (unittest_pb2.optional_int32_extension , 5),
493 (unittest_pb2.optional_fixed32_extension, 1),
494 (unittest_pb2.optional_string_extension , 'foo') ],
495 proto.ListFields())
496
497 def testRepeatedListExtensions(self):
498 proto = unittest_pb2.TestAllExtensions()
499 proto.Extensions[unittest_pb2.repeated_fixed32_extension].append(1)
500 proto.Extensions[unittest_pb2.repeated_int32_extension ].append(5)
501 proto.Extensions[unittest_pb2.repeated_int32_extension ].append(11)
502 proto.Extensions[unittest_pb2.repeated_string_extension ].append('foo')
503 proto.Extensions[unittest_pb2.repeated_string_extension ].append('bar')
504 proto.Extensions[unittest_pb2.repeated_string_extension ].append('baz')
505 proto.Extensions[unittest_pb2.optional_int32_extension ] = 21
506 self.assertEqual(
507 [ (unittest_pb2.optional_int32_extension , 21),
508 (unittest_pb2.repeated_int32_extension , [5, 11]),
509 (unittest_pb2.repeated_fixed32_extension, [1]),
510 (unittest_pb2.repeated_string_extension , ['foo', 'bar', 'baz']) ],
511 proto.ListFields())
512
513 def testListFieldsAndExtensions(self):
514 proto = unittest_pb2.TestFieldOrderings()
515 test_util.SetAllFieldsAndExtensions(proto)
516 unittest_pb2.my_extension_int
517 self.assertEqual(
518 [ (proto.DESCRIPTOR.fields_by_name['my_int' ], 1),
519 (unittest_pb2.my_extension_int , 23),
520 (proto.DESCRIPTOR.fields_by_name['my_string'], 'foo'),
521 (unittest_pb2.my_extension_string , 'bar'),
522 (proto.DESCRIPTOR.fields_by_name['my_float' ], 1.0) ],
523 proto.ListFields())
524
525 def testDefaultValues(self):
526 proto = unittest_pb2.TestAllTypes()
527 self.assertEqual(0, proto.optional_int32)
528 self.assertEqual(0, proto.optional_int64)
529 self.assertEqual(0, proto.optional_uint32)
530 self.assertEqual(0, proto.optional_uint64)
531 self.assertEqual(0, proto.optional_sint32)
532 self.assertEqual(0, proto.optional_sint64)
533 self.assertEqual(0, proto.optional_fixed32)
534 self.assertEqual(0, proto.optional_fixed64)
535 self.assertEqual(0, proto.optional_sfixed32)
536 self.assertEqual(0, proto.optional_sfixed64)
537 self.assertEqual(0.0, proto.optional_float)
538 self.assertEqual(0.0, proto.optional_double)
539 self.assertEqual(False, proto.optional_bool)
540 self.assertEqual('', proto.optional_string)
jieluo@google.combde4a322014-08-12 21:10:30 +0000541 self.assertEqual(b'', proto.optional_bytes)
temporal40ee5512008-07-10 02:12:20 +0000542
543 self.assertEqual(41, proto.default_int32)
544 self.assertEqual(42, proto.default_int64)
545 self.assertEqual(43, proto.default_uint32)
546 self.assertEqual(44, proto.default_uint64)
547 self.assertEqual(-45, proto.default_sint32)
548 self.assertEqual(46, proto.default_sint64)
549 self.assertEqual(47, proto.default_fixed32)
550 self.assertEqual(48, proto.default_fixed64)
551 self.assertEqual(49, proto.default_sfixed32)
552 self.assertEqual(-50, proto.default_sfixed64)
553 self.assertEqual(51.5, proto.default_float)
554 self.assertEqual(52e3, proto.default_double)
555 self.assertEqual(True, proto.default_bool)
556 self.assertEqual('hello', proto.default_string)
jieluo@google.combde4a322014-08-12 21:10:30 +0000557 self.assertEqual(b'world', proto.default_bytes)
temporal40ee5512008-07-10 02:12:20 +0000558 self.assertEqual(unittest_pb2.TestAllTypes.BAR, proto.default_nested_enum)
559 self.assertEqual(unittest_pb2.FOREIGN_BAR, proto.default_foreign_enum)
560 self.assertEqual(unittest_import_pb2.IMPORT_BAR,
561 proto.default_import_enum)
562
kenton@google.com24bf56f2008-09-24 20:31:01 +0000563 proto = unittest_pb2.TestExtremeDefaultValues()
564 self.assertEqual(u'\u1234', proto.utf8_string)
565
temporal40ee5512008-07-10 02:12:20 +0000566 def testHasFieldWithUnknownFieldName(self):
567 proto = unittest_pb2.TestAllTypes()
568 self.assertRaises(ValueError, proto.HasField, 'nonexistent_field')
569
570 def testClearFieldWithUnknownFieldName(self):
571 proto = unittest_pb2.TestAllTypes()
572 self.assertRaises(ValueError, proto.ClearField, 'nonexistent_field')
573
jieluo@google.combde4a322014-08-12 21:10:30 +0000574 def testClearRemovesChildren(self):
575 # Make sure there aren't any implementation bugs that are only partially
576 # clearing the message (which can happen in the more complex C++
577 # implementation which has parallel message lists).
578 proto = unittest_pb2.TestRequiredForeign()
579 for i in range(10):
580 proto.repeated_message.add()
581 proto2 = unittest_pb2.TestRequiredForeign()
582 proto.CopyFrom(proto2)
583 self.assertRaises(IndexError, lambda: proto.repeated_message[5])
584
temporal40ee5512008-07-10 02:12:20 +0000585 def testDisallowedAssignments(self):
586 # It's illegal to assign values directly to repeated fields
587 # or to nonrepeated composite fields. Ensure that this fails.
588 proto = unittest_pb2.TestAllTypes()
589 # Repeated fields.
590 self.assertRaises(AttributeError, setattr, proto, 'repeated_int32', 10)
591 # Lists shouldn't work, either.
592 self.assertRaises(AttributeError, setattr, proto, 'repeated_int32', [10])
593 # Composite fields.
594 self.assertRaises(AttributeError, setattr, proto,
595 'optional_nested_message', 23)
kenton@google.com24bf56f2008-09-24 20:31:01 +0000596 # Assignment to a repeated nested message field without specifying
597 # the index in the array of nested messages.
598 self.assertRaises(AttributeError, setattr, proto.repeated_nested_message,
599 'bb', 34)
600 # Assignment to an attribute of a repeated field.
601 self.assertRaises(AttributeError, setattr, proto.repeated_float,
602 'some_attribute', 34)
temporal40ee5512008-07-10 02:12:20 +0000603 # proto.nonexistent_field = 23 should fail as well.
604 self.assertRaises(AttributeError, setattr, proto, 'nonexistent_field', 23)
605
temporal40ee5512008-07-10 02:12:20 +0000606 def testSingleScalarTypeSafety(self):
607 proto = unittest_pb2.TestAllTypes()
608 self.assertRaises(TypeError, setattr, proto, 'optional_int32', 1.1)
609 self.assertRaises(TypeError, setattr, proto, 'optional_int32', 'foo')
610 self.assertRaises(TypeError, setattr, proto, 'optional_string', 10)
611 self.assertRaises(TypeError, setattr, proto, 'optional_bytes', 10)
612
jieluo@google.combde4a322014-08-12 21:10:30 +0000613 def testIntegerTypes(self):
614 def TestGetAndDeserialize(field_name, value, expected_type):
615 proto = unittest_pb2.TestAllTypes()
616 setattr(proto, field_name, value)
Tamir Duberstein821fcb22015-08-12 14:22:25 -0400617 self.assertIsInstance(getattr(proto, field_name), expected_type)
jieluo@google.combde4a322014-08-12 21:10:30 +0000618 proto2 = unittest_pb2.TestAllTypes()
619 proto2.ParseFromString(proto.SerializeToString())
Tamir Duberstein821fcb22015-08-12 14:22:25 -0400620 self.assertIsInstance(getattr(proto2, field_name), expected_type)
jieluo@google.combde4a322014-08-12 21:10:30 +0000621
622 TestGetAndDeserialize('optional_int32', 1, int)
623 TestGetAndDeserialize('optional_int32', 1 << 30, int)
624 TestGetAndDeserialize('optional_uint32', 1 << 30, int)
Tres Seaverf336d4b2015-01-13 14:21:29 -0500625 try:
626 integer_64 = long
627 except NameError: # Python3
628 integer_64 = int
jieluo@google.combde4a322014-08-12 21:10:30 +0000629 if struct.calcsize('L') == 4:
630 # Python only has signed ints, so 32-bit python can't fit an uint32
631 # in an int.
632 TestGetAndDeserialize('optional_uint32', 1 << 31, long)
633 else:
634 # 64-bit python can fit uint32 inside an int
635 TestGetAndDeserialize('optional_uint32', 1 << 31, int)
Tres Seaverf336d4b2015-01-13 14:21:29 -0500636 TestGetAndDeserialize('optional_int64', 1 << 30, integer_64)
637 TestGetAndDeserialize('optional_int64', 1 << 60, integer_64)
638 TestGetAndDeserialize('optional_uint64', 1 << 30, integer_64)
639 TestGetAndDeserialize('optional_uint64', 1 << 60, integer_64)
jieluo@google.combde4a322014-08-12 21:10:30 +0000640
temporal40ee5512008-07-10 02:12:20 +0000641 def testSingleScalarBoundsChecking(self):
642 def TestMinAndMaxIntegers(field_name, expected_min, expected_max):
643 pb = unittest_pb2.TestAllTypes()
644 setattr(pb, field_name, expected_min)
liujisi@google.com33165fe2010-11-02 13:14:58 +0000645 self.assertEqual(expected_min, getattr(pb, field_name))
temporal40ee5512008-07-10 02:12:20 +0000646 setattr(pb, field_name, expected_max)
liujisi@google.com33165fe2010-11-02 13:14:58 +0000647 self.assertEqual(expected_max, getattr(pb, field_name))
temporal40ee5512008-07-10 02:12:20 +0000648 self.assertRaises(ValueError, setattr, pb, field_name, expected_min - 1)
649 self.assertRaises(ValueError, setattr, pb, field_name, expected_max + 1)
650
651 TestMinAndMaxIntegers('optional_int32', -(1 << 31), (1 << 31) - 1)
652 TestMinAndMaxIntegers('optional_uint32', 0, 0xffffffff)
653 TestMinAndMaxIntegers('optional_int64', -(1 << 63), (1 << 63) - 1)
654 TestMinAndMaxIntegers('optional_uint64', 0, 0xffffffffffffffff)
liujisi@google.com33165fe2010-11-02 13:14:58 +0000655
656 pb = unittest_pb2.TestAllTypes()
657 pb.optional_nested_enum = 1
658 self.assertEqual(1, pb.optional_nested_enum)
659
temporal40ee5512008-07-10 02:12:20 +0000660 def testRepeatedScalarTypeSafety(self):
661 proto = unittest_pb2.TestAllTypes()
662 self.assertRaises(TypeError, proto.repeated_int32.append, 1.1)
663 self.assertRaises(TypeError, proto.repeated_int32.append, 'foo')
664 self.assertRaises(TypeError, proto.repeated_string, 10)
665 self.assertRaises(TypeError, proto.repeated_bytes, 10)
666
667 proto.repeated_int32.append(10)
668 proto.repeated_int32[0] = 23
669 self.assertRaises(IndexError, proto.repeated_int32.__setitem__, 500, 23)
670 self.assertRaises(TypeError, proto.repeated_int32.__setitem__, 0, 'abc')
671
liujisi@google.com33165fe2010-11-02 13:14:58 +0000672 # Repeated enums tests.
673 #proto.repeated_nested_enum.append(0)
674
temporal40ee5512008-07-10 02:12:20 +0000675 def testSingleScalarGettersAndSetters(self):
676 proto = unittest_pb2.TestAllTypes()
677 self.assertEqual(0, proto.optional_int32)
678 proto.optional_int32 = 1
679 self.assertEqual(1, proto.optional_int32)
liujisi@google.com33165fe2010-11-02 13:14:58 +0000680
681 proto.optional_uint64 = 0xffffffffffff
682 self.assertEqual(0xffffffffffff, proto.optional_uint64)
683 proto.optional_uint64 = 0xffffffffffffffff
684 self.assertEqual(0xffffffffffffffff, proto.optional_uint64)
temporal40ee5512008-07-10 02:12:20 +0000685 # TODO(robinson): Test all other scalar field types.
686
687 def testSingleScalarClearField(self):
688 proto = unittest_pb2.TestAllTypes()
689 # Should be allowed to clear something that's not there (a no-op).
690 proto.ClearField('optional_int32')
691 proto.optional_int32 = 1
692 self.assertTrue(proto.HasField('optional_int32'))
693 proto.ClearField('optional_int32')
694 self.assertEqual(0, proto.optional_int32)
695 self.assertTrue(not proto.HasField('optional_int32'))
696 # TODO(robinson): Test all other scalar field types.
697
698 def testEnums(self):
699 proto = unittest_pb2.TestAllTypes()
700 self.assertEqual(1, proto.FOO)
701 self.assertEqual(1, unittest_pb2.TestAllTypes.FOO)
702 self.assertEqual(2, proto.BAR)
703 self.assertEqual(2, unittest_pb2.TestAllTypes.BAR)
704 self.assertEqual(3, proto.BAZ)
705 self.assertEqual(3, unittest_pb2.TestAllTypes.BAZ)
706
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000707 def testEnum_Name(self):
708 self.assertEqual('FOREIGN_FOO',
709 unittest_pb2.ForeignEnum.Name(unittest_pb2.FOREIGN_FOO))
710 self.assertEqual('FOREIGN_BAR',
711 unittest_pb2.ForeignEnum.Name(unittest_pb2.FOREIGN_BAR))
712 self.assertEqual('FOREIGN_BAZ',
713 unittest_pb2.ForeignEnum.Name(unittest_pb2.FOREIGN_BAZ))
714 self.assertRaises(ValueError,
715 unittest_pb2.ForeignEnum.Name, 11312)
716
717 proto = unittest_pb2.TestAllTypes()
718 self.assertEqual('FOO',
719 proto.NestedEnum.Name(proto.FOO))
720 self.assertEqual('FOO',
721 unittest_pb2.TestAllTypes.NestedEnum.Name(proto.FOO))
722 self.assertEqual('BAR',
723 proto.NestedEnum.Name(proto.BAR))
724 self.assertEqual('BAR',
725 unittest_pb2.TestAllTypes.NestedEnum.Name(proto.BAR))
726 self.assertEqual('BAZ',
727 proto.NestedEnum.Name(proto.BAZ))
728 self.assertEqual('BAZ',
729 unittest_pb2.TestAllTypes.NestedEnum.Name(proto.BAZ))
730 self.assertRaises(ValueError,
731 proto.NestedEnum.Name, 11312)
732 self.assertRaises(ValueError,
733 unittest_pb2.TestAllTypes.NestedEnum.Name, 11312)
734
735 def testEnum_Value(self):
736 self.assertEqual(unittest_pb2.FOREIGN_FOO,
737 unittest_pb2.ForeignEnum.Value('FOREIGN_FOO'))
738 self.assertEqual(unittest_pb2.FOREIGN_BAR,
739 unittest_pb2.ForeignEnum.Value('FOREIGN_BAR'))
740 self.assertEqual(unittest_pb2.FOREIGN_BAZ,
741 unittest_pb2.ForeignEnum.Value('FOREIGN_BAZ'))
742 self.assertRaises(ValueError,
743 unittest_pb2.ForeignEnum.Value, 'FO')
744
745 proto = unittest_pb2.TestAllTypes()
746 self.assertEqual(proto.FOO,
747 proto.NestedEnum.Value('FOO'))
748 self.assertEqual(proto.FOO,
749 unittest_pb2.TestAllTypes.NestedEnum.Value('FOO'))
750 self.assertEqual(proto.BAR,
751 proto.NestedEnum.Value('BAR'))
752 self.assertEqual(proto.BAR,
753 unittest_pb2.TestAllTypes.NestedEnum.Value('BAR'))
754 self.assertEqual(proto.BAZ,
755 proto.NestedEnum.Value('BAZ'))
756 self.assertEqual(proto.BAZ,
757 unittest_pb2.TestAllTypes.NestedEnum.Value('BAZ'))
758 self.assertRaises(ValueError,
759 proto.NestedEnum.Value, 'Foo')
760 self.assertRaises(ValueError,
761 unittest_pb2.TestAllTypes.NestedEnum.Value, 'Foo')
762
763 def testEnum_KeysAndValues(self):
764 self.assertEqual(['FOREIGN_FOO', 'FOREIGN_BAR', 'FOREIGN_BAZ'],
Tres Seaverf336d4b2015-01-13 14:21:29 -0500765 list(unittest_pb2.ForeignEnum.keys()))
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000766 self.assertEqual([4, 5, 6],
Tres Seaverf336d4b2015-01-13 14:21:29 -0500767 list(unittest_pb2.ForeignEnum.values()))
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000768 self.assertEqual([('FOREIGN_FOO', 4), ('FOREIGN_BAR', 5),
769 ('FOREIGN_BAZ', 6)],
Tres Seaverf336d4b2015-01-13 14:21:29 -0500770 list(unittest_pb2.ForeignEnum.items()))
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000771
772 proto = unittest_pb2.TestAllTypes()
Tres Seaverf336d4b2015-01-13 14:21:29 -0500773 self.assertEqual(['FOO', 'BAR', 'BAZ', 'NEG'], list(proto.NestedEnum.keys()))
774 self.assertEqual([1, 2, 3, -1], list(proto.NestedEnum.values()))
jieluo@google.combde4a322014-08-12 21:10:30 +0000775 self.assertEqual([('FOO', 1), ('BAR', 2), ('BAZ', 3), ('NEG', -1)],
Tres Seaverf336d4b2015-01-13 14:21:29 -0500776 list(proto.NestedEnum.items()))
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000777
temporal40ee5512008-07-10 02:12:20 +0000778 def testRepeatedScalars(self):
779 proto = unittest_pb2.TestAllTypes()
780
781 self.assertTrue(not proto.repeated_int32)
782 self.assertEqual(0, len(proto.repeated_int32))
pesho.petrov87e64e12008-12-24 01:07:22 +0000783 proto.repeated_int32.append(5)
784 proto.repeated_int32.append(10)
785 proto.repeated_int32.append(15)
temporal40ee5512008-07-10 02:12:20 +0000786 self.assertTrue(proto.repeated_int32)
pesho.petrov87e64e12008-12-24 01:07:22 +0000787 self.assertEqual(3, len(proto.repeated_int32))
temporal40ee5512008-07-10 02:12:20 +0000788
pesho.petrov87e64e12008-12-24 01:07:22 +0000789 self.assertEqual([5, 10, 15], proto.repeated_int32)
790
791 # Test single retrieval.
temporal40ee5512008-07-10 02:12:20 +0000792 self.assertEqual(5, proto.repeated_int32[0])
pesho.petrov87e64e12008-12-24 01:07:22 +0000793 self.assertEqual(15, proto.repeated_int32[-1])
temporal40ee5512008-07-10 02:12:20 +0000794 # Test out-of-bounds indices.
795 self.assertRaises(IndexError, proto.repeated_int32.__getitem__, 1234)
796 self.assertRaises(IndexError, proto.repeated_int32.__getitem__, -1234)
797 # Test incorrect types passed to __getitem__.
798 self.assertRaises(TypeError, proto.repeated_int32.__getitem__, 'foo')
799 self.assertRaises(TypeError, proto.repeated_int32.__getitem__, None)
800
pesho.petrov87e64e12008-12-24 01:07:22 +0000801 # Test single assignment.
802 proto.repeated_int32[1] = 20
803 self.assertEqual([5, 20, 15], proto.repeated_int32)
804
805 # Test insertion.
806 proto.repeated_int32.insert(1, 25)
807 self.assertEqual([5, 25, 20, 15], proto.repeated_int32)
808
809 # Test slice retrieval.
810 proto.repeated_int32.append(30)
811 self.assertEqual([25, 20, 15], proto.repeated_int32[1:4])
812 self.assertEqual([5, 25, 20, 15, 30], proto.repeated_int32[:])
813
kenton@google.com80b1d622009-07-29 01:13:20 +0000814 # Test slice assignment with an iterator
Tres Seaverf336d4b2015-01-13 14:21:29 -0500815 proto.repeated_int32[1:4] = (i for i in range(3))
kenton@google.com80b1d622009-07-29 01:13:20 +0000816 self.assertEqual([5, 0, 1, 2, 30], proto.repeated_int32)
817
pesho.petrov87e64e12008-12-24 01:07:22 +0000818 # Test slice assignment.
819 proto.repeated_int32[1:4] = [35, 40, 45]
820 self.assertEqual([5, 35, 40, 45, 30], proto.repeated_int32)
821
temporal40ee5512008-07-10 02:12:20 +0000822 # Test that we can use the field as an iterator.
823 result = []
824 for i in proto.repeated_int32:
825 result.append(i)
pesho.petrov87e64e12008-12-24 01:07:22 +0000826 self.assertEqual([5, 35, 40, 45, 30], result)
827
828 # Test single deletion.
829 del proto.repeated_int32[2]
830 self.assertEqual([5, 35, 45, 30], proto.repeated_int32)
831
832 # Test slice deletion.
833 del proto.repeated_int32[2:]
834 self.assertEqual([5, 35], proto.repeated_int32)
temporal40ee5512008-07-10 02:12:20 +0000835
liujisi@google.com33165fe2010-11-02 13:14:58 +0000836 # Test extending.
837 proto.repeated_int32.extend([3, 13])
838 self.assertEqual([5, 35, 3, 13], proto.repeated_int32)
839
temporal40ee5512008-07-10 02:12:20 +0000840 # Test clearing.
841 proto.ClearField('repeated_int32')
842 self.assertTrue(not proto.repeated_int32)
843 self.assertEqual(0, len(proto.repeated_int32))
844
liujisi@google.com33165fe2010-11-02 13:14:58 +0000845 proto.repeated_int32.append(1)
846 self.assertEqual(1, proto.repeated_int32[-1])
847 # Test assignment to a negative index.
848 proto.repeated_int32[-1] = 2
849 self.assertEqual(2, proto.repeated_int32[-1])
850
851 # Test deletion at negative indices.
852 proto.repeated_int32[:] = [0, 1, 2, 3]
853 del proto.repeated_int32[-1]
854 self.assertEqual([0, 1, 2], proto.repeated_int32)
855
856 del proto.repeated_int32[-2]
857 self.assertEqual([0, 2], proto.repeated_int32)
858
859 self.assertRaises(IndexError, proto.repeated_int32.__delitem__, -3)
860 self.assertRaises(IndexError, proto.repeated_int32.__delitem__, 300)
861
862 del proto.repeated_int32[-2:-1]
863 self.assertEqual([2], proto.repeated_int32)
864
865 del proto.repeated_int32[100:10000]
866 self.assertEqual([2], proto.repeated_int32)
867
kenton@google.com24bf56f2008-09-24 20:31:01 +0000868 def testRepeatedScalarsRemove(self):
869 proto = unittest_pb2.TestAllTypes()
870
871 self.assertTrue(not proto.repeated_int32)
872 self.assertEqual(0, len(proto.repeated_int32))
873 proto.repeated_int32.append(5)
874 proto.repeated_int32.append(10)
875 proto.repeated_int32.append(5)
876 proto.repeated_int32.append(5)
877
878 self.assertEqual(4, len(proto.repeated_int32))
879 proto.repeated_int32.remove(5)
880 self.assertEqual(3, len(proto.repeated_int32))
881 self.assertEqual(10, proto.repeated_int32[0])
882 self.assertEqual(5, proto.repeated_int32[1])
883 self.assertEqual(5, proto.repeated_int32[2])
884
885 proto.repeated_int32.remove(5)
886 self.assertEqual(2, len(proto.repeated_int32))
887 self.assertEqual(10, proto.repeated_int32[0])
888 self.assertEqual(5, proto.repeated_int32[1])
889
890 proto.repeated_int32.remove(10)
891 self.assertEqual(1, len(proto.repeated_int32))
892 self.assertEqual(5, proto.repeated_int32[0])
893
894 # Remove a non-existent element.
895 self.assertRaises(ValueError, proto.repeated_int32.remove, 123)
896
temporal40ee5512008-07-10 02:12:20 +0000897 def testRepeatedComposites(self):
898 proto = unittest_pb2.TestAllTypes()
899 self.assertTrue(not proto.repeated_nested_message)
900 self.assertEqual(0, len(proto.repeated_nested_message))
901 m0 = proto.repeated_nested_message.add()
902 m1 = proto.repeated_nested_message.add()
903 self.assertTrue(proto.repeated_nested_message)
904 self.assertEqual(2, len(proto.repeated_nested_message))
liujisi@google.com33165fe2010-11-02 13:14:58 +0000905 self.assertListsEqual([m0, m1], proto.repeated_nested_message)
Tamir Duberstein821fcb22015-08-12 14:22:25 -0400906 self.assertIsInstance(m0, unittest_pb2.TestAllTypes.NestedMessage)
temporal40ee5512008-07-10 02:12:20 +0000907
908 # Test out-of-bounds indices.
909 self.assertRaises(IndexError, proto.repeated_nested_message.__getitem__,
910 1234)
911 self.assertRaises(IndexError, proto.repeated_nested_message.__getitem__,
912 -1234)
913
914 # Test incorrect types passed to __getitem__.
915 self.assertRaises(TypeError, proto.repeated_nested_message.__getitem__,
916 'foo')
917 self.assertRaises(TypeError, proto.repeated_nested_message.__getitem__,
918 None)
919
pesho.petrov87e64e12008-12-24 01:07:22 +0000920 # Test slice retrieval.
921 m2 = proto.repeated_nested_message.add()
922 m3 = proto.repeated_nested_message.add()
923 m4 = proto.repeated_nested_message.add()
liujisi@google.com33165fe2010-11-02 13:14:58 +0000924 self.assertListsEqual(
925 [m1, m2, m3], proto.repeated_nested_message[1:4])
926 self.assertListsEqual(
927 [m0, m1, m2, m3, m4], proto.repeated_nested_message[:])
928 self.assertListsEqual(
929 [m0, m1], proto.repeated_nested_message[:2])
930 self.assertListsEqual(
931 [m2, m3, m4], proto.repeated_nested_message[2:])
932 self.assertEqual(
933 m0, proto.repeated_nested_message[0])
934 self.assertListsEqual(
935 [m0], proto.repeated_nested_message[:1])
pesho.petrov87e64e12008-12-24 01:07:22 +0000936
temporal40ee5512008-07-10 02:12:20 +0000937 # Test that we can use the field as an iterator.
938 result = []
939 for i in proto.repeated_nested_message:
940 result.append(i)
liujisi@google.com33165fe2010-11-02 13:14:58 +0000941 self.assertListsEqual([m0, m1, m2, m3, m4], result)
temporal40ee5512008-07-10 02:12:20 +0000942
pesho.petrov87e64e12008-12-24 01:07:22 +0000943 # Test single deletion.
944 del proto.repeated_nested_message[2]
liujisi@google.com33165fe2010-11-02 13:14:58 +0000945 self.assertListsEqual([m0, m1, m3, m4], proto.repeated_nested_message)
pesho.petrov87e64e12008-12-24 01:07:22 +0000946
947 # Test slice deletion.
948 del proto.repeated_nested_message[2:]
liujisi@google.com33165fe2010-11-02 13:14:58 +0000949 self.assertListsEqual([m0, m1], proto.repeated_nested_message)
950
951 # Test extending.
952 n1 = unittest_pb2.TestAllTypes.NestedMessage(bb=1)
953 n2 = unittest_pb2.TestAllTypes.NestedMessage(bb=2)
954 proto.repeated_nested_message.extend([n1,n2])
955 self.assertEqual(4, len(proto.repeated_nested_message))
956 self.assertEqual(n1, proto.repeated_nested_message[2])
957 self.assertEqual(n2, proto.repeated_nested_message[3])
kenton@google.com24bf56f2008-09-24 20:31:01 +0000958
temporal40ee5512008-07-10 02:12:20 +0000959 # Test clearing.
960 proto.ClearField('repeated_nested_message')
961 self.assertTrue(not proto.repeated_nested_message)
962 self.assertEqual(0, len(proto.repeated_nested_message))
963
liujisi@google.com33165fe2010-11-02 13:14:58 +0000964 # Test constructing an element while adding it.
965 proto.repeated_nested_message.add(bb=23)
966 self.assertEqual(1, len(proto.repeated_nested_message))
967 self.assertEqual(23, proto.repeated_nested_message[0].bb)
968
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000969 def testRepeatedCompositeRemove(self):
970 proto = unittest_pb2.TestAllTypes()
971
972 self.assertEqual(0, len(proto.repeated_nested_message))
973 m0 = proto.repeated_nested_message.add()
974 # Need to set some differentiating variable so m0 != m1 != m2:
975 m0.bb = len(proto.repeated_nested_message)
976 m1 = proto.repeated_nested_message.add()
977 m1.bb = len(proto.repeated_nested_message)
978 self.assertTrue(m0 != m1)
979 m2 = proto.repeated_nested_message.add()
980 m2.bb = len(proto.repeated_nested_message)
981 self.assertListsEqual([m0, m1, m2], proto.repeated_nested_message)
982
983 self.assertEqual(3, len(proto.repeated_nested_message))
984 proto.repeated_nested_message.remove(m0)
985 self.assertEqual(2, len(proto.repeated_nested_message))
986 self.assertEqual(m1, proto.repeated_nested_message[0])
987 self.assertEqual(m2, proto.repeated_nested_message[1])
988
989 # Removing m0 again or removing None should raise error
990 self.assertRaises(ValueError, proto.repeated_nested_message.remove, m0)
991 self.assertRaises(ValueError, proto.repeated_nested_message.remove, None)
992 self.assertEqual(2, len(proto.repeated_nested_message))
993
994 proto.repeated_nested_message.remove(m2)
995 self.assertEqual(1, len(proto.repeated_nested_message))
996 self.assertEqual(m1, proto.repeated_nested_message[0])
997
temporal40ee5512008-07-10 02:12:20 +0000998 def testHandWrittenReflection(self):
liujisi@google.com33165fe2010-11-02 13:14:58 +0000999 # Hand written extensions are only supported by the pure-Python
1000 # implementation of the API.
1001 if api_implementation.Type() != 'python':
1002 return
1003
temporal40ee5512008-07-10 02:12:20 +00001004 FieldDescriptor = descriptor.FieldDescriptor
1005 foo_field_descriptor = FieldDescriptor(
1006 name='foo_field', full_name='MyProto.foo_field',
1007 index=0, number=1, type=FieldDescriptor.TYPE_INT64,
1008 cpp_type=FieldDescriptor.CPPTYPE_INT64,
1009 label=FieldDescriptor.LABEL_OPTIONAL, default_value=0,
1010 containing_type=None, message_type=None, enum_type=None,
1011 is_extension=False, extension_scope=None,
1012 options=descriptor_pb2.FieldOptions())
1013 mydescriptor = descriptor.Descriptor(
1014 name='MyProto', full_name='MyProto', filename='ignored',
1015 containing_type=None, nested_types=[], enum_types=[],
1016 fields=[foo_field_descriptor], extensions=[],
1017 options=descriptor_pb2.MessageOptions())
Tres Seaverf336d4b2015-01-13 14:21:29 -05001018 class MyProtoClass(six.with_metaclass(reflection.GeneratedProtocolMessageType, message.Message)):
temporal40ee5512008-07-10 02:12:20 +00001019 DESCRIPTOR = mydescriptor
temporal40ee5512008-07-10 02:12:20 +00001020 myproto_instance = MyProtoClass()
1021 self.assertEqual(0, myproto_instance.foo_field)
1022 self.assertTrue(not myproto_instance.HasField('foo_field'))
1023 myproto_instance.foo_field = 23
1024 self.assertEqual(23, myproto_instance.foo_field)
1025 self.assertTrue(myproto_instance.HasField('foo_field'))
1026
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001027 def testDescriptorProtoSupport(self):
1028 # Hand written descriptors/reflection are only supported by the pure-Python
1029 # implementation of the API.
1030 if api_implementation.Type() != 'python':
1031 return
1032
1033 def AddDescriptorField(proto, field_name, field_type):
1034 AddDescriptorField.field_index += 1
1035 new_field = proto.field.add()
1036 new_field.name = field_name
1037 new_field.type = field_type
1038 new_field.number = AddDescriptorField.field_index
1039 new_field.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL
1040
1041 AddDescriptorField.field_index = 0
1042
1043 desc_proto = descriptor_pb2.DescriptorProto()
1044 desc_proto.name = 'Car'
1045 fdp = descriptor_pb2.FieldDescriptorProto
1046 AddDescriptorField(desc_proto, 'name', fdp.TYPE_STRING)
1047 AddDescriptorField(desc_proto, 'year', fdp.TYPE_INT64)
1048 AddDescriptorField(desc_proto, 'automatic', fdp.TYPE_BOOL)
1049 AddDescriptorField(desc_proto, 'price', fdp.TYPE_DOUBLE)
1050 # Add a repeated field
1051 AddDescriptorField.field_index += 1
1052 new_field = desc_proto.field.add()
1053 new_field.name = 'owners'
1054 new_field.type = fdp.TYPE_STRING
1055 new_field.number = AddDescriptorField.field_index
1056 new_field.label = descriptor_pb2.FieldDescriptorProto.LABEL_REPEATED
1057
1058 desc = descriptor.MakeDescriptor(desc_proto)
Tres Seaverf336d4b2015-01-13 14:21:29 -05001059 self.assertTrue('name' in desc.fields_by_name)
1060 self.assertTrue('year' in desc.fields_by_name)
1061 self.assertTrue('automatic' in desc.fields_by_name)
1062 self.assertTrue('price' in desc.fields_by_name)
1063 self.assertTrue('owners' in desc.fields_by_name)
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001064
Tres Seaverf336d4b2015-01-13 14:21:29 -05001065 class CarMessage(six.with_metaclass(reflection.GeneratedProtocolMessageType, message.Message)):
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001066 DESCRIPTOR = desc
1067
1068 prius = CarMessage()
1069 prius.name = 'prius'
1070 prius.year = 2010
1071 prius.automatic = True
1072 prius.price = 25134.75
1073 prius.owners.extend(['bob', 'susan'])
1074
1075 serialized_prius = prius.SerializeToString()
1076 new_prius = reflection.ParseMessage(desc, serialized_prius)
1077 self.assertTrue(new_prius is not prius)
1078 self.assertEqual(prius, new_prius)
1079
1080 # these are unnecessary assuming message equality works as advertised but
1081 # explicitly check to be safe since we're mucking about in metaclass foo
1082 self.assertEqual(prius.name, new_prius.name)
1083 self.assertEqual(prius.year, new_prius.year)
1084 self.assertEqual(prius.automatic, new_prius.automatic)
1085 self.assertEqual(prius.price, new_prius.price)
1086 self.assertEqual(prius.owners, new_prius.owners)
1087
temporal40ee5512008-07-10 02:12:20 +00001088 def testTopLevelExtensionsForOptionalScalar(self):
1089 extendee_proto = unittest_pb2.TestAllExtensions()
1090 extension = unittest_pb2.optional_int32_extension
1091 self.assertTrue(not extendee_proto.HasExtension(extension))
1092 self.assertEqual(0, extendee_proto.Extensions[extension])
1093 # As with normal scalar fields, just doing a read doesn't actually set the
1094 # "has" bit.
1095 self.assertTrue(not extendee_proto.HasExtension(extension))
1096 # Actually set the thing.
1097 extendee_proto.Extensions[extension] = 23
1098 self.assertEqual(23, extendee_proto.Extensions[extension])
1099 self.assertTrue(extendee_proto.HasExtension(extension))
1100 # Ensure that clearing works as well.
1101 extendee_proto.ClearExtension(extension)
1102 self.assertEqual(0, extendee_proto.Extensions[extension])
1103 self.assertTrue(not extendee_proto.HasExtension(extension))
1104
1105 def testTopLevelExtensionsForRepeatedScalar(self):
1106 extendee_proto = unittest_pb2.TestAllExtensions()
1107 extension = unittest_pb2.repeated_string_extension
1108 self.assertEqual(0, len(extendee_proto.Extensions[extension]))
1109 extendee_proto.Extensions[extension].append('foo')
1110 self.assertEqual(['foo'], extendee_proto.Extensions[extension])
1111 string_list = extendee_proto.Extensions[extension]
1112 extendee_proto.ClearExtension(extension)
1113 self.assertEqual(0, len(extendee_proto.Extensions[extension]))
1114 self.assertTrue(string_list is not extendee_proto.Extensions[extension])
1115 # Shouldn't be allowed to do Extensions[extension] = 'a'
1116 self.assertRaises(TypeError, operator.setitem, extendee_proto.Extensions,
1117 extension, 'a')
1118
1119 def testTopLevelExtensionsForOptionalMessage(self):
1120 extendee_proto = unittest_pb2.TestAllExtensions()
1121 extension = unittest_pb2.optional_foreign_message_extension
1122 self.assertTrue(not extendee_proto.HasExtension(extension))
1123 self.assertEqual(0, extendee_proto.Extensions[extension].c)
1124 # As with normal (non-extension) fields, merely reading from the
1125 # thing shouldn't set the "has" bit.
1126 self.assertTrue(not extendee_proto.HasExtension(extension))
1127 extendee_proto.Extensions[extension].c = 23
1128 self.assertEqual(23, extendee_proto.Extensions[extension].c)
1129 self.assertTrue(extendee_proto.HasExtension(extension))
1130 # Save a reference here.
1131 foreign_message = extendee_proto.Extensions[extension]
1132 extendee_proto.ClearExtension(extension)
1133 self.assertTrue(foreign_message is not extendee_proto.Extensions[extension])
1134 # Setting a field on foreign_message now shouldn't set
1135 # any "has" bits on extendee_proto.
1136 foreign_message.c = 42
1137 self.assertEqual(42, foreign_message.c)
1138 self.assertTrue(foreign_message.HasField('c'))
1139 self.assertTrue(not extendee_proto.HasExtension(extension))
1140 # Shouldn't be allowed to do Extensions[extension] = 'a'
1141 self.assertRaises(TypeError, operator.setitem, extendee_proto.Extensions,
1142 extension, 'a')
1143
1144 def testTopLevelExtensionsForRepeatedMessage(self):
1145 extendee_proto = unittest_pb2.TestAllExtensions()
1146 extension = unittest_pb2.repeatedgroup_extension
1147 self.assertEqual(0, len(extendee_proto.Extensions[extension]))
1148 group = extendee_proto.Extensions[extension].add()
1149 group.a = 23
1150 self.assertEqual(23, extendee_proto.Extensions[extension][0].a)
1151 group.a = 42
1152 self.assertEqual(42, extendee_proto.Extensions[extension][0].a)
1153 group_list = extendee_proto.Extensions[extension]
1154 extendee_proto.ClearExtension(extension)
1155 self.assertEqual(0, len(extendee_proto.Extensions[extension]))
1156 self.assertTrue(group_list is not extendee_proto.Extensions[extension])
1157 # Shouldn't be allowed to do Extensions[extension] = 'a'
1158 self.assertRaises(TypeError, operator.setitem, extendee_proto.Extensions,
1159 extension, 'a')
1160
1161 def testNestedExtensions(self):
1162 extendee_proto = unittest_pb2.TestAllExtensions()
1163 extension = unittest_pb2.TestRequired.single
1164
1165 # We just test the non-repeated case.
1166 self.assertTrue(not extendee_proto.HasExtension(extension))
1167 required = extendee_proto.Extensions[extension]
1168 self.assertEqual(0, required.a)
1169 self.assertTrue(not extendee_proto.HasExtension(extension))
1170 required.a = 23
1171 self.assertEqual(23, extendee_proto.Extensions[extension].a)
1172 self.assertTrue(extendee_proto.HasExtension(extension))
1173 extendee_proto.ClearExtension(extension)
1174 self.assertTrue(required is not extendee_proto.Extensions[extension])
1175 self.assertTrue(not extendee_proto.HasExtension(extension))
1176
jieluo@google.combde4a322014-08-12 21:10:30 +00001177 def testRegisteredExtensions(self):
1178 self.assertTrue('protobuf_unittest.optional_int32_extension' in
1179 unittest_pb2.TestAllExtensions._extensions_by_name)
1180 self.assertTrue(1 in unittest_pb2.TestAllExtensions._extensions_by_number)
1181 # Make sure extensions haven't been registered into types that shouldn't
1182 # have any.
Tres Seavera2abc942015-01-13 15:47:55 -05001183 self.assertEqual(0, len(unittest_pb2.TestAllTypes._extensions_by_name))
jieluo@google.combde4a322014-08-12 21:10:30 +00001184
temporal40ee5512008-07-10 02:12:20 +00001185 # If message A directly contains message B, and
1186 # a.HasField('b') is currently False, then mutating any
1187 # extension in B should change a.HasField('b') to True
1188 # (and so on up the object tree).
1189 def testHasBitsForAncestorsOfExtendedMessage(self):
1190 # Optional scalar extension.
1191 toplevel = more_extensions_pb2.TopLevelMessage()
1192 self.assertTrue(not toplevel.HasField('submessage'))
1193 self.assertEqual(0, toplevel.submessage.Extensions[
1194 more_extensions_pb2.optional_int_extension])
1195 self.assertTrue(not toplevel.HasField('submessage'))
1196 toplevel.submessage.Extensions[
1197 more_extensions_pb2.optional_int_extension] = 23
1198 self.assertEqual(23, toplevel.submessage.Extensions[
1199 more_extensions_pb2.optional_int_extension])
1200 self.assertTrue(toplevel.HasField('submessage'))
1201
1202 # Repeated scalar extension.
1203 toplevel = more_extensions_pb2.TopLevelMessage()
1204 self.assertTrue(not toplevel.HasField('submessage'))
1205 self.assertEqual([], toplevel.submessage.Extensions[
1206 more_extensions_pb2.repeated_int_extension])
1207 self.assertTrue(not toplevel.HasField('submessage'))
1208 toplevel.submessage.Extensions[
1209 more_extensions_pb2.repeated_int_extension].append(23)
1210 self.assertEqual([23], toplevel.submessage.Extensions[
1211 more_extensions_pb2.repeated_int_extension])
1212 self.assertTrue(toplevel.HasField('submessage'))
1213
1214 # Optional message extension.
1215 toplevel = more_extensions_pb2.TopLevelMessage()
1216 self.assertTrue(not toplevel.HasField('submessage'))
1217 self.assertEqual(0, toplevel.submessage.Extensions[
1218 more_extensions_pb2.optional_message_extension].foreign_message_int)
1219 self.assertTrue(not toplevel.HasField('submessage'))
1220 toplevel.submessage.Extensions[
1221 more_extensions_pb2.optional_message_extension].foreign_message_int = 23
1222 self.assertEqual(23, toplevel.submessage.Extensions[
1223 more_extensions_pb2.optional_message_extension].foreign_message_int)
1224 self.assertTrue(toplevel.HasField('submessage'))
1225
1226 # Repeated message extension.
1227 toplevel = more_extensions_pb2.TopLevelMessage()
1228 self.assertTrue(not toplevel.HasField('submessage'))
1229 self.assertEqual(0, len(toplevel.submessage.Extensions[
1230 more_extensions_pb2.repeated_message_extension]))
1231 self.assertTrue(not toplevel.HasField('submessage'))
1232 foreign = toplevel.submessage.Extensions[
1233 more_extensions_pb2.repeated_message_extension].add()
liujisi@google.com33165fe2010-11-02 13:14:58 +00001234 self.assertEqual(foreign, toplevel.submessage.Extensions[
temporal40ee5512008-07-10 02:12:20 +00001235 more_extensions_pb2.repeated_message_extension][0])
1236 self.assertTrue(toplevel.HasField('submessage'))
1237
1238 def testDisconnectionAfterClearingEmptyMessage(self):
1239 toplevel = more_extensions_pb2.TopLevelMessage()
1240 extendee_proto = toplevel.submessage
1241 extension = more_extensions_pb2.optional_message_extension
1242 extension_proto = extendee_proto.Extensions[extension]
1243 extendee_proto.ClearExtension(extension)
1244 extension_proto.foreign_message_int = 23
1245
temporal40ee5512008-07-10 02:12:20 +00001246 self.assertTrue(extension_proto is not extendee_proto.Extensions[extension])
1247
1248 def testExtensionFailureModes(self):
1249 extendee_proto = unittest_pb2.TestAllExtensions()
1250
1251 # Try non-extension-handle arguments to HasExtension,
1252 # ClearExtension(), and Extensions[]...
1253 self.assertRaises(KeyError, extendee_proto.HasExtension, 1234)
1254 self.assertRaises(KeyError, extendee_proto.ClearExtension, 1234)
1255 self.assertRaises(KeyError, extendee_proto.Extensions.__getitem__, 1234)
1256 self.assertRaises(KeyError, extendee_proto.Extensions.__setitem__, 1234, 5)
1257
1258 # Try something that *is* an extension handle, just not for
1259 # this message...
Feng Xiao6ef984a2014-11-10 17:34:54 -08001260 for unknown_handle in (more_extensions_pb2.optional_int_extension,
1261 more_extensions_pb2.optional_message_extension,
1262 more_extensions_pb2.repeated_int_extension,
1263 more_extensions_pb2.repeated_message_extension):
1264 self.assertRaises(KeyError, extendee_proto.HasExtension,
1265 unknown_handle)
1266 self.assertRaises(KeyError, extendee_proto.ClearExtension,
1267 unknown_handle)
1268 self.assertRaises(KeyError, extendee_proto.Extensions.__getitem__,
1269 unknown_handle)
1270 self.assertRaises(KeyError, extendee_proto.Extensions.__setitem__,
1271 unknown_handle, 5)
temporal40ee5512008-07-10 02:12:20 +00001272
1273 # Try call HasExtension() with a valid handle, but for a
1274 # *repeated* field. (Just as with non-extension repeated
1275 # fields, Has*() isn't supported for extension repeated fields).
1276 self.assertRaises(KeyError, extendee_proto.HasExtension,
1277 unittest_pb2.repeated_string_extension)
1278
kenton@google.com2d6daa72009-01-22 01:27:00 +00001279 def testStaticParseFrom(self):
1280 proto1 = unittest_pb2.TestAllTypes()
1281 test_util.SetAllFields(proto1)
1282
1283 string1 = proto1.SerializeToString()
1284 proto2 = unittest_pb2.TestAllTypes.FromString(string1)
1285
1286 # Messages should be equal.
1287 self.assertEqual(proto2, proto1)
1288
temporal779f61c2008-08-13 03:15:00 +00001289 def testMergeFromSingularField(self):
1290 # Test merge with just a singular field.
1291 proto1 = unittest_pb2.TestAllTypes()
1292 proto1.optional_int32 = 1
1293
1294 proto2 = unittest_pb2.TestAllTypes()
1295 # This shouldn't get overwritten.
1296 proto2.optional_string = 'value'
1297
1298 proto2.MergeFrom(proto1)
1299 self.assertEqual(1, proto2.optional_int32)
1300 self.assertEqual('value', proto2.optional_string)
1301
1302 def testMergeFromRepeatedField(self):
1303 # Test merge with just a repeated field.
1304 proto1 = unittest_pb2.TestAllTypes()
1305 proto1.repeated_int32.append(1)
1306 proto1.repeated_int32.append(2)
1307
1308 proto2 = unittest_pb2.TestAllTypes()
1309 proto2.repeated_int32.append(0)
1310 proto2.MergeFrom(proto1)
1311
1312 self.assertEqual(0, proto2.repeated_int32[0])
1313 self.assertEqual(1, proto2.repeated_int32[1])
1314 self.assertEqual(2, proto2.repeated_int32[2])
1315
1316 def testMergeFromOptionalGroup(self):
1317 # Test merge with an optional group.
1318 proto1 = unittest_pb2.TestAllTypes()
1319 proto1.optionalgroup.a = 12
1320 proto2 = unittest_pb2.TestAllTypes()
1321 proto2.MergeFrom(proto1)
1322 self.assertEqual(12, proto2.optionalgroup.a)
1323
1324 def testMergeFromRepeatedNestedMessage(self):
1325 # Test merge with a repeated nested message.
1326 proto1 = unittest_pb2.TestAllTypes()
1327 m = proto1.repeated_nested_message.add()
1328 m.bb = 123
1329 m = proto1.repeated_nested_message.add()
1330 m.bb = 321
1331
1332 proto2 = unittest_pb2.TestAllTypes()
1333 m = proto2.repeated_nested_message.add()
1334 m.bb = 999
1335 proto2.MergeFrom(proto1)
1336 self.assertEqual(999, proto2.repeated_nested_message[0].bb)
1337 self.assertEqual(123, proto2.repeated_nested_message[1].bb)
1338 self.assertEqual(321, proto2.repeated_nested_message[2].bb)
1339
liujisi@google.com33165fe2010-11-02 13:14:58 +00001340 proto3 = unittest_pb2.TestAllTypes()
1341 proto3.repeated_nested_message.MergeFrom(proto2.repeated_nested_message)
1342 self.assertEqual(999, proto3.repeated_nested_message[0].bb)
1343 self.assertEqual(123, proto3.repeated_nested_message[1].bb)
1344 self.assertEqual(321, proto3.repeated_nested_message[2].bb)
1345
temporal779f61c2008-08-13 03:15:00 +00001346 def testMergeFromAllFields(self):
1347 # With all fields set.
1348 proto1 = unittest_pb2.TestAllTypes()
1349 test_util.SetAllFields(proto1)
1350 proto2 = unittest_pb2.TestAllTypes()
1351 proto2.MergeFrom(proto1)
1352
1353 # Messages should be equal.
1354 self.assertEqual(proto2, proto1)
1355
1356 # Serialized string should be equal too.
1357 string1 = proto1.SerializeToString()
1358 string2 = proto2.SerializeToString()
1359 self.assertEqual(string1, string2)
1360
1361 def testMergeFromExtensionsSingular(self):
1362 proto1 = unittest_pb2.TestAllExtensions()
1363 proto1.Extensions[unittest_pb2.optional_int32_extension] = 1
1364
1365 proto2 = unittest_pb2.TestAllExtensions()
1366 proto2.MergeFrom(proto1)
1367 self.assertEqual(
1368 1, proto2.Extensions[unittest_pb2.optional_int32_extension])
1369
1370 def testMergeFromExtensionsRepeated(self):
1371 proto1 = unittest_pb2.TestAllExtensions()
1372 proto1.Extensions[unittest_pb2.repeated_int32_extension].append(1)
1373 proto1.Extensions[unittest_pb2.repeated_int32_extension].append(2)
1374
1375 proto2 = unittest_pb2.TestAllExtensions()
1376 proto2.Extensions[unittest_pb2.repeated_int32_extension].append(0)
1377 proto2.MergeFrom(proto1)
1378 self.assertEqual(
1379 3, len(proto2.Extensions[unittest_pb2.repeated_int32_extension]))
1380 self.assertEqual(
1381 0, proto2.Extensions[unittest_pb2.repeated_int32_extension][0])
1382 self.assertEqual(
1383 1, proto2.Extensions[unittest_pb2.repeated_int32_extension][1])
1384 self.assertEqual(
1385 2, proto2.Extensions[unittest_pb2.repeated_int32_extension][2])
1386
1387 def testMergeFromExtensionsNestedMessage(self):
1388 proto1 = unittest_pb2.TestAllExtensions()
1389 ext1 = proto1.Extensions[
1390 unittest_pb2.repeated_nested_message_extension]
1391 m = ext1.add()
1392 m.bb = 222
1393 m = ext1.add()
1394 m.bb = 333
1395
1396 proto2 = unittest_pb2.TestAllExtensions()
1397 ext2 = proto2.Extensions[
1398 unittest_pb2.repeated_nested_message_extension]
1399 m = ext2.add()
1400 m.bb = 111
1401
1402 proto2.MergeFrom(proto1)
1403 ext2 = proto2.Extensions[
1404 unittest_pb2.repeated_nested_message_extension]
1405 self.assertEqual(3, len(ext2))
1406 self.assertEqual(111, ext2[0].bb)
1407 self.assertEqual(222, ext2[1].bb)
1408 self.assertEqual(333, ext2[2].bb)
1409
kenton@google.com0c293de2010-07-27 20:45:09 +00001410 def testMergeFromBug(self):
1411 message1 = unittest_pb2.TestAllTypes()
1412 message2 = unittest_pb2.TestAllTypes()
kenton@google.com27028bc2010-07-27 21:19:59 +00001413
kenton@google.com0c293de2010-07-27 20:45:09 +00001414 # Cause optional_nested_message to be instantiated within message1, even
1415 # though it is not considered to be "present".
1416 message1.optional_nested_message
1417 self.assertFalse(message1.HasField('optional_nested_message'))
kenton@google.com27028bc2010-07-27 21:19:59 +00001418
kenton@google.com0c293de2010-07-27 20:45:09 +00001419 # Merge into message2. This should not instantiate the field is message2.
1420 message2.MergeFrom(message1)
1421 self.assertFalse(message2.HasField('optional_nested_message'))
1422
temporal779f61c2008-08-13 03:15:00 +00001423 def testCopyFromSingularField(self):
1424 # Test copy with just a singular field.
1425 proto1 = unittest_pb2.TestAllTypes()
1426 proto1.optional_int32 = 1
1427 proto1.optional_string = 'important-text'
1428
1429 proto2 = unittest_pb2.TestAllTypes()
1430 proto2.optional_string = 'value'
1431
1432 proto2.CopyFrom(proto1)
1433 self.assertEqual(1, proto2.optional_int32)
1434 self.assertEqual('important-text', proto2.optional_string)
1435
1436 def testCopyFromRepeatedField(self):
1437 # Test copy with a repeated field.
1438 proto1 = unittest_pb2.TestAllTypes()
1439 proto1.repeated_int32.append(1)
1440 proto1.repeated_int32.append(2)
1441
1442 proto2 = unittest_pb2.TestAllTypes()
1443 proto2.repeated_int32.append(0)
1444 proto2.CopyFrom(proto1)
1445
1446 self.assertEqual(1, proto2.repeated_int32[0])
1447 self.assertEqual(2, proto2.repeated_int32[1])
1448
1449 def testCopyFromAllFields(self):
1450 # With all fields set.
1451 proto1 = unittest_pb2.TestAllTypes()
1452 test_util.SetAllFields(proto1)
1453 proto2 = unittest_pb2.TestAllTypes()
1454 proto2.CopyFrom(proto1)
1455
1456 # Messages should be equal.
1457 self.assertEqual(proto2, proto1)
1458
1459 # Serialized string should be equal too.
1460 string1 = proto1.SerializeToString()
1461 string2 = proto2.SerializeToString()
1462 self.assertEqual(string1, string2)
1463
1464 def testCopyFromSelf(self):
1465 proto1 = unittest_pb2.TestAllTypes()
1466 proto1.repeated_int32.append(1)
1467 proto1.optional_int32 = 2
1468 proto1.optional_string = 'important-text'
1469
1470 proto1.CopyFrom(proto1)
1471 self.assertEqual(1, proto1.repeated_int32[0])
1472 self.assertEqual(2, proto1.optional_int32)
1473 self.assertEqual('important-text', proto1.optional_string)
temporal40ee5512008-07-10 02:12:20 +00001474
liujisi@google.com33165fe2010-11-02 13:14:58 +00001475 def testCopyFromBadType(self):
1476 # The python implementation doesn't raise an exception in this
1477 # case. In theory it should.
1478 if api_implementation.Type() == 'python':
1479 return
1480 proto1 = unittest_pb2.TestAllTypes()
1481 proto2 = unittest_pb2.TestAllExtensions()
1482 self.assertRaises(TypeError, proto1.CopyFrom, proto2)
1483
jieluo@google.combde4a322014-08-12 21:10:30 +00001484 def testDeepCopy(self):
1485 proto1 = unittest_pb2.TestAllTypes()
1486 proto1.optional_int32 = 1
1487 proto2 = copy.deepcopy(proto1)
1488 self.assertEqual(1, proto2.optional_int32)
1489
1490 proto1.repeated_int32.append(2)
1491 proto1.repeated_int32.append(3)
1492 container = copy.deepcopy(proto1.repeated_int32)
1493 self.assertEqual([2, 3], container)
1494
1495 # TODO(anuraag): Implement deepcopy for repeated composite / extension dict
1496
temporal40ee5512008-07-10 02:12:20 +00001497 def testClear(self):
1498 proto = unittest_pb2.TestAllTypes()
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001499 # C++ implementation does not support lazy fields right now so leave it
1500 # out for now.
1501 if api_implementation.Type() == 'python':
1502 test_util.SetAllFields(proto)
1503 else:
1504 test_util.SetAllNonLazyFields(proto)
temporal40ee5512008-07-10 02:12:20 +00001505 # Clear the message.
1506 proto.Clear()
Tres Seavera2abc942015-01-13 15:47:55 -05001507 self.assertEqual(proto.ByteSize(), 0)
temporal40ee5512008-07-10 02:12:20 +00001508 empty_proto = unittest_pb2.TestAllTypes()
Tres Seavera2abc942015-01-13 15:47:55 -05001509 self.assertEqual(proto, empty_proto)
temporal40ee5512008-07-10 02:12:20 +00001510
1511 # Test if extensions which were set are cleared.
1512 proto = unittest_pb2.TestAllExtensions()
1513 test_util.SetAllExtensions(proto)
1514 # Clear the message.
1515 proto.Clear()
Tres Seavera2abc942015-01-13 15:47:55 -05001516 self.assertEqual(proto.ByteSize(), 0)
temporal40ee5512008-07-10 02:12:20 +00001517 empty_proto = unittest_pb2.TestAllExtensions()
Tres Seavera2abc942015-01-13 15:47:55 -05001518 self.assertEqual(proto, empty_proto)
temporal40ee5512008-07-10 02:12:20 +00001519
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001520 def testDisconnectingBeforeClear(self):
1521 proto = unittest_pb2.TestAllTypes()
1522 nested = proto.optional_nested_message
1523 proto.Clear()
1524 self.assertTrue(nested is not proto.optional_nested_message)
1525 nested.bb = 23
1526 self.assertTrue(not proto.HasField('optional_nested_message'))
1527 self.assertEqual(0, proto.optional_nested_message.bb)
1528
1529 proto = unittest_pb2.TestAllTypes()
1530 nested = proto.optional_nested_message
1531 nested.bb = 5
1532 foreign = proto.optional_foreign_message
1533 foreign.c = 6
1534
1535 proto.Clear()
1536 self.assertTrue(nested is not proto.optional_nested_message)
1537 self.assertTrue(foreign is not proto.optional_foreign_message)
1538 self.assertEqual(5, nested.bb)
1539 self.assertEqual(6, foreign.c)
1540 nested.bb = 15
1541 foreign.c = 16
jieluo@google.combde4a322014-08-12 21:10:30 +00001542 self.assertFalse(proto.HasField('optional_nested_message'))
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001543 self.assertEqual(0, proto.optional_nested_message.bb)
jieluo@google.combde4a322014-08-12 21:10:30 +00001544 self.assertFalse(proto.HasField('optional_foreign_message'))
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001545 self.assertEqual(0, proto.optional_foreign_message.c)
1546
jieluo@google.combde4a322014-08-12 21:10:30 +00001547 def testOneOf(self):
1548 proto = unittest_pb2.TestAllTypes()
1549 proto.oneof_uint32 = 10
1550 proto.oneof_nested_message.bb = 11
1551 self.assertEqual(11, proto.oneof_nested_message.bb)
1552 self.assertFalse(proto.HasField('oneof_uint32'))
1553 nested = proto.oneof_nested_message
1554 proto.oneof_string = 'abc'
1555 self.assertEqual('abc', proto.oneof_string)
1556 self.assertEqual(11, nested.bb)
1557 self.assertFalse(proto.HasField('oneof_nested_message'))
1558
kenton@google.comfccb1462009-12-18 02:11:36 +00001559 def assertInitialized(self, proto):
1560 self.assertTrue(proto.IsInitialized())
1561 # Neither method should raise an exception.
1562 proto.SerializeToString()
1563 proto.SerializePartialToString()
1564
1565 def assertNotInitialized(self, proto):
1566 self.assertFalse(proto.IsInitialized())
jieluo@google.com1eba9d92014-08-25 20:17:53 +00001567 self.assertRaises(message.EncodeError, proto.SerializeToString)
kenton@google.comfccb1462009-12-18 02:11:36 +00001568 # "Partial" serialization doesn't care if message is uninitialized.
1569 proto.SerializePartialToString()
1570
temporal40ee5512008-07-10 02:12:20 +00001571 def testIsInitialized(self):
1572 # Trivial cases - all optional fields and extensions.
1573 proto = unittest_pb2.TestAllTypes()
kenton@google.comfccb1462009-12-18 02:11:36 +00001574 self.assertInitialized(proto)
temporal40ee5512008-07-10 02:12:20 +00001575 proto = unittest_pb2.TestAllExtensions()
kenton@google.comfccb1462009-12-18 02:11:36 +00001576 self.assertInitialized(proto)
temporal40ee5512008-07-10 02:12:20 +00001577
1578 # The case of uninitialized required fields.
1579 proto = unittest_pb2.TestRequired()
kenton@google.comfccb1462009-12-18 02:11:36 +00001580 self.assertNotInitialized(proto)
temporal40ee5512008-07-10 02:12:20 +00001581 proto.a = proto.b = proto.c = 2
kenton@google.comfccb1462009-12-18 02:11:36 +00001582 self.assertInitialized(proto)
temporal40ee5512008-07-10 02:12:20 +00001583
1584 # The case of uninitialized submessage.
1585 proto = unittest_pb2.TestRequiredForeign()
kenton@google.comfccb1462009-12-18 02:11:36 +00001586 self.assertInitialized(proto)
temporal40ee5512008-07-10 02:12:20 +00001587 proto.optional_message.a = 1
kenton@google.comfccb1462009-12-18 02:11:36 +00001588 self.assertNotInitialized(proto)
temporal40ee5512008-07-10 02:12:20 +00001589 proto.optional_message.b = 0
1590 proto.optional_message.c = 0
kenton@google.comfccb1462009-12-18 02:11:36 +00001591 self.assertInitialized(proto)
temporal40ee5512008-07-10 02:12:20 +00001592
1593 # Uninitialized repeated submessage.
1594 message1 = proto.repeated_message.add()
kenton@google.comfccb1462009-12-18 02:11:36 +00001595 self.assertNotInitialized(proto)
temporal40ee5512008-07-10 02:12:20 +00001596 message1.a = message1.b = message1.c = 0
kenton@google.comfccb1462009-12-18 02:11:36 +00001597 self.assertInitialized(proto)
temporal40ee5512008-07-10 02:12:20 +00001598
1599 # Uninitialized repeated group in an extension.
1600 proto = unittest_pb2.TestAllExtensions()
1601 extension = unittest_pb2.TestRequired.multi
1602 message1 = proto.Extensions[extension].add()
1603 message2 = proto.Extensions[extension].add()
kenton@google.comfccb1462009-12-18 02:11:36 +00001604 self.assertNotInitialized(proto)
temporal40ee5512008-07-10 02:12:20 +00001605 message1.a = 1
1606 message1.b = 1
1607 message1.c = 1
kenton@google.comfccb1462009-12-18 02:11:36 +00001608 self.assertNotInitialized(proto)
temporal40ee5512008-07-10 02:12:20 +00001609 message2.a = 2
1610 message2.b = 2
1611 message2.c = 2
kenton@google.comfccb1462009-12-18 02:11:36 +00001612 self.assertInitialized(proto)
temporal40ee5512008-07-10 02:12:20 +00001613
1614 # Uninitialized nonrepeated message in an extension.
1615 proto = unittest_pb2.TestAllExtensions()
1616 extension = unittest_pb2.TestRequired.single
1617 proto.Extensions[extension].a = 1
kenton@google.comfccb1462009-12-18 02:11:36 +00001618 self.assertNotInitialized(proto)
temporal40ee5512008-07-10 02:12:20 +00001619 proto.Extensions[extension].b = 2
1620 proto.Extensions[extension].c = 3
kenton@google.comfccb1462009-12-18 02:11:36 +00001621 self.assertInitialized(proto)
1622
1623 # Try passing an errors list.
1624 errors = []
1625 proto = unittest_pb2.TestRequired()
1626 self.assertFalse(proto.IsInitialized(errors))
1627 self.assertEqual(errors, ['a', 'b', 'c'])
temporal40ee5512008-07-10 02:12:20 +00001628
Jisi Liudbea00a2015-10-05 16:08:22 -07001629 @unittest.skipIf(
jieluo@google.combde4a322014-08-12 21:10:30 +00001630 api_implementation.Type() != 'cpp' or api_implementation.Version() != 2,
1631 'Errors are only available from the most recent C++ implementation.')
1632 def testFileDescriptorErrors(self):
1633 file_name = 'test_file_descriptor_errors.proto'
1634 package_name = 'test_file_descriptor_errors.proto'
1635 file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
1636 file_descriptor_proto.name = file_name
1637 file_descriptor_proto.package = package_name
1638 m1 = file_descriptor_proto.message_type.add()
1639 m1.name = 'msg1'
1640 # Compiles the proto into the C++ descriptor pool
1641 descriptor.FileDescriptor(
1642 file_name,
1643 package_name,
1644 serialized_pb=file_descriptor_proto.SerializeToString())
1645 # Add a FileDescriptorProto that has duplicate symbols
1646 another_file_name = 'another_test_file_descriptor_errors.proto'
1647 file_descriptor_proto.name = another_file_name
1648 m2 = file_descriptor_proto.message_type.add()
1649 m2.name = 'msg2'
1650 with self.assertRaises(TypeError) as cm:
1651 descriptor.FileDescriptor(
1652 another_file_name,
1653 package_name,
1654 serialized_pb=file_descriptor_proto.SerializeToString())
1655 self.assertTrue(hasattr(cm, 'exception'), '%s not raised' %
1656 getattr(cm.expected, '__name__', cm.expected))
1657 self.assertIn('test_file_descriptor_errors.proto', str(cm.exception))
1658 # Error message will say something about this definition being a
1659 # duplicate, though we don't check the message exactly to avoid a
1660 # dependency on the C++ logging code.
1661 self.assertIn('test_file_descriptor_errors.msg1', str(cm.exception))
1662
kenton@google.com24bf56f2008-09-24 20:31:01 +00001663 def testStringUTF8Encoding(self):
1664 proto = unittest_pb2.TestAllTypes()
1665
1666 # Assignment of a unicode object to a field of type 'bytes' is not allowed.
1667 self.assertRaises(TypeError,
1668 setattr, proto, 'optional_bytes', u'unicode object')
1669
1670 # Check that the default value is of python's 'unicode' type.
Tres Seaverf336d4b2015-01-13 14:21:29 -05001671 self.assertEqual(type(proto.optional_string), six.text_type)
kenton@google.com24bf56f2008-09-24 20:31:01 +00001672
Tres Seaverf336d4b2015-01-13 14:21:29 -05001673 proto.optional_string = six.text_type('Testing')
kenton@google.com24bf56f2008-09-24 20:31:01 +00001674 self.assertEqual(proto.optional_string, str('Testing'))
1675
1676 # Assign a value of type 'str' which can be encoded in UTF-8.
1677 proto.optional_string = str('Testing')
Tres Seaverf336d4b2015-01-13 14:21:29 -05001678 self.assertEqual(proto.optional_string, six.text_type('Testing'))
kenton@google.com24bf56f2008-09-24 20:31:01 +00001679
Feng Xiao6ef984a2014-11-10 17:34:54 -08001680 # Try to assign a 'bytes' object which contains non-UTF-8.
kenton@google.com24bf56f2008-09-24 20:31:01 +00001681 self.assertRaises(ValueError,
jieluo@google.combde4a322014-08-12 21:10:30 +00001682 setattr, proto, 'optional_string', b'a\x80a')
Feng Xiao6ef984a2014-11-10 17:34:54 -08001683 # No exception: Assign already encoded UTF-8 bytes to a string field.
1684 utf8_bytes = u'Тест'.encode('utf-8')
1685 proto.optional_string = utf8_bytes
1686 # No exception: Assign the a non-ascii unicode object.
1687 proto.optional_string = u'Тест'
1688 # No exception thrown (normal str assignment containing ASCII).
kenton@google.com24bf56f2008-09-24 20:31:01 +00001689 proto.optional_string = 'abc'
1690
1691 def testStringUTF8Serialization(self):
Feng Xiaoeee38b02015-08-22 18:25:48 -07001692 proto = message_set_extensions_pb2.TestMessageSet()
1693 extension_message = message_set_extensions_pb2.TestMessageSetExtension2
kenton@google.com24bf56f2008-09-24 20:31:01 +00001694 extension = extension_message.message_set_extension
1695
1696 test_utf8 = u'Тест'
1697 test_utf8_bytes = test_utf8.encode('utf-8')
1698
1699 # 'Test' in another language, using UTF-8 charset.
1700 proto.Extensions[extension].str = test_utf8
1701
1702 # Serialize using the MessageSet wire format (this is specified in the
1703 # .proto file).
1704 serialized = proto.SerializeToString()
1705
1706 # Check byte size.
1707 self.assertEqual(proto.ByteSize(), len(serialized))
1708
1709 raw = unittest_mset_pb2.RawMessageSet()
jieluo@google.combde4a322014-08-12 21:10:30 +00001710 bytes_read = raw.MergeFromString(serialized)
1711 self.assertEqual(len(serialized), bytes_read)
kenton@google.com24bf56f2008-09-24 20:31:01 +00001712
Feng Xiaoeee38b02015-08-22 18:25:48 -07001713 message2 = message_set_extensions_pb2.TestMessageSetExtension2()
kenton@google.com24bf56f2008-09-24 20:31:01 +00001714
1715 self.assertEqual(1, len(raw.item))
1716 # Check that the type_id is the same as the tag ID in the .proto file.
Feng Xiaoeee38b02015-08-22 18:25:48 -07001717 self.assertEqual(raw.item[0].type_id, 98418634)
kenton@google.com24bf56f2008-09-24 20:31:01 +00001718
liujisi@google.com33165fe2010-11-02 13:14:58 +00001719 # Check the actual bytes on the wire.
Feng Xiaoeee38b02015-08-22 18:25:48 -07001720 self.assertTrue(raw.item[0].message.endswith(test_utf8_bytes))
jieluo@google.combde4a322014-08-12 21:10:30 +00001721 bytes_read = message2.MergeFromString(raw.item[0].message)
1722 self.assertEqual(len(raw.item[0].message), bytes_read)
kenton@google.com24bf56f2008-09-24 20:31:01 +00001723
Tres Seaverf336d4b2015-01-13 14:21:29 -05001724 self.assertEqual(type(message2.str), six.text_type)
kenton@google.com24bf56f2008-09-24 20:31:01 +00001725 self.assertEqual(message2.str, test_utf8)
1726
liujisi@google.com33165fe2010-11-02 13:14:58 +00001727 # The pure Python API throws an exception on MergeFromString(),
1728 # if any of the string fields of the message can't be UTF-8 decoded.
1729 # The C++ implementation of the API has no way to check that on
1730 # MergeFromString and thus has no way to throw the exception.
1731 #
1732 # The pure Python API always returns objects of type 'unicode' (UTF-8
jieluo@google.combde4a322014-08-12 21:10:30 +00001733 # encoded), or 'bytes' (in 7 bit ASCII).
1734 badbytes = raw.item[0].message.replace(
1735 test_utf8_bytes, len(test_utf8_bytes) * b'\xff')
liujisi@google.com33165fe2010-11-02 13:14:58 +00001736
1737 unicode_decode_failed = False
1738 try:
jieluo@google.combde4a322014-08-12 21:10:30 +00001739 message2.MergeFromString(badbytes)
1740 except UnicodeDecodeError:
liujisi@google.com33165fe2010-11-02 13:14:58 +00001741 unicode_decode_failed = True
1742 string_field = message2.str
jieluo@google.combde4a322014-08-12 21:10:30 +00001743 self.assertTrue(unicode_decode_failed or type(string_field) is bytes)
1744
1745 def testBytesInTextFormat(self):
1746 proto = unittest_pb2.TestAllTypes(optional_bytes=b'\x00\x7f\x80\xff')
1747 self.assertEqual(u'optional_bytes: "\\000\\177\\200\\377"\n',
Tres Seaverf336d4b2015-01-13 14:21:29 -05001748 six.text_type(proto))
kenton@google.com24bf56f2008-09-24 20:31:01 +00001749
kenton@google.comfccb1462009-12-18 02:11:36 +00001750 def testEmptyNestedMessage(self):
1751 proto = unittest_pb2.TestAllTypes()
1752 proto.optional_nested_message.MergeFrom(
1753 unittest_pb2.TestAllTypes.NestedMessage())
1754 self.assertTrue(proto.HasField('optional_nested_message'))
1755
1756 proto = unittest_pb2.TestAllTypes()
1757 proto.optional_nested_message.CopyFrom(
1758 unittest_pb2.TestAllTypes.NestedMessage())
1759 self.assertTrue(proto.HasField('optional_nested_message'))
1760
1761 proto = unittest_pb2.TestAllTypes()
jieluo@google.combde4a322014-08-12 21:10:30 +00001762 bytes_read = proto.optional_nested_message.MergeFromString(b'')
1763 self.assertEqual(0, bytes_read)
kenton@google.comfccb1462009-12-18 02:11:36 +00001764 self.assertTrue(proto.HasField('optional_nested_message'))
1765
1766 proto = unittest_pb2.TestAllTypes()
jieluo@google.combde4a322014-08-12 21:10:30 +00001767 proto.optional_nested_message.ParseFromString(b'')
kenton@google.comfccb1462009-12-18 02:11:36 +00001768 self.assertTrue(proto.HasField('optional_nested_message'))
1769
1770 serialized = proto.SerializeToString()
1771 proto2 = unittest_pb2.TestAllTypes()
jieluo@google.combde4a322014-08-12 21:10:30 +00001772 self.assertEqual(
1773 len(serialized),
1774 proto2.MergeFromString(serialized))
kenton@google.comfccb1462009-12-18 02:11:36 +00001775 self.assertTrue(proto2.HasField('optional_nested_message'))
1776
1777 def testSetInParent(self):
1778 proto = unittest_pb2.TestAllTypes()
1779 self.assertFalse(proto.HasField('optionalgroup'))
1780 proto.optionalgroup.SetInParent()
1781 self.assertTrue(proto.HasField('optionalgroup'))
1782
Feng Xiao6ef984a2014-11-10 17:34:54 -08001783 def testPackageInitializationImport(self):
1784 """Test that we can import nested messages from their __init__.py.
1785
1786 Such setup is not trivial since at the time of processing of __init__.py one
1787 can't refer to its submodules by name in code, so expressions like
1788 google.protobuf.internal.import_test_package.inner_pb2
1789 don't work. They do work in imports, so we have assign an alias at import
1790 and then use that alias in generated code.
1791 """
1792 # We import here since it's the import that used to fail, and we want
1793 # the failure to have the right context.
1794 # pylint: disable=g-import-not-at-top
1795 from google.protobuf.internal import import_test_package
1796 # pylint: enable=g-import-not-at-top
1797 msg = import_test_package.myproto.Outer()
1798 # Just check the default value.
1799 self.assertEqual(57, msg.inner.value)
1800
temporal40ee5512008-07-10 02:12:20 +00001801# Since we had so many tests for protocol buffer equality, we broke these out
1802# into separate TestCase classes.
1803
1804
Tamir Duberstein9f42f5f2015-01-13 14:47:32 -05001805class TestAllTypesEqualityTest(unittest.TestCase):
temporal40ee5512008-07-10 02:12:20 +00001806
1807 def setUp(self):
1808 self.first_proto = unittest_pb2.TestAllTypes()
1809 self.second_proto = unittest_pb2.TestAllTypes()
1810
liujisi@google.com33165fe2010-11-02 13:14:58 +00001811 def testNotHashable(self):
1812 self.assertRaises(TypeError, hash, self.first_proto)
1813
temporal40ee5512008-07-10 02:12:20 +00001814 def testSelfEquality(self):
1815 self.assertEqual(self.first_proto, self.first_proto)
1816
1817 def testEmptyProtosEqual(self):
1818 self.assertEqual(self.first_proto, self.second_proto)
1819
1820
Tamir Duberstein9f42f5f2015-01-13 14:47:32 -05001821class FullProtosEqualityTest(unittest.TestCase):
temporal40ee5512008-07-10 02:12:20 +00001822
1823 """Equality tests using completely-full protos as a starting point."""
1824
1825 def setUp(self):
1826 self.first_proto = unittest_pb2.TestAllTypes()
1827 self.second_proto = unittest_pb2.TestAllTypes()
1828 test_util.SetAllFields(self.first_proto)
1829 test_util.SetAllFields(self.second_proto)
1830
liujisi@google.com33165fe2010-11-02 13:14:58 +00001831 def testNotHashable(self):
1832 self.assertRaises(TypeError, hash, self.first_proto)
1833
kenton@google.comd37d46d2009-04-25 02:53:47 +00001834 def testNoneNotEqual(self):
1835 self.assertNotEqual(self.first_proto, None)
1836 self.assertNotEqual(None, self.second_proto)
1837
1838 def testNotEqualToOtherMessage(self):
1839 third_proto = unittest_pb2.TestRequired()
1840 self.assertNotEqual(self.first_proto, third_proto)
1841 self.assertNotEqual(third_proto, self.second_proto)
1842
temporal40ee5512008-07-10 02:12:20 +00001843 def testAllFieldsFilledEquality(self):
1844 self.assertEqual(self.first_proto, self.second_proto)
1845
1846 def testNonRepeatedScalar(self):
1847 # Nonrepeated scalar field change should cause inequality.
1848 self.first_proto.optional_int32 += 1
1849 self.assertNotEqual(self.first_proto, self.second_proto)
1850 # ...as should clearing a field.
1851 self.first_proto.ClearField('optional_int32')
1852 self.assertNotEqual(self.first_proto, self.second_proto)
1853
1854 def testNonRepeatedComposite(self):
1855 # Change a nonrepeated composite field.
1856 self.first_proto.optional_nested_message.bb += 1
1857 self.assertNotEqual(self.first_proto, self.second_proto)
1858 self.first_proto.optional_nested_message.bb -= 1
1859 self.assertEqual(self.first_proto, self.second_proto)
1860 # Clear a field in the nested message.
1861 self.first_proto.optional_nested_message.ClearField('bb')
1862 self.assertNotEqual(self.first_proto, self.second_proto)
1863 self.first_proto.optional_nested_message.bb = (
1864 self.second_proto.optional_nested_message.bb)
1865 self.assertEqual(self.first_proto, self.second_proto)
1866 # Remove the nested message entirely.
1867 self.first_proto.ClearField('optional_nested_message')
1868 self.assertNotEqual(self.first_proto, self.second_proto)
1869
1870 def testRepeatedScalar(self):
1871 # Change a repeated scalar field.
1872 self.first_proto.repeated_int32.append(5)
1873 self.assertNotEqual(self.first_proto, self.second_proto)
1874 self.first_proto.ClearField('repeated_int32')
1875 self.assertNotEqual(self.first_proto, self.second_proto)
1876
1877 def testRepeatedComposite(self):
1878 # Change value within a repeated composite field.
1879 self.first_proto.repeated_nested_message[0].bb += 1
1880 self.assertNotEqual(self.first_proto, self.second_proto)
1881 self.first_proto.repeated_nested_message[0].bb -= 1
1882 self.assertEqual(self.first_proto, self.second_proto)
1883 # Add a value to a repeated composite field.
1884 self.first_proto.repeated_nested_message.add()
1885 self.assertNotEqual(self.first_proto, self.second_proto)
1886 self.second_proto.repeated_nested_message.add()
1887 self.assertEqual(self.first_proto, self.second_proto)
1888
1889 def testNonRepeatedScalarHasBits(self):
1890 # Ensure that we test "has" bits as well as value for
1891 # nonrepeated scalar field.
1892 self.first_proto.ClearField('optional_int32')
1893 self.second_proto.optional_int32 = 0
1894 self.assertNotEqual(self.first_proto, self.second_proto)
1895
1896 def testNonRepeatedCompositeHasBits(self):
1897 # Ensure that we test "has" bits as well as value for
1898 # nonrepeated composite field.
1899 self.first_proto.ClearField('optional_nested_message')
1900 self.second_proto.optional_nested_message.ClearField('bb')
1901 self.assertNotEqual(self.first_proto, self.second_proto)
temporal40ee5512008-07-10 02:12:20 +00001902 self.first_proto.optional_nested_message.bb = 0
1903 self.first_proto.optional_nested_message.ClearField('bb')
1904 self.assertEqual(self.first_proto, self.second_proto)
1905
1906
Tamir Duberstein9f42f5f2015-01-13 14:47:32 -05001907class ExtensionEqualityTest(unittest.TestCase):
temporal40ee5512008-07-10 02:12:20 +00001908
1909 def testExtensionEquality(self):
1910 first_proto = unittest_pb2.TestAllExtensions()
1911 second_proto = unittest_pb2.TestAllExtensions()
1912 self.assertEqual(first_proto, second_proto)
1913 test_util.SetAllExtensions(first_proto)
1914 self.assertNotEqual(first_proto, second_proto)
1915 test_util.SetAllExtensions(second_proto)
1916 self.assertEqual(first_proto, second_proto)
1917
1918 # Ensure that we check value equality.
1919 first_proto.Extensions[unittest_pb2.optional_int32_extension] += 1
1920 self.assertNotEqual(first_proto, second_proto)
1921 first_proto.Extensions[unittest_pb2.optional_int32_extension] -= 1
1922 self.assertEqual(first_proto, second_proto)
1923
1924 # Ensure that we also look at "has" bits.
1925 first_proto.ClearExtension(unittest_pb2.optional_int32_extension)
1926 second_proto.Extensions[unittest_pb2.optional_int32_extension] = 0
1927 self.assertNotEqual(first_proto, second_proto)
1928 first_proto.Extensions[unittest_pb2.optional_int32_extension] = 0
1929 self.assertEqual(first_proto, second_proto)
1930
1931 # Ensure that differences in cached values
1932 # don't matter if "has" bits are both false.
1933 first_proto = unittest_pb2.TestAllExtensions()
1934 second_proto = unittest_pb2.TestAllExtensions()
1935 self.assertEqual(
1936 0, first_proto.Extensions[unittest_pb2.optional_int32_extension])
1937 self.assertEqual(first_proto, second_proto)
1938
1939
Tamir Duberstein9f42f5f2015-01-13 14:47:32 -05001940class MutualRecursionEqualityTest(unittest.TestCase):
temporal40ee5512008-07-10 02:12:20 +00001941
1942 def testEqualityWithMutualRecursion(self):
1943 first_proto = unittest_pb2.TestMutualRecursionA()
1944 second_proto = unittest_pb2.TestMutualRecursionA()
1945 self.assertEqual(first_proto, second_proto)
1946 first_proto.bb.a.bb.optional_int32 = 23
1947 self.assertNotEqual(first_proto, second_proto)
1948 second_proto.bb.a.bb.optional_int32 = 23
1949 self.assertEqual(first_proto, second_proto)
1950
1951
Tamir Duberstein9f42f5f2015-01-13 14:47:32 -05001952class ByteSizeTest(unittest.TestCase):
temporal40ee5512008-07-10 02:12:20 +00001953
1954 def setUp(self):
1955 self.proto = unittest_pb2.TestAllTypes()
1956 self.extended_proto = more_extensions_pb2.ExtendedMessage()
kenton@google.com2d6daa72009-01-22 01:27:00 +00001957 self.packed_proto = unittest_pb2.TestPackedTypes()
1958 self.packed_extended_proto = unittest_pb2.TestPackedExtensions()
temporal40ee5512008-07-10 02:12:20 +00001959
1960 def Size(self):
1961 return self.proto.ByteSize()
1962
1963 def testEmptyMessage(self):
1964 self.assertEqual(0, self.proto.ByteSize())
1965
liujisi@google.com33165fe2010-11-02 13:14:58 +00001966 def testSizedOnKwargs(self):
1967 # Use a separate message to ensure testing right after creation.
1968 proto = unittest_pb2.TestAllTypes()
1969 self.assertEqual(0, proto.ByteSize())
1970 proto_kwargs = unittest_pb2.TestAllTypes(optional_int64 = 1)
1971 # One byte for the tag, one to encode varint 1.
1972 self.assertEqual(2, proto_kwargs.ByteSize())
1973
temporal40ee5512008-07-10 02:12:20 +00001974 def testVarints(self):
1975 def Test(i, expected_varint_size):
1976 self.proto.Clear()
1977 self.proto.optional_int64 = i
1978 # Add one to the varint size for the tag info
1979 # for tag 1.
1980 self.assertEqual(expected_varint_size + 1, self.Size())
1981 Test(0, 1)
1982 Test(1, 1)
1983 for i, num_bytes in zip(range(7, 63, 7), range(1, 10000)):
1984 Test((1 << i) - 1, num_bytes)
1985 Test(-1, 10)
1986 Test(-2, 10)
1987 Test(-(1 << 63), 10)
1988
1989 def testStrings(self):
1990 self.proto.optional_string = ''
1991 # Need one byte for tag info (tag #14), and one byte for length.
1992 self.assertEqual(2, self.Size())
1993
1994 self.proto.optional_string = 'abc'
1995 # Need one byte for tag info (tag #14), and one byte for length.
1996 self.assertEqual(2 + len(self.proto.optional_string), self.Size())
1997
1998 self.proto.optional_string = 'x' * 128
1999 # Need one byte for tag info (tag #14), and TWO bytes for length.
2000 self.assertEqual(3 + len(self.proto.optional_string), self.Size())
2001
2002 def testOtherNumerics(self):
2003 self.proto.optional_fixed32 = 1234
2004 # One byte for tag and 4 bytes for fixed32.
2005 self.assertEqual(5, self.Size())
2006 self.proto = unittest_pb2.TestAllTypes()
2007
2008 self.proto.optional_fixed64 = 1234
2009 # One byte for tag and 8 bytes for fixed64.
2010 self.assertEqual(9, self.Size())
2011 self.proto = unittest_pb2.TestAllTypes()
2012
2013 self.proto.optional_float = 1.234
2014 # One byte for tag and 4 bytes for float.
2015 self.assertEqual(5, self.Size())
2016 self.proto = unittest_pb2.TestAllTypes()
2017
2018 self.proto.optional_double = 1.234
2019 # One byte for tag and 8 bytes for float.
2020 self.assertEqual(9, self.Size())
2021 self.proto = unittest_pb2.TestAllTypes()
2022
2023 self.proto.optional_sint32 = 64
2024 # One byte for tag and 2 bytes for zig-zag-encoded 64.
2025 self.assertEqual(3, self.Size())
2026 self.proto = unittest_pb2.TestAllTypes()
2027
2028 def testComposites(self):
2029 # 3 bytes.
2030 self.proto.optional_nested_message.bb = (1 << 14)
2031 # Plus one byte for bb tag.
2032 # Plus 1 byte for optional_nested_message serialized size.
2033 # Plus two bytes for optional_nested_message tag.
2034 self.assertEqual(3 + 1 + 1 + 2, self.Size())
2035
2036 def testGroups(self):
2037 # 4 bytes.
2038 self.proto.optionalgroup.a = (1 << 21)
2039 # Plus two bytes for |a| tag.
2040 # Plus 2 * two bytes for START_GROUP and END_GROUP tags.
2041 self.assertEqual(4 + 2 + 2*2, self.Size())
2042
2043 def testRepeatedScalars(self):
2044 self.proto.repeated_int32.append(10) # 1 byte.
2045 self.proto.repeated_int32.append(128) # 2 bytes.
2046 # Also need 2 bytes for each entry for tag.
2047 self.assertEqual(1 + 2 + 2*2, self.Size())
2048
kenton@google.com2d6daa72009-01-22 01:27:00 +00002049 def testRepeatedScalarsExtend(self):
2050 self.proto.repeated_int32.extend([10, 128]) # 3 bytes.
2051 # Also need 2 bytes for each entry for tag.
2052 self.assertEqual(1 + 2 + 2*2, self.Size())
2053
kenton@google.com24bf56f2008-09-24 20:31:01 +00002054 def testRepeatedScalarsRemove(self):
2055 self.proto.repeated_int32.append(10) # 1 byte.
2056 self.proto.repeated_int32.append(128) # 2 bytes.
2057 # Also need 2 bytes for each entry for tag.
2058 self.assertEqual(1 + 2 + 2*2, self.Size())
2059 self.proto.repeated_int32.remove(128)
2060 self.assertEqual(1 + 2, self.Size())
2061
temporal40ee5512008-07-10 02:12:20 +00002062 def testRepeatedComposites(self):
2063 # Empty message. 2 bytes tag plus 1 byte length.
2064 foreign_message_0 = self.proto.repeated_nested_message.add()
2065 # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
2066 foreign_message_1 = self.proto.repeated_nested_message.add()
2067 foreign_message_1.bb = 7
2068 self.assertEqual(2 + 1 + 2 + 1 + 1 + 1, self.Size())
2069
kenton@google.com24bf56f2008-09-24 20:31:01 +00002070 def testRepeatedCompositesDelete(self):
2071 # Empty message. 2 bytes tag plus 1 byte length.
2072 foreign_message_0 = self.proto.repeated_nested_message.add()
2073 # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
2074 foreign_message_1 = self.proto.repeated_nested_message.add()
2075 foreign_message_1.bb = 9
2076 self.assertEqual(2 + 1 + 2 + 1 + 1 + 1, self.Size())
2077
2078 # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
2079 del self.proto.repeated_nested_message[0]
2080 self.assertEqual(2 + 1 + 1 + 1, self.Size())
2081
2082 # Now add a new message.
2083 foreign_message_2 = self.proto.repeated_nested_message.add()
2084 foreign_message_2.bb = 12
2085
2086 # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
2087 # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
2088 self.assertEqual(2 + 1 + 1 + 1 + 2 + 1 + 1 + 1, self.Size())
2089
2090 # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
2091 del self.proto.repeated_nested_message[1]
2092 self.assertEqual(2 + 1 + 1 + 1, self.Size())
2093
2094 del self.proto.repeated_nested_message[0]
2095 self.assertEqual(0, self.Size())
2096
temporal40ee5512008-07-10 02:12:20 +00002097 def testRepeatedGroups(self):
2098 # 2-byte START_GROUP plus 2-byte END_GROUP.
2099 group_0 = self.proto.repeatedgroup.add()
2100 # 2-byte START_GROUP plus 2-byte |a| tag + 1-byte |a|
2101 # plus 2-byte END_GROUP.
2102 group_1 = self.proto.repeatedgroup.add()
2103 group_1.a = 7
2104 self.assertEqual(2 + 2 + 2 + 2 + 1 + 2, self.Size())
2105
2106 def testExtensions(self):
2107 proto = unittest_pb2.TestAllExtensions()
2108 self.assertEqual(0, proto.ByteSize())
2109 extension = unittest_pb2.optional_int32_extension # Field #1, 1 byte.
2110 proto.Extensions[extension] = 23
2111 # 1 byte for tag, 1 byte for value.
2112 self.assertEqual(2, proto.ByteSize())
2113
2114 def testCacheInvalidationForNonrepeatedScalar(self):
2115 # Test non-extension.
2116 self.proto.optional_int32 = 1
2117 self.assertEqual(2, self.proto.ByteSize())
2118 self.proto.optional_int32 = 128
2119 self.assertEqual(3, self.proto.ByteSize())
2120 self.proto.ClearField('optional_int32')
2121 self.assertEqual(0, self.proto.ByteSize())
2122
2123 # Test within extension.
2124 extension = more_extensions_pb2.optional_int_extension
2125 self.extended_proto.Extensions[extension] = 1
2126 self.assertEqual(2, self.extended_proto.ByteSize())
2127 self.extended_proto.Extensions[extension] = 128
2128 self.assertEqual(3, self.extended_proto.ByteSize())
2129 self.extended_proto.ClearExtension(extension)
2130 self.assertEqual(0, self.extended_proto.ByteSize())
2131
2132 def testCacheInvalidationForRepeatedScalar(self):
2133 # Test non-extension.
2134 self.proto.repeated_int32.append(1)
2135 self.assertEqual(3, self.proto.ByteSize())
2136 self.proto.repeated_int32.append(1)
2137 self.assertEqual(6, self.proto.ByteSize())
2138 self.proto.repeated_int32[1] = 128
2139 self.assertEqual(7, self.proto.ByteSize())
2140 self.proto.ClearField('repeated_int32')
2141 self.assertEqual(0, self.proto.ByteSize())
2142
2143 # Test within extension.
2144 extension = more_extensions_pb2.repeated_int_extension
2145 repeated = self.extended_proto.Extensions[extension]
2146 repeated.append(1)
2147 self.assertEqual(2, self.extended_proto.ByteSize())
2148 repeated.append(1)
2149 self.assertEqual(4, self.extended_proto.ByteSize())
2150 repeated[1] = 128
2151 self.assertEqual(5, self.extended_proto.ByteSize())
2152 self.extended_proto.ClearExtension(extension)
2153 self.assertEqual(0, self.extended_proto.ByteSize())
2154
2155 def testCacheInvalidationForNonrepeatedMessage(self):
2156 # Test non-extension.
2157 self.proto.optional_foreign_message.c = 1
2158 self.assertEqual(5, self.proto.ByteSize())
2159 self.proto.optional_foreign_message.c = 128
2160 self.assertEqual(6, self.proto.ByteSize())
2161 self.proto.optional_foreign_message.ClearField('c')
2162 self.assertEqual(3, self.proto.ByteSize())
2163 self.proto.ClearField('optional_foreign_message')
2164 self.assertEqual(0, self.proto.ByteSize())
liujisi@google.com33165fe2010-11-02 13:14:58 +00002165
2166 if api_implementation.Type() == 'python':
2167 # This is only possible in pure-Python implementation of the API.
2168 child = self.proto.optional_foreign_message
2169 self.proto.ClearField('optional_foreign_message')
2170 child.c = 128
2171 self.assertEqual(0, self.proto.ByteSize())
temporal40ee5512008-07-10 02:12:20 +00002172
2173 # Test within extension.
2174 extension = more_extensions_pb2.optional_message_extension
2175 child = self.extended_proto.Extensions[extension]
2176 self.assertEqual(0, self.extended_proto.ByteSize())
2177 child.foreign_message_int = 1
2178 self.assertEqual(4, self.extended_proto.ByteSize())
2179 child.foreign_message_int = 128
2180 self.assertEqual(5, self.extended_proto.ByteSize())
2181 self.extended_proto.ClearExtension(extension)
2182 self.assertEqual(0, self.extended_proto.ByteSize())
2183
2184 def testCacheInvalidationForRepeatedMessage(self):
2185 # Test non-extension.
2186 child0 = self.proto.repeated_foreign_message.add()
2187 self.assertEqual(3, self.proto.ByteSize())
2188 self.proto.repeated_foreign_message.add()
2189 self.assertEqual(6, self.proto.ByteSize())
2190 child0.c = 1
2191 self.assertEqual(8, self.proto.ByteSize())
2192 self.proto.ClearField('repeated_foreign_message')
2193 self.assertEqual(0, self.proto.ByteSize())
2194
2195 # Test within extension.
2196 extension = more_extensions_pb2.repeated_message_extension
2197 child_list = self.extended_proto.Extensions[extension]
2198 child0 = child_list.add()
2199 self.assertEqual(2, self.extended_proto.ByteSize())
2200 child_list.add()
2201 self.assertEqual(4, self.extended_proto.ByteSize())
2202 child0.foreign_message_int = 1
2203 self.assertEqual(6, self.extended_proto.ByteSize())
2204 child0.ClearField('foreign_message_int')
2205 self.assertEqual(4, self.extended_proto.ByteSize())
2206 self.extended_proto.ClearExtension(extension)
2207 self.assertEqual(0, self.extended_proto.ByteSize())
2208
kenton@google.com2d6daa72009-01-22 01:27:00 +00002209 def testPackedRepeatedScalars(self):
2210 self.assertEqual(0, self.packed_proto.ByteSize())
2211
2212 self.packed_proto.packed_int32.append(10) # 1 byte.
2213 self.packed_proto.packed_int32.append(128) # 2 bytes.
2214 # The tag is 2 bytes (the field number is 90), and the varint
2215 # storing the length is 1 byte.
2216 int_size = 1 + 2 + 3
2217 self.assertEqual(int_size, self.packed_proto.ByteSize())
2218
2219 self.packed_proto.packed_double.append(4.2) # 8 bytes
2220 self.packed_proto.packed_double.append(3.25) # 8 bytes
2221 # 2 more tag bytes, 1 more length byte.
2222 double_size = 8 + 8 + 3
2223 self.assertEqual(int_size+double_size, self.packed_proto.ByteSize())
2224
2225 self.packed_proto.ClearField('packed_int32')
2226 self.assertEqual(double_size, self.packed_proto.ByteSize())
2227
2228 def testPackedExtensions(self):
2229 self.assertEqual(0, self.packed_extended_proto.ByteSize())
2230 extension = self.packed_extended_proto.Extensions[
2231 unittest_pb2.packed_fixed32_extension]
2232 extension.extend([1, 2, 3, 4]) # 16 bytes
2233 # Tag is 3 bytes.
2234 self.assertEqual(19, self.packed_extended_proto.ByteSize())
2235
temporal40ee5512008-07-10 02:12:20 +00002236
temporal40ee5512008-07-10 02:12:20 +00002237# Issues to be sure to cover include:
2238# * Handling of unrecognized tags ("uninterpreted_bytes").
2239# * Handling of MessageSets.
2240# * Consistent ordering of tags in the wire format,
2241# including ordering between extensions and non-extension
2242# fields.
2243# * Consistent serialization of negative numbers, especially
2244# negative int32s.
2245# * Handling of empty submessages (with and without "has"
2246# bits set).
2247
Tamir Duberstein9f42f5f2015-01-13 14:47:32 -05002248class SerializationTest(unittest.TestCase):
temporal40ee5512008-07-10 02:12:20 +00002249
2250 def testSerializeEmtpyMessage(self):
2251 first_proto = unittest_pb2.TestAllTypes()
2252 second_proto = unittest_pb2.TestAllTypes()
2253 serialized = first_proto.SerializeToString()
2254 self.assertEqual(first_proto.ByteSize(), len(serialized))
jieluo@google.combde4a322014-08-12 21:10:30 +00002255 self.assertEqual(
2256 len(serialized),
2257 second_proto.MergeFromString(serialized))
temporal40ee5512008-07-10 02:12:20 +00002258 self.assertEqual(first_proto, second_proto)
2259
2260 def testSerializeAllFields(self):
2261 first_proto = unittest_pb2.TestAllTypes()
2262 second_proto = unittest_pb2.TestAllTypes()
2263 test_util.SetAllFields(first_proto)
2264 serialized = first_proto.SerializeToString()
2265 self.assertEqual(first_proto.ByteSize(), len(serialized))
jieluo@google.combde4a322014-08-12 21:10:30 +00002266 self.assertEqual(
2267 len(serialized),
2268 second_proto.MergeFromString(serialized))
temporal40ee5512008-07-10 02:12:20 +00002269 self.assertEqual(first_proto, second_proto)
2270
2271 def testSerializeAllExtensions(self):
2272 first_proto = unittest_pb2.TestAllExtensions()
2273 second_proto = unittest_pb2.TestAllExtensions()
2274 test_util.SetAllExtensions(first_proto)
2275 serialized = first_proto.SerializeToString()
jieluo@google.combde4a322014-08-12 21:10:30 +00002276 self.assertEqual(
2277 len(serialized),
2278 second_proto.MergeFromString(serialized))
2279 self.assertEqual(first_proto, second_proto)
2280
2281 def testSerializeWithOptionalGroup(self):
2282 first_proto = unittest_pb2.TestAllTypes()
2283 second_proto = unittest_pb2.TestAllTypes()
2284 first_proto.optionalgroup.a = 242
2285 serialized = first_proto.SerializeToString()
2286 self.assertEqual(
2287 len(serialized),
2288 second_proto.MergeFromString(serialized))
temporal40ee5512008-07-10 02:12:20 +00002289 self.assertEqual(first_proto, second_proto)
2290
kenton@google.comfccb1462009-12-18 02:11:36 +00002291 def testSerializeNegativeValues(self):
2292 first_proto = unittest_pb2.TestAllTypes()
2293
2294 first_proto.optional_int32 = -1
2295 first_proto.optional_int64 = -(2 << 40)
2296 first_proto.optional_sint32 = -3
2297 first_proto.optional_sint64 = -(4 << 40)
2298 first_proto.optional_sfixed32 = -5
2299 first_proto.optional_sfixed64 = -(6 << 40)
2300
2301 second_proto = unittest_pb2.TestAllTypes.FromString(
2302 first_proto.SerializeToString())
2303
2304 self.assertEqual(first_proto, second_proto)
2305
2306 def testParseTruncated(self):
liujisi@google.com33165fe2010-11-02 13:14:58 +00002307 # This test is only applicable for the Python implementation of the API.
2308 if api_implementation.Type() != 'python':
2309 return
2310
kenton@google.comfccb1462009-12-18 02:11:36 +00002311 first_proto = unittest_pb2.TestAllTypes()
2312 test_util.SetAllFields(first_proto)
2313 serialized = first_proto.SerializeToString()
2314
Tres Seaverf336d4b2015-01-13 14:21:29 -05002315 for truncation_point in range(len(serialized) + 1):
kenton@google.comfccb1462009-12-18 02:11:36 +00002316 try:
2317 second_proto = unittest_pb2.TestAllTypes()
2318 unknown_fields = unittest_pb2.TestEmptyMessage()
2319 pos = second_proto._InternalParse(serialized, 0, truncation_point)
2320 # If we didn't raise an error then we read exactly the amount expected.
2321 self.assertEqual(truncation_point, pos)
2322
2323 # Parsing to unknown fields should not throw if parsing to known fields
2324 # did not.
2325 try:
2326 pos2 = unknown_fields._InternalParse(serialized, 0, truncation_point)
2327 self.assertEqual(truncation_point, pos2)
2328 except message.DecodeError:
2329 self.fail('Parsing unknown fields failed when parsing known fields '
2330 'did not.')
2331 except message.DecodeError:
2332 # Parsing unknown fields should also fail.
2333 self.assertRaises(message.DecodeError, unknown_fields._InternalParse,
2334 serialized, 0, truncation_point)
2335
temporal40ee5512008-07-10 02:12:20 +00002336 def testCanonicalSerializationOrder(self):
2337 proto = more_messages_pb2.OutOfOrderFields()
2338 # These are also their tag numbers. Even though we're setting these in
2339 # reverse-tag order AND they're listed in reverse tag-order in the .proto
2340 # file, they should nonetheless be serialized in tag order.
2341 proto.optional_sint32 = 5
2342 proto.Extensions[more_messages_pb2.optional_uint64] = 4
2343 proto.optional_uint32 = 3
2344 proto.Extensions[more_messages_pb2.optional_int64] = 2
2345 proto.optional_int32 = 1
2346 serialized = proto.SerializeToString()
2347 self.assertEqual(proto.ByteSize(), len(serialized))
kenton@google.comfccb1462009-12-18 02:11:36 +00002348 d = _MiniDecoder(serialized)
temporal40ee5512008-07-10 02:12:20 +00002349 ReadTag = d.ReadFieldNumberAndWireType
2350 self.assertEqual((1, wire_format.WIRETYPE_VARINT), ReadTag())
2351 self.assertEqual(1, d.ReadInt32())
2352 self.assertEqual((2, wire_format.WIRETYPE_VARINT), ReadTag())
2353 self.assertEqual(2, d.ReadInt64())
2354 self.assertEqual((3, wire_format.WIRETYPE_VARINT), ReadTag())
2355 self.assertEqual(3, d.ReadUInt32())
2356 self.assertEqual((4, wire_format.WIRETYPE_VARINT), ReadTag())
2357 self.assertEqual(4, d.ReadUInt64())
2358 self.assertEqual((5, wire_format.WIRETYPE_VARINT), ReadTag())
2359 self.assertEqual(5, d.ReadSInt32())
2360
2361 def testCanonicalSerializationOrderSameAsCpp(self):
2362 # Copy of the same test we use for C++.
2363 proto = unittest_pb2.TestFieldOrderings()
2364 test_util.SetAllFieldsAndExtensions(proto)
2365 serialized = proto.SerializeToString()
2366 test_util.ExpectAllFieldsAndExtensionsInOrder(serialized)
2367
2368 def testMergeFromStringWhenFieldsAlreadySet(self):
2369 first_proto = unittest_pb2.TestAllTypes()
2370 first_proto.repeated_string.append('foobar')
2371 first_proto.optional_int32 = 23
2372 first_proto.optional_nested_message.bb = 42
2373 serialized = first_proto.SerializeToString()
2374
2375 second_proto = unittest_pb2.TestAllTypes()
2376 second_proto.repeated_string.append('baz')
2377 second_proto.optional_int32 = 100
2378 second_proto.optional_nested_message.bb = 999
2379
jieluo@google.combde4a322014-08-12 21:10:30 +00002380 bytes_parsed = second_proto.MergeFromString(serialized)
2381 self.assertEqual(len(serialized), bytes_parsed)
2382
temporal40ee5512008-07-10 02:12:20 +00002383 # Ensure that we append to repeated fields.
2384 self.assertEqual(['baz', 'foobar'], list(second_proto.repeated_string))
2385 # Ensure that we overwrite nonrepeatd scalars.
2386 self.assertEqual(23, second_proto.optional_int32)
2387 # Ensure that we recursively call MergeFromString() on
2388 # submessages.
2389 self.assertEqual(42, second_proto.optional_nested_message.bb)
2390
2391 def testMessageSetWireFormat(self):
Feng Xiaoeee38b02015-08-22 18:25:48 -07002392 proto = message_set_extensions_pb2.TestMessageSet()
2393 extension_message1 = message_set_extensions_pb2.TestMessageSetExtension1
2394 extension_message2 = message_set_extensions_pb2.TestMessageSetExtension2
temporal40ee5512008-07-10 02:12:20 +00002395 extension1 = extension_message1.message_set_extension
2396 extension2 = extension_message2.message_set_extension
Feng Xiaoe841bac2015-12-11 17:09:20 -08002397 extension3 = message_set_extensions_pb2.message_set_extension3
temporal40ee5512008-07-10 02:12:20 +00002398 proto.Extensions[extension1].i = 123
2399 proto.Extensions[extension2].str = 'foo'
Feng Xiaoe841bac2015-12-11 17:09:20 -08002400 proto.Extensions[extension3].text = 'bar'
temporal40ee5512008-07-10 02:12:20 +00002401
2402 # Serialize using the MessageSet wire format (this is specified in the
2403 # .proto file).
2404 serialized = proto.SerializeToString()
2405
2406 raw = unittest_mset_pb2.RawMessageSet()
2407 self.assertEqual(False,
2408 raw.DESCRIPTOR.GetOptions().message_set_wire_format)
jieluo@google.combde4a322014-08-12 21:10:30 +00002409 self.assertEqual(
2410 len(serialized),
2411 raw.MergeFromString(serialized))
Feng Xiaoe841bac2015-12-11 17:09:20 -08002412 self.assertEqual(3, len(raw.item))
temporal40ee5512008-07-10 02:12:20 +00002413
Feng Xiaoeee38b02015-08-22 18:25:48 -07002414 message1 = message_set_extensions_pb2.TestMessageSetExtension1()
jieluo@google.combde4a322014-08-12 21:10:30 +00002415 self.assertEqual(
2416 len(raw.item[0].message),
2417 message1.MergeFromString(raw.item[0].message))
temporal40ee5512008-07-10 02:12:20 +00002418 self.assertEqual(123, message1.i)
2419
Feng Xiaoeee38b02015-08-22 18:25:48 -07002420 message2 = message_set_extensions_pb2.TestMessageSetExtension2()
jieluo@google.combde4a322014-08-12 21:10:30 +00002421 self.assertEqual(
2422 len(raw.item[1].message),
2423 message2.MergeFromString(raw.item[1].message))
temporal40ee5512008-07-10 02:12:20 +00002424 self.assertEqual('foo', message2.str)
2425
Feng Xiaoe841bac2015-12-11 17:09:20 -08002426 message3 = message_set_extensions_pb2.TestMessageSetExtension3()
2427 self.assertEqual(
2428 len(raw.item[2].message),
2429 message3.MergeFromString(raw.item[2].message))
2430 self.assertEqual('bar', message3.text)
2431
temporal40ee5512008-07-10 02:12:20 +00002432 # Deserialize using the MessageSet wire format.
Feng Xiaoeee38b02015-08-22 18:25:48 -07002433 proto2 = message_set_extensions_pb2.TestMessageSet()
jieluo@google.combde4a322014-08-12 21:10:30 +00002434 self.assertEqual(
2435 len(serialized),
2436 proto2.MergeFromString(serialized))
temporal40ee5512008-07-10 02:12:20 +00002437 self.assertEqual(123, proto2.Extensions[extension1].i)
2438 self.assertEqual('foo', proto2.Extensions[extension2].str)
Feng Xiaoe841bac2015-12-11 17:09:20 -08002439 self.assertEqual('bar', proto2.Extensions[extension3].text)
temporal40ee5512008-07-10 02:12:20 +00002440
2441 # Check byte size.
2442 self.assertEqual(proto2.ByteSize(), len(serialized))
2443 self.assertEqual(proto.ByteSize(), len(serialized))
2444
2445 def testMessageSetWireFormatUnknownExtension(self):
2446 # Create a message using the message set wire format with an unknown
2447 # message.
2448 raw = unittest_mset_pb2.RawMessageSet()
2449
2450 # Add an item.
2451 item = raw.item.add()
Feng Xiaoeee38b02015-08-22 18:25:48 -07002452 item.type_id = 98418603
2453 extension_message1 = message_set_extensions_pb2.TestMessageSetExtension1
2454 message1 = message_set_extensions_pb2.TestMessageSetExtension1()
temporal40ee5512008-07-10 02:12:20 +00002455 message1.i = 12345
2456 item.message = message1.SerializeToString()
2457
2458 # Add a second, unknown extension.
2459 item = raw.item.add()
Feng Xiaoeee38b02015-08-22 18:25:48 -07002460 item.type_id = 98418604
2461 extension_message1 = message_set_extensions_pb2.TestMessageSetExtension1
2462 message1 = message_set_extensions_pb2.TestMessageSetExtension1()
temporal40ee5512008-07-10 02:12:20 +00002463 message1.i = 12346
2464 item.message = message1.SerializeToString()
2465
2466 # Add another unknown extension.
2467 item = raw.item.add()
Feng Xiaoeee38b02015-08-22 18:25:48 -07002468 item.type_id = 98418605
2469 message1 = message_set_extensions_pb2.TestMessageSetExtension2()
temporal40ee5512008-07-10 02:12:20 +00002470 message1.str = 'foo'
2471 item.message = message1.SerializeToString()
2472
2473 serialized = raw.SerializeToString()
2474
2475 # Parse message using the message set wire format.
Feng Xiaoeee38b02015-08-22 18:25:48 -07002476 proto = message_set_extensions_pb2.TestMessageSet()
jieluo@google.combde4a322014-08-12 21:10:30 +00002477 self.assertEqual(
2478 len(serialized),
2479 proto.MergeFromString(serialized))
temporal40ee5512008-07-10 02:12:20 +00002480
2481 # Check that the message parsed well.
Feng Xiaoeee38b02015-08-22 18:25:48 -07002482 extension_message1 = message_set_extensions_pb2.TestMessageSetExtension1
temporal40ee5512008-07-10 02:12:20 +00002483 extension1 = extension_message1.message_set_extension
Tres Seavera2abc942015-01-13 15:47:55 -05002484 self.assertEqual(12345, proto.Extensions[extension1].i)
temporal40ee5512008-07-10 02:12:20 +00002485
2486 def testUnknownFields(self):
2487 proto = unittest_pb2.TestAllTypes()
2488 test_util.SetAllFields(proto)
2489
2490 serialized = proto.SerializeToString()
2491
2492 # The empty message should be parsable with all of the fields
2493 # unknown.
2494 proto2 = unittest_pb2.TestEmptyMessage()
2495
2496 # Parsing this message should succeed.
jieluo@google.combde4a322014-08-12 21:10:30 +00002497 self.assertEqual(
2498 len(serialized),
2499 proto2.MergeFromString(serialized))
temporal40ee5512008-07-10 02:12:20 +00002500
kenton@google.com24bf56f2008-09-24 20:31:01 +00002501 # Now test with a int64 field set.
2502 proto = unittest_pb2.TestAllTypes()
2503 proto.optional_int64 = 0x0fffffffffffffff
2504 serialized = proto.SerializeToString()
2505 # The empty message should be parsable with all of the fields
2506 # unknown.
2507 proto2 = unittest_pb2.TestEmptyMessage()
2508 # Parsing this message should succeed.
jieluo@google.combde4a322014-08-12 21:10:30 +00002509 self.assertEqual(
2510 len(serialized),
2511 proto2.MergeFromString(serialized))
kenton@google.com24bf56f2008-09-24 20:31:01 +00002512
temporal779f61c2008-08-13 03:15:00 +00002513 def _CheckRaises(self, exc_class, callable_obj, exception):
2514 """This method checks if the excpetion type and message are as expected."""
2515 try:
2516 callable_obj()
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00002517 except exc_class as ex:
temporal779f61c2008-08-13 03:15:00 +00002518 # Check if the exception message is the right one.
2519 self.assertEqual(exception, str(ex))
2520 return
2521 else:
2522 raise self.failureException('%s not raised' % str(exc_class))
2523
2524 def testSerializeUninitialized(self):
2525 proto = unittest_pb2.TestRequired()
jieluo@google.com24095cc2014-08-14 18:04:22 +00002526 self._CheckRaises(
2527 message.EncodeError,
2528 proto.SerializeToString,
2529 'Message protobuf_unittest.TestRequired is missing required fields: '
2530 'a,b,c')
temporal779f61c2008-08-13 03:15:00 +00002531 # Shouldn't raise exceptions.
2532 partial = proto.SerializePartialToString()
2533
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00002534 proto2 = unittest_pb2.TestRequired()
2535 self.assertFalse(proto2.HasField('a'))
2536 # proto2 ParseFromString does not check that required fields are set.
2537 proto2.ParseFromString(partial)
2538 self.assertFalse(proto2.HasField('a'))
2539
temporal779f61c2008-08-13 03:15:00 +00002540 proto.a = 1
jieluo@google.com24095cc2014-08-14 18:04:22 +00002541 self._CheckRaises(
2542 message.EncodeError,
2543 proto.SerializeToString,
2544 'Message protobuf_unittest.TestRequired is missing required fields: b,c')
temporal779f61c2008-08-13 03:15:00 +00002545 # Shouldn't raise exceptions.
2546 partial = proto.SerializePartialToString()
2547
2548 proto.b = 2
jieluo@google.com24095cc2014-08-14 18:04:22 +00002549 self._CheckRaises(
2550 message.EncodeError,
2551 proto.SerializeToString,
2552 'Message protobuf_unittest.TestRequired is missing required fields: c')
temporal779f61c2008-08-13 03:15:00 +00002553 # Shouldn't raise exceptions.
2554 partial = proto.SerializePartialToString()
2555
2556 proto.c = 3
2557 serialized = proto.SerializeToString()
2558 # Shouldn't raise exceptions.
2559 partial = proto.SerializePartialToString()
2560
2561 proto2 = unittest_pb2.TestRequired()
jieluo@google.combde4a322014-08-12 21:10:30 +00002562 self.assertEqual(
2563 len(serialized),
2564 proto2.MergeFromString(serialized))
temporal779f61c2008-08-13 03:15:00 +00002565 self.assertEqual(1, proto2.a)
2566 self.assertEqual(2, proto2.b)
2567 self.assertEqual(3, proto2.c)
jieluo@google.combde4a322014-08-12 21:10:30 +00002568 self.assertEqual(
2569 len(partial),
2570 proto2.MergeFromString(partial))
temporal779f61c2008-08-13 03:15:00 +00002571 self.assertEqual(1, proto2.a)
2572 self.assertEqual(2, proto2.b)
2573 self.assertEqual(3, proto2.c)
2574
kenton@google.comfccb1462009-12-18 02:11:36 +00002575 def testSerializeUninitializedSubMessage(self):
2576 proto = unittest_pb2.TestRequiredForeign()
2577
2578 # Sub-message doesn't exist yet, so this succeeds.
2579 proto.SerializeToString()
2580
2581 proto.optional_message.a = 1
jieluo@google.com24095cc2014-08-14 18:04:22 +00002582 self._CheckRaises(
2583 message.EncodeError,
2584 proto.SerializeToString,
2585 'Message protobuf_unittest.TestRequiredForeign '
2586 'is missing required fields: '
2587 'optional_message.b,optional_message.c')
kenton@google.comfccb1462009-12-18 02:11:36 +00002588
2589 proto.optional_message.b = 2
2590 proto.optional_message.c = 3
2591 proto.SerializeToString()
2592
2593 proto.repeated_message.add().a = 1
2594 proto.repeated_message.add().b = 2
jieluo@google.com24095cc2014-08-14 18:04:22 +00002595 self._CheckRaises(
2596 message.EncodeError,
2597 proto.SerializeToString,
2598 'Message protobuf_unittest.TestRequiredForeign is missing required fields: '
2599 'repeated_message[0].b,repeated_message[0].c,'
2600 'repeated_message[1].a,repeated_message[1].c')
kenton@google.comfccb1462009-12-18 02:11:36 +00002601
2602 proto.repeated_message[0].b = 2
2603 proto.repeated_message[0].c = 3
2604 proto.repeated_message[1].a = 1
2605 proto.repeated_message[1].c = 3
2606 proto.SerializeToString()
2607
kenton@google.com80b1d622009-07-29 01:13:20 +00002608 def testSerializeAllPackedFields(self):
kenton@google.com2d6daa72009-01-22 01:27:00 +00002609 first_proto = unittest_pb2.TestPackedTypes()
2610 second_proto = unittest_pb2.TestPackedTypes()
2611 test_util.SetAllPackedFields(first_proto)
2612 serialized = first_proto.SerializeToString()
2613 self.assertEqual(first_proto.ByteSize(), len(serialized))
kenton@google.com80b1d622009-07-29 01:13:20 +00002614 bytes_read = second_proto.MergeFromString(serialized)
2615 self.assertEqual(second_proto.ByteSize(), bytes_read)
kenton@google.com2d6daa72009-01-22 01:27:00 +00002616 self.assertEqual(first_proto, second_proto)
2617
2618 def testSerializeAllPackedExtensions(self):
2619 first_proto = unittest_pb2.TestPackedExtensions()
2620 second_proto = unittest_pb2.TestPackedExtensions()
2621 test_util.SetAllPackedExtensions(first_proto)
2622 serialized = first_proto.SerializeToString()
kenton@google.com80b1d622009-07-29 01:13:20 +00002623 bytes_read = second_proto.MergeFromString(serialized)
2624 self.assertEqual(second_proto.ByteSize(), bytes_read)
kenton@google.com2d6daa72009-01-22 01:27:00 +00002625 self.assertEqual(first_proto, second_proto)
2626
2627 def testMergePackedFromStringWhenSomeFieldsAlreadySet(self):
2628 first_proto = unittest_pb2.TestPackedTypes()
2629 first_proto.packed_int32.extend([1, 2])
2630 first_proto.packed_double.append(3.0)
2631 serialized = first_proto.SerializeToString()
2632
2633 second_proto = unittest_pb2.TestPackedTypes()
2634 second_proto.packed_int32.append(3)
2635 second_proto.packed_double.extend([1.0, 2.0])
2636 second_proto.packed_sint32.append(4)
2637
jieluo@google.combde4a322014-08-12 21:10:30 +00002638 self.assertEqual(
2639 len(serialized),
2640 second_proto.MergeFromString(serialized))
kenton@google.com2d6daa72009-01-22 01:27:00 +00002641 self.assertEqual([3, 1, 2], second_proto.packed_int32)
2642 self.assertEqual([1.0, 2.0, 3.0], second_proto.packed_double)
2643 self.assertEqual([4], second_proto.packed_sint32)
2644
2645 def testPackedFieldsWireFormat(self):
2646 proto = unittest_pb2.TestPackedTypes()
2647 proto.packed_int32.extend([1, 2, 150, 3]) # 1 + 1 + 2 + 1 bytes
2648 proto.packed_double.extend([1.0, 1000.0]) # 8 + 8 bytes
2649 proto.packed_float.append(2.0) # 4 bytes, will be before double
2650 serialized = proto.SerializeToString()
2651 self.assertEqual(proto.ByteSize(), len(serialized))
kenton@google.comfccb1462009-12-18 02:11:36 +00002652 d = _MiniDecoder(serialized)
kenton@google.com2d6daa72009-01-22 01:27:00 +00002653 ReadTag = d.ReadFieldNumberAndWireType
2654 self.assertEqual((90, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
2655 self.assertEqual(1+1+1+2, d.ReadInt32())
2656 self.assertEqual(1, d.ReadInt32())
2657 self.assertEqual(2, d.ReadInt32())
2658 self.assertEqual(150, d.ReadInt32())
2659 self.assertEqual(3, d.ReadInt32())
2660 self.assertEqual((100, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
2661 self.assertEqual(4, d.ReadInt32())
2662 self.assertEqual(2.0, d.ReadFloat())
2663 self.assertEqual((101, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
2664 self.assertEqual(8+8, d.ReadInt32())
2665 self.assertEqual(1.0, d.ReadDouble())
2666 self.assertEqual(1000.0, d.ReadDouble())
2667 self.assertTrue(d.EndOfStream())
2668
kenton@google.comfccb1462009-12-18 02:11:36 +00002669 def testParsePackedFromUnpacked(self):
2670 unpacked = unittest_pb2.TestUnpackedTypes()
2671 test_util.SetAllUnpackedFields(unpacked)
2672 packed = unittest_pb2.TestPackedTypes()
jieluo@google.combde4a322014-08-12 21:10:30 +00002673 serialized = unpacked.SerializeToString()
2674 self.assertEqual(
2675 len(serialized),
2676 packed.MergeFromString(serialized))
kenton@google.comfccb1462009-12-18 02:11:36 +00002677 expected = unittest_pb2.TestPackedTypes()
2678 test_util.SetAllPackedFields(expected)
2679 self.assertEqual(expected, packed)
2680
2681 def testParseUnpackedFromPacked(self):
2682 packed = unittest_pb2.TestPackedTypes()
2683 test_util.SetAllPackedFields(packed)
2684 unpacked = unittest_pb2.TestUnpackedTypes()
jieluo@google.combde4a322014-08-12 21:10:30 +00002685 serialized = packed.SerializeToString()
2686 self.assertEqual(
2687 len(serialized),
2688 unpacked.MergeFromString(serialized))
kenton@google.comfccb1462009-12-18 02:11:36 +00002689 expected = unittest_pb2.TestUnpackedTypes()
2690 test_util.SetAllUnpackedFields(expected)
2691 self.assertEqual(expected, unpacked)
2692
kenton@google.comcfa2d8a2009-04-18 00:02:12 +00002693 def testFieldNumbers(self):
2694 proto = unittest_pb2.TestAllTypes()
2695 self.assertEqual(unittest_pb2.TestAllTypes.NestedMessage.BB_FIELD_NUMBER, 1)
2696 self.assertEqual(unittest_pb2.TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER, 1)
2697 self.assertEqual(unittest_pb2.TestAllTypes.OPTIONALGROUP_FIELD_NUMBER, 16)
2698 self.assertEqual(
2699 unittest_pb2.TestAllTypes.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER, 18)
2700 self.assertEqual(
2701 unittest_pb2.TestAllTypes.OPTIONAL_NESTED_ENUM_FIELD_NUMBER, 21)
2702 self.assertEqual(unittest_pb2.TestAllTypes.REPEATED_INT32_FIELD_NUMBER, 31)
2703 self.assertEqual(unittest_pb2.TestAllTypes.REPEATEDGROUP_FIELD_NUMBER, 46)
2704 self.assertEqual(
2705 unittest_pb2.TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER, 48)
2706 self.assertEqual(
2707 unittest_pb2.TestAllTypes.REPEATED_NESTED_ENUM_FIELD_NUMBER, 51)
2708
2709 def testExtensionFieldNumbers(self):
2710 self.assertEqual(unittest_pb2.TestRequired.single.number, 1000)
2711 self.assertEqual(unittest_pb2.TestRequired.SINGLE_FIELD_NUMBER, 1000)
2712 self.assertEqual(unittest_pb2.TestRequired.multi.number, 1001)
2713 self.assertEqual(unittest_pb2.TestRequired.MULTI_FIELD_NUMBER, 1001)
2714 self.assertEqual(unittest_pb2.optional_int32_extension.number, 1)
2715 self.assertEqual(unittest_pb2.OPTIONAL_INT32_EXTENSION_FIELD_NUMBER, 1)
2716 self.assertEqual(unittest_pb2.optionalgroup_extension.number, 16)
2717 self.assertEqual(unittest_pb2.OPTIONALGROUP_EXTENSION_FIELD_NUMBER, 16)
2718 self.assertEqual(unittest_pb2.optional_nested_message_extension.number, 18)
2719 self.assertEqual(
2720 unittest_pb2.OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 18)
2721 self.assertEqual(unittest_pb2.optional_nested_enum_extension.number, 21)
2722 self.assertEqual(unittest_pb2.OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER,
2723 21)
2724 self.assertEqual(unittest_pb2.repeated_int32_extension.number, 31)
2725 self.assertEqual(unittest_pb2.REPEATED_INT32_EXTENSION_FIELD_NUMBER, 31)
2726 self.assertEqual(unittest_pb2.repeatedgroup_extension.number, 46)
2727 self.assertEqual(unittest_pb2.REPEATEDGROUP_EXTENSION_FIELD_NUMBER, 46)
2728 self.assertEqual(unittest_pb2.repeated_nested_message_extension.number, 48)
2729 self.assertEqual(
2730 unittest_pb2.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 48)
2731 self.assertEqual(unittest_pb2.repeated_nested_enum_extension.number, 51)
2732 self.assertEqual(unittest_pb2.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER,
2733 51)
temporal40ee5512008-07-10 02:12:20 +00002734
kenton@google.com80b1d622009-07-29 01:13:20 +00002735 def testInitKwargs(self):
2736 proto = unittest_pb2.TestAllTypes(
2737 optional_int32=1,
2738 optional_string='foo',
2739 optional_bool=True,
jieluo@google.combde4a322014-08-12 21:10:30 +00002740 optional_bytes=b'bar',
kenton@google.com80b1d622009-07-29 01:13:20 +00002741 optional_nested_message=unittest_pb2.TestAllTypes.NestedMessage(bb=1),
2742 optional_foreign_message=unittest_pb2.ForeignMessage(c=1),
2743 optional_nested_enum=unittest_pb2.TestAllTypes.FOO,
2744 optional_foreign_enum=unittest_pb2.FOREIGN_FOO,
2745 repeated_int32=[1, 2, 3])
2746 self.assertTrue(proto.IsInitialized())
2747 self.assertTrue(proto.HasField('optional_int32'))
2748 self.assertTrue(proto.HasField('optional_string'))
2749 self.assertTrue(proto.HasField('optional_bool'))
2750 self.assertTrue(proto.HasField('optional_bytes'))
2751 self.assertTrue(proto.HasField('optional_nested_message'))
2752 self.assertTrue(proto.HasField('optional_foreign_message'))
2753 self.assertTrue(proto.HasField('optional_nested_enum'))
2754 self.assertTrue(proto.HasField('optional_foreign_enum'))
2755 self.assertEqual(1, proto.optional_int32)
2756 self.assertEqual('foo', proto.optional_string)
2757 self.assertEqual(True, proto.optional_bool)
jieluo@google.combde4a322014-08-12 21:10:30 +00002758 self.assertEqual(b'bar', proto.optional_bytes)
kenton@google.com80b1d622009-07-29 01:13:20 +00002759 self.assertEqual(1, proto.optional_nested_message.bb)
2760 self.assertEqual(1, proto.optional_foreign_message.c)
2761 self.assertEqual(unittest_pb2.TestAllTypes.FOO,
2762 proto.optional_nested_enum)
2763 self.assertEqual(unittest_pb2.FOREIGN_FOO, proto.optional_foreign_enum)
2764 self.assertEqual([1, 2, 3], proto.repeated_int32)
2765
2766 def testInitArgsUnknownFieldName(self):
2767 def InitalizeEmptyMessageWithExtraKeywordArg():
2768 unused_proto = unittest_pb2.TestEmptyMessage(unknown='unknown')
Feng Xiaoe841bac2015-12-11 17:09:20 -08002769 self._CheckRaises(
2770 ValueError,
2771 InitalizeEmptyMessageWithExtraKeywordArg,
2772 'Protocol message TestEmptyMessage has no "unknown" field.')
kenton@google.com80b1d622009-07-29 01:13:20 +00002773
2774 def testInitRequiredKwargs(self):
2775 proto = unittest_pb2.TestRequired(a=1, b=1, c=1)
2776 self.assertTrue(proto.IsInitialized())
2777 self.assertTrue(proto.HasField('a'))
2778 self.assertTrue(proto.HasField('b'))
2779 self.assertTrue(proto.HasField('c'))
2780 self.assertTrue(not proto.HasField('dummy2'))
2781 self.assertEqual(1, proto.a)
2782 self.assertEqual(1, proto.b)
2783 self.assertEqual(1, proto.c)
2784
2785 def testInitRequiredForeignKwargs(self):
2786 proto = unittest_pb2.TestRequiredForeign(
2787 optional_message=unittest_pb2.TestRequired(a=1, b=1, c=1))
2788 self.assertTrue(proto.IsInitialized())
2789 self.assertTrue(proto.HasField('optional_message'))
2790 self.assertTrue(proto.optional_message.IsInitialized())
2791 self.assertTrue(proto.optional_message.HasField('a'))
2792 self.assertTrue(proto.optional_message.HasField('b'))
2793 self.assertTrue(proto.optional_message.HasField('c'))
2794 self.assertTrue(not proto.optional_message.HasField('dummy2'))
2795 self.assertEqual(unittest_pb2.TestRequired(a=1, b=1, c=1),
2796 proto.optional_message)
2797 self.assertEqual(1, proto.optional_message.a)
2798 self.assertEqual(1, proto.optional_message.b)
2799 self.assertEqual(1, proto.optional_message.c)
2800
2801 def testInitRepeatedKwargs(self):
2802 proto = unittest_pb2.TestAllTypes(repeated_int32=[1, 2, 3])
2803 self.assertTrue(proto.IsInitialized())
2804 self.assertEqual(1, proto.repeated_int32[0])
2805 self.assertEqual(2, proto.repeated_int32[1])
2806 self.assertEqual(3, proto.repeated_int32[2])
2807
2808
Tamir Duberstein9f42f5f2015-01-13 14:47:32 -05002809class OptionsTest(unittest.TestCase):
temporal40ee5512008-07-10 02:12:20 +00002810
2811 def testMessageOptions(self):
Feng Xiaoeee38b02015-08-22 18:25:48 -07002812 proto = message_set_extensions_pb2.TestMessageSet()
temporal40ee5512008-07-10 02:12:20 +00002813 self.assertEqual(True,
2814 proto.DESCRIPTOR.GetOptions().message_set_wire_format)
2815 proto = unittest_pb2.TestAllTypes()
2816 self.assertEqual(False,
2817 proto.DESCRIPTOR.GetOptions().message_set_wire_format)
2818
kenton@google.com2d6daa72009-01-22 01:27:00 +00002819 def testPackedOptions(self):
2820 proto = unittest_pb2.TestAllTypes()
2821 proto.optional_int32 = 1
2822 proto.optional_double = 3.0
2823 for field_descriptor, _ in proto.ListFields():
2824 self.assertEqual(False, field_descriptor.GetOptions().packed)
2825
2826 proto = unittest_pb2.TestPackedTypes()
2827 proto.packed_int32.append(1)
2828 proto.packed_double.append(3.0)
2829 for field_descriptor, _ in proto.ListFields():
2830 self.assertEqual(True, field_descriptor.GetOptions().packed)
Feng Xiaoeee38b02015-08-22 18:25:48 -07002831 self.assertEqual(descriptor.FieldDescriptor.LABEL_REPEATED,
kenton@google.com2d6daa72009-01-22 01:27:00 +00002832 field_descriptor.label)
2833
temporal40ee5512008-07-10 02:12:20 +00002834
temporal40ee5512008-07-10 02:12:20 +00002835
Tamir Duberstein9f42f5f2015-01-13 14:47:32 -05002836class ClassAPITest(unittest.TestCase):
jieluo@google.combde4a322014-08-12 21:10:30 +00002837
Jisi Liudbea00a2015-10-05 16:08:22 -07002838 @unittest.skipIf(
Feng Xiao6ef984a2014-11-10 17:34:54 -08002839 api_implementation.Type() == 'cpp' and api_implementation.Version() == 2,
2840 'C++ implementation requires a call to MakeDescriptor()')
jieluo@google.combde4a322014-08-12 21:10:30 +00002841 def testMakeClassWithNestedDescriptor(self):
2842 leaf_desc = descriptor.Descriptor('leaf', 'package.parent.child.leaf', '',
2843 containing_type=None, fields=[],
2844 nested_types=[], enum_types=[],
2845 extensions=[])
2846 child_desc = descriptor.Descriptor('child', 'package.parent.child', '',
2847 containing_type=None, fields=[],
2848 nested_types=[leaf_desc], enum_types=[],
2849 extensions=[])
2850 sibling_desc = descriptor.Descriptor('sibling', 'package.parent.sibling',
2851 '', containing_type=None, fields=[],
2852 nested_types=[], enum_types=[],
2853 extensions=[])
2854 parent_desc = descriptor.Descriptor('parent', 'package.parent', '',
2855 containing_type=None, fields=[],
2856 nested_types=[child_desc, sibling_desc],
2857 enum_types=[], extensions=[])
2858 message_class = reflection.MakeClass(parent_desc)
2859 self.assertIn('child', message_class.__dict__)
2860 self.assertIn('sibling', message_class.__dict__)
2861 self.assertIn('leaf', message_class.child.__dict__)
2862
2863 def _GetSerializedFileDescriptor(self, name):
2864 """Get a serialized representation of a test FileDescriptorProto.
2865
2866 Args:
2867 name: All calls to this must use a unique message name, to avoid
2868 collisions in the cpp descriptor pool.
2869 Returns:
2870 A string containing the serialized form of a test FileDescriptorProto.
2871 """
2872 file_descriptor_str = (
2873 'message_type {'
2874 ' name: "' + name + '"'
2875 ' field {'
2876 ' name: "flat"'
2877 ' number: 1'
2878 ' label: LABEL_REPEATED'
2879 ' type: TYPE_UINT32'
2880 ' }'
2881 ' field {'
2882 ' name: "bar"'
2883 ' number: 2'
2884 ' label: LABEL_OPTIONAL'
2885 ' type: TYPE_MESSAGE'
2886 ' type_name: "Bar"'
2887 ' }'
2888 ' nested_type {'
2889 ' name: "Bar"'
2890 ' field {'
2891 ' name: "baz"'
2892 ' number: 3'
2893 ' label: LABEL_OPTIONAL'
2894 ' type: TYPE_MESSAGE'
2895 ' type_name: "Baz"'
2896 ' }'
2897 ' nested_type {'
2898 ' name: "Baz"'
2899 ' enum_type {'
2900 ' name: "deep_enum"'
2901 ' value {'
2902 ' name: "VALUE_A"'
2903 ' number: 0'
2904 ' }'
2905 ' }'
2906 ' field {'
2907 ' name: "deep"'
2908 ' number: 4'
2909 ' label: LABEL_OPTIONAL'
2910 ' type: TYPE_UINT32'
2911 ' }'
2912 ' }'
2913 ' }'
2914 '}')
2915 file_descriptor = descriptor_pb2.FileDescriptorProto()
2916 text_format.Merge(file_descriptor_str, file_descriptor)
2917 return file_descriptor.SerializeToString()
2918
2919 def testParsingFlatClassWithExplicitClassDeclaration(self):
2920 """Test that the generated class can parse a flat message."""
Feng Xiaoa3a26052015-08-26 21:56:26 -07002921 # TODO(xiaofeng): This test fails with cpp implemetnation in the call
2922 # of six.with_metaclass(). The other two callsites of with_metaclass
2923 # in this file are both excluded from cpp test, so it might be expected
2924 # to fail. Need someone more familiar with the python code to take a
2925 # look at this.
2926 if api_implementation.Type() != 'python':
2927 return
jieluo@google.combde4a322014-08-12 21:10:30 +00002928 file_descriptor = descriptor_pb2.FileDescriptorProto()
2929 file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('A'))
2930 msg_descriptor = descriptor.MakeDescriptor(
2931 file_descriptor.message_type[0])
2932
Tres Seaverf336d4b2015-01-13 14:21:29 -05002933 class MessageClass(six.with_metaclass(reflection.GeneratedProtocolMessageType, message.Message)):
jieluo@google.combde4a322014-08-12 21:10:30 +00002934 DESCRIPTOR = msg_descriptor
2935 msg = MessageClass()
2936 msg_str = (
2937 'flat: 0 '
2938 'flat: 1 '
2939 'flat: 2 ')
2940 text_format.Merge(msg_str, msg)
2941 self.assertEqual(msg.flat, [0, 1, 2])
2942
2943 def testParsingFlatClass(self):
2944 """Test that the generated class can parse a flat message."""
2945 file_descriptor = descriptor_pb2.FileDescriptorProto()
2946 file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('B'))
2947 msg_descriptor = descriptor.MakeDescriptor(
2948 file_descriptor.message_type[0])
2949 msg_class = reflection.MakeClass(msg_descriptor)
2950 msg = msg_class()
2951 msg_str = (
2952 'flat: 0 '
2953 'flat: 1 '
2954 'flat: 2 ')
2955 text_format.Merge(msg_str, msg)
2956 self.assertEqual(msg.flat, [0, 1, 2])
2957
2958 def testParsingNestedClass(self):
2959 """Test that the generated class can parse a nested message."""
2960 file_descriptor = descriptor_pb2.FileDescriptorProto()
2961 file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('C'))
2962 msg_descriptor = descriptor.MakeDescriptor(
2963 file_descriptor.message_type[0])
2964 msg_class = reflection.MakeClass(msg_descriptor)
2965 msg = msg_class()
2966 msg_str = (
2967 'bar {'
2968 ' baz {'
2969 ' deep: 4'
2970 ' }'
2971 '}')
2972 text_format.Merge(msg_str, msg)
2973 self.assertEqual(msg.bar.baz.deep, 4)
2974
temporal40ee5512008-07-10 02:12:20 +00002975if __name__ == '__main__':
Tamir Duberstein9f42f5f2015-01-13 14:47:32 -05002976 unittest.main()