aboutsummaryrefslogtreecommitdiffstats
path: root/python/google/protobuf/text_format.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/google/protobuf/text_format.py')
-rwxr-xr-xpython/google/protobuf/text_format.py31
1 files changed, 27 insertions, 4 deletions
diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py
index 1cddce6..cc6ac90 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 = 1e10000 # overflows, thus will actually be infinity.
+_NAN = _INFINITY * 0
+
+
class ParseError(Exception):
"""Thrown in case of ASCII parsing error."""
@@ -149,6 +155,10 @@ def _MergeField(tokenizer, message):
name.append(tokenizer.ConsumeIdentifier())
name = '.'.join(name)
+ if not message_descriptor.is_extendable:
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Message type "%s" does not have extensions.' %
+ message_descriptor.full_name)
field = message.Extensions._FindExtensionByName(name)
if not field:
raise tokenizer.ParseErrorPreviousToken(
@@ -198,6 +208,7 @@ def _MergeField(tokenizer, message):
sub_message = message.Extensions[field]
else:
sub_message = getattr(message, field.name)
+ sub_message.SetInParent()
while not tokenizer.TryConsume(end_token):
if tokenizer.AtEnd():
@@ -293,7 +304,7 @@ class _Tokenizer(object):
'[a-zA-Z_][0-9a-zA-Z_+-]*|' # an identifier
'[0-9+-][0-9a-zA-Z_.+-]*|' # a number
'\"([^\"\n\\\\]|\\\\.)*(\"|\\\\?$)|' # a double-quoted string
- '\'([^\"\n\\\\]|\\\\.)*(\'|\\\\?$)') # a single-quoted string
+ '\'([^\'\n\\\\]|\\\\.)*(\'|\\\\?$)') # a single-quoted string
_IDENTIFIER = re.compile('\w+')
_INTEGER_CHECKERS = [type_checkers.Uint32ValueChecker(),
type_checkers.Int32ValueChecker(),
@@ -473,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)
@@ -525,6 +536,18 @@ class _Tokenizer(object):
Raises:
ParseError: If a byte array value couldn't be consumed.
"""
+ list = [self._ConsumeSingleByteString()]
+ while len(self.token) > 0 and self.token[0] in ('\'', '"'):
+ list.append(self._ConsumeSingleByteString())
+ return "".join(list)
+
+ def _ConsumeSingleByteString(self):
+ """Consume one token of a string literal.
+
+ String literals (whether bytes or text) can come in multiple adjacent
+ tokens which are automatically concatenated, like in C or Python. This
+ method only consumes one token.
+ """
text = self.token
if len(text) < 1 or text[0] not in ('\'', '"'):
raise self._ParseError('Exptected string.')