protobuf 5.29.0rc3__py3-none-any.whl → 6.33.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of protobuf might be problematic. Click here for more details.

Files changed (45) hide show
  1. google/protobuf/__init__.py +1 -1
  2. google/protobuf/any.py +15 -1
  3. google/protobuf/any_pb2.py +5 -5
  4. google/protobuf/api_pb2.py +15 -11
  5. google/protobuf/compiler/plugin_pb2.py +5 -5
  6. google/protobuf/descriptor.py +413 -248
  7. google/protobuf/descriptor_database.py +22 -4
  8. google/protobuf/descriptor_pb2.py +320 -120
  9. google/protobuf/descriptor_pool.py +31 -13
  10. google/protobuf/duration_pb2.py +5 -5
  11. google/protobuf/empty_pb2.py +5 -5
  12. google/protobuf/field_mask_pb2.py +5 -5
  13. google/protobuf/internal/api_implementation.py +0 -6
  14. google/protobuf/internal/builder.py +4 -3
  15. google/protobuf/internal/containers.py +13 -0
  16. google/protobuf/internal/decoder.py +163 -133
  17. google/protobuf/internal/extension_dict.py +3 -3
  18. google/protobuf/internal/field_mask.py +6 -4
  19. google/protobuf/internal/python_edition_defaults.py +1 -1
  20. google/protobuf/internal/python_message.py +86 -70
  21. google/protobuf/internal/testing_refleaks.py +11 -2
  22. google/protobuf/internal/type_checkers.py +52 -5
  23. google/protobuf/internal/well_known_types.py +63 -46
  24. google/protobuf/json_format.py +113 -71
  25. google/protobuf/message.py +26 -0
  26. google/protobuf/message_factory.py +16 -63
  27. google/protobuf/proto.py +38 -1
  28. google/protobuf/proto_text.py +129 -0
  29. google/protobuf/reflection.py +0 -49
  30. google/protobuf/runtime_version.py +9 -29
  31. google/protobuf/source_context_pb2.py +5 -5
  32. google/protobuf/struct_pb2.py +5 -5
  33. google/protobuf/symbol_database.py +0 -18
  34. google/protobuf/text_format.py +49 -29
  35. google/protobuf/timestamp_pb2.py +5 -5
  36. google/protobuf/type_pb2.py +5 -5
  37. google/protobuf/unknown_fields.py +3 -4
  38. google/protobuf/wrappers_pb2.py +5 -5
  39. {protobuf-5.29.0rc3.dist-info → protobuf-6.33.3.dist-info}/METADATA +3 -3
  40. protobuf-6.33.3.dist-info/RECORD +58 -0
  41. google/protobuf/internal/_parameterized.py +0 -420
  42. google/protobuf/service.py +0 -213
  43. protobuf-5.29.0rc3.dist-info/RECORD +0 -59
  44. {protobuf-5.29.0rc3.dist-info → protobuf-6.33.3.dist-info}/LICENSE +0 -0
  45. {protobuf-5.29.0rc3.dist-info → protobuf-6.33.3.dist-info}/WHEEL +0 -0
@@ -29,6 +29,7 @@ __author__ = 'robinson@google.com (Will Robinson)'
29
29
 
30
30
  import datetime
31
31
  from io import BytesIO
32
+ import math
32
33
  import struct
33
34
  import sys
34
35
  import warnings
@@ -255,7 +256,8 @@ def _IsMessageSetExtension(field):
255
256
  field.containing_type.has_options and
256
257
  field.containing_type.GetOptions().message_set_wire_format and
257
258
  field.type == _FieldDescriptor.TYPE_MESSAGE and
258
- field.label == _FieldDescriptor.LABEL_OPTIONAL)
259
+ not field.is_required and
260
+ not field.is_repeated)
259
261
 
260
262
 
261
263
  def _IsMapField(field):
@@ -268,7 +270,6 @@ def _IsMessageMapField(field):
268
270
  return value_type.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE
269
271
 
270
272
  def _AttachFieldHelpers(cls, field_descriptor):
