diff options
author | ptmcg <ptmcg@austin.rr.com> | 2021-11-12 10:11:53 -0600 |
---|---|---|
committer | ptmcg <ptmcg@austin.rr.com> | 2021-11-12 10:11:53 -0600 |
commit | 16b766b97c9c144be8c3fad4fec00417728abfa6 (patch) | |
tree | 4a49acfc67c667d9527d2c467ce8243ad7059c94 | |
parent | b429eb6cda915fb89620cc103913d0faa1b8ef16 (diff) | |
download | pyparsing-git-16b766b97c9c144be8c3fad4fec00417728abfa6.tar.gz |
Add warning suppression detection for all diagnostic warningspyparsing_3.0.6
-rw-r--r-- | CHANGES | 6 | ||||
-rw-r--r-- | pyparsing/__init__.py | 2 | ||||
-rw-r--r-- | pyparsing/core.py | 59 | ||||
-rw-r--r-- | tests/test_unit.py | 61 |
4 files changed, 107 insertions, 21 deletions
@@ -4,8 +4,10 @@ Change Log Version 3.0.6 - --------------- -- Refactored warning suppression code to preserve internal results names, - which, while undocumented, had been adopted by some projects. +- Added `suppress_warning()` method to individually suppress a warning on a + specific ParserElement. Used to refactor `original_text_for` to preserve + internal results names, which, while undocumented, had been adopted by + some projects. - Fix bug when `delimited_list` was called with a str literal instead of a parse expression. diff --git a/pyparsing/__init__.py b/pyparsing/__init__.py index c3b86ad..288618f 100644 --- a/pyparsing/__init__.py +++ b/pyparsing/__init__.py @@ -126,7 +126,7 @@ class version_info(NamedTuple): __version_info__ = version_info(3, 0, 6, "final", 0) -__version_time__ = "12 Nov 2021 13:44 UTC" +__version_time__ = "12 Nov 2021 16:06 UTC" __version__ = __version_info__.__version__ __versionTime__ = __version_time__ __author__ = "Paul McGuire <ptmcg.gm+pyparsing@gmail.com>" diff --git a/pyparsing/core.py b/pyparsing/core.py index 39075d8..ff24eee 100644 --- a/pyparsing/core.py +++ b/pyparsing/core.py @@ -471,6 +471,18 @@ class ParserElement(ABC): self.suppress_warnings_ = [] def suppress_warning(self, warning_type: Diagnostics): + """ + Suppress warnings emitted for a particular diagnostic on this expression. + + Example:: + + base = pp.Forward() + base.suppress_warning(Diagnostics.warn_on_parse_using_empty_Forward) + + # statement would normally raise a warning, but is now suppressed + print(base.parseString("x")) + + """ self.suppress_warnings_.append(warning_type) return self @@ -3987,8 +3999,17 @@ class Or(ParseExpression): return "{" + " ^ ".join(str(e) for e in self.exprs) + "}" def _setResultsName(self, name, listAllMatches=False): - if __diag__.warn_multiple_tokens_in_named_alternation: - if any(isinstance(e, And) for e in self.exprs): + if ( + __diag__.warn_multiple_tokens_in_named_alternation + and Diagnostics.warn_multiple_tokens_in_named_alternation + not in self.suppress_warnings_ + ): + if any( + isinstance(e, And) + and Diagnostics.warn_multiple_tokens_in_named_alternation + not in e.suppress_warnings_ + for e in self.exprs + ): warnings.warn( "{}: setting results name {!r} on {} expression " "will return a list of all parsed tokens in an And alternative, " @@ -4087,8 +4108,17 @@ class MatchFirst(ParseExpression): return "{" + " | ".join(str(e) for e in self.exprs) + "}" def _setResultsName(self, name, listAllMatches=False): - if __diag__.warn_multiple_tokens_in_named_alternation: - if any(isinstance(e, And) for e in self.exprs): + if ( + __diag__.warn_multiple_tokens_in_named_alternation + and Diagnostics.warn_multiple_tokens_in_named_alternation + not in self.suppress_warnings_ + ): + if any( + isinstance(e, And) + and Diagnostics.warn_multiple_tokens_in_named_alternation + not in e.suppress_warnings_ + for e in self.exprs + ): warnings.warn( "{}: setting results name {!r} on {} expression " "will return a list of all parsed tokens in an And alternative, " @@ -5103,6 +5133,8 @@ class Forward(ParseElementEnhance): if ( __diag__.warn_on_match_first_with_lshift_operator and caller_line == self.lshift_line + and Diagnostics.warn_on_match_first_with_lshift_operator + not in self.suppress_warnings_ ): warnings.warn( "using '<<' operator with '|' is probably an error, use '<<='", @@ -5113,7 +5145,11 @@ class Forward(ParseElementEnhance): def __del__(self): # see if we are getting dropped because of '=' reassignment of var instead of '<<=' or '<<' - if self.expr is None and __diag__.warn_on_assignment_to_Forward: + if ( + self.expr is None + and __diag__.warn_on_assignment_to_Forward + and Diagnostics.warn_on_assignment_to_Forward not in self.suppress_warnings_ + ): warnings.warn_explicit( "Forward defined here but no expression attached later using '<<=' or '<<'", UserWarning, @@ -5122,7 +5158,12 @@ class Forward(ParseElementEnhance): ) def parseImpl(self, instring, loc, doActions=True): - if self.expr is None and __diag__.warn_on_parse_using_empty_Forward: + if ( + self.expr is None + and __diag__.warn_on_parse_using_empty_Forward + and Diagnostics.warn_on_parse_using_empty_Forward + not in self.suppress_warnings_ + ): # walk stack until parse_string, scan_string, search_string, or transform_string is found parse_fns = [ "parse_string", @@ -5259,7 +5300,11 @@ class Forward(ParseElementEnhance): return ret def _setResultsName(self, name, list_all_matches=False): - if __diag__.warn_name_set_on_empty_Forward: + if ( + __diag__.warn_name_set_on_empty_Forward + and Diagnostics.warn_name_set_on_empty_Forward + not in self.suppress_warnings_ + ): if self.expr is None: warnings.warn( "{}: setting results name {!r} on {} expression " diff --git a/tests/test_unit.py b/tests/test_unit.py index a3c9c07..4c41e7f 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -114,13 +114,13 @@ class TestCase(unittest.TestCase): @contextlib.contextmanager def assertDoesNotWarn(self, warning_type: type = UserWarning, msg: str = None): - if msg is None: - msg = "unexpected warning raised" with warnings.catch_warnings(record=True) as w: warnings.simplefilter("error") try: yield except Exception as e: + if msg is None: + msg = "unexpected warning {} raised".format(e) if isinstance(e, warning_type): self.fail("{}: {}".format(msg, e)) else: @@ -180,7 +180,7 @@ class Test01b_PyparsingUnitTestUtilitiesTests(TestCase): # test assertDoesNotWarn raises an AssertionError with self.assertRaises(AssertionError): with self.assertDoesNotWarn( - msg="failed to warn when naming an empty Forward expression", + msg="warned when parsing with an empty Forward expression warning was suppressed", ): base = pp.Forward() try: @@ -7409,6 +7409,11 @@ class Test02_WithoutPackrat(ppt.TestParseResultsAsserts, TestCase): ): expr = (expr_a | expr_b)("rexp") + with self.assertDoesNotWarn( + UserWarning, msg="warned when And within alternation warning was suppressed" + ): + expr = (expr_a | expr_b).suppress_warning(pp.Diagnostics.warn_multiple_tokens_in_named_alternation)("rexp") + success, report = expr.runTests( """ not the bird @@ -7470,6 +7475,11 @@ class Test02_WithoutPackrat(ppt.TestParseResultsAsserts, TestCase): ): expr = (expr_a ^ expr_b)("rexp") + with self.assertDoesNotWarn( + UserWarning, msg="warned when And within alternation warning was suppressed" + ): + expr = (expr_a ^ expr_b).suppress_warning(pp.Diagnostics.warn_multiple_tokens_in_named_alternation)("rexp") + expr.runTests( """\ not the bird @@ -7641,17 +7651,19 @@ class Test02_WithoutPackrat(ppt.TestParseResultsAsserts, TestCase): ): path = coord[...].setResultsName("path") - def testDontWarnUngroupedNamedTokensIfUngroupedNamesStartWithNOWARN(self): - """ - - warn_ungrouped_named_tokens_in_collection - flag to enable warnings when a results - name is defined on a containing expression with ungrouped subexpressions that also - have results names (default=True) - """ + with self.assertDoesNotWarn( + UserWarning, + msg="warned when named repetition of" + " ungrouped named expressions warning was suppressed", + ): + path = coord[...].suppress_warning(pp.Diagnostics.warn_ungrouped_named_tokens_in_collection).setResultsName("path") + + def testDontWarnUngroupedNamedTokensIfWarningSuppressed(self): with ppt.reset_pyparsing_context(): pp.enable_diag(pp.Diagnostics.warn_ungrouped_named_tokens_in_collection) with self.assertDoesNotWarn( - msg="raised {} warning inner names start with '_NOWARN'".format( + msg="raised {} warning when warn on ungrouped named tokens was suppressed (original_text_for)".format( pp.Diagnostics.warn_ungrouped_named_tokens_in_collection ) ): @@ -7681,6 +7693,12 @@ class Test02_WithoutPackrat(ppt.TestParseResultsAsserts, TestCase): ): base("x") + with self.assertDoesNotWarn( + UserWarning, + msg="warned when naming an empty Forward expression warning was suppressed", + ): + base.suppress_warning(pp.Diagnostics.warn_name_set_on_empty_Forward)("x") + def testWarnParsingEmptyForward(self): """ - warn_on_parse_using_empty_Forward - flag to enable warnings when a Forward @@ -7705,13 +7723,23 @@ class Test02_WithoutPackrat(ppt.TestParseResultsAsserts, TestCase): with self.assertWarns( UserWarning, - msg="failed to warn when naming an empty Forward expression", + msg="failed to warn when parsing using an empty Forward expression", ): try: print(base.parseString("x")) except ParseException as pe: pass + with self.assertDoesNotWarn( + UserWarning, + msg="warned when parsing using an empty Forward expression warning was suppressed", + ): + base.suppress_warning(pp.Diagnostics.warn_on_parse_using_empty_Forward) + try: + print(base.parseString("x")) + except ParseException as pe: + pass + def testWarnIncorrectAssignmentToForward(self): """ - warn_on_parse_using_empty_Forward - flag to enable warnings when a Forward @@ -7741,6 +7769,17 @@ class Test02_WithoutPackrat(ppt.TestParseResultsAsserts, TestCase): ): a_method() + def a_method(): + base = pp.Forward().suppress_warning(pp.Diagnostics.warn_on_assignment_to_Forward) + base = pp.Word(pp.alphas)[...] | "(" + base + ")" + + with self.assertDoesNotWarn( + UserWarning, + msg="warned when using '=' to assign expression to a Forward warning was suppressed", + ): + a_method() + + def testWarnOnMultipleStringArgsToOneOf(self): """ - warn_on_multiple_string_args_to_oneof - flag to enable warnings when oneOf is |