summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorptmcg <ptmcg@9bf210a0-9d2d-494c-87cf-cfb32e7dff7b>2016-02-06 20:04:48 +0000
committerptmcg <ptmcg@9bf210a0-9d2d-494c-87cf-cfb32e7dff7b>2016-02-06 20:04:48 +0000
commitd3c21497c5f9a3658658f37165ffa8e1f436e9fe (patch)
tree298bd4c1f17ee2b9949090f3d50cb88e57ec8e87 /src
parentd8ba11404b98487b806e7fac2ade880fdad76cda (diff)
downloadpyparsing-d3c21497c5f9a3658658f37165ffa8e1f436e9fe.tar.gz
Add support for pickling ParseResults with protocols 2 and higher (default protocol in Py3 is 3)
git-svn-id: svn://svn.code.sf.net/p/pyparsing/code/trunk@318 9bf210a0-9d2d-494c-87cf-cfb32e7dff7b
Diffstat (limited to 'src')
-rw-r--r--src/CHANGES7
-rw-r--r--src/pyparsing.py7
-rw-r--r--src/unitTests.py40
3 files changed, 49 insertions, 5 deletions
diff --git a/src/CHANGES b/src/CHANGES
index ff211a2..4fe0eda 100644
--- a/src/CHANGES
+++ b/src/CHANGES
@@ -13,6 +13,13 @@ Version 2.0.8 -
most recently to Michael Cohen, who sent in a proposed patch, and got
me to finally tackle this problem.
+- Added compatibility for pickle protocols 2-4 when pickling ParseResults.
+ In Python 2.x, protocol 0 was the default, and protocol 2 did not work.
+ In Python 3.x, protocol 3 is the default, so explicitly naming
+ protocol 0 or 1 was required to pickle ParseResults. With this release,
+ all protocols 0-4 are supported. Thanks for reporting this on StackOverflow,
+ Arne Wolframm, and for providing a nice simple test case!
+
- Added expression names for many internal and builtin expressions, to
reduce name and error message overhead during parsing.
diff --git a/src/pyparsing.py b/src/pyparsing.py
index f1f19c8..eaa99b3 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.8"
-__versionTime__ = "23 Jan 2016 01:33"
+__versionTime__ = "6 Feb 2016 13:47"
__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
import string
@@ -282,6 +282,8 @@ class ParseResults(object):
self.__name = None
self.__parent = None
self.__accumNames = {}
+ self.__asList = asList
+ self.__modal = modal
if isinstance(toklist, list):
self.__toklist = toklist[:]
elif isinstance(toklist, _generatorType):
@@ -688,6 +690,9 @@ class ParseResults(object):
else:
self.__parent = None
+ def __getnewargs__(self):
+ return self.__toklist, self.__name, self.__asList, self.__modal
+
def __dir__(self):
return (dir(type(self)) + list(self.keys()))
diff --git a/src/unitTests.py b/src/unitTests.py
index cf840eb..f38606b 100644
--- a/src/unitTests.py
+++ b/src/unitTests.py
@@ -1283,6 +1283,11 @@ class OperatorPrecedenceGrammarTest4(ParseTestCase):
print_(results)
assert str(results) == expected, "failed to match expected results, got '%s'" % str(results)
print_()
+
+class Greeting():
+ def __init__(self, toks):
+ self.salutation = toks[0]
+ self.greetee = toks[1]
class ParseResultsPickleTest(ParseTestCase):
@@ -1295,9 +1300,7 @@ class ParseResultsPickleTest(ParseTestCase):
print_(result.dump())
print_()
- # TODO - add support for protocols >= 2
- #~ for protocol in range(pickle.HIGHEST_PROTOCOL+1):
- for protocol in range(2):
+ for protocol in range(pickle.HIGHEST_PROTOCOL+1):
print_("Test pickle dump protocol", protocol)
try:
pickleString = pickle.dumps(result, protocol)
@@ -1311,6 +1314,35 @@ class ParseResultsPickleTest(ParseTestCase):
assert result.dump() == newresult.dump(), "Error pickling ParseResults object (protocol=%d)" % protocol
print_()
+ import pyparsing as pp
+ import pickle
+
+
+ word = pp.Word(pp.alphas+"'.")
+ salutation = pp.OneOrMore(word)
+ comma = pp.Literal(",")
+ greetee = pp.OneOrMore(word)
+ endpunc = pp.oneOf("! ?")
+ greeting = salutation + pp.Suppress(comma) + greetee + pp.Suppress(endpunc)
+ greeting.setParseAction(Greeting)
+
+ string = 'Good morning, Miss Crabtree!'
+
+ result = greeting.parseString(string)
+
+ for protocol in range(pickle.HIGHEST_PROTOCOL+1):
+ print_("Test pickle dump protocol", protocol)
+ pkl = "pickle_test_protocol_%d.pkl" % protocol
+ try:
+ pickleString = pickle.dumps(result, protocol)
+ except Exception as e:
+ print_("dumps exception:", e)
+ newresult = ParseResults([])
+ else:
+ newresult = pickle.loads(pickleString)
+ print_(newresult.dump())
+
+
class ParseResultsWithNamedTupleTest(ParseTestCase):
def runTest(self):
@@ -2627,7 +2659,7 @@ if console:
testRunner = TextTestRunner()
testRunner.run( makeTestSuite() )
- #~ testclass = TrimArityExceptionMaskingTest
+ #~ testclass = ParseResultsPickleTest
#~ if lp is None:
#~ testRunner.run( makeTestSuiteTemp(testclass) )
#~ else: