diff options
author | kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d> | 2009-12-23 02:01:01 +0000 |
---|---|---|
committer | kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d> | 2009-12-23 02:01:01 +0000 |
commit | d0047c43d955174d79a2df623dbb4007965252b5 (patch) | |
tree | 43b2b4dbffe90e2ca7b00da247c6a631484d0bde /python/google | |
parent | eef5f8396dd527c17ab7e419ca8781052031d05d (diff) | |
download | protobuf-d0047c43d955174d79a2df623dbb4007965252b5.tar.gz protobuf-d0047c43d955174d79a2df623dbb4007965252b5.tar.bz2 protobuf-d0047c43d955174d79a2df623dbb4007965252b5.zip |
In Python, avoid relying on float('inf') and float('nan') as these don't work on Windows with Python pre-2.6.
Diffstat (limited to 'python/google')
-rwxr-xr-x | python/google/protobuf/internal/generator_test.py | 27 | ||||
-rwxr-xr-x | python/google/protobuf/internal/text_format_test.py | 14 | ||||
-rwxr-xr-x | python/google/protobuf/text_format.py | 12 |
3 files changed, 42 insertions, 11 deletions
diff --git a/python/google/protobuf/internal/generator_test.py b/python/google/protobuf/internal/generator_test.py index dd27c9a3..78360b53 100755 --- a/python/google/protobuf/internal/generator_test.py +++ b/python/google/protobuf/internal/generator_test.py @@ -78,12 +78,27 @@ class GeneratorTest(unittest.TestCase): def testExtremeDefaultValues(self): message = unittest_pb2.TestExtremeDefaultValues() - self.assertEquals(float('inf'), message.inf_double) - self.assertEquals(float('-inf'), message.neg_inf_double) - self.assert_(message.nan_double != message.nan_double) - self.assertEquals(float('inf'), message.inf_float) - self.assertEquals(float('-inf'), message.neg_inf_float) - self.assert_(message.nan_float != message.nan_float) + + # Python pre-2.6 does not have isinf() or isnan() functions, so we have + # to provide our own. + def isnan(val): + # NaN is never equal to itself. + return val != val + def isinf(val): + # Infinity times zero equals NaN. + return not isnan(val) and isnan(val * 0) + + self.assertTrue(isinf(message.inf_double)) + self.assertTrue(message.inf_double > 0) + self.assertTrue(isinf(message.neg_inf_double)) + self.assertTrue(message.neg_inf_double < 0) + self.assertTrue(isnan(message.nan_double)) + + self.assertTrue(isinf(message.inf_float)) + self.assertTrue(message.inf_float > 0) + self.assertTrue(isinf(message.neg_inf_float)) + self.assertTrue(message.neg_inf_float < 0) + self.assertTrue(isnan(message.nan_float)) def testHasDefaultValues(self): desc = unittest_pb2.TestAllTypes.DESCRIPTOR diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py index 6d46f7e4..e0991cb1 100755 --- a/python/google/protobuf/internal/text_format_test.py +++ b/python/google/protobuf/internal/text_format_test.py @@ -325,10 +325,10 @@ class TokenizerTest(unittest.TestCase): '{', (tokenizer.ConsumeIdentifier, 'A'), ':', - (tokenizer.ConsumeFloat, float('inf')), + (tokenizer.ConsumeFloat, text_format._INFINITY), (tokenizer.ConsumeIdentifier, 'B'), ':', - (tokenizer.ConsumeFloat, float('-inf')), + (tokenizer.ConsumeFloat, -text_format._INFINITY), (tokenizer.ConsumeIdentifier, 'C'), ':', (tokenizer.ConsumeBool, True), @@ -413,6 +413,16 @@ class TokenizerTest(unittest.TestCase): tokenizer = text_format._Tokenizer(text) self.assertRaises(text_format.ParseError, tokenizer.ConsumeBool) + def testInfNan(self): + # Make sure our infinity and NaN definitions are sound. + self.assertEquals(float, type(text_format._INFINITY)) + self.assertEquals(float, type(text_format._NAN)) + self.assertTrue(text_format._NAN != text_format._NAN) + + inf_times_zero = text_format._INFINITY * 0 + self.assertTrue(inf_times_zero != inf_times_zero) + self.assertTrue(text_format._INFINITY > 0) + if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py index c5713b63..2def19c2 100755 --- a/python/google/protobuf/text_format.py +++ b/python/google/protobuf/text_format.py @@ -43,6 +43,12 @@ __all__ = [ 'MessageToString', 'PrintMessage', 'PrintField', 'PrintFieldValue', 'Merge' ] +# Infinity and NaN are not explicitly supported by Python pre-2.6, and +# float('inf') does not work on Windows (pre-2.6). +_INFINITY = float('1e10000') +_NAN = _INFINITY * 0 + + class ParseError(Exception): """Thrown in case of ASCII parsing error.""" @@ -478,12 +484,12 @@ class _Tokenizer(object): if re.match(self._FLOAT_INFINITY, text): self.NextToken() if text.startswith('-'): - return float('-inf') - return float('inf') + return -_INFINITY + return _INFINITY if re.match(self._FLOAT_NAN, text): self.NextToken() - return float('nan') + return _NAN try: result = float(text) |