summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorptmcg <ptmcg@9bf210a0-9d2d-494c-87cf-cfb32e7dff7b>2016-03-06 18:14:08 +0000
committerptmcg <ptmcg@9bf210a0-9d2d-494c-87cf-cfb32e7dff7b>2016-03-06 18:14:08 +0000
commit09ad6b4f0deccf6ae60e697117e3b24fc9cfc513 (patch)
tree8a8f62bb07a0df5bf795210cba9363708ac8d325
parentd81f2cce3f16bc62a0dc9729137d0226ed446fa2 (diff)
downloadpyparsing-09ad6b4f0deccf6ae60e697117e3b24fc9cfc513.tar.gz
Fixed bug in ParseResults.toDict(), in which dict values were always converted to dicts, even if they were just unkeyed lists of tokens.
git-svn-id: svn://svn.code.sf.net/p/pyparsing/code/trunk@329 9bf210a0-9d2d-494c-87cf-cfb32e7dff7b
-rw-r--r--src/CHANGES4
-rw-r--r--src/pyparsing.py14
-rw-r--r--src/unitTests.py35
3 files changed, 51 insertions, 2 deletions
diff --git a/src/CHANGES b/src/CHANGES
index 580a2fb..f615f4d 100644
--- a/src/CHANGES
+++ b/src/CHANGES
@@ -6,6 +6,10 @@ Version 2.1.1 -
------------------------------
- Added support for assigning to ParseResults using slices.
+- Fixed bug in ParseResults.toDict(), in which dict values were always
+ converted to dicts, even if they were just unkeyed lists of tokens.
+ Reported on SO by Gerald Thibault, thanks Gerald!
+
- Fixed bug in SkipTo when using failOn, reported by robyschek, thanks!
- Fixed bug in Each introduced in 2.1.0, reported by AND patch and
diff --git a/src/pyparsing.py b/src/pyparsing.py
index 61bfc21..b1d5598 100644
--- a/src/pyparsing.py
+++ b/src/pyparsing.py
@@ -58,7 +58,7 @@ The pyparsing module handles some of the problems that are typically vexing when
"""
__version__ = "2.1.1"
-__versionTime__ = "23 Feb 2016 16:16"
+__versionTime__ = "5 Mar 2016 23:42"
__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
import string
@@ -541,7 +541,17 @@ class ParseResults(object):
item_fn = self.items
else:
item_fn = self.iteritems
- return dict((k,v.asDict()) if isinstance(v, ParseResults) else (k,v) for k,v in item_fn())
+
+ def toItem(obj):
+ if isinstance(obj, ParseResults):
+ if obj.haskeys():
+ return obj.asDict()
+ else:
+ return [toItem(v) for v in obj]
+ else:
+ return obj
+
+ return dict((k,toItem(v)) for k,v in item_fn())
def copy( self ):
"""Returns a new copy of a C{ParseResults} object."""
diff --git a/src/unitTests.py b/src/unitTests.py
index f31ceb9..07a0d72 100644
--- a/src/unitTests.py
+++ b/src/unitTests.py
@@ -2504,6 +2504,40 @@ class ZeroOrMoreStopTest(ParseTestCase):
expr = BEGIN + ZeroOrMore(body_word, stopOn=ender) + END
assert test == expr, "Did not successfully stop on ending expression %r" % ender
+class NestedAsDictTest(ParseTestCase):
+ def runTest(self):
+ from pyparsing import Literal, Forward, alphanums, Group, delimitedList, Dict, Word, Optional
+
+ equals = Literal("=").suppress()
+ lbracket = Literal("[").suppress()
+ rbracket = Literal("]").suppress()
+ lbrace = Literal("{").suppress()
+ rbrace = Literal("}").suppress()
+
+ value_dict = Forward()
+ value_list = Forward()
+ value_string = Word(alphanums + "@. ")
+
+ value = value_list ^ value_dict ^ value_string
+ values = Group(delimitedList(value, ","))
+ #~ values = delimitedList(value, ",").setParseAction(lambda toks: [toks.asList()])
+
+ value_list << lbracket + values + rbracket
+
+ identifier = Word(alphanums + "_.")
+
+ assignment = Group(identifier + equals + Optional(value))
+ assignments = Dict(delimitedList(assignment, ';'))
+ value_dict << lbrace + assignments + rbrace
+
+ response = assignments
+
+ rsp = 'username=goat; errors={username=[already taken, too short]}; empty_field='
+ result_dict = response.parseString(rsp).asDict()
+ print(result_dict)
+ assert result_dict['username'] == 'goat', "failed to process string in ParseResults correctly"
+ assert result_dict['errors']['username'] == ['already taken', 'too short'], "failed to process nested ParseResults correctly"
+
class MiscellaneousParserTests(ParseTestCase):
def runTest(self):
import pyparsing
@@ -2722,6 +2756,7 @@ def makeTestSuite():
suite.addTest( TrimArityExceptionMaskingTest() )
suite.addTest( OneOrMoreStopTest() )
suite.addTest( ZeroOrMoreStopTest() )
+ suite.addTest( NestedAsDictTest() )
suite.addTest( MiscellaneousParserTests() )
if TEST_USING_PACKRAT:
# retest using packrat parsing (disable those tests that aren't compatible)