Skip to content

Commit

Permalink
Better exception messages for nested expressions; enhance assertRaise…
Browse files Browse the repository at this point in the history
…sParseException to yield internal context manager (which has exception attribute)
  • Loading branch information
ptmcg committed Feb 25, 2024
1 parent 5d48b2d commit a1b7aad
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
2 changes: 2 additions & 0 deletions pyparsing/helpers.py
Expand Up @@ -537,6 +537,8 @@ def nested_expr(
else:
ret <<= Group(Suppress(opener) + ZeroOrMore(ret | content) + Suppress(closer))
ret.set_name(f"nested {opener}{closer} expression")
# don't override error message from content expressions
ret.errmsg = None
return ret


Expand Down
8 changes: 4 additions & 4 deletions pyparsing/testing.py
Expand Up @@ -241,12 +241,12 @@ def assertRaisesParseException(
if expected_msg is not None:
if isinstance(expected_msg, str):
expected_msg = re.escape(expected_msg)
with self.assertRaisesRegex(exc_type, expected_msg, msg=msg):
yield
with self.assertRaisesRegex(exc_type, expected_msg, msg=msg) as ctx:
yield ctx

else:
with self.assertRaises(exc_type, msg=msg):
yield
with self.assertRaises(exc_type, msg=msg) as ctx:
yield ctx

@staticmethod
def with_line_numbers(
Expand Down
35 changes: 35 additions & 0 deletions tests/test_unit.py
Expand Up @@ -10040,6 +10040,41 @@ def testForwardExceptionText(self):
ff2 <<= wd
ff2.parse_string("123")

def testForwardExceptionText2(self):
"""
Test various expressions for error messages, under conditions in wrapped ParserElements
"""
v = "(omit closing paren"
w = "('omit closing quote)"

for s, expr, expected in (
(v, pp.nested_expr(), "Expected ')'"),
(v, pp.Combine(pp.nested_expr(), adjacent=False), "Expected ')'"),
(v, pp.QuotedString("(", endQuoteChar=")"), "Expected quoted string, starting with ( ending with ), found '('"),
(w, pp.nested_expr(content=pp.sgl_quoted_string), "Expected ')'"),
("", pp.nested_expr(), ""),
("", pp.Word("A"), ""),
):
print(repr(s))
print(expr)

with self.subTest("parse expr", expr=expr, s=s, expected=expected):
with self.assertRaisesParseException(expected_msg=expected) as ctx:
expr.parse_string(s, parse_all=True)
print(ctx.exception)

with self.subTest("parse expr[1, ...]", expr=expr, s=s, expected=expected):
with self.assertRaisesParseException(expected_msg=expected) as ctx:
expr[1, ...].parse_string(s, parse_all=True)
print(ctx.exception)

with self.subTest("parse DelimitedList(expr)", expr=expr, s=s, expected=expected):
with self.assertRaisesParseException(expected_msg=expected) as ctx:
pp.DelimitedList(expr).parse_string(s, parse_all=True)
print(ctx.exception)

print()

def testMiscellaneousExceptionBits(self):
pp.ParserElement.verbose_stacktrace = True

Expand Down

0 comments on commit a1b7aad

Please sign in to comment.