271
- is_repeated = field_descriptor.label == _FieldDescriptor.LABEL_REPEATED
272
273
  field_descriptor._default_constructor = _DefaultValueConstructorForField(
273
274
  field_descriptor
274
275
  )
@@ -281,7 +282,9 @@ def _AttachFieldHelpers(cls, field_descriptor):
281
282
  type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], False
282
283
  )
283
284
 
284
- if is_repeated and wire_format.IsTypePackable(field_descriptor.type):
285
+ if field_descriptor.is_repeated and wire_format.IsTypePackable(
286
+ field_descriptor.type
287
+ ):
285
288
  # To support wire compatibility of adding packed = true, add a decoder for
286
289
  # packed values regardless of the field's options.
287
290
  AddFieldByTag(wire_format.WIRETYPE_LENGTH_DELIMITED, True)
@@ -290,7 +293,7 @@ def _AttachFieldHelpers(cls, field_descriptor):
290
293
  def _MaybeAddEncoder(cls, field_descriptor):
291
294
  if hasattr(field_descriptor, '_encoder'):
292
295
  return
293
- is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED)
296
+ is_repeated = field_descriptor.is_repeated
294
297
  is_map_entry = _IsMapField(field_descriptor)
295
298
  is_packed = field_descriptor.is_packed
296
299
 
@@ -315,7 +318,7 @@ def _MaybeAddDecoder(cls, field_descriptor):
315
318
  if hasattr(field_descriptor, '_decoders'):
316
319
  return
317
320
 
318
- is_repeated = field_descriptor.label == _FieldDescriptor.LABEL_REPEATED
321
+ is_repeated = field_descriptor.is_repeated
319
322
  is_map_entry = _IsMapField(field_descriptor)
320
323
  helper_decoders = {}
321
324
 
@@ -386,7 +389,7 @@ def _AddEnumValues(descriptor, cls):
386
389
 
387
390
 
388
391
  def _GetInitializeDefaultForMap(field):
389
- if field.label != _FieldDescriptor.LABEL_REPEATED:
392
+ if not field.is_repeated:
390
393
  raise ValueError('map_entry set on non-repeated field %s' % (
391
394
  field.name))
392
395
  fields_by_name = field.message_type.fields_by_name
@@ -424,7 +427,7 @@ def _DefaultValueConstructorForField(field):
424
427
  if _IsMapField(field):
425
428
  return _GetInitializeDefaultForMap(field)
426
429
 
427
- if field.label == _FieldDescriptor.LABEL_REPEATED:
430
+ if field.is_repeated:
428
431
  if field.has_default_value and field.default_value != []:
429
432
  raise ValueError('Repeated field default value not empty list: %s' % (
430
433
  field.default_value))
@@ -495,6 +498,35 @@ def _AddInitMethod(message_descriptor, cls):
495
498
  return value
496
499
 
497
500
  def init(self, **kwargs):
501
+
502
+ def init_wkt_or_merge(field, msg, value):
503
+ if isinstance(value, message_mod.Message):
504
+ msg.MergeFrom(value)
505
+ elif (
506
+ isinstance(value, dict)
507
+ and field.message_type.full_name == _StructFullTypeName
508
+ ):
509
+ msg.Clear()
510
+ if len(value) == 1 and 'fields' in value:
511
+ try:
512
+ msg.update(value)
513
+ except:
514
+ msg.Clear()
515
+ msg.__init__(**value)
516
+ else:
517
+ msg.update(value)
518
+ elif hasattr(msg, '_internal_assign'):
519
+ msg._internal_assign(value)
520
+ else:
521
+ raise TypeError(
522
+ 'Message field {0}.{1} must be initialized with a '
523
+ 'dict or instance of same class, got {2}.'.format(
524
+ message_descriptor.name,
525
+ field.name,
526
+ type(value).__name__,
527
+ )
528
+ )
529
+
498
530
  self._cached_byte_size = 0
499
531
  self._cached_byte_size_dirty = len(kwargs) > 0
500
532
  self._fields = {}
