E57F Added name property setter, and enhanced set_name() to accept a None … · pyparsing/pyparsing@a9e7d47 · GitHub
[go: up one dir, main page]

Skip to content

Commit a9e7d47

Browse files
committed
Added name property setter, and enhanced set_name() to accept a None value to clear the name and the resulting error message
1 parent 0adebab commit a9e7d47

File tree

3 files changed

+51
-10
lines changed

3 files changed

+51
-10
lines changed

CHANGES

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ Version 3.1.3 - in development
1919
not themselves defined as `staticmethods`. When called using a `ParserElement` instance,
2020
this resulted in a `TypeError` exception. Reported by eylenburg (#548).
2121

22+
- To address a compatibility issue in RDFLib, added a property setter for the
23+
`ParserElement.name` property, to call ParserElement.set_name.
24+
25+
- Modified `ParserElement.set_name()` to accept a None value, to clear the defined
26+
name and corresponding error message for a `ParserElement`.
27+
2228
- Updated railroad diagram generation for `ZeroOrMore` and `OneOrMore` expressions with
2329
`stop_on` expressions, while investigating #558, reported by user Gu_f.
2430

pyparsing/core.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,9 +1881,14 @@ def _generateDefaultName(self) -> str:
18811881
Child classes must define this method, which defines how the ``default_name`` is set.
18821882
"""
18831883

1884-
def set_name(self, name: str) -> "ParserElement":
1884+
def set_name(self, name: typing.Optional[str]) -> "ParserElement":
18851885
"""
1886-
Define name for this expression, makes debugging and exception messages clearer.
1886+
Define name for this expression, makes debugging and exception messages clearer. If
1887+
`__diag__.enable_debug_on_named_expressions` is set to True, setting a name will also
1888+
enable debug for this expression.
1889+
1890+
If `name` is None, clears any custom name for this expression, and clears the
1891+
debug flag is it was enabled via `__diag__.enable_debug_on_named_expressions`.
18871892
18881893
Example::
18891894
@@ -1894,16 +1899,22 @@ def set_name(self, name: str) -> "ParserElement":
18941899
integer.parse_string("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1)
18951900
"""
18961901
self.customName = name
1897-
self.errmsg = f"Expected {self.name}"
1902+
self.errmsg = f"Expected {str(self)}"
1903+
18981904
if __diag__.enable_debug_on_named_expressions:
1899-
self.set_debug()
1905+
self.set_debug(name is not None)
1906+
19001907
return self
19011908

19021909
@property
19031910
def name(self) -> str:
19041911
# This will use a user-defined name if available, but otherwise defaults back to the auto-generated name
19051912
return self.customName if self.customName is not None else self.default_name
19061913

1914+
@name.setter
1915+
def name(self, new_name) -> None:
1916+
self.set_name(new_name)
1917+
19071918
def __str__(self) -> str:
19081919
return self.name
19091920

@@ -3580,7 +3591,7 @@ def __init__(self):
35803591
self.orig_whiteChars = set() | self.whiteChars
35813592
self.whiteChars.discard("\n")
35823593
self.skipper = Empty().set_whitespace_chars(self.whiteChars)
3583-
self.errmsg = "Expected start of line"
3594+
self.set_name("start of line")
35843595

35853596
def preParse(self, instring: str, loc: int) -> int:
35863597
if loc == 0:
@@ -3609,7 +3620,7 @@ def __init__(self):
36093620
super().__init__()
36103621
self.whiteChars.discard("\n")
36113622
self.set_whitespace_chars(self.whiteChars, copy_defaults=False)
3612-
self.errmsg = "Expected end of line"
3623+
self.set_name("end of line")
36133624

36143625
def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
36153626
if loc < len(instring):
@@ -3630,7 +3641,7 @@ class StringStart(PositionToken):
36303641

36313642
def __init__(self):
36323643
super().__init__()
3633-
self.errmsg = "Expected start of text"
3644+
self.set_name("start of text")
36343645

36353646
def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
36363647
# see if entire string up to here is just whitespace and ignoreables
@@ -3647,7 +3658,7 @@ class StringEnd(PositionToken):
36473658

36483659
def __init__(self):
36493660
super().__init__()
3650-
self.errmsg = "Expected end of text"
3661+
self.set_name("end of text")
36513662

36523663
def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
36533664
if loc < len(instring):
@@ -3674,7 +3685,7 @@ def __init__(self, word_chars: str = printables, *, wordChars: str = printables)
36743685
wordChars = word_chars if wordChars == printables else wordChars
36753686
super().__init__()
36763687
self.wordChars = set(wordChars)
3677-
self.errmsg = "Not at the start of a word"
3688+
self.set_name("start of a word")
36783689

36793690
def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
36803691
if loc != 0:
@@ -3700,7 +3711,7 @@ def __init__(self, word_chars: str = printables, *, wordChars: str = printables)
37003711
super().__init__()
37013712
self.wordChars = set(wordChars)
37023713
self.skipWhitespace = False
3703-
self.errmsg = "Not at the end of a word"
3714+
self.set_name("end of a word")
37043715

37053716
def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
37063717
instrlen = len(instring)
@@ -4519,6 +4530,8 @@ def parseImpl(self, instring, loc, do_actions=True):
45194530

45204531
try:
45214532
return self.expr._parse(instring, loc, do_actions, callPreParse=False)
4533+
except ParseSyntaxException:
4534+
raise
45224535
except ParseBaseException as pbe:
45234536
if not isinstance(self, Forward) or self.customName is not None:
45244537
if self.errmsg:

tests/test_unit.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2208,6 +2208,28 @@ def testRecursiveCombine(self):
22082208

22092209
self.assertParseResultsEquals(testVal, expected_list=expected)
22102210

2211+
def testSetNameToStrAndNone(self):
2212+
wd = pp.Word(pp.alphas)
2213+
with self.subTest():
2214+
self.assertEqual("W:(A-Za-z)", wd.name)
2215+
2216+
with self.subTest():
2217+
wd.set_name("test_word")
2218+
self.assertEqual("test_word", wd.name)
2219+
2220+
with self.subTest():
2221+
wd.set_name(None)
2222+
self.assertEqual("W:(A-Za-z)", wd.name)
2223+
2224+
# same tests but using name property setter
2225+
with self.subTest():
2226+
wd.name = "test_word"
2227+
self.assertEqual("test_word", wd.name)
2228+
2229+
with self.subTest():
2230+
wd.name = None
2231+
self.assertEqual("W:(A-Za-z)", wd.name)
2232+
22112233
def testCombineSetName(self):
22122234
ab = pp.Combine(
22132235
pp.Literal("a").set_name("AAA") | pp.Literal("b").set_name("BBB")

0 commit comments

Comments
 (0)
0