From e36ea59917ad0bfb499f3066ef477c1899259bd8 Mon Sep 17 00:00:00 2001 From: Anton Grbin Date: Tue, 19 Apr 2022 14:47:01 +0200 Subject: [PATCH 1/3] make it standalone --- python/google/protobuf/json_format.py | 39 ++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py index b3e85933e9609..a391f204473b6 100644 --- a/python/google/protobuf/json_format.py +++ b/python/google/protobuf/json_format.py @@ -43,6 +43,7 @@ __author__ = 'jieluo@google.com (Jie Luo)' +import ctypes import base64 from collections import OrderedDict import json @@ -51,7 +52,6 @@ import re import sys -from google.protobuf.internal import type_checkers from google.protobuf import descriptor from google.protobuf import symbol_database @@ -75,6 +75,37 @@ _VALID_EXTENSION_NAME = re.compile(r'\[[a-zA-Z0-9\._]*\]$') +# NOTE(anton): copied from internal/type_checkers.py to avoid having json_format.py depend on internal interface of the +# protobuf +# library. +# Depending on an internal protobuf interface can hurt us since we are forking this file in noom-contracts, and the +# version of the protobuf libary used on the client is under client's control. +# The other two imports in this file (descriptor and symbol_database) are part of the protobuf public interface, and +# there is less risk that this will change under us. +def TruncateToFourByteFloat(original): + return ctypes.c_float(original).value + + +# NOTE(anton): same comment from above TruncateToFourByteFloat applies here. +def ToShortestFloat(original): + """Returns the shortest float that has same value in wire.""" + # All 4 byte floats have between 6 and 9 significant digits, so we + # start with 6 as the lower bound. + # It has to be iterative because use '.9g' directly can not get rid + # of the noises for most values. For example if set a float_field=0.9 + # use '.9g' will print 0.899999976. + precision = 6 + rounded = float('{0:.{1}g}'.format(original, precision)) + while TruncateToFourByteFloat(rounded) != original: + precision += 1 + rounded = float('{0:.{1}g}'.format(original, precision)) + return rounded + +# NOTE(anton): same comment from above TruncateToFourByteFloat applies here. +_FLOAT_MAX = float.fromhex('0x1.fffffep+127') +_FLOAT_MIN = -_FLOAT_MAX + + class Error(Exception): """Top-level module error for json_format.""" @@ -308,7 +339,7 @@ def _FieldToJsonObject(self, field, value): if self.float_format: return float(format(value, self.float_format)) else: - return type_checkers.ToShortestFloat(value) + return ToShortestFloat(value) return value @@ -791,10 +822,10 @@ def _ConvertFloat(value, field): 'use quoted "-Infinity" instead.') if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT: # pylint: disable=protected-access - if value > type_checkers._FLOAT_MAX: + if value > _FLOAT_MAX: raise ParseError('Float value too large') # pylint: disable=protected-access - if value < type_checkers._FLOAT_MIN: + if value < _FLOAT_MIN: raise ParseError('Float value too small') if value == 'nan': raise ParseError('Couldn\'t parse float "nan", use "NaN" instead.') From 3878da28f18a950c90b55b72d480308452fe16d9 Mon Sep 17 00:00:00 2001 From: Anton Grbin Date: Tue, 19 Apr 2022 14:49:41 +0200 Subject: [PATCH 2/3] fix code spell --- python/google/protobuf/json_format.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py index a391f204473b6..9f569f50b7964 100644 --- a/python/google/protobuf/json_format.py +++ b/python/google/protobuf/json_format.py @@ -79,7 +79,7 @@ # protobuf # library. # Depending on an internal protobuf interface can hurt us since we are forking this file in noom-contracts, and the -# version of the protobuf libary used on the client is under client's control. +# version of the protobuf library used on the client is under client's control. # The other two imports in this file (descriptor and symbol_database) are part of the protobuf public interface, and # there is less risk that this will change under us. def TruncateToFourByteFloat(original): From 66eb2d983c268e2dd152a7c48557ca5115baeea7 Mon Sep 17 00:00:00 2001 From: Anton Grbin Date: Mon, 20 Jun 2022 17:17:32 +0200 Subject: [PATCH 3/3] address comments --- python/google/protobuf/json_format.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py index 9f569f50b7964..573cc0d3dec52 100644 --- a/python/google/protobuf/json_format.py +++ b/python/google/protobuf/json_format.py @@ -76,8 +76,7 @@ # NOTE(anton): copied from internal/type_checkers.py to avoid having json_format.py depend on internal interface of the -# protobuf -# library. +# protobuf library. # Depending on an internal protobuf interface can hurt us since we are forking this file in noom-contracts, and the # version of the protobuf library used on the client is under client's control. # The other two imports in this file (descriptor and symbol_database) are part of the protobuf public interface, and @@ -105,7 +104,6 @@ def ToShortestFloat(original): _FLOAT_MAX = float.fromhex('0x1.fffffep+127') _FLOAT_MIN = -_FLOAT_MAX - class Error(Exception): """Top-level module error for json_format."""