@@ -516,21 +548,28 @@ def _AddInitMethod(message_descriptor, cls):
516
548
  if field_value is None:
517
549
  # field=None is the same as no field at all.
518
550
  continue
519
- if field.label == _FieldDescriptor.LABEL_REPEATED:
551
+ if field.is_repeated:
520
552
  field_copy = field._default_constructor(self)
521
553
  if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite
522
554
  if _IsMapField(field):
523
555
  if _IsMessageMapField(field):
524
556
  for key in field_value:
525
- field_copy[key].MergeFrom(field_value[key])
557
+ item_value = field_value[key]
558
+ if isinstance(item_value, dict):
559
+ field_copy[key].__init__(**item_value)
560
+ else:
561
+ field_copy[key].MergeFrom(item_value)
526
562
  else:
527
563
  field_copy.update(field_value)
528
564
  else:
529
565
  for val in field_value:
530
- if isinstance(val, dict):
566
+ if isinstance(val, dict) and (
567
+ field.message_type.full_name != _StructFullTypeName
568
+ ):
531
569
  field_copy.add(**val)
532
570
  else:
533
- field_copy.add().MergeFrom(val)
571
+ new_msg = field_copy.add()
572
+ init_wkt_or_merge(field, new_msg, val)
534
573
  else: # Scalar
535
574
  if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM:
