summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorptmcg <ptmcg@9bf210a0-9d2d-494c-87cf-cfb32e7dff7b>2015-11-10 01:06:19 +0000
committerptmcg <ptmcg@9bf210a0-9d2d-494c-87cf-cfb32e7dff7b>2015-11-10 01:06:19 +0000
commit13cb75b6313b67b0aee7fa0e32cd6527c0a23f0f (patch)
treed0a3292de09a1656c4975ca6f0d3b35f79cf8905
parente34e6dc341fed963fc3d455987194d6ce5635b1f (diff)
downloadpyparsing-13cb75b6313b67b0aee7fa0e32cd6527c0a23f0f.tar.gz
Fix bug in Each when containing an Optional that has a results name or parse action
git-svn-id: svn://svn.code.sf.net/p/pyparsing/code/trunk@299 9bf210a0-9d2d-494c-87cf-cfb32e7dff7b
-rw-r--r--src/CHANGES3
-rw-r--r--src/pyparsing.py5
-rw-r--r--src/unitTests.py10
3 files changed, 15 insertions, 3 deletions
diff --git a/src/CHANGES b/src/CHANGES
index dc1fcef..2536be0 100644
--- a/src/CHANGES
+++ b/src/CHANGES
@@ -7,6 +7,9 @@ Version 2.0.6 -
- Fixed a bug in Each when multiple Optional elements are present.
Thanks for reporting this, whereswalden on SO.
+- Fixed another bug in Each, when Optional elements have results names
+ or parse actions, reported by Max Rothman - thank you, Max!
+
- Added optional parseAll argument to runTests, whether tests should
require the entire input string to be parsed or not (similar to
parseAll argument to parseString). Plus a little neaten-up of the
diff --git a/src/pyparsing.py b/src/pyparsing.py
index 1bbd510..3e02dbe 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.0.6"
-__versionTime__ = "4 Nov 2015 02:26"
+__versionTime__ = "9 Nov 2015 19:03"
__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
import string
@@ -2575,6 +2575,7 @@ class Each(ParseExpression):
def parseImpl( self, instring, loc, doActions=True ):
if self.initExprGroups:
+ self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional))
opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ]
opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)]
self.optionals = opt1 + opt2
@@ -2598,7 +2599,7 @@ class Each(ParseExpression):
except ParseException:
failed.append(e)
else:
- matchOrder.append(e)
+ matchOrder.append(self.opt1map.get(id(e),e))
if e in tmpReqd:
tmpReqd.remove(e)
elif e in tmpOpt:
diff --git a/src/unitTests.py b/src/unitTests.py
index 947d441..520423d 100644
--- a/src/unitTests.py
+++ b/src/unitTests.py
@@ -2289,6 +2289,13 @@ class PatientOrTest(ParseTestCase):
failed = False
assert not failed, "invalid logic in Or, fails on longest match with exception in parse action"
+class EachWithOptionalWithResultsNameTest(ParseTestCase):
+ def runTest(self):
+ from pyparsing import Optional
+
+ result = (Optional('foo')('one') & Optional('bar')('two')).parseString('bar foo')
+ print_(result.dump())
+ assert sorted(result.keys()) == ['one','two']
class MiscellaneousParserTests(ParseTestCase):
def runTest(self):
@@ -2523,7 +2530,8 @@ def makeTestSuiteTemp():
#~ suite.addTest( LocatedExprTest() )
#~ suite.addTest( AddConditionTest() )
#~ suite.addTest( WithAttributeParseActionTest() )
- suite.addTest( PatientOrTest() )
+ #~ suite.addTest( PatientOrTest() )
+ suite.addTest( EachWithOptionalWithResultsNameTest() )
return suite