Skip to content

Commit

Permalink
Issue #350 - fixed whitespace skipping around White expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
ptmcg committed Jan 2, 2022
1 parent 30bd0f3 commit 1ccf846
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 10 deletions.
5 changes: 4 additions & 1 deletion CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ Version 3.0.7 -
or WordEnd instead of just taking the default value. Originally posted
as a question by Parag on StackOverflow, good catch!

- Fixed bug #350, in which White expressions could fail to match due to
unintended whitespace-skipping. Reported by Fu Hanxi, thank you!

- Fixed bug in ParserElement.run_tests where comments would be displayed
using with_line_numbers, even if with_line_numbers was set to False.
using with_line_numbers.

- Added optional "min" and "max" arguments to `delimited_list`. PR
submitted by Marius, thanks!
Expand Down
2 changes: 1 addition & 1 deletion pyparsing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def __repr__(self):


__version_info__ = version_info(3, 0, 7, "final", 0)
__version_time__ = "02 Jan 2022 22:04 UTC"
__version_time__ = "02 Jan 2022 22:56 UTC"
__version__ = __version_info__.__version__
__versionTime__ = __version_time__
__author__ = "Paul McGuire <[email protected]>"
Expand Down
23 changes: 15 additions & 8 deletions pyparsing/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3339,7 +3339,7 @@ def __init__(self, ws: str = " \t\r\n", min: int = 1, max: int = 0, exact: int =
super().__init__()
self.matchWhite = ws
self.set_whitespace_chars(
"".join(c for c in self.whiteChars if c not in self.matchWhite),
"".join(c for c in self.whiteStrs if c not in self.matchWhite),
copy_defaults=True,
)
# self.leave_whitespace()
Expand Down Expand Up @@ -3780,11 +3780,14 @@ def __init__(self, exprs_arg: IterableType[ParserElement], savelist: bool = True
super().__init__(exprs, savelist)
if self.exprs:
self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
self.set_whitespace_chars(
self.exprs[0].whiteChars,
copy_defaults=self.exprs[0].copyDefaultWhiteChars,
)
self.skipWhitespace = self.exprs[0].skipWhitespace
if not isinstance(self.exprs[0], White):
self.set_whitespace_chars(
self.exprs[0].whiteChars,
copy_defaults=self.exprs[0].copyDefaultWhiteChars,
)
self.skipWhitespace = self.exprs[0].skipWhitespace
else:
self.skipWhitespace = False
else:
self.mayReturnEmpty = True
self.callPreparse = True
Expand Down Expand Up @@ -3913,7 +3916,9 @@ def streamline(self) -> ParserElement:
if self.exprs:
self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
self.saveAsList = any(e.saveAsList for e in self.exprs)
self.skipWhitespace = all(e.skipWhitespace for e in self.exprs)
self.skipWhitespace = all(
e.skipWhitespace and not isinstance(e, White) for e in self.exprs
)
else:
self.saveAsList = False
return self
Expand Down Expand Up @@ -4069,7 +4074,9 @@ def streamline(self) -> ParserElement:
if self.exprs:
self.saveAsList = any(e.saveAsList for e in self.exprs)
self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
self.skipWhitespace = all(e.skipWhitespace for e in self.exprs)
self.skipWhitespace = all(
e.skipWhitespace and not isinstance(e, White) for e in self.exprs
)
else:
self.saveAsList = False
self.mayReturnEmpty = True
Expand Down
14 changes: 14 additions & 0 deletions tests/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,20 @@ def testScanStringWithOverlap(self):
msg="scanString with overlaps failed",
)

def testCombineWithResultsNames(self):
# test case reproducing Issue #350
from pyparsing import White, alphas, Word

parser = White(' \t').set_results_name('indent') + Word(alphas).set_results_name('word')
result = parser.parse_string(' test')
print(result.dump())
self.assertParseResultsEquals(result, [' ', 'test'], {'indent': ' ', 'word': 'test'})

parser = White(' \t') + Word(alphas).set_results_name('word')
result = parser.parse_string(' test')
print(result.dump())
self.assertParseResultsEquals(result, [' ', 'test'], {'word': 'test'})

def testTransformString(self):
make_int_with_commas = ppc.integer().addParseAction(
lambda t: "{:,}".format(t[0])
Expand Down

0 comments on commit 1ccf846

Please sign in to comment.