536
575
  field_value = [_GetIntegerEnumValue(field.enum_type, val)
@@ -539,38 +578,14 @@ def _AddInitMethod(message_descriptor, cls):
539
578
  self._fields[field] = field_copy
540
579
  elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
541
580
  field_copy = field._default_constructor(self)
542
- new_val = None
543
- if isinstance(field_value, message_mod.Message):
544
- new_val = field_value
545
- elif isinstance(field_value, dict):
546
- if field.message_type.full_name == _StructFullTypeName:
547
- field_copy.Clear()
548
- if len(field_value) == 1 and 'fields' in field_value:
549
- try:
550
- field_copy.update(field_value)
551
- except:
552
- # Fall back to init normal message field
553
- field_copy.Clear()
554
- new_val = field.message_type._concrete_class(**field_value)
555
- else:
556
- field_copy.update(field_value)
557
- else:
558
- new_val = field.message_type._concrete_class(**field_value)
559
- elif hasattr(field_copy, '_internal_assign'):
560
- field_copy._internal_assign(field_value)
581
+ if isinstance(field_value, dict) and (
582
+ field.message_type.full_name != _StructFullTypeName
583
+ ):
584
+ new_val = field.message_type._concrete_class(**field_value)
585
+ field_copy.MergeFrom(new_val)
561
586
  else:
562
- raise TypeError(
563
- 'Message field {0}.{1} must be initialized with a '
564
- 'dict or instance of same class, got {2}.'.format(
565
- message_descriptor.name,
566
- field_name,
567
- type(field_value).__name__,
568
- )
569
- )
570
-
571
- if new_val != None:
572
587
  try:
573
- field_copy.MergeFrom(new_val)
588
+ init_wkt_or_merge(field, field_copy, field_value)
574
589
  except TypeError:
575
590
  _ReraiseTypeErrorWithFieldName(message_descriptor.name, field_name)
576
591
  self._fields[field] = field_copy
@@ -631,7 +646,7 @@ def _AddPropertiesForField(field, cls):
631
646
  constant_name = field.name.upper() + '_FIELD_NUMBER'
632
647
  setattr(cls, constant_name, field.number)
633
648
 
634
- if field.label == _FieldDescriptor.LABEL_REPEATED:
649
+ if field.is_repeated:
635
650
  _AddPropertiesForRepeatedField(field, cls)
636
651
  elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
637
652
  _AddPropertiesForNonRepeatedCompositeField(field, cls)
@@ -716,14 +731,14 @@ def _AddPropertiesForNonRepeatedScalarField(field, cls):
716
731
 
717
732
  def field_setter(self, new_value):
718
733
  # pylint: disable=protected-access
719
- # Testing the value for truthiness captures all of the proto3 defaults
720
- # (0, 0.0, enum 0, and False).
734
+ # Testing the value for truthiness captures all of the implicit presence
735
+ # defaults (0, 0.0, enum 0, and False), except for -0.0.
721
736
  try:
722
737
  new_value = type_checker.CheckValue(new_value)
723
738
  except TypeError as e:
724
739
  raise TypeError(
725
740
  'Cannot set %s to %.1024r: %s' % (field.full_name, new_value, e))
726
- if not field.has_presence and not new_value:
741
+ if not field.has_presence and decoder.IsDefaultScalarValue(new_value):
727
742
  self._fields.pop(field, None)
728
743
  else:
729
744
  self._fields[field] = new_value
@@ -822,6 +837,13 @@ def _AddPropertiesForExtensions(descriptor, cls):
822
837
  pool = descriptor.file.pool
823
838
 
824
839
  def _AddStaticMethods(cls):
840
+
841
+ def RegisterExtension(_):
842
+ """no-op to keep generated code <=4.23 working with new runtimes."""
843
+ # This was originally removed in 5.26 (cl/595989309).
844
+ pass
845
+
846
+ cls.RegisterExtension = staticmethod(RegisterExtension)
825
847
  def FromString(s):
826
848
  message = cls()
827
849
  message.MergeFromString(s)
@@ -833,7 +855,7 @@ def _IsPresent(item):
833
855
  """Given a (FieldDescriptor, value) tuple from _fields, return true if the
834
856
  value should be included in the list returned by ListFields()."""
835
857
 
836
- if item[0].label == _FieldDescriptor.LABEL_REPEATED:
858
+ if item[0].is_repeated:
837
859
  return bool(item[1])
838
860
  elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
839
861
  return item[1]._is_present_in_parent
@@ -857,7 +879,7 @@ def _AddHasFieldMethod(message_descriptor, cls):
857
879
 
858
880
  hassable_fields = {}
859
881
  for field in message_descriptor.fields:
860
- if field.label == _FieldDescriptor.LABEL_REPEATED:
882
+ if field.is_repeated:
861
883
  continue
862
884
  # For proto3, only submessages and fields inside a oneof have presence.
863
885
  if not field.has_presence:
@@ -945,7 +967,7 @@ def _AddHasExtensionMethod(cls):
945
967
  """Helper for _AddMessageMethods()."""
946
968
  def HasExtension(self, field_descriptor):
947
969
  extension_dict._VerifyExtensionHandle(self, field_descriptor)
948
- if field_descriptor.label == _FieldDescriptor.LABEL_REPEATED:
970
+ if field_descriptor.is_repeated:
949
971
  raise KeyError('"%s" is repeated.' % field_descriptor.full_name)
950
972
 
951
973
  if field_descriptor.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
@@ -1192,12 +1214,10 @@ def _AddMergeFromStringMethod(message_descriptor, cls):
1192
1214
  return length # Return this for legacy reasons.
1193
1215
  cls.MergeFromString = MergeFromString
1194
1216
 
1195
- local_ReadTag = decoder.ReadTag
1196
- local_SkipField = decoder.SkipField
1197
1217
  fields_by_tag = cls._fields_by_tag
1198
1218
  message_set_decoders_by_tag = cls._message_set_decoders_by_tag
1199
1219
 
1200
- def InternalParse(self, buffer, pos, end):
1220
+ def InternalParse(self, buffer, pos, end, current_depth=0):
1201
1221
  """Create a message from serialized bytes.
1202
1222
 
1203
1223
  Args:
@@ -1215,7 +1235,7 @@ def _AddMergeFromStringMethod(message_descriptor, cls):
1215
1235
  self._Modified()
1216
1236
  field_dict = self._fields
1217
1237
  while pos != end:
1218
- (tag_bytes, new_pos) = local_ReadTag(buffer, pos)
1238
+ (tag_bytes, new_pos) = decoder.ReadTag(buffer, pos)
1219
1239
  field_decoder, field_des = message_set_decoders_by_tag.get(
1220
1240
  tag_bytes, (None, None)
1221
1241
  )
@@ -1226,31 +1246,28 @@ def _AddMergeFromStringMethod(message_descriptor, cls):
1226
1246
  if field_des is None:
1227
1247
  if not self._unknown_fields: # pylint: disable=protected-access
1228
1248
  self._unknown_fields = [] # pylint: disable=protected-access
1229
- # pylint: disable=protected-access
1230
- (tag, _) = decoder._DecodeVarint(tag_bytes, 0)
1231
- field_number, wire_type = wire_format.UnpackTag(tag)
1249
+ field_number, wire_type = decoder.DecodeTag(tag_bytes)
1232
1250
  if field_number == 0:
1233
1251
  raise message_mod.DecodeError('Field number 0 is illegal.')
1234
- # TODO: remove old_pos.
1235
- old_pos = new_pos
1236
1252
  (data, new_pos) = decoder._DecodeUnknownField(
1237
- buffer, new_pos, wire_type) # pylint: disable=protected-access
1238
- if new_pos == -1:
1239
- return pos
1240
- # TODO: remove _unknown_fields.
1241
- new_pos = local_SkipField(buffer, old_pos, end, tag_bytes)
1253
+ buffer, new_pos, end, field_number, wire_type
1254
+ ) # pylint: disable=protected-access
1242
1255
  if new_pos == -1:
1243
1256
  return pos
1244
1257
  self._unknown_fields.append(
1245
- (tag_bytes, buffer[old_pos:new_pos].tobytes()))
1258
+ (tag_bytes, buffer[pos + len(tag_bytes) : new_pos].tobytes())
1259
+ )
1246
1260
  pos = new_pos
1247
1261
  else:
1248
1262
  _MaybeAddDecoder(cls, field_des)
1249
1263
  field_decoder = field_des._decoders[is_packed]
1250
- pos = field_decoder(buffer, new_pos, end, self, field_dict)
1264
+ pos = field_decoder(
1265
+ buffer, new_pos, end, self, field_dict, current_depth
1266
+ )
1251
1267
  if field_des.containing_oneof:
1252
1268
  self._UpdateOneofState(field_des)
1253
1269
  return pos
1270
+
1254
1271
  cls._InternalParse = InternalParse
1255
1272
 
1256
1273
 
@@ -1259,7 +1276,7 @@ def _AddIsInitializedMethod(message_descriptor, cls):
1259
1276
  protocol message class."""
1260
1277
 
1261
1278
  required_fields = [field for field in message_descriptor.fields
1262
- if field.label == _FieldDescriptor.LABEL_REQUIRED]
1279
+ if field.is_required]
1263
1280
 
