Skip to content

Commit

Permalink
Fix Dict() bugfix to wrap tokenlist.as_dict() if self.resultsName
Browse files Browse the repository at this point in the history
  • Loading branch information
ptmcg committed Oct 29, 2021
1 parent 8bbc83e commit ae447cd
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGES
Expand Up @@ -4,6 +4,8 @@ Change Log

Version 3.0.4 -
---------------
- Fixed bug in which Dict classes did not correctly return tokens as nested
ParseResults, reported by and fix identified by Bu Sun Kim, many thanks!!!


Version 3.0.3 -
Expand Down
2 changes: 1 addition & 1 deletion pyparsing/core.py
Expand Up @@ -5414,7 +5414,7 @@ def postParse(self, instring, loc, tokenlist):
tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0], i)

if self._asPythonDict:
return tokenlist.as_dict()
return [tokenlist.as_dict()] if self.resultsName else tokenlist.as_dict()
else:
return [tokenlist] if self.resultsName else tokenlist

Expand Down
95 changes: 95 additions & 0 deletions tests/test_unit.py
Expand Up @@ -2914,6 +2914,101 @@ def testParseResultsExtendWithParseResults(self):
result1, expected, msg="issue with ParseResults.extend(ParseResults)"
)

def testParseResultsWithNestedNames(self):
from pyparsing import (
Dict,
Literal,
Group,
Optional,
Regex,
QuotedString,
oneOf,
Or,
CaselessKeyword,
ZeroOrMore,
)

RELATION_SYMBOLS = "= > < >= <= <> =="

def _set_info(string, location, tokens):
for t in tokens:
try:
t["_info_"] = (string, location)
except TypeError:
pass
tokens["_info_"] = (string, location)

def keywords(name):
words = "any all within encloses adj".split()
return Or(map(CaselessKeyword, words))

charString1 = Group(Regex(r'[^()=<>"/\s]+'))("identifier")
charString1.addParseAction(_set_info)
charString2 = Group(QuotedString('"', "\\"))("quoted")
charString2.addParseAction(_set_info)

term = Group(charString1 | charString2)
modifier_key = charString1

# relations
comparitor_symbol = oneOf(RELATION_SYMBOLS)
named_comparitors = keywords("comparitors")
comparitor = Group(comparitor_symbol | named_comparitors)("comparitor")
comparitor.addParseAction(_set_info)

def modifier_list1(key):
modifier = Dict(
Literal("/")
+ Group(modifier_key(key))("name")
+ Optional(comparitor_symbol("symbol") + term("value"))
)("modifier")
modifier.addParseAction(_set_info)
return ZeroOrMore(modifier)("modifier_list")

def modifier_list2(key):
modifier = Dict(
Literal("/")
+ Group(modifier_key(key))("name")
+ Optional(comparitor_symbol("symbol") + term("value")),
asdict=True,
)("modifier")
modifier.addParseAction(_set_info)
return ZeroOrMore(modifier)("modifier_list")

def modifier_list3(key):
modifier = Group( # this line is different from the others, must group to get results names
Dict(
Literal("/")
+ Group(modifier_key(key))("name")
+ Optional(comparitor_symbol("symbol") + term("value"))
)
)
modifier.addParseAction(_set_info)
return ZeroOrMore(modifier)("modifier_list")

def modifier_list4(key):
modifier = Dict(
Literal("/")
+ Group(modifier_key(key))("name")
+ Optional(comparitor_symbol("symbol") + term("value")),
asdict=True,
)
modifier.addParseAction(_set_info)
return ZeroOrMore(modifier)("modifier_list")

for modifier_list_fn in (
modifier_list1,
modifier_list2,
modifier_list3,
modifier_list4,
):
modifier_parser = modifier_list_fn("default")

result = modifier_parser.parseString("/respectaccents/ignoreaccents")
for r in result:
print(r)
print(r.get("_info_"))

def testParseResultsFromDict(self):
"""test helper classmethod ParseResults.from_dict()"""

Expand Down

0 comments on commit ae447cd

Please sign in to comment.