Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: third_party/protobuf/python/google/protobuf/internal/message_test.py

Issue 1291903002: Pull new version of protobuf sources. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #! /usr/bin/python 1 #! /usr/bin/env python
2 # 2 #
3 # Protocol Buffers - Google's data interchange format 3 # Protocol Buffers - Google's data interchange format
4 # Copyright 2008 Google Inc. All rights reserved. 4 # Copyright 2008 Google Inc. All rights reserved.
5 # http://code.google.com/p/protobuf/ 5 # https://developers.google.com/protocol-buffers/
6 # 6 #
7 # Redistribution and use in source and binary forms, with or without 7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are 8 # modification, are permitted provided that the following conditions are
9 # met: 9 # met:
10 # 10 #
11 # * Redistributions of source code must retain the above copyright 11 # * Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer. 12 # notice, this list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above 13 # * Redistributions in binary form must reproduce the above
14 # copyright notice, this list of conditions and the following disclaimer 14 # copyright notice, this list of conditions and the following disclaimer
15 # in the documentation and/or other materials provided with the 15 # in the documentation and/or other materials provided with the
(...skipping 24 matching lines...) Expand all
40 sense to call this a test of the "message" module, which only declares an 40 sense to call this a test of the "message" module, which only declares an
41 abstract interface. 41 abstract interface.
42 """ 42 """
43 43
44 __author__ = 'gps@google.com (Gregory P. Smith)' 44 __author__ = 'gps@google.com (Gregory P. Smith)'
45 45
46 import copy 46 import copy
47 import math 47 import math
48 import operator 48 import operator
49 import pickle 49 import pickle
50 import sys
51 import unittest
50 52
51 import unittest 53 import unittest
52 from google.protobuf import unittest_import_pb2 54 from google.protobuf.internal import _parameterized
55 from google.protobuf import map_unittest_pb2
53 from google.protobuf import unittest_pb2 56 from google.protobuf import unittest_pb2
57 from google.protobuf import unittest_proto3_arena_pb2
54 from google.protobuf.internal import api_implementation 58 from google.protobuf.internal import api_implementation
55 from google.protobuf.internal import test_util 59 from google.protobuf.internal import test_util
56 from google.protobuf import message 60 from google.protobuf import message
57 61
58 # Python pre-2.6 does not have isinf() or isnan() functions, so we have 62 # Python pre-2.6 does not have isinf() or isnan() functions, so we have
59 # to provide our own. 63 # to provide our own.
60 def isnan(val): 64 def isnan(val):
61 # NaN is never equal to itself. 65 # NaN is never equal to itself.
62 return val != val 66 return val != val
63 def isinf(val): 67 def isinf(val):
64 # Infinity times zero equals NaN. 68 # Infinity times zero equals NaN.
65 return not isnan(val) and isnan(val * 0) 69 return not isnan(val) and isnan(val * 0)
66 def IsPosInf(val): 70 def IsPosInf(val):
67 return isinf(val) and (val > 0) 71 return isinf(val) and (val > 0)
68 def IsNegInf(val): 72 def IsNegInf(val):
69 return isinf(val) and (val < 0) 73 return isinf(val) and (val < 0)
70 74
75
76 @_parameterized.Parameters(
77 (unittest_pb2),
78 (unittest_proto3_arena_pb2))
71 class MessageTest(unittest.TestCase): 79 class MessageTest(unittest.TestCase):
72 80
73 def testGoldenMessage(self): 81 def testBadUtf8String(self, message_module):
74 golden_data = test_util.GoldenFile('golden_message').read() 82 if api_implementation.Type() != 'python':
75 golden_message = unittest_pb2.TestAllTypes() 83 self.skipTest("Skipping testBadUtf8String, currently only the python "
84 "api implementation raises UnicodeDecodeError when a "
85 "string field contains bad utf-8.")
86 bad_utf8_data = test_util.GoldenFileData('bad_utf8_string')
87 with self.assertRaises(UnicodeDecodeError) as context:
88 message_module.TestAllTypes.FromString(bad_utf8_data)
89 self.assertIn('TestAllTypes.optional_string', str(context.exception))
90
91 def testGoldenMessage(self, message_module):
92 # Proto3 doesn't have the "default_foo" members or foreign enums,
93 # and doesn't preserve unknown fields, so for proto3 we use a golden
94 # message that doesn't have these fields set.
95 if message_module is unittest_pb2:
96 golden_data = test_util.GoldenFileData(
97 'golden_message_oneof_implemented')
98 else:
99 golden_data = test_util.GoldenFileData('golden_message_proto3')
100
101 golden_message = message_module.TestAllTypes()
76 golden_message.ParseFromString(golden_data) 102 golden_message.ParseFromString(golden_data)
77 test_util.ExpectAllFieldsSet(self, golden_message) 103 if message_module is unittest_pb2:
104 test_util.ExpectAllFieldsSet(self, golden_message)
78 self.assertEqual(golden_data, golden_message.SerializeToString()) 105 self.assertEqual(golden_data, golden_message.SerializeToString())
79 golden_copy = copy.deepcopy(golden_message) 106 golden_copy = copy.deepcopy(golden_message)
80 self.assertEqual(golden_data, golden_copy.SerializeToString()) 107 self.assertEqual(golden_data, golden_copy.SerializeToString())
81 108
82 def testGoldenExtensions(self): 109 def testGoldenPackedMessage(self, message_module):
83 golden_data = test_util.GoldenFile('golden_message').read() 110 golden_data = test_util.GoldenFileData('golden_packed_fields_message')
84 golden_message = unittest_pb2.TestAllExtensions() 111 golden_message = message_module.TestPackedTypes()
85 golden_message.ParseFromString(golden_data) 112 golden_message.ParseFromString(golden_data)
86 all_set = unittest_pb2.TestAllExtensions() 113 all_set = message_module.TestPackedTypes()
87 test_util.SetAllExtensions(all_set)
88 self.assertEquals(all_set, golden_message)
89 self.assertEqual(golden_data, golden_message.SerializeToString())
90 golden_copy = copy.deepcopy(golden_message)
91 self.assertEqual(golden_data, golden_copy.SerializeToString())
92
93 def testGoldenPackedMessage(self):
94 golden_data = test_util.GoldenFile('golden_packed_fields_message').read()
95 golden_message = unittest_pb2.TestPackedTypes()
96 golden_message.ParseFromString(golden_data)
97 all_set = unittest_pb2.TestPackedTypes()
98 test_util.SetAllPackedFields(all_set) 114 test_util.SetAllPackedFields(all_set)
99 self.assertEquals(all_set, golden_message) 115 self.assertEqual(all_set, golden_message)
100 self.assertEqual(golden_data, all_set.SerializeToString()) 116 self.assertEqual(golden_data, all_set.SerializeToString())
101 golden_copy = copy.deepcopy(golden_message) 117 golden_copy = copy.deepcopy(golden_message)
102 self.assertEqual(golden_data, golden_copy.SerializeToString()) 118 self.assertEqual(golden_data, golden_copy.SerializeToString())
103 119
104 def testGoldenPackedExtensions(self): 120 def testPickleSupport(self, message_module):
105 golden_data = test_util.GoldenFile('golden_packed_fields_message').read() 121 golden_data = test_util.GoldenFileData('golden_message')
106 golden_message = unittest_pb2.TestPackedExtensions() 122 golden_message = message_module.TestAllTypes()
107 golden_message.ParseFromString(golden_data)
108 all_set = unittest_pb2.TestPackedExtensions()
109 test_util.SetAllPackedExtensions(all_set)
110 self.assertEquals(all_set, golden_message)
111 self.assertEqual(golden_data, all_set.SerializeToString())
112 golden_copy = copy.deepcopy(golden_message)
113 self.assertEqual(golden_data, golden_copy.SerializeToString())
114
115 def testPickleSupport(self):
116 golden_data = test_util.GoldenFile('golden_message').read()
117 golden_message = unittest_pb2.TestAllTypes()
118 golden_message.ParseFromString(golden_data) 123 golden_message.ParseFromString(golden_data)
119 pickled_message = pickle.dumps(golden_message) 124 pickled_message = pickle.dumps(golden_message)
120 125
121 unpickled_message = pickle.loads(pickled_message) 126 unpickled_message = pickle.loads(pickled_message)
122 self.assertEquals(unpickled_message, golden_message) 127 self.assertEqual(unpickled_message, golden_message)
123 128
124 def testPickleIncompleteProto(self): 129 def testPositiveInfinity(self, message_module):
125 golden_message = unittest_pb2.TestRequired(a=1) 130 if message_module is unittest_pb2:
126 pickled_message = pickle.dumps(golden_message) 131 golden_data = (b'\x5D\x00\x00\x80\x7F'
132 b'\x61\x00\x00\x00\x00\x00\x00\xF0\x7F'
133 b'\xCD\x02\x00\x00\x80\x7F'
134 b'\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\x7F')
135 else:
136 golden_data = (b'\x5D\x00\x00\x80\x7F'
137 b'\x61\x00\x00\x00\x00\x00\x00\xF0\x7F'
138 b'\xCA\x02\x04\x00\x00\x80\x7F'
139 b'\xD2\x02\x08\x00\x00\x00\x00\x00\x00\xF0\x7F')
127 140
128 unpickled_message = pickle.loads(pickled_message) 141 golden_message = message_module.TestAllTypes()
129 self.assertEquals(unpickled_message, golden_message)
130 self.assertEquals(unpickled_message.a, 1)
131 # This is still an incomplete proto - so serializing should fail
132 self.assertRaises(message.EncodeError, unpickled_message.SerializeToString)
133
134 def testPositiveInfinity(self):
135 golden_data = ('\x5D\x00\x00\x80\x7F'
136 '\x61\x00\x00\x00\x00\x00\x00\xF0\x7F'
137 '\xCD\x02\x00\x00\x80\x7F'
138 '\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\x7F')
139 golden_message = unittest_pb2.TestAllTypes()
140 golden_message.ParseFromString(golden_data) 142 golden_message.ParseFromString(golden_data)
141 self.assertTrue(IsPosInf(golden_message.optional_float)) 143 self.assertTrue(IsPosInf(golden_message.optional_float))
142 self.assertTrue(IsPosInf(golden_message.optional_double)) 144 self.assertTrue(IsPosInf(golden_message.optional_double))
143 self.assertTrue(IsPosInf(golden_message.repeated_float[0])) 145 self.assertTrue(IsPosInf(golden_message.repeated_float[0]))
144 self.assertTrue(IsPosInf(golden_message.repeated_double[0])) 146 self.assertTrue(IsPosInf(golden_message.repeated_double[0]))
145 self.assertEqual(golden_data, golden_message.SerializeToString()) 147 self.assertEqual(golden_data, golden_message.SerializeToString())
146 148
147 def testNegativeInfinity(self): 149 def testNegativeInfinity(self, message_module):
148 golden_data = ('\x5D\x00\x00\x80\xFF' 150 if message_module is unittest_pb2:
149 '\x61\x00\x00\x00\x00\x00\x00\xF0\xFF' 151 golden_data = (b'\x5D\x00\x00\x80\xFF'
150 '\xCD\x02\x00\x00\x80\xFF' 152 b'\x61\x00\x00\x00\x00\x00\x00\xF0\xFF'
151 '\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\xFF') 153 b'\xCD\x02\x00\x00\x80\xFF'
152 golden_message = unittest_pb2.TestAllTypes() 154 b'\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\xFF')
155 else:
156 golden_data = (b'\x5D\x00\x00\x80\xFF'
157 b'\x61\x00\x00\x00\x00\x00\x00\xF0\xFF'
158 b'\xCA\x02\x04\x00\x00\x80\xFF'
159 b'\xD2\x02\x08\x00\x00\x00\x00\x00\x00\xF0\xFF')
160
161 golden_message = message_module.TestAllTypes()
153 golden_message.ParseFromString(golden_data) 162 golden_message.ParseFromString(golden_data)
154 self.assertTrue(IsNegInf(golden_message.optional_float)) 163 self.assertTrue(IsNegInf(golden_message.optional_float))
155 self.assertTrue(IsNegInf(golden_message.optional_double)) 164 self.assertTrue(IsNegInf(golden_message.optional_double))
156 self.assertTrue(IsNegInf(golden_message.repeated_float[0])) 165 self.assertTrue(IsNegInf(golden_message.repeated_float[0]))
157 self.assertTrue(IsNegInf(golden_message.repeated_double[0])) 166 self.assertTrue(IsNegInf(golden_message.repeated_double[0]))
158 self.assertEqual(golden_data, golden_message.SerializeToString()) 167 self.assertEqual(golden_data, golden_message.SerializeToString())
159 168
160 def testNotANumber(self): 169 def testNotANumber(self, message_module):
161 golden_data = ('\x5D\x00\x00\xC0\x7F' 170 golden_data = (b'\x5D\x00\x00\xC0\x7F'
162 '\x61\x00\x00\x00\x00\x00\x00\xF8\x7F' 171 b'\x61\x00\x00\x00\x00\x00\x00\xF8\x7F'
163 '\xCD\x02\x00\x00\xC0\x7F' 172 b'\xCD\x02\x00\x00\xC0\x7F'
164 '\xD1\x02\x00\x00\x00\x00\x00\x00\xF8\x7F') 173 b'\xD1\x02\x00\x00\x00\x00\x00\x00\xF8\x7F')
165 golden_message = unittest_pb2.TestAllTypes() 174 golden_message = message_module.TestAllTypes()
166 golden_message.ParseFromString(golden_data) 175 golden_message.ParseFromString(golden_data)
167 self.assertTrue(isnan(golden_message.optional_float)) 176 self.assertTrue(isnan(golden_message.optional_float))
168 self.assertTrue(isnan(golden_message.optional_double)) 177 self.assertTrue(isnan(golden_message.optional_double))
169 self.assertTrue(isnan(golden_message.repeated_float[0])) 178 self.assertTrue(isnan(golden_message.repeated_float[0]))
170 self.assertTrue(isnan(golden_message.repeated_double[0])) 179 self.assertTrue(isnan(golden_message.repeated_double[0]))
171 180
172 # The protocol buffer may serialize to any one of multiple different 181 # The protocol buffer may serialize to any one of multiple different
173 # representations of a NaN. Rather than verify a specific representation, 182 # representations of a NaN. Rather than verify a specific representation,
174 # verify the serialized string can be converted into a correctly 183 # verify the serialized string can be converted into a correctly
175 # behaving protocol buffer. 184 # behaving protocol buffer.
176 serialized = golden_message.SerializeToString() 185 serialized = golden_message.SerializeToString()
177 message = unittest_pb2.TestAllTypes() 186 message = message_module.TestAllTypes()
178 message.ParseFromString(serialized) 187 message.ParseFromString(serialized)
179 self.assertTrue(isnan(message.optional_float)) 188 self.assertTrue(isnan(message.optional_float))
180 self.assertTrue(isnan(message.optional_double)) 189 self.assertTrue(isnan(message.optional_double))
181 self.assertTrue(isnan(message.repeated_float[0])) 190 self.assertTrue(isnan(message.repeated_float[0]))
182 self.assertTrue(isnan(message.repeated_double[0])) 191 self.assertTrue(isnan(message.repeated_double[0]))
183 192
184 def testPositiveInfinityPacked(self): 193 def testPositiveInfinityPacked(self, message_module):
185 golden_data = ('\xA2\x06\x04\x00\x00\x80\x7F' 194 golden_data = (b'\xA2\x06\x04\x00\x00\x80\x7F'
186 '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\x7F') 195 b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\x7F')
187 golden_message = unittest_pb2.TestPackedTypes() 196 golden_message = message_module.TestPackedTypes()
188 golden_message.ParseFromString(golden_data) 197 golden_message.ParseFromString(golden_data)
189 self.assertTrue(IsPosInf(golden_message.packed_float[0])) 198 self.assertTrue(IsPosInf(golden_message.packed_float[0]))
190 self.assertTrue(IsPosInf(golden_message.packed_double[0])) 199 self.assertTrue(IsPosInf(golden_message.packed_double[0]))
191 self.assertEqual(golden_data, golden_message.SerializeToString()) 200 self.assertEqual(golden_data, golden_message.SerializeToString())
192 201
193 def testNegativeInfinityPacked(self): 202 def testNegativeInfinityPacked(self, message_module):
194 golden_data = ('\xA2\x06\x04\x00\x00\x80\xFF' 203 golden_data = (b'\xA2\x06\x04\x00\x00\x80\xFF'
195 '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\xFF') 204 b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\xFF')
196 golden_message = unittest_pb2.TestPackedTypes() 205 golden_message = message_module.TestPackedTypes()
197 golden_message.ParseFromString(golden_data) 206 golden_message.ParseFromString(golden_data)
198 self.assertTrue(IsNegInf(golden_message.packed_float[0])) 207 self.assertTrue(IsNegInf(golden_message.packed_float[0]))
199 self.assertTrue(IsNegInf(golden_message.packed_double[0])) 208 self.assertTrue(IsNegInf(golden_message.packed_double[0]))
200 self.assertEqual(golden_data, golden_message.SerializeToString()) 209 self.assertEqual(golden_data, golden_message.SerializeToString())
201 210
202 def testNotANumberPacked(self): 211 def testNotANumberPacked(self, message_module):
203 golden_data = ('\xA2\x06\x04\x00\x00\xC0\x7F' 212 golden_data = (b'\xA2\x06\x04\x00\x00\xC0\x7F'
204 '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF8\x7F') 213 b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF8\x7F')
205 golden_message = unittest_pb2.TestPackedTypes() 214 golden_message = message_module.TestPackedTypes()
206 golden_message.ParseFromString(golden_data) 215 golden_message.ParseFromString(golden_data)
207 self.assertTrue(isnan(golden_message.packed_float[0])) 216 self.assertTrue(isnan(golden_message.packed_float[0]))
208 self.assertTrue(isnan(golden_message.packed_double[0])) 217 self.assertTrue(isnan(golden_message.packed_double[0]))
209 218
210 serialized = golden_message.SerializeToString() 219 serialized = golden_message.SerializeToString()
211 message = unittest_pb2.TestPackedTypes() 220 message = message_module.TestPackedTypes()
212 message.ParseFromString(serialized) 221 message.ParseFromString(serialized)
213 self.assertTrue(isnan(message.packed_float[0])) 222 self.assertTrue(isnan(message.packed_float[0]))
214 self.assertTrue(isnan(message.packed_double[0])) 223 self.assertTrue(isnan(message.packed_double[0]))
215 224
216 def testExtremeFloatValues(self): 225 def testExtremeFloatValues(self, message_module):
217 message = unittest_pb2.TestAllTypes() 226 message = message_module.TestAllTypes()
218 227
219 # Most positive exponent, no significand bits set. 228 # Most positive exponent, no significand bits set.
220 kMostPosExponentNoSigBits = math.pow(2, 127) 229 kMostPosExponentNoSigBits = math.pow(2, 127)
221 message.optional_float = kMostPosExponentNoSigBits 230 message.optional_float = kMostPosExponentNoSigBits
222 message.ParseFromString(message.SerializeToString()) 231 message.ParseFromString(message.SerializeToString())
223 self.assertTrue(message.optional_float == kMostPosExponentNoSigBits) 232 self.assertTrue(message.optional_float == kMostPosExponentNoSigBits)
224 233
225 # Most positive exponent, one significand bit set. 234 # Most positive exponent, one significand bit set.
226 kMostPosExponentOneSigBit = 1.5 * math.pow(2, 127) 235 kMostPosExponentOneSigBit = 1.5 * math.pow(2, 127)
227 message.optional_float = kMostPosExponentOneSigBit 236 message.optional_float = kMostPosExponentOneSigBit
(...skipping 23 matching lines...) Expand all
251 260
252 # Repeat last two cases with values of the same magnitude, but negative. 261 # Repeat last two cases with values of the same magnitude, but negative.
253 message.optional_float = -kMostNegExponentNoSigBits 262 message.optional_float = -kMostNegExponentNoSigBits
254 message.ParseFromString(message.SerializeToString()) 263 message.ParseFromString(message.SerializeToString())
255 self.assertTrue(message.optional_float == -kMostNegExponentNoSigBits) 264 self.assertTrue(message.optional_float == -kMostNegExponentNoSigBits)
256 265
257 message.optional_float = -kMostNegExponentOneSigBit 266 message.optional_float = -kMostNegExponentOneSigBit
258 message.ParseFromString(message.SerializeToString()) 267 message.ParseFromString(message.SerializeToString())
259 self.assertTrue(message.optional_float == -kMostNegExponentOneSigBit) 268 self.assertTrue(message.optional_float == -kMostNegExponentOneSigBit)
260 269
261 def testExtremeDoubleValues(self): 270 def testExtremeDoubleValues(self, message_module):
262 message = unittest_pb2.TestAllTypes() 271 message = message_module.TestAllTypes()
263 272
264 # Most positive exponent, no significand bits set. 273 # Most positive exponent, no significand bits set.
265 kMostPosExponentNoSigBits = math.pow(2, 1023) 274 kMostPosExponentNoSigBits = math.pow(2, 1023)
266 message.optional_double = kMostPosExponentNoSigBits 275 message.optional_double = kMostPosExponentNoSigBits
267 message.ParseFromString(message.SerializeToString()) 276 message.ParseFromString(message.SerializeToString())
268 self.assertTrue(message.optional_double == kMostPosExponentNoSigBits) 277 self.assertTrue(message.optional_double == kMostPosExponentNoSigBits)
269 278
270 # Most positive exponent, one significand bit set. 279 # Most positive exponent, one significand bit set.
271 kMostPosExponentOneSigBit = 1.5 * math.pow(2, 1023) 280 kMostPosExponentOneSigBit = 1.5 * math.pow(2, 1023)
272 message.optional_double = kMostPosExponentOneSigBit 281 message.optional_double = kMostPosExponentOneSigBit
(...skipping 23 matching lines...) Expand all
296 305
297 # Repeat last two cases with values of the same magnitude, but negative. 306 # Repeat last two cases with values of the same magnitude, but negative.
298 message.optional_double = -kMostNegExponentNoSigBits 307 message.optional_double = -kMostNegExponentNoSigBits
299 message.ParseFromString(message.SerializeToString()) 308 message.ParseFromString(message.SerializeToString())
300 self.assertTrue(message.optional_double == -kMostNegExponentNoSigBits) 309 self.assertTrue(message.optional_double == -kMostNegExponentNoSigBits)
301 310
302 message.optional_double = -kMostNegExponentOneSigBit 311 message.optional_double = -kMostNegExponentOneSigBit
303 message.ParseFromString(message.SerializeToString()) 312 message.ParseFromString(message.SerializeToString())
304 self.assertTrue(message.optional_double == -kMostNegExponentOneSigBit) 313 self.assertTrue(message.optional_double == -kMostNegExponentOneSigBit)
305 314
306 def testSortingRepeatedScalarFieldsDefaultComparator(self): 315 def testFloatPrinting(self, message_module):
316 message = message_module.TestAllTypes()
317 message.optional_float = 2.0
318 self.assertEqual(str(message), 'optional_float: 2.0\n')
319
320 def testHighPrecisionFloatPrinting(self, message_module):
321 message = message_module.TestAllTypes()
322 message.optional_double = 0.12345678912345678
323 if sys.version_info.major >= 3:
324 self.assertEqual(str(message), 'optional_double: 0.12345678912345678\n')
325 else:
326 self.assertEqual(str(message), 'optional_double: 0.123456789123\n')
327
328 def testUnknownFieldPrinting(self, message_module):
329 populated = message_module.TestAllTypes()
330 test_util.SetAllNonLazyFields(populated)
331 empty = message_module.TestEmptyMessage()
332 empty.ParseFromString(populated.SerializeToString())
333 self.assertEqual(str(empty), '')
334
335 def testRepeatedNestedFieldIteration(self, message_module):
336 msg = message_module.TestAllTypes()
337 msg.repeated_nested_message.add(bb=1)
338 msg.repeated_nested_message.add(bb=2)
339 msg.repeated_nested_message.add(bb=3)
340 msg.repeated_nested_message.add(bb=4)
341
342 self.assertEqual([1, 2, 3, 4],
343 [m.bb for m in msg.repeated_nested_message])
344 self.assertEqual([4, 3, 2, 1],
345 [m.bb for m in reversed(msg.repeated_nested_message)])
346 self.assertEqual([4, 3, 2, 1],
347 [m.bb for m in msg.repeated_nested_message[::-1]])
348
349 def testSortingRepeatedScalarFieldsDefaultComparator(self, message_module):
307 """Check some different types with the default comparator.""" 350 """Check some different types with the default comparator."""
308 message = unittest_pb2.TestAllTypes() 351 message = message_module.TestAllTypes()
309 352
310 # TODO(mattp): would testing more scalar types strengthen test? 353 # TODO(mattp): would testing more scalar types strengthen test?
311 message.repeated_int32.append(1) 354 message.repeated_int32.append(1)
312 message.repeated_int32.append(3) 355 message.repeated_int32.append(3)
313 message.repeated_int32.append(2) 356 message.repeated_int32.append(2)
314 message.repeated_int32.sort() 357 message.repeated_int32.sort()
315 self.assertEqual(message.repeated_int32[0], 1) 358 self.assertEqual(message.repeated_int32[0], 1)
316 self.assertEqual(message.repeated_int32[1], 2) 359 self.assertEqual(message.repeated_int32[1], 2)
317 self.assertEqual(message.repeated_int32[2], 3) 360 self.assertEqual(message.repeated_int32[2], 3)
318 361
319 message.repeated_float.append(1.1) 362 message.repeated_float.append(1.1)
320 message.repeated_float.append(1.3) 363 message.repeated_float.append(1.3)
321 message.repeated_float.append(1.2) 364 message.repeated_float.append(1.2)
322 message.repeated_float.sort() 365 message.repeated_float.sort()
323 self.assertAlmostEqual(message.repeated_float[0], 1.1) 366 self.assertAlmostEqual(message.repeated_float[0], 1.1)
324 self.assertAlmostEqual(message.repeated_float[1], 1.2) 367 self.assertAlmostEqual(message.repeated_float[1], 1.2)
325 self.assertAlmostEqual(message.repeated_float[2], 1.3) 368 self.assertAlmostEqual(message.repeated_float[2], 1.3)
326 369
327 message.repeated_string.append('a') 370 message.repeated_string.append('a')
328 message.repeated_string.append('c') 371 message.repeated_string.append('c')
329 message.repeated_string.append('b') 372 message.repeated_string.append('b')
330 message.repeated_string.sort() 373 message.repeated_string.sort()
331 self.assertEqual(message.repeated_string[0], 'a') 374 self.assertEqual(message.repeated_string[0], 'a')
332 self.assertEqual(message.repeated_string[1], 'b') 375 self.assertEqual(message.repeated_string[1], 'b')
333 self.assertEqual(message.repeated_string[2], 'c') 376 self.assertEqual(message.repeated_string[2], 'c')
334 377
335 message.repeated_bytes.append('a') 378 message.repeated_bytes.append(b'a')
336 message.repeated_bytes.append('c') 379 message.repeated_bytes.append(b'c')
337 message.repeated_bytes.append('b') 380 message.repeated_bytes.append(b'b')
338 message.repeated_bytes.sort() 381 message.repeated_bytes.sort()
339 self.assertEqual(message.repeated_bytes[0], 'a') 382 self.assertEqual(message.repeated_bytes[0], b'a')
340 self.assertEqual(message.repeated_bytes[1], 'b') 383 self.assertEqual(message.repeated_bytes[1], b'b')
341 self.assertEqual(message.repeated_bytes[2], 'c') 384 self.assertEqual(message.repeated_bytes[2], b'c')
342 385
343 def testSortingRepeatedScalarFieldsCustomComparator(self): 386 def testSortingRepeatedScalarFieldsCustomComparator(self, message_module):
344 """Check some different types with custom comparator.""" 387 """Check some different types with custom comparator."""
345 message = unittest_pb2.TestAllTypes() 388 message = message_module.TestAllTypes()
346 389
347 message.repeated_int32.append(-3) 390 message.repeated_int32.append(-3)
348 message.repeated_int32.append(-2) 391 message.repeated_int32.append(-2)
349 message.repeated_int32.append(-1) 392 message.repeated_int32.append(-1)
350 message.repeated_int32.sort(lambda x,y: cmp(abs(x), abs(y))) 393 message.repeated_int32.sort(key=abs)
351 self.assertEqual(message.repeated_int32[0], -1) 394 self.assertEqual(message.repeated_int32[0], -1)
352 self.assertEqual(message.repeated_int32[1], -2) 395 self.assertEqual(message.repeated_int32[1], -2)
353 self.assertEqual(message.repeated_int32[2], -3) 396 self.assertEqual(message.repeated_int32[2], -3)
354 397
355 message.repeated_string.append('aaa') 398 message.repeated_string.append('aaa')
356 message.repeated_string.append('bb') 399 message.repeated_string.append('bb')
357 message.repeated_string.append('c') 400 message.repeated_string.append('c')
358 message.repeated_string.sort(lambda x,y: cmp(len(x), len(y))) 401 message.repeated_string.sort(key=len)
359 self.assertEqual(message.repeated_string[0], 'c') 402 self.assertEqual(message.repeated_string[0], 'c')
360 self.assertEqual(message.repeated_string[1], 'bb') 403 self.assertEqual(message.repeated_string[1], 'bb')
361 self.assertEqual(message.repeated_string[2], 'aaa') 404 self.assertEqual(message.repeated_string[2], 'aaa')
362 405
363 def testSortingRepeatedCompositeFieldsCustomComparator(self): 406 def testSortingRepeatedCompositeFieldsCustomComparator(self, message_module):
364 """Check passing a custom comparator to sort a repeated composite field.""" 407 """Check passing a custom comparator to sort a repeated composite field."""
365 message = unittest_pb2.TestAllTypes() 408 message = message_module.TestAllTypes()
366 409
367 message.repeated_nested_message.add().bb = 1 410 message.repeated_nested_message.add().bb = 1
368 message.repeated_nested_message.add().bb = 3 411 message.repeated_nested_message.add().bb = 3
369 message.repeated_nested_message.add().bb = 2 412 message.repeated_nested_message.add().bb = 2
370 message.repeated_nested_message.add().bb = 6 413 message.repeated_nested_message.add().bb = 6
371 message.repeated_nested_message.add().bb = 5 414 message.repeated_nested_message.add().bb = 5
372 message.repeated_nested_message.add().bb = 4 415 message.repeated_nested_message.add().bb = 4
373 message.repeated_nested_message.sort(lambda x,y: cmp(x.bb, y.bb)) 416 message.repeated_nested_message.sort(key=operator.attrgetter('bb'))
374 self.assertEqual(message.repeated_nested_message[0].bb, 1) 417 self.assertEqual(message.repeated_nested_message[0].bb, 1)
375 self.assertEqual(message.repeated_nested_message[1].bb, 2) 418 self.assertEqual(message.repeated_nested_message[1].bb, 2)
376 self.assertEqual(message.repeated_nested_message[2].bb, 3) 419 self.assertEqual(message.repeated_nested_message[2].bb, 3)
377 self.assertEqual(message.repeated_nested_message[3].bb, 4) 420 self.assertEqual(message.repeated_nested_message[3].bb, 4)
378 self.assertEqual(message.repeated_nested_message[4].bb, 5) 421 self.assertEqual(message.repeated_nested_message[4].bb, 5)
379 self.assertEqual(message.repeated_nested_message[5].bb, 6) 422 self.assertEqual(message.repeated_nested_message[5].bb, 6)
380 423
381 def testRepeatedCompositeFieldSortArguments(self): 424 def testRepeatedCompositeFieldSortArguments(self, message_module):
382 """Check sorting a repeated composite field using list.sort() arguments.""" 425 """Check sorting a repeated composite field using list.sort() arguments."""
383 message = unittest_pb2.TestAllTypes() 426 message = message_module.TestAllTypes()
384 427
385 get_bb = operator.attrgetter('bb') 428 get_bb = operator.attrgetter('bb')
386 cmp_bb = lambda a, b: cmp(a.bb, b.bb) 429 cmp_bb = lambda a, b: cmp(a.bb, b.bb)
387 message.repeated_nested_message.add().bb = 1 430 message.repeated_nested_message.add().bb = 1
388 message.repeated_nested_message.add().bb = 3 431 message.repeated_nested_message.add().bb = 3
389 message.repeated_nested_message.add().bb = 2 432 message.repeated_nested_message.add().bb = 2
390 message.repeated_nested_message.add().bb = 6 433 message.repeated_nested_message.add().bb = 6
391 message.repeated_nested_message.add().bb = 5 434 message.repeated_nested_message.add().bb = 5
392 message.repeated_nested_message.add().bb = 4 435 message.repeated_nested_message.add().bb = 4
393 message.repeated_nested_message.sort(key=get_bb) 436 message.repeated_nested_message.sort(key=get_bb)
394 self.assertEqual([k.bb for k in message.repeated_nested_message], 437 self.assertEqual([k.bb for k in message.repeated_nested_message],
395 [1, 2, 3, 4, 5, 6]) 438 [1, 2, 3, 4, 5, 6])
396 message.repeated_nested_message.sort(key=get_bb, reverse=True) 439 message.repeated_nested_message.sort(key=get_bb, reverse=True)
397 self.assertEqual([k.bb for k in message.repeated_nested_message], 440 self.assertEqual([k.bb for k in message.repeated_nested_message],
398 [6, 5, 4, 3, 2, 1]) 441 [6, 5, 4, 3, 2, 1])
442 if sys.version_info.major >= 3: return # No cmp sorting in PY3.
399 message.repeated_nested_message.sort(sort_function=cmp_bb) 443 message.repeated_nested_message.sort(sort_function=cmp_bb)
400 self.assertEqual([k.bb for k in message.repeated_nested_message], 444 self.assertEqual([k.bb for k in message.repeated_nested_message],
401 [1, 2, 3, 4, 5, 6]) 445 [1, 2, 3, 4, 5, 6])
402 message.repeated_nested_message.sort(cmp=cmp_bb, reverse=True) 446 message.repeated_nested_message.sort(cmp=cmp_bb, reverse=True)
403 self.assertEqual([k.bb for k in message.repeated_nested_message], 447 self.assertEqual([k.bb for k in message.repeated_nested_message],
404 [6, 5, 4, 3, 2, 1]) 448 [6, 5, 4, 3, 2, 1])
405 449
406 def testRepeatedScalarFieldSortArguments(self): 450 def testRepeatedScalarFieldSortArguments(self, message_module):
407 """Check sorting a scalar field using list.sort() arguments.""" 451 """Check sorting a scalar field using list.sort() arguments."""
408 message = unittest_pb2.TestAllTypes() 452 message = message_module.TestAllTypes()
409 453
410 abs_cmp = lambda a, b: cmp(abs(a), abs(b))
411 message.repeated_int32.append(-3) 454 message.repeated_int32.append(-3)
412 message.repeated_int32.append(-2) 455 message.repeated_int32.append(-2)
413 message.repeated_int32.append(-1) 456 message.repeated_int32.append(-1)
414 message.repeated_int32.sort(key=abs) 457 message.repeated_int32.sort(key=abs)
415 self.assertEqual(list(message.repeated_int32), [-1, -2, -3]) 458 self.assertEqual(list(message.repeated_int32), [-1, -2, -3])
416 message.repeated_int32.sort(key=abs, reverse=True) 459 message.repeated_int32.sort(key=abs, reverse=True)
417 self.assertEqual(list(message.repeated_int32), [-3, -2, -1]) 460 self.assertEqual(list(message.repeated_int32), [-3, -2, -1])
418 message.repeated_int32.sort(sort_function=abs_cmp) 461 if sys.version_info.major < 3: # No cmp sorting in PY3.
419 self.assertEqual(list(message.repeated_int32), [-1, -2, -3]) 462 abs_cmp = lambda a, b: cmp(abs(a), abs(b))
420 message.repeated_int32.sort(cmp=abs_cmp, reverse=True) 463 message.repeated_int32.sort(sort_function=abs_cmp)
421 self.assertEqual(list(message.repeated_int32), [-3, -2, -1]) 464 self.assertEqual(list(message.repeated_int32), [-1, -2, -3])
465 message.repeated_int32.sort(cmp=abs_cmp, reverse=True)
466 self.assertEqual(list(message.repeated_int32), [-3, -2, -1])
422 467
423 len_cmp = lambda a, b: cmp(len(a), len(b))
424 message.repeated_string.append('aaa') 468 message.repeated_string.append('aaa')
425 message.repeated_string.append('bb') 469 message.repeated_string.append('bb')
426 message.repeated_string.append('c') 470 message.repeated_string.append('c')
427 message.repeated_string.sort(key=len) 471 message.repeated_string.sort(key=len)
428 self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa']) 472 self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa'])
429 message.repeated_string.sort(key=len, reverse=True) 473 message.repeated_string.sort(key=len, reverse=True)
430 self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c']) 474 self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c'])
431 message.repeated_string.sort(sort_function=len_cmp) 475 if sys.version_info.major < 3: # No cmp sorting in PY3.
432 self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa']) 476 len_cmp = lambda a, b: cmp(len(a), len(b))
433 message.repeated_string.sort(cmp=len_cmp, reverse=True) 477 message.repeated_string.sort(sort_function=len_cmp)
434 self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c']) 478 self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa'])
435 479 message.repeated_string.sort(cmp=len_cmp, reverse=True)
480 self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c'])
481
482 def testRepeatedFieldsComparable(self, message_module):
483 m1 = message_module.TestAllTypes()
484 m2 = message_module.TestAllTypes()
485 m1.repeated_int32.append(0)
486 m1.repeated_int32.append(1)
487 m1.repeated_int32.append(2)
488 m2.repeated_int32.append(0)
489 m2.repeated_int32.append(1)
490 m2.repeated_int32.append(2)
491 m1.repeated_nested_message.add().bb = 1
492 m1.repeated_nested_message.add().bb = 2
493 m1.repeated_nested_message.add().bb = 3
494 m2.repeated_nested_message.add().bb = 1
495 m2.repeated_nested_message.add().bb = 2
496 m2.repeated_nested_message.add().bb = 3
497
498 if sys.version_info.major >= 3: return # No cmp() in PY3.
499
500 # These comparisons should not raise errors.
501 _ = m1 < m2
502 _ = m1.repeated_nested_message < m2.repeated_nested_message
503
504 # Make sure cmp always works. If it wasn't defined, these would be
505 # id() comparisons and would all fail.
506 self.assertEqual(cmp(m1, m2), 0)
507 self.assertEqual(cmp(m1.repeated_int32, m2.repeated_int32), 0)
508 self.assertEqual(cmp(m1.repeated_int32, [0, 1, 2]), 0)
509 self.assertEqual(cmp(m1.repeated_nested_message,
510 m2.repeated_nested_message), 0)
511 with self.assertRaises(TypeError):
512 # Can't compare repeated composite containers to lists.
513 cmp(m1.repeated_nested_message, m2.repeated_nested_message[:])
514
515 # TODO(anuraag): Implement extensiondict comparison in C++ and then add test
516
517 def ensureNestedMessageExists(self, msg, attribute):
518 """Make sure that a nested message object exists.
519
520 As soon as a nested message attribute is accessed, it will be present in the
521 _fields dict, without being marked as actually being set.
522 """
523 getattr(msg, attribute)
524 self.assertFalse(msg.HasField(attribute))
525
526 def testOneofGetCaseNonexistingField(self, message_module):
527 m = message_module.TestAllTypes()
528 self.assertRaises(ValueError, m.WhichOneof, 'no_such_oneof_field')
529
530 def testOneofDefaultValues(self, message_module):
531 m = message_module.TestAllTypes()
532 self.assertIs(None, m.WhichOneof('oneof_field'))
533 self.assertFalse(m.HasField('oneof_uint32'))
534
535 # Oneof is set even when setting it to a default value.
536 m.oneof_uint32 = 0
537 self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
538 self.assertTrue(m.HasField('oneof_uint32'))
539 self.assertFalse(m.HasField('oneof_string'))
540
541 m.oneof_string = ""
542 self.assertEqual('oneof_string', m.WhichOneof('oneof_field'))
543 self.assertTrue(m.HasField('oneof_string'))
544 self.assertFalse(m.HasField('oneof_uint32'))
545
546 def testOneofSemantics(self, message_module):
547 m = message_module.TestAllTypes()
548 self.assertIs(None, m.WhichOneof('oneof_field'))
549
550 m.oneof_uint32 = 11
551 self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
552 self.assertTrue(m.HasField('oneof_uint32'))
553
554 m.oneof_string = u'foo'
555 self.assertEqual('oneof_string', m.WhichOneof('oneof_field'))
556 self.assertFalse(m.HasField('oneof_uint32'))
557 self.assertTrue(m.HasField('oneof_string'))
558
559 m.oneof_nested_message.bb = 11
560 self.assertEqual('oneof_nested_message', m.WhichOneof('oneof_field'))
561 self.assertFalse(m.HasField('oneof_string'))
562 self.assertTrue(m.HasField('oneof_nested_message'))
563
564 m.oneof_bytes = b'bb'
565 self.assertEqual('oneof_bytes', m.WhichOneof('oneof_field'))
566 self.assertFalse(m.HasField('oneof_nested_message'))
567 self.assertTrue(m.HasField('oneof_bytes'))
568
569 def testOneofCompositeFieldReadAccess(self, message_module):
570 m = message_module.TestAllTypes()
571 m.oneof_uint32 = 11
572
573 self.ensureNestedMessageExists(m, 'oneof_nested_message')
574 self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
575 self.assertEqual(11, m.oneof_uint32)
576
577 def testOneofWhichOneof(self, message_module):
578 m = message_module.TestAllTypes()
579 self.assertIs(None, m.WhichOneof('oneof_field'))
580 if message_module is unittest_pb2:
581 self.assertFalse(m.HasField('oneof_field'))
582
583 m.oneof_uint32 = 11
584 self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
585 if message_module is unittest_pb2:
586 self.assertTrue(m.HasField('oneof_field'))
587
588 m.oneof_bytes = b'bb'
589 self.assertEqual('oneof_bytes', m.WhichOneof('oneof_field'))
590
591 m.ClearField('oneof_bytes')
592 self.assertIs(None, m.WhichOneof('oneof_field'))
593 if message_module is unittest_pb2:
594 self.assertFalse(m.HasField('oneof_field'))
595
596 def testOneofClearField(self, message_module):
597 m = message_module.TestAllTypes()
598 m.oneof_uint32 = 11
599 m.ClearField('oneof_field')
600 if message_module is unittest_pb2:
601 self.assertFalse(m.HasField('oneof_field'))
602 self.assertFalse(m.HasField('oneof_uint32'))
603 self.assertIs(None, m.WhichOneof('oneof_field'))
604
605 def testOneofClearSetField(self, message_module):
606 m = message_module.TestAllTypes()
607 m.oneof_uint32 = 11
608 m.ClearField('oneof_uint32')
609 if message_module is unittest_pb2:
610 self.assertFalse(m.HasField('oneof_field'))
611 self.assertFalse(m.HasField('oneof_uint32'))
612 self.assertIs(None, m.WhichOneof('oneof_field'))
613
614 def testOneofClearUnsetField(self, message_module):
615 m = message_module.TestAllTypes()
616 m.oneof_uint32 = 11
617 self.ensureNestedMessageExists(m, 'oneof_nested_message')
618 m.ClearField('oneof_nested_message')
619 self.assertEqual(11, m.oneof_uint32)
620 if message_module is unittest_pb2:
621 self.assertTrue(m.HasField('oneof_field'))
622 self.assertTrue(m.HasField('oneof_uint32'))
623 self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
624
625 def testOneofDeserialize(self, message_module):
626 m = message_module.TestAllTypes()
627 m.oneof_uint32 = 11
628 m2 = message_module.TestAllTypes()
629 m2.ParseFromString(m.SerializeToString())
630 self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
631
632 def testOneofCopyFrom(self, message_module):
633 m = message_module.TestAllTypes()
634 m.oneof_uint32 = 11
635 m2 = message_module.TestAllTypes()
636 m2.CopyFrom(m)
637 self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
638
639 def testOneofNestedMergeFrom(self, message_module):
640 m = message_module.NestedTestAllTypes()
641 m.payload.oneof_uint32 = 11
642 m2 = message_module.NestedTestAllTypes()
643 m2.payload.oneof_bytes = b'bb'
644 m2.child.payload.oneof_bytes = b'bb'
645 m2.MergeFrom(m)
646 self.assertEqual('oneof_uint32', m2.payload.WhichOneof('oneof_field'))
647 self.assertEqual('oneof_bytes', m2.child.payload.WhichOneof('oneof_field'))
648
649 def testOneofMessageMergeFrom(self, message_module):
650 m = message_module.NestedTestAllTypes()
651 m.payload.oneof_nested_message.bb = 11
652 m.child.payload.oneof_nested_message.bb = 12
653 m2 = message_module.NestedTestAllTypes()
654 m2.payload.oneof_uint32 = 13
655 m2.MergeFrom(m)
656 self.assertEqual('oneof_nested_message',
657 m2.payload.WhichOneof('oneof_field'))
658 self.assertEqual('oneof_nested_message',
659 m2.child.payload.WhichOneof('oneof_field'))
660
661 def testOneofNestedMessageInit(self, message_module):
662 m = message_module.TestAllTypes(
663 oneof_nested_message=message_module.TestAllTypes.NestedMessage())
664 self.assertEqual('oneof_nested_message', m.WhichOneof('oneof_field'))
665
666 def testOneofClear(self, message_module):
667 m = message_module.TestAllTypes()
668 m.oneof_uint32 = 11
669 m.Clear()
670 self.assertIsNone(m.WhichOneof('oneof_field'))
671 m.oneof_bytes = b'bb'
672 self.assertEqual('oneof_bytes', m.WhichOneof('oneof_field'))
673
674 def testAssignByteStringToUnicodeField(self, message_module):
675 """Assigning a byte string to a string field should result
676 in the value being converted to a Unicode string."""
677 m = message_module.TestAllTypes()
678 m.optional_string = str('')
679 self.assertTrue(isinstance(m.optional_string, unicode))
680
681 # TODO(haberman): why are these tests Google-internal only?
682
683 def testLongValuedSlice(self, message_module):
684 """It should be possible to use long-valued indicies in slices
685
686 This didn't used to work in the v2 C++ implementation.
687 """
688 m = message_module.TestAllTypes()
689
690 # Repeated scalar
691 m.repeated_int32.append(1)
692 sl = m.repeated_int32[long(0):long(len(m.repeated_int32))]
693 self.assertEqual(len(m.repeated_int32), len(sl))
694
695 # Repeated composite
696 m.repeated_nested_message.add().bb = 3
697 sl = m.repeated_nested_message[long(0):long(len(m.repeated_nested_message))]
698 self.assertEqual(len(m.repeated_nested_message), len(sl))
699
700 def testExtendShouldNotSwallowExceptions(self, message_module):
701 """This didn't use to work in the v2 C++ implementation."""
702 m = message_module.TestAllTypes()
703 with self.assertRaises(NameError) as _:
704 m.repeated_int32.extend(a for i in range(10)) # pylint: disable=undefined -variable
705 with self.assertRaises(NameError) as _:
706 m.repeated_nested_enum.extend(
707 a for i in range(10)) # pylint: disable=undefined-variable
708
709 FALSY_VALUES = [None, False, 0, 0.0, b'', u'', bytearray(), [], {}, set()]
710
711 def testExtendInt32WithNothing(self, message_module):
712 """Test no-ops extending repeated int32 fields."""
713 m = message_module.TestAllTypes()
714 self.assertSequenceEqual([], m.repeated_int32)
715
716 # TODO(ptucker): Deprecate this behavior. b/18413862
717 for falsy_value in MessageTest.FALSY_VALUES:
718 m.repeated_int32.extend(falsy_value)
719 self.assertSequenceEqual([], m.repeated_int32)
720
721 m.repeated_int32.extend([])
722 self.assertSequenceEqual([], m.repeated_int32)
723
724 def testExtendFloatWithNothing(self, message_module):
725 """Test no-ops extending repeated float fields."""
726 m = message_module.TestAllTypes()
727 self.assertSequenceEqual([], m.repeated_float)
728
729 # TODO(ptucker): Deprecate this behavior. b/18413862
730 for falsy_value in MessageTest.FALSY_VALUES:
731 m.repeated_float.extend(falsy_value)
732 self.assertSequenceEqual([], m.repeated_float)
733
734 m.repeated_float.extend([])
735 self.assertSequenceEqual([], m.repeated_float)
736
737 def testExtendStringWithNothing(self, message_module):
738 """Test no-ops extending repeated string fields."""
739 m = message_module.TestAllTypes()
740 self.assertSequenceEqual([], m.repeated_string)
741
742 # TODO(ptucker): Deprecate this behavior. b/18413862
743 for falsy_value in MessageTest.FALSY_VALUES:
744 m.repeated_string.extend(falsy_value)
745 self.assertSequenceEqual([], m.repeated_string)
746
747 m.repeated_string.extend([])
748 self.assertSequenceEqual([], m.repeated_string)
749
750 def testExtendInt32WithPythonList(self, message_module):
751 """Test extending repeated int32 fields with python lists."""
752 m = message_module.TestAllTypes()
753 self.assertSequenceEqual([], m.repeated_int32)
754 m.repeated_int32.extend([0])
755 self.assertSequenceEqual([0], m.repeated_int32)
756 m.repeated_int32.extend([1, 2])
757 self.assertSequenceEqual([0, 1, 2], m.repeated_int32)
758 m.repeated_int32.extend([3, 4])
759 self.assertSequenceEqual([0, 1, 2, 3, 4], m.repeated_int32)
760
761 def testExtendFloatWithPythonList(self, message_module):
762 """Test extending repeated float fields with python lists."""
763 m = message_module.TestAllTypes()
764 self.assertSequenceEqual([], m.repeated_float)
765 m.repeated_float.extend([0.0])
766 self.assertSequenceEqual([0.0], m.repeated_float)
767 m.repeated_float.extend([1.0, 2.0])
768 self.assertSequenceEqual([0.0, 1.0, 2.0], m.repeated_float)
769 m.repeated_float.extend([3.0, 4.0])
770 self.assertSequenceEqual([0.0, 1.0, 2.0, 3.0, 4.0], m.repeated_float)
771
772 def testExtendStringWithPythonList(self, message_module):
773 """Test extending repeated string fields with python lists."""
774 m = message_module.TestAllTypes()
775 self.assertSequenceEqual([], m.repeated_string)
776 m.repeated_string.extend([''])
777 self.assertSequenceEqual([''], m.repeated_string)
778 m.repeated_string.extend(['11', '22'])
779 self.assertSequenceEqual(['', '11', '22'], m.repeated_string)
780 m.repeated_string.extend(['33', '44'])
781 self.assertSequenceEqual(['', '11', '22', '33', '44'], m.repeated_string)
782
783 def testExtendStringWithString(self, message_module):
784 """Test extending repeated string fields with characters from a string."""
785 m = message_module.TestAllTypes()
786 self.assertSequenceEqual([], m.repeated_string)
787 m.repeated_string.extend('abc')
788 self.assertSequenceEqual(['a', 'b', 'c'], m.repeated_string)
789
790 class TestIterable(object):
791 """This iterable object mimics the behavior of numpy.array.
792
793 __nonzero__ fails for length > 1, and returns bool(item[0]) for length == 1.
794
795 """
796
797 def __init__(self, values=None):
798 self._list = values or []
799
800 def __nonzero__(self):
801 size = len(self._list)
802 if size == 0:
803 return False
804 if size == 1:
805 return bool(self._list[0])
806 raise ValueError('Truth value is ambiguous.')
807
808 def __len__(self):
809 return len(self._list)
810
811 def __iter__(self):
812 return self._list.__iter__()
813
814 def testExtendInt32WithIterable(self, message_module):
815 """Test extending repeated int32 fields with iterable."""
816 m = message_module.TestAllTypes()
817 self.assertSequenceEqual([], m.repeated_int32)
818 m.repeated_int32.extend(MessageTest.TestIterable([]))
819 self.assertSequenceEqual([], m.repeated_int32)
820 m.repeated_int32.extend(MessageTest.TestIterable([0]))
821 self.assertSequenceEqual([0], m.repeated_int32)
822 m.repeated_int32.extend(MessageTest.TestIterable([1, 2]))
823 self.assertSequenceEqual([0, 1, 2], m.repeated_int32)
824 m.repeated_int32.extend(MessageTest.TestIterable([3, 4]))
825 self.assertSequenceEqual([0, 1, 2, 3, 4], m.repeated_int32)
826
827 def testExtendFloatWithIterable(self, message_module):
828 """Test extending repeated float fields with iterable."""
829 m = message_module.TestAllTypes()
830 self.assertSequenceEqual([], m.repeated_float)
831 m.repeated_float.extend(MessageTest.TestIterable([]))
832 self.assertSequenceEqual([], m.repeated_float)
833 m.repeated_float.extend(MessageTest.TestIterable([0.0]))
834 self.assertSequenceEqual([0.0], m.repeated_float)
835 m.repeated_float.extend(MessageTest.TestIterable([1.0, 2.0]))
836 self.assertSequenceEqual([0.0, 1.0, 2.0], m.repeated_float)
837 m.repeated_float.extend(MessageTest.TestIterable([3.0, 4.0]))
838 self.assertSequenceEqual([0.0, 1.0, 2.0, 3.0, 4.0], m.repeated_float)
839
840 def testExtendStringWithIterable(self, message_module):
841 """Test extending repeated string fields with iterable."""
842 m = message_module.TestAllTypes()
843 self.assertSequenceEqual([], m.repeated_string)
844 m.repeated_string.extend(MessageTest.TestIterable([]))
845 self.assertSequenceEqual([], m.repeated_string)
846 m.repeated_string.extend(MessageTest.TestIterable(['']))
847 self.assertSequenceEqual([''], m.repeated_string)
848 m.repeated_string.extend(MessageTest.TestIterable(['1', '2']))
849 self.assertSequenceEqual(['', '1', '2'], m.repeated_string)
850 m.repeated_string.extend(MessageTest.TestIterable(['3', '4']))
851 self.assertSequenceEqual(['', '1', '2', '3', '4'], m.repeated_string)
852
853 def testPickleRepeatedScalarContainer(self, message_module):
854 # TODO(tibell): The pure-Python implementation support pickling of
855 # scalar containers in *some* cases. For now the cpp2 version
856 # throws an exception to avoid a segfault. Investigate if we
857 # want to support pickling of these fields.
858 #
859 # For more information see: https://b2.corp.google.com/u/0/issues/18677897
860 if (api_implementation.Type() != 'cpp' or
861 api_implementation.Version() == 2):
862 return
863 m = message_module.TestAllTypes()
864 with self.assertRaises(pickle.PickleError) as _:
865 pickle.dumps(m.repeated_int32, pickle.HIGHEST_PROTOCOL)
866
867
868 def testSortEmptyRepeatedCompositeContainer(self, message_module):
869 """Exercise a scenario that has led to segfaults in the past.
870 """
871 m = message_module.TestAllTypes()
872 m.repeated_nested_message.sort()
873
874 def testHasFieldOnRepeatedField(self, message_module):
875 """Using HasField on a repeated field should raise an exception.
876 """
877 m = message_module.TestAllTypes()
878 with self.assertRaises(ValueError) as _:
879 m.HasField('repeated_int32')
880
881 def testRepeatedScalarFieldPop(self, message_module):
882 m = message_module.TestAllTypes()
883 with self.assertRaises(IndexError) as _:
884 m.repeated_int32.pop()
885 m.repeated_int32.extend(range(5))
886 self.assertEqual(4, m.repeated_int32.pop())
887 self.assertEqual(0, m.repeated_int32.pop(0))
888 self.assertEqual(2, m.repeated_int32.pop(1))
889 self.assertEqual([1, 3], m.repeated_int32)
890
891 def testRepeatedCompositeFieldPop(self, message_module):
892 m = message_module.TestAllTypes()
893 with self.assertRaises(IndexError) as _:
894 m.repeated_nested_message.pop()
895 for i in range(5):
896 n = m.repeated_nested_message.add()
897 n.bb = i
898 self.assertEqual(4, m.repeated_nested_message.pop().bb)
899 self.assertEqual(0, m.repeated_nested_message.pop(0).bb)
900 self.assertEqual(2, m.repeated_nested_message.pop(1).bb)
901 self.assertEqual([1, 3], [n.bb for n in m.repeated_nested_message])
902
903
904 # Class to test proto2-only features (required, extensions, etc.)
905 class Proto2Test(unittest.TestCase):
906
907 def testFieldPresence(self):
908 message = unittest_pb2.TestAllTypes()
909
910 self.assertFalse(message.HasField("optional_int32"))
911 self.assertFalse(message.HasField("optional_bool"))
912 self.assertFalse(message.HasField("optional_nested_message"))
913
914 with self.assertRaises(ValueError):
915 message.HasField("field_doesnt_exist")
916
917 with self.assertRaises(ValueError):
918 message.HasField("repeated_int32")
919 with self.assertRaises(ValueError):
920 message.HasField("repeated_nested_message")
921
922 self.assertEqual(0, message.optional_int32)
923 self.assertEqual(False, message.optional_bool)
924 self.assertEqual(0, message.optional_nested_message.bb)
925
926 # Fields are set even when setting the values to default values.
927 message.optional_int32 = 0
928 message.optional_bool = False
929 message.optional_nested_message.bb = 0
930 self.assertTrue(message.HasField("optional_int32"))
931 self.assertTrue(message.HasField("optional_bool"))
932 self.assertTrue(message.HasField("optional_nested_message"))
933
934 # Set the fields to non-default values.
935 message.optional_int32 = 5
936 message.optional_bool = True
937 message.optional_nested_message.bb = 15
938
939 self.assertTrue(message.HasField("optional_int32"))
940 self.assertTrue(message.HasField("optional_bool"))
941 self.assertTrue(message.HasField("optional_nested_message"))
942
943 # Clearing the fields unsets them and resets their value to default.
944 message.ClearField("optional_int32")
945 message.ClearField("optional_bool")
946 message.ClearField("optional_nested_message")
947
948 self.assertFalse(message.HasField("optional_int32"))
949 self.assertFalse(message.HasField("optional_bool"))
950 self.assertFalse(message.HasField("optional_nested_message"))
951 self.assertEqual(0, message.optional_int32)
952 self.assertEqual(False, message.optional_bool)
953 self.assertEqual(0, message.optional_nested_message.bb)
954
955 # TODO(tibell): The C++ implementations actually allows assignment
956 # of unknown enum values to *scalar* fields (but not repeated
957 # fields). Once checked enum fields becomes the default in the
958 # Python implementation, the C++ implementation should follow suit.
959 def testAssignInvalidEnum(self):
960 """It should not be possible to assign an invalid enum number to an
961 enum field."""
962 m = unittest_pb2.TestAllTypes()
963
964 with self.assertRaises(ValueError) as _:
965 m.optional_nested_enum = 1234567
966 self.assertRaises(ValueError, m.repeated_nested_enum.append, 1234567)
967
968 def testGoldenExtensions(self):
969 golden_data = test_util.GoldenFileData('golden_message')
970 golden_message = unittest_pb2.TestAllExtensions()
971 golden_message.ParseFromString(golden_data)
972 all_set = unittest_pb2.TestAllExtensions()
973 test_util.SetAllExtensions(all_set)
974 self.assertEqual(all_set, golden_message)
975 self.assertEqual(golden_data, golden_message.SerializeToString())
976 golden_copy = copy.deepcopy(golden_message)
977 self.assertEqual(golden_data, golden_copy.SerializeToString())
978
979 def testGoldenPackedExtensions(self):
980 golden_data = test_util.GoldenFileData('golden_packed_fields_message')
981 golden_message = unittest_pb2.TestPackedExtensions()
982 golden_message.ParseFromString(golden_data)
983 all_set = unittest_pb2.TestPackedExtensions()
984 test_util.SetAllPackedExtensions(all_set)
985 self.assertEqual(all_set, golden_message)
986 self.assertEqual(golden_data, all_set.SerializeToString())
987 golden_copy = copy.deepcopy(golden_message)
988 self.assertEqual(golden_data, golden_copy.SerializeToString())
989
990 def testPickleIncompleteProto(self):
991 golden_message = unittest_pb2.TestRequired(a=1)
992 pickled_message = pickle.dumps(golden_message)
993
994 unpickled_message = pickle.loads(pickled_message)
995 self.assertEqual(unpickled_message, golden_message)
996 self.assertEqual(unpickled_message.a, 1)
997 # This is still an incomplete proto - so serializing should fail
998 self.assertRaises(message.EncodeError, unpickled_message.SerializeToString)
999
1000
1001 # TODO(haberman): this isn't really a proto2-specific test except that this
1002 # message has a required field in it. Should probably be factored out so
1003 # that we can test the other parts with proto3.
436 def testParsingMerge(self): 1004 def testParsingMerge(self):
437 """Check the merge behavior when a required or optional field appears 1005 """Check the merge behavior when a required or optional field appears
438 multiple times in the input.""" 1006 multiple times in the input."""
439 messages = [ 1007 messages = [
440 unittest_pb2.TestAllTypes(), 1008 unittest_pb2.TestAllTypes(),
441 unittest_pb2.TestAllTypes(), 1009 unittest_pb2.TestAllTypes(),
442 unittest_pb2.TestAllTypes() ] 1010 unittest_pb2.TestAllTypes() ]
443 messages[0].optional_int32 = 1 1011 messages[0].optional_int32 = 1
444 messages[1].optional_int64 = 2 1012 messages[1].optional_int64 = 2
445 messages[2].optional_int32 = 3 1013 messages[2].optional_int32 = 3
(...skipping 29 matching lines...) Expand all
475 self.assertEqual(parsing_merge.Extensions[ 1043 self.assertEqual(parsing_merge.Extensions[
476 unittest_pb2.TestParsingMerge.optional_ext], 1044 unittest_pb2.TestParsingMerge.optional_ext],
477 merged_message) 1045 merged_message)
478 1046
479 # Repeated fields should not be merged. 1047 # Repeated fields should not be merged.
480 self.assertEqual(len(parsing_merge.repeated_all_types), 3) 1048 self.assertEqual(len(parsing_merge.repeated_all_types), 3)
481 self.assertEqual(len(parsing_merge.repeatedgroup), 3) 1049 self.assertEqual(len(parsing_merge.repeatedgroup), 3)
482 self.assertEqual(len(parsing_merge.Extensions[ 1050 self.assertEqual(len(parsing_merge.Extensions[
483 unittest_pb2.TestParsingMerge.repeated_ext]), 3) 1051 unittest_pb2.TestParsingMerge.repeated_ext]), 3)
484 1052
485 1053 def testPythonicInit(self):
486 def testSortEmptyRepeatedCompositeContainer(self): 1054 message = unittest_pb2.TestAllTypes(
487 """Exercise a scenario that has led to segfaults in the past. 1055 optional_int32=100,
488 """ 1056 optional_fixed32=200,
489 m = unittest_pb2.TestAllTypes() 1057 optional_float=300.5,
490 m.repeated_nested_message.sort() 1058 optional_bytes=b'x',
1059 optionalgroup={'a': 400},
1060 optional_nested_message={'bb': 500},
1061 optional_nested_enum='BAZ',
1062 repeatedgroup=[{'a': 600},
1063 {'a': 700}],
1064 repeated_nested_enum=['FOO', unittest_pb2.TestAllTypes.BAR],
1065 default_int32=800,
1066 oneof_string='y')
1067 self.assertTrue(isinstance(message, unittest_pb2.TestAllTypes))
1068 self.assertEqual(100, message.optional_int32)
1069 self.assertEqual(200, message.optional_fixed32)
1070 self.assertEqual(300.5, message.optional_float)
1071 self.assertEqual(b'x', message.optional_bytes)
1072 self.assertEqual(400, message.optionalgroup.a)
1073 self.assertTrue(isinstance(message.optional_nested_message,
1074 unittest_pb2.TestAllTypes.NestedMessage))
1075 self.assertEqual(500, message.optional_nested_message.bb)
1076 self.assertEqual(unittest_pb2.TestAllTypes.BAZ,
1077 message.optional_nested_enum)
1078 self.assertEqual(2, len(message.repeatedgroup))
1079 self.assertEqual(600, message.repeatedgroup[0].a)
1080 self.assertEqual(700, message.repeatedgroup[1].a)
1081 self.assertEqual(2, len(message.repeated_nested_enum))
1082 self.assertEqual(unittest_pb2.TestAllTypes.FOO,
1083 message.repeated_nested_enum[0])
1084 self.assertEqual(unittest_pb2.TestAllTypes.BAR,
1085 message.repeated_nested_enum[1])
1086 self.assertEqual(800, message.default_int32)
1087 self.assertEqual('y', message.oneof_string)
1088 self.assertFalse(message.HasField('optional_int64'))
1089 self.assertEqual(0, len(message.repeated_float))
1090 self.assertEqual(42, message.default_int64)
1091
1092 message = unittest_pb2.TestAllTypes(optional_nested_enum=u'BAZ')
1093 self.assertEqual(unittest_pb2.TestAllTypes.BAZ,
1094 message.optional_nested_enum)
1095
1096 with self.assertRaises(ValueError):
1097 unittest_pb2.TestAllTypes(
1098 optional_nested_message={'INVALID_NESTED_FIELD': 17})
1099
1100 with self.assertRaises(TypeError):
1101 unittest_pb2.TestAllTypes(
1102 optional_nested_message={'bb': 'INVALID_VALUE_TYPE'})
1103
1104 with self.assertRaises(ValueError):
1105 unittest_pb2.TestAllTypes(optional_nested_enum='INVALID_LABEL')
1106
1107 with self.assertRaises(ValueError):
1108 unittest_pb2.TestAllTypes(repeated_nested_enum='FOO')
1109
1110
1111 # Class to test proto3-only features/behavior (updated field presence & enums)
1112 class Proto3Test(unittest.TestCase):
1113
1114 # Utility method for comparing equality with a map.
1115 def assertMapIterEquals(self, map_iter, dict_value):
1116 # Avoid mutating caller's copy.
1117 dict_value = dict(dict_value)
1118
1119 for k, v in map_iter:
1120 self.assertEqual(v, dict_value[k])
1121 del dict_value[k]
1122
1123 self.assertEqual({}, dict_value)
1124
1125 def testFieldPresence(self):
1126 message = unittest_proto3_arena_pb2.TestAllTypes()
1127
1128 # We can't test presence of non-repeated, non-submessage fields.
1129 with self.assertRaises(ValueError):
1130 message.HasField('optional_int32')
1131 with self.assertRaises(ValueError):
1132 message.HasField('optional_float')
1133 with self.assertRaises(ValueError):
1134 message.HasField('optional_string')
1135 with self.assertRaises(ValueError):
1136 message.HasField('optional_bool')
1137
1138 # But we can still test presence of submessage fields.
1139 self.assertFalse(message.HasField('optional_nested_message'))
1140
1141 # As with proto2, we can't test presence of fields that don't exist, or
1142 # repeated fields.
1143 with self.assertRaises(ValueError):
1144 message.HasField('field_doesnt_exist')
1145
1146 with self.assertRaises(ValueError):
1147 message.HasField('repeated_int32')
1148 with self.assertRaises(ValueError):
1149 message.HasField('repeated_nested_message')
1150
1151 # Fields should default to their type-specific default.
1152 self.assertEqual(0, message.optional_int32)
1153 self.assertEqual(0, message.optional_float)
1154 self.assertEqual('', message.optional_string)
1155 self.assertEqual(False, message.optional_bool)
1156 self.assertEqual(0, message.optional_nested_message.bb)
1157
1158 # Setting a submessage should still return proper presence information.
1159 message.optional_nested_message.bb = 0
1160 self.assertTrue(message.HasField('optional_nested_message'))
1161
1162 # Set the fields to non-default values.
1163 message.optional_int32 = 5
1164 message.optional_float = 1.1
1165 message.optional_string = 'abc'
1166 message.optional_bool = True
1167 message.optional_nested_message.bb = 15
1168
1169 # Clearing the fields unsets them and resets their value to default.
1170 message.ClearField('optional_int32')
1171 message.ClearField('optional_float')
1172 message.ClearField('optional_string')
1173 message.ClearField('optional_bool')
1174 message.ClearField('optional_nested_message')
1175
1176 self.assertEqual(0, message.optional_int32)
1177 self.assertEqual(0, message.optional_float)
1178 self.assertEqual('', message.optional_string)
1179 self.assertEqual(False, message.optional_bool)
1180 self.assertEqual(0, message.optional_nested_message.bb)
1181
1182 def testAssignUnknownEnum(self):
1183 """Assigning an unknown enum value is allowed and preserves the value."""
1184 m = unittest_proto3_arena_pb2.TestAllTypes()
1185
1186 m.optional_nested_enum = 1234567
1187 self.assertEqual(1234567, m.optional_nested_enum)
1188 m.repeated_nested_enum.append(22334455)
1189 self.assertEqual(22334455, m.repeated_nested_enum[0])
1190 # Assignment is a different code path than append for the C++ impl.
1191 m.repeated_nested_enum[0] = 7654321
1192 self.assertEqual(7654321, m.repeated_nested_enum[0])
1193 serialized = m.SerializeToString()
1194
1195 m2 = unittest_proto3_arena_pb2.TestAllTypes()
1196 m2.ParseFromString(serialized)
1197 self.assertEqual(1234567, m2.optional_nested_enum)
1198 self.assertEqual(7654321, m2.repeated_nested_enum[0])
1199
1200 # Map isn't really a proto3-only feature. But there is no proto2 equivalent
1201 # of google/protobuf/map_unittest.proto right now, so it's not easy to
1202 # test both with the same test like we do for the other proto2/proto3 tests.
1203 # (google/protobuf/map_protobuf_unittest.proto is very different in the set
1204 # of messages and fields it contains).
1205 def testScalarMapDefaults(self):
1206 msg = map_unittest_pb2.TestMap()
1207
1208 # Scalars start out unset.
1209 self.assertFalse(-123 in msg.map_int32_int32)
1210 self.assertFalse(-2**33 in msg.map_int64_int64)
1211 self.assertFalse(123 in msg.map_uint32_uint32)
1212 self.assertFalse(2**33 in msg.map_uint64_uint64)
1213 self.assertFalse('abc' in msg.map_string_string)
1214 self.assertFalse(888 in msg.map_int32_enum)
1215
1216 # Accessing an unset key returns the default.
1217 self.assertEqual(0, msg.map_int32_int32[-123])
1218 self.assertEqual(0, msg.map_int64_int64[-2**33])
1219 self.assertEqual(0, msg.map_uint32_uint32[123])
1220 self.assertEqual(0, msg.map_uint64_uint64[2**33])
1221 self.assertEqual('', msg.map_string_string['abc'])
1222 self.assertEqual(0, msg.map_int32_enum[888])
1223
1224 # It also sets the value in the map
1225 self.assertTrue(-123 in msg.map_int32_int32)
1226 self.assertTrue(-2**33 in msg.map_int64_int64)
1227 self.assertTrue(123 in msg.map_uint32_uint32)
1228 self.assertTrue(2**33 in msg.map_uint64_uint64)
1229 self.assertTrue('abc' in msg.map_string_string)
1230 self.assertTrue(888 in msg.map_int32_enum)
1231
1232 self.assertTrue(isinstance(msg.map_string_string['abc'], unicode))
1233
1234 # Accessing an unset key still throws TypeError of the type of the key
1235 # is incorrect.
1236 with self.assertRaises(TypeError):
1237 msg.map_string_string[123]
1238
1239 self.assertFalse(123 in msg.map_string_string)
1240
1241 def testMapGet(self):
1242 # Need to test that get() properly returns the default, even though the dict
1243 # has defaultdict-like semantics.
1244 msg = map_unittest_pb2.TestMap()
1245
1246 self.assertIsNone(msg.map_int32_int32.get(5))
1247 self.assertEquals(10, msg.map_int32_int32.get(5, 10))
1248 self.assertIsNone(msg.map_int32_int32.get(5))
1249
1250 msg.map_int32_int32[5] = 15
1251 self.assertEquals(15, msg.map_int32_int32.get(5))
1252
1253 self.assertIsNone(msg.map_int32_foreign_message.get(5))
1254 self.assertEquals(10, msg.map_int32_foreign_message.get(5, 10))
1255
1256 submsg = msg.map_int32_foreign_message[5]
1257 self.assertIs(submsg, msg.map_int32_foreign_message.get(5))
1258
1259 def testScalarMap(self):
1260 msg = map_unittest_pb2.TestMap()
1261
1262 self.assertEqual(0, len(msg.map_int32_int32))
1263 self.assertFalse(5 in msg.map_int32_int32)
1264
1265 msg.map_int32_int32[-123] = -456
1266 msg.map_int64_int64[-2**33] = -2**34
1267 msg.map_uint32_uint32[123] = 456
1268 msg.map_uint64_uint64[2**33] = 2**34
1269 msg.map_string_string['abc'] = '123'
1270 msg.map_int32_enum[888] = 2
1271
1272 self.assertEqual([], msg.FindInitializationErrors())
1273
1274 self.assertEqual(1, len(msg.map_string_string))
1275
1276 # Bad key.
1277 with self.assertRaises(TypeError):
1278 msg.map_string_string[123] = '123'
1279
1280 # Verify that trying to assign a bad key doesn't actually add a member to
1281 # the map.
1282 self.assertEqual(1, len(msg.map_string_string))
1283
1284 # Bad value.
1285 with self.assertRaises(TypeError):
1286 msg.map_string_string['123'] = 123
1287
1288 serialized = msg.SerializeToString()
1289 msg2 = map_unittest_pb2.TestMap()
1290 msg2.ParseFromString(serialized)
1291
1292 # Bad key.
1293 with self.assertRaises(TypeError):
1294 msg2.map_string_string[123] = '123'
1295
1296 # Bad value.
1297 with self.assertRaises(TypeError):
1298 msg2.map_string_string['123'] = 123
1299
1300 self.assertEqual(-456, msg2.map_int32_int32[-123])
1301 self.assertEqual(-2**34, msg2.map_int64_int64[-2**33])
1302 self.assertEqual(456, msg2.map_uint32_uint32[123])
1303 self.assertEqual(2**34, msg2.map_uint64_uint64[2**33])
1304 self.assertEqual('123', msg2.map_string_string['abc'])
1305 self.assertEqual(2, msg2.map_int32_enum[888])
1306
1307 def testStringUnicodeConversionInMap(self):
1308 msg = map_unittest_pb2.TestMap()
1309
1310 unicode_obj = u'\u1234'
1311 bytes_obj = unicode_obj.encode('utf8')
1312
1313 msg.map_string_string[bytes_obj] = bytes_obj
1314
1315 (key, value) = msg.map_string_string.items()[0]
1316
1317 self.assertEqual(key, unicode_obj)
1318 self.assertEqual(value, unicode_obj)
1319
1320 self.assertTrue(isinstance(key, unicode))
1321 self.assertTrue(isinstance(value, unicode))
1322
1323 def testMessageMap(self):
1324 msg = map_unittest_pb2.TestMap()
1325
1326 self.assertEqual(0, len(msg.map_int32_foreign_message))
1327 self.assertFalse(5 in msg.map_int32_foreign_message)
1328
1329 msg.map_int32_foreign_message[123]
1330 # get_or_create() is an alias for getitem.
1331 msg.map_int32_foreign_message.get_or_create(-456)
1332
1333 self.assertEqual(2, len(msg.map_int32_foreign_message))
1334 self.assertIn(123, msg.map_int32_foreign_message)
1335 self.assertIn(-456, msg.map_int32_foreign_message)
1336 self.assertEqual(2, len(msg.map_int32_foreign_message))
1337
1338 # Bad key.
1339 with self.assertRaises(TypeError):
1340 msg.map_int32_foreign_message['123']
1341
1342 # Can't assign directly to submessage.
1343 with self.assertRaises(ValueError):
1344 msg.map_int32_foreign_message[999] = msg.map_int32_foreign_message[123]
1345
1346 # Verify that trying to assign a bad key doesn't actually add a member to
1347 # the map.
1348 self.assertEqual(2, len(msg.map_int32_foreign_message))
1349
1350 serialized = msg.SerializeToString()
1351 msg2 = map_unittest_pb2.TestMap()
1352 msg2.ParseFromString(serialized)
1353
1354 self.assertEqual(2, len(msg2.map_int32_foreign_message))
1355 self.assertIn(123, msg2.map_int32_foreign_message)
1356 self.assertIn(-456, msg2.map_int32_foreign_message)
1357 self.assertEqual(2, len(msg2.map_int32_foreign_message))
1358
1359 def testMergeFrom(self):
1360 msg = map_unittest_pb2.TestMap()
1361 msg.map_int32_int32[12] = 34
1362 msg.map_int32_int32[56] = 78
1363 msg.map_int64_int64[22] = 33
1364 msg.map_int32_foreign_message[111].c = 5
1365 msg.map_int32_foreign_message[222].c = 10
1366
1367 msg2 = map_unittest_pb2.TestMap()
1368 msg2.map_int32_int32[12] = 55
1369 msg2.map_int64_int64[88] = 99
1370 msg2.map_int32_foreign_message[222].c = 15
1371
1372 msg2.MergeFrom(msg)
1373
1374 self.assertEqual(34, msg2.map_int32_int32[12])
1375 self.assertEqual(78, msg2.map_int32_int32[56])
1376 self.assertEqual(33, msg2.map_int64_int64[22])
1377 self.assertEqual(99, msg2.map_int64_int64[88])
1378 self.assertEqual(5, msg2.map_int32_foreign_message[111].c)
1379 self.assertEqual(10, msg2.map_int32_foreign_message[222].c)
1380
1381 # Verify that there is only one entry per key, even though the MergeFrom
1382 # may have internally created multiple entries for a single key in the
1383 # list representation.
1384 as_dict = {}
1385 for key in msg2.map_int32_foreign_message:
1386 self.assertFalse(key in as_dict)
1387 as_dict[key] = msg2.map_int32_foreign_message[key].c
1388
1389 self.assertEqual({111: 5, 222: 10}, as_dict)
1390
1391 # Special case: test that delete of item really removes the item, even if
1392 # there might have physically been duplicate keys due to the previous merge.
1393 # This is only a special case for the C++ implementation which stores the
1394 # map as an array.
1395 del msg2.map_int32_int32[12]
1396 self.assertFalse(12 in msg2.map_int32_int32)
1397
1398 del msg2.map_int32_foreign_message[222]
1399 self.assertFalse(222 in msg2.map_int32_foreign_message)
1400
1401 def testIntegerMapWithLongs(self):
1402 msg = map_unittest_pb2.TestMap()
1403 msg.map_int32_int32[long(-123)] = long(-456)
1404 msg.map_int64_int64[long(-2**33)] = long(-2**34)
1405 msg.map_uint32_uint32[long(123)] = long(456)
1406 msg.map_uint64_uint64[long(2**33)] = long(2**34)
1407
1408 serialized = msg.SerializeToString()
1409 msg2 = map_unittest_pb2.TestMap()
1410 msg2.ParseFromString(serialized)
1411
1412 self.assertEqual(-456, msg2.map_int32_int32[-123])
1413 self.assertEqual(-2**34, msg2.map_int64_int64[-2**33])
1414 self.assertEqual(456, msg2.map_uint32_uint32[123])
1415 self.assertEqual(2**34, msg2.map_uint64_uint64[2**33])
1416
1417 def testMapAssignmentCausesPresence(self):
1418 msg = map_unittest_pb2.TestMapSubmessage()
1419 msg.test_map.map_int32_int32[123] = 456
1420
1421 serialized = msg.SerializeToString()
1422 msg2 = map_unittest_pb2.TestMapSubmessage()
1423 msg2.ParseFromString(serialized)
1424
1425 self.assertEqual(msg, msg2)
1426
1427 # Now test that various mutations of the map properly invalidate the
1428 # cached size of the submessage.
1429 msg.test_map.map_int32_int32[888] = 999
1430 serialized = msg.SerializeToString()
1431 msg2.ParseFromString(serialized)
1432 self.assertEqual(msg, msg2)
1433
1434 msg.test_map.map_int32_int32.clear()
1435 serialized = msg.SerializeToString()
1436 msg2.ParseFromString(serialized)
1437 self.assertEqual(msg, msg2)
1438
1439 def testMapAssignmentCausesPresenceForSubmessages(self):
1440 msg = map_unittest_pb2.TestMapSubmessage()
1441 msg.test_map.map_int32_foreign_message[123].c = 5
1442
1443 serialized = msg.SerializeToString()
1444 msg2 = map_unittest_pb2.TestMapSubmessage()
1445 msg2.ParseFromString(serialized)
1446
1447 self.assertEqual(msg, msg2)
1448
1449 # Now test that various mutations of the map properly invalidate the
1450 # cached size of the submessage.
1451 msg.test_map.map_int32_foreign_message[888].c = 7
1452 serialized = msg.SerializeToString()
1453 msg2.ParseFromString(serialized)
1454 self.assertEqual(msg, msg2)
1455
1456 msg.test_map.map_int32_foreign_message[888].MergeFrom(
1457 msg.test_map.map_int32_foreign_message[123])
1458 serialized = msg.SerializeToString()
1459 msg2.ParseFromString(serialized)
1460 self.assertEqual(msg, msg2)
1461
1462 msg.test_map.map_int32_foreign_message.clear()
1463 serialized = msg.SerializeToString()
1464 msg2.ParseFromString(serialized)
1465 self.assertEqual(msg, msg2)
1466
1467 def testModifyMapWhileIterating(self):
1468 msg = map_unittest_pb2.TestMap()
1469
1470 string_string_iter = iter(msg.map_string_string)
1471 int32_foreign_iter = iter(msg.map_int32_foreign_message)
1472
1473 msg.map_string_string['abc'] = '123'
1474 msg.map_int32_foreign_message[5].c = 5
1475
1476 with self.assertRaises(RuntimeError):
1477 for key in string_string_iter:
1478 pass
1479
1480 with self.assertRaises(RuntimeError):
1481 for key in int32_foreign_iter:
1482 pass
1483
1484 def testSubmessageMap(self):
1485 msg = map_unittest_pb2.TestMap()
1486
1487 submsg = msg.map_int32_foreign_message[111]
1488 self.assertIs(submsg, msg.map_int32_foreign_message[111])
1489 self.assertTrue(isinstance(submsg, unittest_pb2.ForeignMessage))
1490
1491 submsg.c = 5
1492
1493 serialized = msg.SerializeToString()
1494 msg2 = map_unittest_pb2.TestMap()
1495 msg2.ParseFromString(serialized)
1496
1497 self.assertEqual(5, msg2.map_int32_foreign_message[111].c)
1498
1499 # Doesn't allow direct submessage assignment.
1500 with self.assertRaises(ValueError):
1501 msg.map_int32_foreign_message[88] = unittest_pb2.ForeignMessage()
1502
1503 def testMapIteration(self):
1504 msg = map_unittest_pb2.TestMap()
1505
1506 for k, v in msg.map_int32_int32.iteritems():
1507 # Should not be reached.
1508 self.assertTrue(False)
1509
1510 msg.map_int32_int32[2] = 4
1511 msg.map_int32_int32[3] = 6
1512 msg.map_int32_int32[4] = 8
1513 self.assertEqual(3, len(msg.map_int32_int32))
1514
1515 matching_dict = {2: 4, 3: 6, 4: 8}
1516 self.assertMapIterEquals(msg.map_int32_int32.iteritems(), matching_dict)
1517
1518 def testMapIterationClearMessage(self):
1519 # Iterator needs to work even if message and map are deleted.
1520 msg = map_unittest_pb2.TestMap()
1521
1522 msg.map_int32_int32[2] = 4
1523 msg.map_int32_int32[3] = 6
1524 msg.map_int32_int32[4] = 8
1525
1526 it = msg.map_int32_int32.iteritems()
1527 del msg
1528
1529 matching_dict = {2: 4, 3: 6, 4: 8}
1530 self.assertMapIterEquals(it, matching_dict)
1531
1532 def testMapConstruction(self):
1533 msg = map_unittest_pb2.TestMap(map_int32_int32={1: 2, 3: 4})
1534 self.assertEqual(2, msg.map_int32_int32[1])
1535 self.assertEqual(4, msg.map_int32_int32[3])
1536
1537 msg = map_unittest_pb2.TestMap(
1538 map_int32_foreign_message={3: unittest_pb2.ForeignMessage(c=5)})
1539 self.assertEqual(5, msg.map_int32_foreign_message[3].c)
1540
1541 def testMapValidAfterFieldCleared(self):
1542 # Map needs to work even if field is cleared.
1543 # For the C++ implementation this tests the correctness of
1544 # ScalarMapContainer::Release()
1545 msg = map_unittest_pb2.TestMap()
1546 map = msg.map_int32_int32
1547
1548 map[2] = 4
1549 map[3] = 6
1550 map[4] = 8
1551
1552 msg.ClearField('map_int32_int32')
1553 matching_dict = {2: 4, 3: 6, 4: 8}
1554 self.assertMapIterEquals(map.iteritems(), matching_dict)
1555
1556 def testMapIterValidAfterFieldCleared(self):
1557 # Map iterator needs to work even if field is cleared.
1558 # For the C++ implementation this tests the correctness of
1559 # ScalarMapContainer::Release()
1560 msg = map_unittest_pb2.TestMap()
1561
1562 msg.map_int32_int32[2] = 4
1563 msg.map_int32_int32[3] = 6
1564 msg.map_int32_int32[4] = 8
1565
1566 it = msg.map_int32_int32.iteritems()
1567
1568 msg.ClearField('map_int32_int32')
1569 matching_dict = {2: 4, 3: 6, 4: 8}
1570 self.assertMapIterEquals(it, matching_dict)
1571
1572 def testMapDelete(self):
1573 msg = map_unittest_pb2.TestMap()
1574
1575 self.assertEqual(0, len(msg.map_int32_int32))
1576
1577 msg.map_int32_int32[4] = 6
1578 self.assertEqual(1, len(msg.map_int32_int32))
1579
1580 with self.assertRaises(KeyError):
1581 del msg.map_int32_int32[88]
1582
1583 del msg.map_int32_int32[4]
1584 self.assertEqual(0, len(msg.map_int32_int32))
1585
1586
1587
1588 class ValidTypeNamesTest(unittest.TestCase):
1589
1590 def assertImportFromName(self, msg, base_name):
1591 # Parse <type 'module.class_name'> to extra 'some.name' as a string.
1592 tp_name = str(type(msg)).split("'")[1]
1593 valid_names = ('Repeated%sContainer' % base_name,
1594 'Repeated%sFieldContainer' % base_name)
1595 self.assertTrue(any(tp_name.endswith(v) for v in valid_names),
1596 '%r does end with any of %r' % (tp_name, valid_names))
1597
1598 parts = tp_name.split('.')
1599 class_name = parts[-1]
1600 module_name = '.'.join(parts[:-1])
1601 __import__(module_name, fromlist=[class_name])
1602
1603 def testTypeNamesCanBeImported(self):
1604 # If import doesn't work, pickling won't work either.
1605 pb = unittest_pb2.TestAllTypes()
1606 self.assertImportFromName(pb.repeated_int32, 'Scalar')
1607 self.assertImportFromName(pb.repeated_nested_message, 'Composite')
491 1608
492 1609
493 if __name__ == '__main__': 1610 if __name__ == '__main__':
494 unittest.main() 1611 unittest.main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698