1264
1281
  def IsInitialized(self, errors=None):
1265
1282
  """Checks if all required fields of a message are set.
@@ -1284,7 +1301,7 @@ def _AddIsInitializedMethod(message_descriptor, cls):
1284
1301
 
1285
1302
  for field, value in list(self._fields.items()): # dict can change size!
1286
1303
  if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
1287
- if field.label == _FieldDescriptor.LABEL_REPEATED:
1304
+ if field.is_repeated:
1288
1305
  if (field.message_type._is_map_entry):
1289
1306
  continue
1290
1307
  for element in value:
@@ -1332,7 +1349,7 @@ def _AddIsInitializedMethod(message_descriptor, cls):
1332
1349
  else:
1333
1350
  # ScalarMaps can't have any initialization errors.
1334
1351
  pass
1335
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
1352
+ elif field.is_repeated:
1336
1353
  for i in range(len(value)):
1337
1354
  element = value[i]
1338
1355
  prefix = '%s[%d].' % (name, i)
@@ -1357,7 +1374,6 @@ def _FullyQualifiedClassName(klass):
1357
1374
 
1358
1375
 
1359
1376
  def _AddMergeFromMethod(cls):
1360
- LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED
1361
1377
  CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE
1362
1378
 
1363
1379
  def MergeFrom(self, msg):
@@ -1373,7 +1389,7 @@ def _AddMergeFromMethod(cls):
1373
1389
  fields = self._fields
1374
1390
 
1375
1391
  for field, value in msg._fields.items():
1376
- if field.label == LABEL_REPEATED:
1392
+ if field.is_repeated:
1377
1393
  field_value = fields.get(field)
1378
1394
  if field_value is None:
1379
1395
  # Construct a new object to represent this field.
@@ -1442,7 +1458,7 @@ def _DiscardUnknownFields(self):
1442
1458
  if _IsMessageMapField(field):
1443
1459
  for key in value:
1444
1460
  value[key].DiscardUnknownFields()
1445
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
1461
+ elif field.is_repeated:
1446
1462
  for sub_message in value:
1447
1463
  sub_message.DiscardUnknownFields()
1448
1464
  else:
@@ -37,6 +37,9 @@ class LocalTestResult(unittest.TestResult):
37
37
  def addSkip(self, test, reason):
38
38
  pass
39
39
 
40
+ def addDuration(self, test, duration):
41
+ pass
42
+
40
43
 
41
44
  class ReferenceLeakCheckerMixin(object):
42
45
  """A mixin class for TestCase, which checks reference counts."""
@@ -59,11 +62,13 @@ class ReferenceLeakCheckerMixin(object):
59
62
  super(ReferenceLeakCheckerMixin, self).run(result=result)
60
63
  super(ReferenceLeakCheckerMixin, self).run(result=result)
61
64
 
62
- oldrefcount = 0
63
65
  local_result = LocalTestResult(result)
64
66
  num_flakes = 0
65
-
66
67
  refcount_deltas = []
68
+
69
+ # Observe the refcount, then create oldrefcount which actually makes the
70
+ # refcount 1 higher than the recorded value immediately
71
+ oldrefcount = self._getRefcounts()
67
72
  while len(refcount_deltas) < self.NB_RUNS:
68
73
  oldrefcount = self._getRefcounts()
69
74
  super(ReferenceLeakCheckerMixin, self).run(result=local_result)
@@ -87,6 +92,10 @@ class ReferenceLeakCheckerMixin(object):
87
92
  result.addError(self, sys.exc_info())
88
93
 
89
94
  def _getRefcounts(self):
95
+ if hasattr(sys, "_clear_internal_caches"): # Since 3.13
96
+ sys._clear_internal_caches() # pylint: disable=protected-access
97
+ else:
98
+ sys._clear_type_cache() # pylint: disable=protected-access
90
99
  copyreg.dispatch_table.clear()
91
100
  copyreg.dispatch_table.update(self._saved_pickle_registry)
92
101
  # It is sometimes necessary to gc.collect() multiple times, to ensure
@@ -22,16 +22,20 @@ TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization
22
22
 
23
23
  __author__ = 'robinson@google.com (Will Robinson)'
24
24
 
25
- import struct
26
25
  import numbers
26
+ import struct
27
+ import warnings
27
28
 
29
+ from google.protobuf import descriptor
28
30
  from google.protobuf.internal import decoder
29
31
  from google.protobuf.internal import encoder
30
32
  from google.protobuf.internal import wire_format
31
- from google.protobuf import descriptor
32
33
 
33
34
  _FieldDescriptor = descriptor.FieldDescriptor
34
-
35
+ # TODO: Remove this warning count after 34.0
36
+ # Assign bool to int/enum warnings will print 100 times at most which should
37
+ # be enough for users to notice and do not cause timeout.
38
+ _BoolWarningCount = 100
35
39
 
36
40
  def TruncateToFourByteFloat(original):
37
41
  return struct.unpack('<f', struct.pack('<f', original))[0]
@@ -113,12 +117,21 @@ class BoolValueChecker(object):
113
117
  """Type checker used for bool fields."""
114
118
 
115
119
  def CheckValue(self, proposed_value):
116
- if not hasattr(proposed_value, '__index__') or (
117
- type(proposed_value).__module__ == 'numpy' and
120
+ if not hasattr(proposed_value, '__index__'):
121
+ # Under NumPy 2.3, numpy.bool does not have an __index__ method.
122
+ if (type(proposed_value).__module__ == 'numpy' and
123
+ type(proposed_value).__name__ == 'bool'):
124
+ return bool(proposed_value)
125
+ message = ('%.1024r has type %s, but expected one of: %s' %
126
+ (proposed_value, type(proposed_value), (bool, int)))
127
+ raise TypeError(message)
128
+
129
+ if (type(proposed_value).__module__ == 'numpy' and
118
130
  type(proposed_value).__name__ == 'ndarray'):
119
131
  message = ('%.1024r has type %s, but expected one of: %s' %
120
132
  (proposed_value, type(proposed_value), (bool, int)))
121
133
  raise TypeError(message)
134
+
122
135
  return bool(proposed_value)
123
136
 
124
137
  def DefaultValue(self):
@@ -132,6 +145,21 @@ class IntValueChecker(object):
132
145
  """Checker used for integer fields. Performs type-check and range check."""
133
146
 
134
147
  def CheckValue(self, proposed_value):
148
+ global _BoolWarningCount
149
+ if type(proposed_value) == bool and _BoolWarningCount > 0:
150
+ _BoolWarningCount -= 1
151
+ message = (
152
+ '%.1024r has type %s, but expected one of: %s. This warning '
153
+ 'will turn into error in 7.34.0, please fix it before that.'
154
+ % (
155
+ proposed_value,
156
+ type(proposed_value),
157
+ (int,),
158
+ )
159
+ )
160
+ # TODO: Raise errors in 2026 Q1 release
161
+ warnings.warn(message)
162
+
135
163
  if not hasattr(proposed_value, '__index__') or (
136
164
  type(proposed_value).__module__ == 'numpy' and
137
165
  type(proposed_value).__name__ == 'ndarray'):
@@ -158,6 +186,20 @@ class EnumValueChecker(object):
158
186
  self._enum_type = enum_type
159
187
 
160
188
  def CheckValue(self, proposed_value):
189
+ global _BoolWarningCount
190
+ if type(proposed_value) == bool and _BoolWarningCount > 0:
191
+ _BoolWarningCount -= 1
192
+ message = (
193
+ '%.1024r has type %s, but expected one of: %s. This warning '
194
+ 'will turn into error in 7.34.0, please fix it before that.'
195
+ % (
196
+ proposed_value,
197
+ type(proposed_value),
198
+ (int,),
199
+ )
200
+ )
201
+ # TODO: Raise errors in 2026 Q1 release
202
+ warnings.warn(message)
161
203
  if not isinstance(proposed_value, numbers.Integral):
162
204
  message = ('%.1024r has type %s, but expected one of: %s' %
163
205
  (proposed_value, type(proposed_value), (int,)))
@@ -231,6 +273,7 @@ class Uint64ValueChecker(IntValueChecker):
231
273
  # The max 4 bytes float is about 3.4028234663852886e+38
232
274
  _FLOAT_MAX = float.fromhex('0x1.fffffep+127')
233
275
  _FLOAT_MIN = -_FLOAT_MAX
276
+ _MAX_FLOAT_AS_DOUBLE_ROUNDED = 3.4028235677973366e38
234
277
  _INF = float('inf')
235
278
  _NEG_INF = float('-inf')
236
279
 
@@ -269,8 +312,12 @@ class FloatValueChecker(DoubleValueChecker):
269
312
  converted_value = super().CheckValue(proposed_value)
270
313
  # This inf rounding matches the C++ proto SafeDoubleToFloat logic.
271
314
  if converted_value > _FLOAT_MAX:
315
+ if converted_value <= _MAX_FLOAT_AS_DOUBLE_ROUNDED:
316
+ return _FLOAT_MAX
272
317
  return _INF
273
318
  if converted_value < _FLOAT_MIN:
319
+ if converted_value >= -_MAX_FLOAT_AS_DOUBLE_ROUNDED:
320
+ return _FLOAT_MIN
274
321
  return _NEG_INF
275
322
 
276
323
  return TruncateToFourByteFloat(converted_value)