From 99cee9263f4ab1117a179d475f9e24cdd956724a Mon Sep 17 00:00:00 2001 From: ptmcg Date: Thu, 8 Sep 2016 23:36:49 +0000 Subject: Fix Py3 bug in ParseResults.getName; fixed bug in Keyword and CaselessKeyword when using setDefaultKeywordChars. git-svn-id: svn://svn.code.sf.net/p/pyparsing/code/trunk@429 9bf210a0-9d2d-494c-87cf-cfb32e7dff7b --- src/CHANGES | 6 ++++++ src/pyparsing.py | 12 ++++++----- src/unitTests.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/src/CHANGES b/src/CHANGES index e32cc21..979b5c3 100644 --- a/src/CHANGES +++ b/src/CHANGES @@ -8,6 +8,9 @@ Version 2.1.9 - "close" matches, that is, strings with at most 'n' mismatching characters. +- Fixed bug in Keyword.setDefaultKeywordChars(), reported by Kobayashi + shinji - nice catch, thanks! + - Minor API change in pyparsing_common. Renamed some of the common expressions to PEP8 format (to be consistent with the other pyparsing_common expressions): @@ -30,6 +33,9 @@ Version 2.1.9 - small step - when pyparsing 3.0 comes around, everything will change to PEP8 snake case.) +- Fixed Python3 compatibility bug when using dict keys() and values() + in ParseResults.getName(). + Version 2.1.8 - ------------------------------ diff --git a/src/pyparsing.py b/src/pyparsing.py index 50ffe84..c8b317b 100644 --- a/src/pyparsing.py +++ b/src/pyparsing.py @@ -61,7 +61,7 @@ The pyparsing module handles some of the problems that are typically vexing when """ __version__ = "2.1.9" -__versionTime__ = "18 Aug 2016 13:32 UTC" +__versionTime__ = "08 Sep 2016 23:33 UTC" __author__ = "Paul McGuire " import string @@ -840,8 +840,8 @@ class ParseResults(object): return None elif (len(self) == 1 and len(self.__tokdict) == 1 and - self.__tokdict.values()[0][0][1] in (0,-1)): - return self.__tokdict.keys()[0] + next(iter(self.__tokdict.values()))[0][1] in (0,-1)): + return next(iter(self.__tokdict.keys())) else: return None @@ -2406,8 +2406,10 @@ class Keyword(Token): """ DEFAULT_KEYWORD_CHARS = alphanums+"_$" - def __init__( self, matchString, identChars=DEFAULT_KEYWORD_CHARS, caseless=False ): + def __init__( self, matchString, identChars=None, caseless=False ): super(Keyword,self).__init__() + if identChars is None: + identChars = Keyword.DEFAULT_KEYWORD_CHARS self.match = matchString self.matchLen = len(matchString) try: @@ -2482,7 +2484,7 @@ class CaselessKeyword(Keyword): (Contrast with example for L{CaselessLiteral}.) """ - def __init__( self, matchString, identChars=Keyword.DEFAULT_KEYWORD_CHARS ): + def __init__( self, matchString, identChars=None ): super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) def parseImpl( self, instring, loc, doActions=True ): diff --git a/src/unitTests.py b/src/unitTests.py index 0e09be9..7e57e2b 100644 --- a/src/unitTests.py +++ b/src/unitTests.py @@ -3138,7 +3138,61 @@ class CloseMatchTest(ParseTestCase): assert r[1].mismatches == exp, "fail CloseMatch between %r and %r" % (searchseq.sequence, r[0]) print(r[0], 'exc: %s' % r[1] if exp is None and isinstance(r[1], Exception) else ("no match", "match")[r[1].mismatches == exp]) - + +class DefaultKeywordCharsTest(ParseTestCase): + def runTest(self): + import pyparsing as pp + + try: + pp.Keyword("start").parseString("start1000") + except pp.ParseException: + pass + else: + assert False, "failed to fail on default keyword chars" + + try: + pp.Keyword("start", identChars=pp.alphas).parseString("start1000") + except pp.ParseException: + assert False, "failed to match keyword using updated keyword chars" + else: + pass + + save_kwd_chars = pp.Keyword.DEFAULT_KEYWORD_CHARS + pp.Keyword.setDefaultKeywordChars(pp.alphas) + try: + pp.Keyword("start").parseString("start1000") + except pp.ParseException: + assert False, "failed to match keyword using updated keyword chars" + else: + pass + + pp.Keyword.setDefaultKeywordChars(save_kwd_chars) + + try: + pp.CaselessKeyword("START").parseString("start1000") + except pp.ParseException: + pass + else: + assert False, "failed to fail on default keyword chars" + + try: + pp.CaselessKeyword("START", identChars=pp.alphas).parseString("start1000") + except pp.ParseException: + assert False, "failed to match keyword using updated keyword chars" + else: + pass + + pp.Keyword.setDefaultKeywordChars(pp.alphas) + try: + pp.CaselessKeyword("START").parseString("start1000") + except pp.ParseException: + assert False, "failed to match keyword using updated keyword chars" + else: + pass + + pp.Keyword.setDefaultKeywordChars(save_kwd_chars) + + class MiscellaneousParserTests(ParseTestCase): def runTest(self): import pyparsing @@ -3263,6 +3317,15 @@ class MiscellaneousParserTests(ParseTestCase): assert names==[None, 'B', 'B', 'A', 'B', 'B', 'A', 'B', 'C', 'B', 'A'], \ "failure in getting names for tokens" + from pyparsing import Keyword, Word, alphas, OneOrMore + IF,AND,BUT = map(Keyword, "if and but".split()) + ident = ~(IF | AND | BUT) + Word(alphas)("non-key") + scanner = OneOrMore(IF | AND | BUT | ident) + def getNameTester(s,l,t): + print(t, t.getName()) + ident.addParseAction(getNameTester) + scanner.parseString("lsjd sldkjf IF Saslkj AND lsdjf") + # test ParseResults.get() method if "H" in runtests: print_("verify behavior of ParseResults.get()") -- cgit v1.2.1