aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2024-09-15 00:01:34 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2024-09-15 00:09:43 +0300
commitaef4832c0a5e57f13a63b9248f32b61a7bd2b97a (patch)
tree62106da64d5eb602fffa2f86409deabe65658d19
parent616250021dbd2936aed9368d3c4044045fbb91c6 (diff)
downloadydb-aef4832c0a5e57f13a63b9248f32b61a7bd2b97a.tar.gz
Intermediate changes
commit_hash:ced60bdb33f400d18d13d42a274f9015c16b4ece
-rw-r--r--contrib/python/pyparsing/py3/.dist-info/METADATA2
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/__init__.py6
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/actions.py2
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/common.py23
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/core.py405
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/diagram/__init__.py45
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/exceptions.py3
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/helpers.py10
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/results.py16
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/unicode.py32
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/util.py2
-rw-r--r--contrib/python/pyparsing/py3/ya.make2
12 files changed, 324 insertions, 224 deletions
diff --git a/contrib/python/pyparsing/py3/.dist-info/METADATA b/contrib/python/pyparsing/py3/.dist-info/METADATA
index cac4d35d87..1aa7a1fc04 100644
--- a/contrib/python/pyparsing/py3/.dist-info/METADATA
+++ b/contrib/python/pyparsing/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pyparsing
-Version: 3.1.2
+Version: 3.1.4
Summary: pyparsing module - Classes and methods to define and execute parsing grammars
Author-email: Paul McGuire <ptmcg.gm+pyparsing@gmail.com>
Requires-Python: >=3.6.8
diff --git a/contrib/python/pyparsing/py3/pyparsing/__init__.py b/contrib/python/pyparsing/py3/pyparsing/__init__.py
index 79d8153ce3..a440cfbefa 100644
--- a/contrib/python/pyparsing/py3/pyparsing/__init__.py
+++ b/contrib/python/pyparsing/py3/pyparsing/__init__.py
@@ -120,8 +120,8 @@ class version_info(NamedTuple):
return f"{__name__}.{type(self).__name__}({', '.join('{}={!r}'.format(*nv) for nv in zip(self._fields, self))})"
-__version_info__ = version_info(3, 1, 2, "final", 1)
-__version_time__ = "06 Mar 2024 07:08 UTC"
+__version_info__ = version_info(3, 1, 4, "final", 1)
+__version_time__ = "25 Aug 2024 14:40 UTC"
__version__ = __version_info__.__version__
__versionTime__ = __version_time__
__author__ = "Paul McGuire <ptmcg.gm+pyparsing@gmail.com>"
@@ -143,7 +143,7 @@ from .common import (
_builtin_exprs as common_builtin_exprs,
)
-# define backward compat synonyms
+# Compatibility synonyms
if "pyparsing_unicode" not in globals():
pyparsing_unicode = unicode # type: ignore[misc]
if "pyparsing_common" not in globals():
diff --git a/contrib/python/pyparsing/py3/pyparsing/actions.py b/contrib/python/pyparsing/py3/pyparsing/actions.py
index ce51b3957c..1d2dce99e1 100644
--- a/contrib/python/pyparsing/py3/pyparsing/actions.py
+++ b/contrib/python/pyparsing/py3/pyparsing/actions.py
@@ -196,7 +196,7 @@ def with_class(classname, namespace=""):
return with_attribute(**{classattr: classname})
-# pre-PEP8 compatibility symbols
+# Compatibility synonyms
# fmt: off
replaceWith = replaced_by_pep8("replaceWith", replace_with)
removeQuotes = replaced_by_pep8("removeQuotes", remove_quotes)
diff --git a/contrib/python/pyparsing/py3/pyparsing/common.py b/contrib/python/pyparsing/py3/pyparsing/common.py
index 74faa46085..649aad0096 100644
--- a/contrib/python/pyparsing/py3/pyparsing/common.py
+++ b/contrib/python/pyparsing/py3/pyparsing/common.py
@@ -418,20 +418,15 @@ class pyparsing_common:
# fmt: on
# pre-PEP8 compatibility names
- convertToInteger = convert_to_integer
- """Deprecated - use :class:`convert_to_integer`"""
- convertToFloat = convert_to_float
- """Deprecated - use :class:`convert_to_float`"""
- convertToDate = convert_to_date
- """Deprecated - use :class:`convert_to_date`"""
- convertToDatetime = convert_to_datetime
- """Deprecated - use :class:`convert_to_datetime`"""
- stripHTMLTags = strip_html_tags
- """Deprecated - use :class:`strip_html_tags`"""
- upcaseTokens = upcase_tokens
- """Deprecated - use :class:`upcase_tokens`"""
- downcaseTokens = downcase_tokens
- """Deprecated - use :class:`downcase_tokens`"""
+ # fmt: off
+ convertToInteger = staticmethod(replaced_by_pep8("convertToInteger", convert_to_integer))
+ convertToFloat = staticmethod(replaced_by_pep8("convertToFloat", convert_to_float))
+ convertToDate = staticmethod(replaced_by_pep8("convertToDate", convert_to_date))
+ convertToDatetime = staticmethod(replaced_by_pep8("convertToDatetime", convert_to_datetime))
+ stripHTMLTags = staticmethod(replaced_by_pep8("stripHTMLTags", strip_html_tags))
+ upcaseTokens = staticmethod(replaced_by_pep8("upcaseTokens", upcase_tokens))
+ downcaseTokens = staticmethod(replaced_by_pep8("downcaseTokens", downcase_tokens))
+ # fmt: on
_builtin_exprs = [
diff --git a/contrib/python/pyparsing/py3/pyparsing/core.py b/contrib/python/pyparsing/py3/pyparsing/core.py
index b19d122160..cbe73c987a 100644
--- a/contrib/python/pyparsing/py3/pyparsing/core.py
+++ b/contrib/python/pyparsing/py3/pyparsing/core.py
@@ -53,6 +53,11 @@ from .unicode import pyparsing_unicode
_MAX_INT = sys.maxsize
str_type: Tuple[type, ...] = (str, bytes)
+if sys.version_info >= (3, 7):
+ _RePattern = re.Pattern
+else:
+ _RePattern = typing.Pattern
+
#
# Copyright (c) 2003-2022 Paul T. McGuire
#
@@ -218,19 +223,11 @@ if _should_enable_warnings(
# build list of single arg builtins, that can be used as parse actions
+# fmt: off
_single_arg_builtins = {
- sum,
- len,
- sorted,
- reversed,
- list,
- tuple,
- set,
- any,
- all,
- min,
- max,
+ sum, len, sorted, reversed, list, tuple, set, any, all, min, max
}
+# fmt: on
_generatorType = types.GeneratorType
ParseImplReturnType = Tuple[int, Any]
@@ -255,13 +252,13 @@ DebugSuccessAction = Callable[
DebugExceptionAction = Callable[[str, int, "ParserElement", Exception, bool], None]
-alphas = string.ascii_uppercase + string.ascii_lowercase
-identchars = pyparsing_unicode.Latin1.identchars
-identbodychars = pyparsing_unicode.Latin1.identbodychars
-nums = "0123456789"
-hexnums = nums + "ABCDEFabcdef"
-alphanums = alphas + nums
-printables = "".join([c for c in string.printable if c not in string.whitespace])
+alphas: str = string.ascii_uppercase + string.ascii_lowercase
+identchars: str = pyparsing_unicode.Latin1.identchars
+identbodychars: str = pyparsing_unicode.Latin1.identbodychars
+nums: str = "0123456789"
+hexnums: str = nums + "ABCDEFabcdef"
+alphanums: str = alphas + nums
+printables: str = "".join([c for c in string.printable if c not in string.whitespace])
_trim_arity_call_line: traceback.StackSummary = None # type: ignore[assignment]
@@ -280,7 +277,7 @@ def _trim_arity(func, max_limit=3):
# user's parse action 'func', so that we don't incur call penalty at parse time
# fmt: off
- LINE_DIFF = 7
+ LINE_DIFF = 9
# IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND
# THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!!
_trim_arity_call_line = (_trim_arity_call_line or traceback.extract_stack(limit=2)[-1])
@@ -288,6 +285,8 @@ def _trim_arity(func, max_limit=3):
def wrapper(*args):
nonlocal found_arity, limit
+ if found_arity:
+ return func(*args[limit:])
while 1:
try:
ret = func(*args[limit:])
@@ -476,7 +475,7 @@ class ParserElement(ABC):
self.streamlined = False
# optimize exception handling for subclasses that don't advance parse index
self.mayIndexError = True
- self.errmsg = ""
+ self.errmsg: Union[str, None] = ""
# mark results names as modal (report only last) or cumulative (list all)
self.modalResults = True
# custom debug actions
@@ -582,15 +581,15 @@ class ParserElement(ABC):
listAllMatches = listAllMatches or list_all_matches
return self._setResultsName(name, listAllMatches)
- def _setResultsName(self, name, listAllMatches=False):
+ def _setResultsName(self, name, list_all_matches=False) -> "ParserElement":
if name is None:
return self
newself = self.copy()
if name.endswith("*"):
name = name[:-1]
- listAllMatches = True
+ list_all_matches = True
newself.resultsName = name
- newself.modalResults = not listAllMatches
+ newself.modalResults = not list_all_matches
return newself
def set_break(self, break_flag: bool = True) -> "ParserElement":
@@ -602,12 +601,12 @@ class ParserElement(ABC):
if break_flag:
_parseMethod = self._parse
- def breaker(instring, loc, doActions=True, callPreParse=True):
+ def breaker(instring, loc, do_actions=True, callPreParse=True):
import pdb
# this call to pdb.set_trace() is intentional, not a checkin error
pdb.set_trace()
- return _parseMethod(instring, loc, doActions, callPreParse)
+ return _parseMethod(instring, loc, do_actions, callPreParse)
breaker._originalParseMethod = _parseMethod # type: ignore [attr-defined]
self._parse = breaker # type: ignore [assignment]
@@ -615,7 +614,7 @@ class ParserElement(ABC):
self._parse = self._parse._originalParseMethod # type: ignore [attr-defined, assignment]
return self
- def set_parse_action(self, *fns: ParseAction, **kwargs) -> "ParserElement":
+ def set_parse_action(self, *fns: ParseAction, **kwargs: Any) -> "ParserElement":
"""
Define one or more actions to perform when successfully matching parse element definition.
@@ -691,19 +690,19 @@ class ParserElement(ABC):
''')
"""
if list(fns) == [None]:
- self.parseAction = []
+ self.parseAction.clear()
return self
if not all(callable(fn) for fn in fns):
raise TypeError("parse actions must be callable")
- self.parseAction = [_trim_arity(fn) for fn in fns]
+ self.parseAction[:] = [_trim_arity(fn) for fn in fns]
self.callDuringTry = kwargs.get(
"call_during_try", kwargs.get("callDuringTry", False)
)
return self
- def add_parse_action(self, *fns: ParseAction, **kwargs) -> "ParserElement":
+ def add_parse_action(self, *fns: ParseAction, **kwargs: Any) -> "ParserElement":
"""
Add one or more parse actions to expression's list of parse actions. See :class:`set_parse_action`.
@@ -715,7 +714,7 @@ class ParserElement(ABC):
)
return self
- def add_condition(self, *fns: ParseCondition, **kwargs) -> "ParserElement":
+ def add_condition(self, *fns: ParseCondition, **kwargs: Any) -> "ParserElement":
"""Add a boolean predicate function to expression's list of parse actions. See
:class:`set_parse_action` for function call signatures. Unlike ``set_parse_action``,
functions passed to ``add_condition`` need to return boolean success/fail of the condition.
@@ -801,7 +800,7 @@ class ParserElement(ABC):
return loc
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
return loc, []
def postParse(self, instring, loc, tokenlist):
@@ -809,10 +808,10 @@ class ParserElement(ABC):
# @profile
def _parseNoCache(
- self, instring, loc, doActions=True, callPreParse=True
+ self, instring, loc, do_actions=True, callPreParse=True
) -> Tuple[int, ParseResults]:
TRY, MATCH, FAIL = 0, 1, 2
- debugging = self.debug # and doActions)
+ debugging = self.debug # and do_actions)
len_instring = len(instring)
if debugging or self.failAction:
@@ -827,11 +826,11 @@ class ParserElement(ABC):
self.debugActions.debug_try(instring, tokens_start, self, False)
if self.mayIndexError or pre_loc >= len_instring:
try:
- loc, tokens = self.parseImpl(instring, pre_loc, doActions)
+ loc, tokens = self.parseImpl(instring, pre_loc, do_actions)
except IndexError:
raise ParseException(instring, len_instring, self.errmsg, self)
else:
- loc, tokens = self.parseImpl(instring, pre_loc, doActions)
+ loc, tokens = self.parseImpl(instring, pre_loc, do_actions)
except Exception as err:
# print("Exception raised:", err)
if self.debugActions.debug_fail:
@@ -849,18 +848,18 @@ class ParserElement(ABC):
tokens_start = pre_loc
if self.mayIndexError or pre_loc >= len_instring:
try:
- loc, tokens = self.parseImpl(instring, pre_loc, doActions)
+ loc, tokens = self.parseImpl(instring, pre_loc, do_actions)
except IndexError:
raise ParseException(instring, len_instring, self.errmsg, self)
else:
- loc, tokens = self.parseImpl(instring, pre_loc, doActions)
+ loc, tokens = self.parseImpl(instring, pre_loc, do_actions)
tokens = self.postParse(instring, loc, tokens)
ret_tokens = ParseResults(
tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults
)
- if self.parseAction and (doActions or self.callDuringTry):
+ if self.parseAction and (do_actions or self.callDuringTry):
if debugging:
try:
for fn in self.parseAction:
@@ -919,7 +918,7 @@ class ParserElement(ABC):
do_actions: bool = False,
) -> int:
try:
- return self._parse(instring, loc, doActions=do_actions)[0]
+ return self._parse(instring, loc, do_actions=do_actions)[0]
except ParseFatalException:
if raise_fatal:
raise
@@ -960,18 +959,18 @@ class ParserElement(ABC):
# this method gets repeatedly called during backtracking with the same arguments -
# we can cache these arguments and save ourselves the trouble of re-parsing the contained expression
def _parseCache(
- self, instring, loc, doActions=True, callPreParse=True
+ self, instring, loc, do_actions=True, callPreParse=True
) -> Tuple[int, ParseResults]:
HIT, MISS = 0, 1
TRY, MATCH, FAIL = 0, 1, 2
- lookup = (self, instring, loc, callPreParse, doActions)
+ lookup = (self, instring, loc, callPreParse, do_actions)
with ParserElement.packrat_cache_lock:
cache = ParserElement.packrat_cache
value = cache.get(lookup)
if value is cache.not_in_cache:
ParserElement.packrat_cache_stats[MISS] += 1
try:
- value = self._parseNoCache(instring, loc, doActions, callPreParse)
+ value = self._parseNoCache(instring, loc, do_actions, callPreParse)
except ParseBaseException as pe:
# cache a copy of the exception, without the traceback
cache.set(lookup, pe.__class__(*pe.args))
@@ -1190,7 +1189,7 @@ class ParserElement(ABC):
loc, tokens = self._parse(instring, 0)
if parseAll:
loc = self.preParse(instring, loc)
- se = Empty() + StringEnd()
+ se = Empty() + StringEnd().set_debug(False)
se._parse(instring, loc)
except ParseBaseException as exc:
if ParserElement.verbose_stacktrace:
@@ -1887,9 +1886,14 @@ class ParserElement(ABC):
Child classes must define this method, which defines how the ``default_name`` is set.
"""
- def set_name(self, name: str) -> "ParserElement":
+ def set_name(self, name: typing.Optional[str]) -> "ParserElement":
"""
- Define name for this expression, makes debugging and exception messages clearer.
+ Define name for this expression, makes debugging and exception messages clearer. If
+ `__diag__.enable_debug_on_named_expressions` is set to True, setting a name will also
+ enable debug for this expression.
+
+ If `name` is None, clears any custom name for this expression, and clears the
+ debug flag is it was enabled via `__diag__.enable_debug_on_named_expressions`.
Example::
@@ -1900,9 +1904,11 @@ class ParserElement(ABC):
integer.parse_string("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1)
"""
self.customName = name
- self.errmsg = f"Expected {self.name}"
+ self.errmsg = f"Expected {str(self)}"
+
if __diag__.enable_debug_on_named_expressions:
- self.set_debug()
+ self.set_debug(name is not None)
+
return self
@property
@@ -1910,6 +1916,10 @@ class ParserElement(ABC):
# This will use a user-defined name if available, but otherwise defaults back to the auto-generated name
return self.customName if self.customName is not None else self.default_name
+ @name.setter
+ def name(self, new_name) -> None:
+ self.set_name(new_name)
+
def __str__(self) -> str:
return self.name
@@ -2014,7 +2024,9 @@ class ParserElement(ABC):
full_dump: bool = True,
print_results: bool = True,
failure_tests: bool = False,
- post_parse: typing.Optional[Callable[[str, ParseResults], str]] = None,
+ post_parse: typing.Optional[
+ Callable[[str, ParseResults], typing.Optional[str]]
+ ] = None,
file: typing.Optional[TextIO] = None,
with_line_numbers: bool = False,
*,
@@ -2022,7 +2034,9 @@ class ParserElement(ABC):
fullDump: bool = True,
printResults: bool = True,
failureTests: bool = False,
- postParse: typing.Optional[Callable[[str, ParseResults], str]] = None,
+ postParse: typing.Optional[
+ Callable[[str, ParseResults], typing.Optional[str]]
+ ] = None,
) -> Tuple[bool, List[Tuple[str, Union[ParseResults, Exception]]]]:
"""
Execute the parse expression on a series of test strings, showing each
@@ -2159,7 +2173,7 @@ class ParserElement(ABC):
f"{nlstr}{nlstr.join(comments) if comments else ''}",
pyparsing_test.with_line_numbers(t) if with_line_numbers else t,
]
- comments = []
+ comments.clear()
try:
# convert newline marks to actual newlines, and strip leading BOM if present
t = NL.transform_string(t.lstrip(BOM))
@@ -2264,10 +2278,15 @@ class ParserElement(ABC):
# Compatibility synonyms
# fmt: off
- inlineLiteralsUsing = replaced_by_pep8("inlineLiteralsUsing", inline_literals_using)
- setDefaultWhitespaceChars = replaced_by_pep8(
+ inlineLiteralsUsing = staticmethod(replaced_by_pep8("inlineLiteralsUsing", inline_literals_using))
+ setDefaultWhitespaceChars = staticmethod(replaced_by_pep8(
"setDefaultWhitespaceChars", set_default_whitespace_chars
- )
+ ))
+ disableMemoization = staticmethod(replaced_by_pep8("disableMemoization", disable_memoization))
+ enableLeftRecursion = staticmethod(replaced_by_pep8("enableLeftRecursion", enable_left_recursion))
+ enablePackrat = staticmethod(replaced_by_pep8("enablePackrat", enable_packrat))
+ resetCache = staticmethod(replaced_by_pep8("resetCache", reset_cache))
+
setResultsName = replaced_by_pep8("setResultsName", set_results_name)
setBreak = replaced_by_pep8("setBreak", set_break)
setParseAction = replaced_by_pep8("setParseAction", set_parse_action)
@@ -2275,8 +2294,6 @@ class ParserElement(ABC):
addCondition = replaced_by_pep8("addCondition", add_condition)
setFailAction = replaced_by_pep8("setFailAction", set_fail_action)
tryParse = replaced_by_pep8("tryParse", try_parse)
- enableLeftRecursion = replaced_by_pep8("enableLeftRecursion", enable_left_recursion)
- enablePackrat = replaced_by_pep8("enablePackrat", enable_packrat)
parseString = replaced_by_pep8("parseString", parse_string)
scanString = replaced_by_pep8("scanString", scan_string)
transformString = replaced_by_pep8("transformString", transform_string)
@@ -2290,8 +2307,7 @@ class ParserElement(ABC):
setName = replaced_by_pep8("setName", set_name)
parseFile = replaced_by_pep8("parseFile", parse_file)
runTests = replaced_by_pep8("runTests", run_tests)
- canParseNext = can_parse_next
- resetCache = reset_cache
+ canParseNext = replaced_by_pep8("canParseNext", can_parse_next)
defaultName = default_name
# fmt: on
@@ -2331,7 +2347,7 @@ class _PendingSkip(ParserElement):
def __repr__(self):
return self.defaultName
- def parseImpl(self, *args):
+ def parseImpl(self, *args) -> ParseImplReturnType:
raise Exception(
"use of `...` expression without following SkipTo target expression"
)
@@ -2360,7 +2376,7 @@ class NoMatch(Token):
self.mayIndexError = False
self.errmsg = "Unmatchable token"
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
raise ParseException(instring, loc, self.errmsg, self)
@@ -2409,7 +2425,7 @@ class Literal(Token):
def _generateDefaultName(self) -> str:
return repr(self.match)
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
if instring[loc] == self.firstMatchChar and instring.startswith(
self.match, loc
):
@@ -2430,12 +2446,12 @@ class Empty(Literal):
def _generateDefaultName(self) -> str:
return "Empty"
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
return loc, []
class _SingleCharLiteral(Literal):
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
if instring[loc] == self.firstMatchChar:
return loc + 1, self.match
raise ParseException(instring, loc, self.errmsg, self)
@@ -2505,7 +2521,7 @@ class Keyword(Token):
def _generateDefaultName(self) -> str:
return repr(self.match)
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
errmsg = self.errmsg
errloc = loc
if self.caseless:
@@ -2556,7 +2572,10 @@ class Keyword(Token):
"""
Keyword.DEFAULT_KEYWORD_CHARS = chars
- setDefaultKeywordChars = set_default_keyword_chars
+ # Compatibility synonyms
+ setDefaultKeywordChars = staticmethod(
+ replaced_by_pep8("setDefaultKeywordChars", set_default_keyword_chars)
+ )
class CaselessLiteral(Literal):
@@ -2580,7 +2599,7 @@ class CaselessLiteral(Literal):
self.returnString = match_string
self.errmsg = f"Expected {self.name}"
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
if instring[loc : loc + self.matchLen].upper() == self.match:
return loc + self.matchLen, self.returnString
raise ParseException(instring, loc, self.errmsg, self)
@@ -2666,7 +2685,7 @@ class CloseMatch(Token):
def _generateDefaultName(self) -> str:
return f"{type(self).__name__}:{self.match_string!r}"
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
start = loc
instrlen = len(instring)
maxloc = start + len(self.match_string)
@@ -2911,36 +2930,36 @@ class Word(Token):
return base + f"{{{self.minLen},{self.maxLen}}}"
return base
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
if instring[loc] not in self.initChars:
raise ParseException(instring, loc, self.errmsg, self)
start = loc
loc += 1
instrlen = len(instring)
- bodychars = self.bodyChars
+ body_chars: set[str] = self.bodyChars
maxloc = start + self.maxLen
maxloc = min(maxloc, instrlen)
- while loc < maxloc and instring[loc] in bodychars:
+ while loc < maxloc and instring[loc] in body_chars:
loc += 1
- throwException = False
+ throw_exception = False
if loc - start < self.minLen:
- throwException = True
- elif self.maxSpecified and loc < instrlen and instring[loc] in bodychars:
- throwException = True
+ throw_exception = True
+ elif self.maxSpecified and loc < instrlen and instring[loc] in body_chars:
+ throw_exception = True
elif self.asKeyword and (
- (start > 0 and instring[start - 1] in bodychars)
- or (loc < instrlen and instring[loc] in bodychars)
+ (start > 0 and instring[start - 1] in body_chars)
+ or (loc < instrlen and instring[loc] in body_chars)
):
- throwException = True
+ throw_exception = True
- if throwException:
+ if throw_exception:
raise ParseException(instring, loc, self.errmsg, self)
return loc, instring[start:loc]
- def parseImpl_regex(self, instring, loc, doActions=True):
+ def parseImpl_regex(self, instring, loc, do_actions=True) -> ParseImplReturnType:
result = self.re_match(instring, loc)
if not result:
raise ParseException(instring, loc, self.errmsg, self)
@@ -3043,7 +3062,7 @@ class Regex(Token):
self.parseImpl = self.parseImplAsMatch # type: ignore [assignment]
@cached_property
- def re(self):
+ def re(self) -> _RePattern:
if self._re:
return self._re
@@ -3053,17 +3072,18 @@ class Regex(Token):
raise ValueError(f"invalid pattern ({self.pattern!r}) passed to Regex")
@cached_property
- def re_match(self):
+ def re_match(self) -> Callable[[str], Any]:
return self.re.match
@cached_property
- def mayReturnEmpty(self):
+ def mayReturnEmpty(self) -> bool:
return self.re_match("") is not None
def _generateDefaultName(self) -> str:
- return "Re:({})".format(repr(self.pattern).replace("\\\\", "\\"))
+ unescaped = self.pattern.replace("\\\\", "\\")
+ return f"Re:({unescaped!r})"
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
result = self.re_match(instring, loc)
if not result:
raise ParseException(instring, loc, self.errmsg, self)
@@ -3077,7 +3097,7 @@ class Regex(Token):
return loc, ret
- def parseImplAsGroupList(self, instring, loc, doActions=True):
+ def parseImplAsGroupList(self, instring, loc, do_actions=True):
result = self.re_match(instring, loc)
if not result:
raise ParseException(instring, loc, self.errmsg, self)
@@ -3086,7 +3106,7 @@ class Regex(Token):
ret = result.groups()
return loc, ret
- def parseImplAsMatch(self, instring, loc, doActions=True):
+ def parseImplAsMatch(self, instring, loc, do_actions=True):
result = self.re_match(instring, loc)
if not result:
raise ParseException(instring, loc, self.errmsg, self)
@@ -3223,7 +3243,7 @@ class QuotedString(Token):
# fmt: off
# build up re pattern for the content between the quote delimiters
- inner_pattern = []
+ inner_pattern: List[str] = []
if esc_quote:
inner_pattern.append(rf"(?:{re.escape(esc_quote)})")
@@ -3245,12 +3265,12 @@ class QuotedString(Token):
self.re_flags |= re.MULTILINE | re.DOTALL
inner_pattern.append(
rf"(?:[^{_escape_regex_range_chars(self.end_quote_char[0])}"
- rf"{(_escape_regex_range_chars(esc_char) if self.has_esc_char else '')}])"
+ rf"{(_escape_regex_range_chars(self.esc_char) if self.has_esc_char else '')}])"
)
else:
inner_pattern.append(
rf"(?:[^{_escape_regex_range_chars(self.end_quote_char[0])}\n\r"
- rf"{(_escape_regex_range_chars(esc_char) if self.has_esc_char else '')}])"
+ rf"{(_escape_regex_range_chars(self.esc_char) if self.has_esc_char else '')}])"
)
self.pattern = "".join(
@@ -3298,7 +3318,7 @@ class QuotedString(Token):
return f"quoted string, starting with {self.quote_char} ending with {self.end_quote_char}"
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
# check first character of opening quote to see if that is a match
# before doing the more complicated regex match
result = (
@@ -3412,7 +3432,7 @@ class CharsNotIn(Token):
else:
return f"!W:({self.notChars})"
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
notchars = self.notCharsSet
if instring[loc] in notchars:
raise ParseException(instring, loc, self.errmsg, self)
@@ -3490,7 +3510,7 @@ class White(Token):
def _generateDefaultName(self) -> str:
return "".join(White.whiteStrs[c] for c in self.matchWhite)
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
if instring[loc] not in self.matchWhite:
raise ParseException(instring, loc, self.errmsg, self)
start = loc
@@ -3538,7 +3558,7 @@ class GoToColumn(PositionToken):
return loc
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
thiscol = col(loc, instring)
if thiscol > self.col:
raise ParseException(instring, loc, "Text not in expected column", self)
@@ -3576,7 +3596,7 @@ class LineStart(PositionToken):
self.orig_whiteChars = set() | self.whiteChars
self.whiteChars.discard("\n")
self.skipper = Empty().set_whitespace_chars(self.whiteChars)
- self.errmsg = "Expected start of line"
+ self.set_name("start of line")
def preParse(self, instring: str, loc: int) -> int:
if loc == 0:
@@ -3590,7 +3610,7 @@ class LineStart(PositionToken):
return ret
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
if col(loc, instring) == 1:
return loc, []
raise ParseException(instring, loc, self.errmsg, self)
@@ -3605,9 +3625,9 @@ class LineEnd(PositionToken):
super().__init__()
self.whiteChars.discard("\n")
self.set_whitespace_chars(self.whiteChars, copy_defaults=False)
- self.errmsg = "Expected end of line"
+ self.set_name("end of line")
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
if loc < len(instring):
if instring[loc] == "\n":
return loc + 1, "\n"
@@ -3626,9 +3646,9 @@ class StringStart(PositionToken):
def __init__(self):
super().__init__()
- self.errmsg = "Expected start of text"
+ self.set_name("start of text")
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
# see if entire string up to here is just whitespace and ignoreables
if loc != 0 and loc != self.preParse(instring, 0):
raise ParseException(instring, loc, self.errmsg, self)
@@ -3643,9 +3663,9 @@ class StringEnd(PositionToken):
def __init__(self):
super().__init__()
- self.errmsg = "Expected end of text"
+ self.set_name("end of text")
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
if loc < len(instring):
raise ParseException(instring, loc, self.errmsg, self)
if loc == len(instring):
@@ -3670,9 +3690,9 @@ class WordStart(PositionToken):
wordChars = word_chars if wordChars == printables else wordChars
super().__init__()
self.wordChars = set(wordChars)
- self.errmsg = "Not at the start of a word"
+ self.set_name("start of a word")
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
if loc != 0:
if (
instring[loc - 1] in self.wordChars
@@ -3696,9 +3716,9 @@ class WordEnd(PositionToken):
super().__init__()
self.wordChars = set(wordChars)
self.skipWhitespace = False
- self.errmsg = "Not at the end of a word"
+ self.set_name("end of a word")
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
instrlen = len(instring)
if instrlen > 0 and loc < instrlen:
if (
@@ -3709,6 +3729,47 @@ class WordEnd(PositionToken):
return loc, []
+class Tag(Token):
+ """
+ A meta-element for inserting a named result into the parsed
+ tokens that may be checked later in a parse action or while
+ processing the parsed results. Accepts an optional tag value,
+ defaulting to `True`.
+
+ Example::
+
+ end_punc = "." | ("!" + Tag("enthusiastic")))
+ greeting = "Hello," + Word(alphas) + end_punc
+
+ result = greeting.parse_string("Hello, World.")
+ print(result.dump())
+
+ result = greeting.parse_string("Hello, World!")
+ print(result.dump())
+
+ prints::
+
+ ['Hello,', 'World', '.']
+
+ ['Hello,', 'World', '!']
+ - enthusiastic: True
+ """
+ def __init__(self, tag_name: str, value: Any = True):
+ super().__init__()
+ self.mayReturnEmpty = True
+ self.mayIndexError = False
+ self.leave_whitespace()
+ self.tag_name = tag_name
+ self.tag_value = value
+ self.add_parse_action(self._add_tag)
+
+ def _add_tag(self, tokens: ParseResults):
+ tokens[self.tag_name] = self.tag_value
+
+ def _generateDefaultName(self) -> str:
+ return f"{type(self).__name__}:{self.tag_name}={self.tag_value!r}"
+
+
class ParseExpression(ParserElement):
"""Abstract subclass of ParserElement, for combining and
post-processing parsed tokens.
@@ -3846,13 +3907,13 @@ class ParseExpression(ParserElement):
ret.exprs = [e.copy() for e in self.exprs]
return ret
- def _setResultsName(self, name, listAllMatches=False):
+ def _setResultsName(self, name, list_all_matches=False) -> ParserElement:
if not (
__diag__.warn_ungrouped_named_tokens_in_collection
and Diagnostics.warn_ungrouped_named_tokens_in_collection
not in self.suppress_warnings_
):
- return super()._setResultsName(name, listAllMatches)
+ return super()._setResultsName(name, list_all_matches)
for e in self.exprs:
if (
@@ -3871,7 +3932,7 @@ class ParseExpression(ParserElement):
warnings.warn(warning, stacklevel=3)
break
- return super()._setResultsName(name, listAllMatches)
+ return super()._setResultsName(name, list_all_matches)
# Compatibility synonyms
# fmt: off
@@ -3911,7 +3972,7 @@ class And(ParseExpression):
):
exprs: List[ParserElement] = list(exprs_arg)
if exprs and Ellipsis in exprs:
- tmp = []
+ tmp: List[ParserElement] = []
for i, expr in enumerate(exprs):
if expr is not Ellipsis:
tmp.append(expr)
@@ -3991,11 +4052,11 @@ class And(ParseExpression):
self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
return self
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True):
# pass False as callPreParse arg to _parse for first element, since we already
# pre-parsed the string as part of our And pre-parsing
loc, resultlist = self.exprs[0]._parse(
- instring, loc, doActions, callPreParse=False
+ instring, loc, do_actions, callPreParse=False
)
errorStop = False
for e in self.exprs[1:]:
@@ -4005,7 +4066,7 @@ class And(ParseExpression):
continue
if errorStop:
try:
- loc, exprtokens = e._parse(instring, loc, doActions)
+ loc, exprtokens = e._parse(instring, loc, do_actions)
except ParseSyntaxException:
raise
except ParseBaseException as pe:
@@ -4016,7 +4077,7 @@ class And(ParseExpression):
instring, len(instring), self.errmsg, self
)
else:
- loc, exprtokens = e._parse(instring, loc, doActions)
+ loc, exprtokens = e._parse(instring, loc, do_actions)
resultlist += exprtokens
return loc, resultlist
@@ -4080,11 +4141,11 @@ class Or(ParseExpression):
self.saveAsList = False
return self
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
maxExcLoc = -1
maxException = None
- matches = []
- fatals = []
+ matches: List[Tuple[int, ParserElement]] = []
+ fatals: List[ParseFatalException] = []
if all(e.callPreparse for e in self.exprs):
loc = self.preParse(instring, loc)
for e in self.exprs:
@@ -4117,11 +4178,11 @@ class Or(ParseExpression):
# might change whether or how much they match of the input.
matches.sort(key=itemgetter(0), reverse=True)
- if not doActions:
+ if not do_actions:
# no further conditions or parse actions to change the selection of
# alternative, so the first match will be the best match
best_expr = matches[0][1]
- return best_expr._parse(instring, loc, doActions)
+ return best_expr._parse(instring, loc, do_actions)
longest = -1, None
for loc1, expr1 in matches:
@@ -4130,7 +4191,7 @@ class Or(ParseExpression):
return longest
try:
- loc2, toks = expr1._parse(instring, loc, doActions)
+ loc2, toks = expr1._parse(instring, loc, do_actions)
except ParseException as err:
err.__traceback__ = None
if err.loc > maxExcLoc:
@@ -4173,7 +4234,7 @@ class Or(ParseExpression):
def _generateDefaultName(self) -> str:
return f"{{{' ^ '.join(str(e) for e in self.exprs)}}}"
- def _setResultsName(self, name, listAllMatches=False):
+ def _setResultsName(self, name, list_all_matches=False) -> ParserElement:
if (
__diag__.warn_multiple_tokens_in_named_alternation
and Diagnostics.warn_multiple_tokens_in_named_alternation
@@ -4194,7 +4255,7 @@ class Or(ParseExpression):
)
warnings.warn(warning, stacklevel=3)
- return super()._setResultsName(name, listAllMatches)
+ return super()._setResultsName(name, list_all_matches)
class MatchFirst(ParseExpression):
@@ -4239,13 +4300,13 @@ class MatchFirst(ParseExpression):
self.mayReturnEmpty = True
return self
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
maxExcLoc = -1
maxException = None
for e in self.exprs:
try:
- return e._parse(instring, loc, doActions)
+ return e._parse(instring, loc, do_actions)
except ParseFatalException as pfe:
pfe.__traceback__ = None
pfe.parser_element = e
@@ -4280,7 +4341,7 @@ class MatchFirst(ParseExpression):
def _generateDefaultName(self) -> str:
return f"{{{' | '.join(str(e) for e in self.exprs)}}}"
- def _setResultsName(self, name, listAllMatches=False):
+ def _setResultsName(self, name, list_all_matches=False) -> ParserElement:
if (
__diag__.warn_multiple_tokens_in_named_alternation
and Diagnostics.warn_multiple_tokens_in_named_alternation
@@ -4301,7 +4362,7 @@ class MatchFirst(ParseExpression):
)
warnings.warn(warning, stacklevel=3)
- return super()._setResultsName(name, listAllMatches)
+ return super()._setResultsName(name, list_all_matches)
class Each(ParseExpression):
@@ -4387,7 +4448,7 @@ class Each(ParseExpression):
self.mayReturnEmpty = True
return self
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
if self.initExprGroups:
self.opt1map = dict(
(id(e.expr), e) for e in self.exprs if isinstance(e, Opt)
@@ -4419,11 +4480,11 @@ class Each(ParseExpression):
tmpReqd = self.required[:]
tmpOpt = self.optionals[:]
multis = self.multioptionals[:]
- matchOrder = []
+ matchOrder: List[ParserElement] = []
keepMatching = True
- failed = []
- fatals = []
+ failed: List[ParserElement] = []
+ fatals: List[ParseFatalException] = []
while keepMatching:
tmpExprs = tmpReqd + tmpOpt + multis
failed.clear()
@@ -4469,7 +4530,7 @@ class Each(ParseExpression):
total_results = ParseResults([])
for e in matchOrder:
- loc, results = e._parse(instring, loc, doActions)
+ loc, results = e._parse(instring, loc, do_actions)
total_results += results
return loc, total_results
@@ -4509,12 +4570,14 @@ class ParseElementEnhance(ParserElement):
def recurse(self) -> List[ParserElement]:
return [self.expr] if self.expr is not None else []
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True):
if self.expr is None:
raise ParseException(instring, loc, "No expression defined", self)
try:
- return self.expr._parse(instring, loc, doActions, callPreParse=False)
+ return self.expr._parse(instring, loc, do_actions, callPreParse=False)
+ except ParseSyntaxException:
+ raise
except ParseBaseException as pbe:
if not isinstance(self, Forward) or self.customName is not None:
if self.errmsg:
@@ -4611,14 +4674,14 @@ class IndentedBlock(ParseElementEnhance):
self._grouped = grouped
self.parent_anchor = 1
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
# advance parse position to non-whitespace by using an Empty()
# this should be the column to be used for all subsequent indented lines
anchor_loc = Empty().preParse(instring, loc)
# see if self.expr matches at the current location - if not it will raise an exception
# and no further work is necessary
- self.expr.try_parse(instring, anchor_loc, do_actions=doActions)
+ self.expr.try_parse(instring, anchor_loc, do_actions=do_actions)
indent_col = col(anchor_loc, instring)
peer_detect_expr = self._Indent(indent_col)
@@ -4643,7 +4706,7 @@ class IndentedBlock(ParseElementEnhance):
else:
wrapper = lambda expr: expr
return (wrapper(block) + Optional(trailing_undent)).parseImpl(
- instring, anchor_loc, doActions
+ instring, anchor_loc, do_actions
)
@@ -4662,10 +4725,10 @@ class AtStringStart(ParseElementEnhance):
super().__init__(expr)
self.callPreparse = False
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
if loc != 0:
raise ParseException(instring, loc, "not found at string start")
- return super().parseImpl(instring, loc, doActions)
+ return super().parseImpl(instring, loc, do_actions)
class AtLineStart(ParseElementEnhance):
@@ -4695,10 +4758,10 @@ class AtLineStart(ParseElementEnhance):
super().__init__(expr)
self.callPreparse = False
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
if col(loc, instring) != 1:
raise ParseException(instring, loc, "not found at line start")
- return super().parseImpl(instring, loc, doActions)
+ return super().parseImpl(instring, loc, do_actions)
class FollowedBy(ParseElementEnhance):
@@ -4728,10 +4791,10 @@ class FollowedBy(ParseElementEnhance):
super().__init__(expr)
self.mayReturnEmpty = True
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
# by using self._expr.parse and deleting the contents of the returned ParseResults list
# we keep any named results that were defined in the FollowedBy expression
- _, ret = self.expr._parse(instring, loc, doActions=doActions)
+ _, ret = self.expr._parse(instring, loc, do_actions=do_actions)
del ret[:]
return loc, ret
@@ -4793,7 +4856,7 @@ class PrecededBy(ParseElementEnhance):
self.skipWhitespace = False
self.parseAction.append(lambda s, l, t: t.__delitem__(slice(None, None)))
- def parseImpl(self, instring, loc=0, doActions=True):
+ def parseImpl(self, instring, loc=0, do_actions=True) -> ParseImplReturnType:
if self.exact:
if loc < self.retreat:
raise ParseException(instring, loc, self.errmsg)
@@ -4848,9 +4911,9 @@ class Located(ParseElementEnhance):
"""
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
start = loc
- loc, tokens = self.expr._parse(instring, start, doActions, callPreParse=False)
+ loc, tokens = self.expr._parse(instring, start, do_actions, callPreParse=False)
ret_tokens = ParseResults([start, tokens, loc])
ret_tokens["locn_start"] = start
ret_tokens["value"] = tokens
@@ -4896,8 +4959,8 @@ class NotAny(ParseElementEnhance):
self.mayReturnEmpty = True
self.errmsg = f"Found unwanted token, {self.expr}"
- def parseImpl(self, instring, loc, doActions=True):
- if self.expr.can_parse_next(instring, loc, do_actions=doActions):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
+ if self.expr.can_parse_next(instring, loc, do_actions=do_actions):
raise ParseException(instring, loc, self.errmsg, self)
return loc, []
@@ -4927,7 +4990,7 @@ class _MultipleMatch(ParseElementEnhance):
self.not_ender = ~ender if ender is not None else None
return self
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
self_expr_parse = self.expr._parse
self_skip_ignorables = self._skipIgnorables
check_ender = self.not_ender is not None
@@ -4938,7 +5001,7 @@ class _MultipleMatch(ParseElementEnhance):
# if so, fail)
if check_ender:
try_not_ender(instring, loc)
- loc, tokens = self_expr_parse(instring, loc, doActions)
+ loc, tokens = self_expr_parse(instring, loc, do_actions)
try:
hasIgnoreExprs = not not self.ignoreExprs
while 1:
@@ -4948,14 +5011,14 @@ class _MultipleMatch(ParseElementEnhance):
preloc = self_skip_ignorables(instring, loc)
else:
preloc = loc
- loc, tmptokens = self_expr_parse(instring, preloc, doActions)
+ loc, tmptokens = self_expr_parse(instring, preloc, do_actions)
tokens += tmptokens
except (ParseException, IndexError):
pass
return loc, tokens
- def _setResultsName(self, name, listAllMatches=False):
+ def _setResultsName(self, name, list_all_matches=False) -> ParserElement:
if (
__diag__.warn_ungrouped_named_tokens_in_collection
and Diagnostics.warn_ungrouped_named_tokens_in_collection
@@ -4978,7 +5041,7 @@ class _MultipleMatch(ParseElementEnhance):
warnings.warn(warning, stacklevel=3)
break
- return super()._setResultsName(name, listAllMatches)
+ return super()._setResultsName(name, list_all_matches)
class OneOrMore(_MultipleMatch):
@@ -5037,9 +5100,9 @@ class ZeroOrMore(_MultipleMatch):
super().__init__(expr, stopOn=stopOn or stop_on)
self.mayReturnEmpty = True
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
try:
- return super().parseImpl(instring, loc, doActions)
+ return super().parseImpl(instring, loc, do_actions)
except (ParseException, IndexError):
return loc, ParseResults([], name=self.resultsName)
@@ -5170,10 +5233,10 @@ class Opt(ParseElementEnhance):
self.defaultValue = default
self.mayReturnEmpty = True
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
self_expr = self.expr
try:
- loc, tokens = self_expr._parse(instring, loc, doActions, callPreParse=False)
+ loc, tokens = self_expr._parse(instring, loc, do_actions, callPreParse=False)
except (ParseException, IndexError):
default_value = self.defaultValue
if default_value is not self.__optionalNotMatched:
@@ -5279,7 +5342,7 @@ class SkipTo(ParseElementEnhance):
self.failOn = self._literalStringClass(failOn)
else:
self.failOn = failOn
- self.errmsg = "No match found for " + str(self.expr)
+ self.errmsg = f"No match found for {self.expr}"
self.ignorer = Empty().leave_whitespace()
self._update_ignorer()
@@ -5295,7 +5358,7 @@ class SkipTo(ParseElementEnhance):
super().ignore(expr)
self._update_ignorer()
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True):
startloc = loc
instrlen = len(instring)
self_expr_parse = self.expr._parse
@@ -5325,7 +5388,7 @@ class SkipTo(ParseElementEnhance):
prev_tmploc = tmploc
try:
- self_expr_parse(instring, tmploc, doActions=False, callPreParse=False)
+ self_expr_parse(instring, tmploc, do_actions=False, callPreParse=False)
except (ParseException, IndexError):
# no match, advance loc in string
tmploc += 1
@@ -5343,7 +5406,7 @@ class SkipTo(ParseElementEnhance):
skipresult = ParseResults(skiptext)
if self.includeMatch:
- loc, mat = self_expr_parse(instring, loc, doActions, callPreParse=False)
+ loc, mat = self_expr_parse(instring, loc, do_actions, callPreParse=False)
skipresult += mat
return loc, skipresult
@@ -5440,7 +5503,7 @@ class Forward(ParseElementEnhance):
lineno=self.caller_frame.lineno,
)
- def parseImpl(self, instring, loc, doActions=True):
+ def parseImpl(self, instring, loc, do_actions=True) -> ParseImplReturnType:
if (
self.expr is None
and __diag__.warn_on_parse_using_empty_Forward
@@ -5466,7 +5529,7 @@ class Forward(ParseElementEnhance):
stacklevel=stacklevel,
)
if not ParserElement._left_recursion_enabled:
- return super().parseImpl(instring, loc, doActions)
+ return super().parseImpl(instring, loc, do_actions)
# ## Bounded Recursion algorithm ##
# Recursion only needs to be processed at ``Forward`` elements, since they are
# the only ones that can actually refer to themselves. The general idea is
@@ -5484,13 +5547,13 @@ class Forward(ParseElementEnhance):
#
# There is a complication since we not only *parse* but also *transform* via
# actions: We do not want to run the actions too often while expanding. Thus,
- # we expand using `doActions=False` and only run `doActions=True` if the next
+ # we expand using `do_actions=False` and only run `do_actions=True` if the next
# recursion level is acceptable.
with ParserElement.recursion_lock:
memo = ParserElement.recursion_memos
try:
# we are parsing at a specific recursion expansion - use it as-is
- prev_loc, prev_result = memo[loc, self, doActions]
+ prev_loc, prev_result = memo[loc, self, do_actions]
if isinstance(prev_result, Exception):
raise prev_result
return prev_loc, prev_result.copy()
@@ -5498,14 +5561,14 @@ class Forward(ParseElementEnhance):
act_key = (loc, self, True)
peek_key = (loc, self, False)
# we are searching for the best recursion expansion - keep on improving
- # both `doActions` cases must be tracked separately here!
+ # both `do_actions` cases must be tracked separately here!
prev_loc, prev_peek = memo[peek_key] = (
loc - 1,
ParseException(
instring, loc, "Forward recursion without base case", self
),
)
- if doActions:
+ if do_actions:
memo[act_key] = memo[peek_key]
while True:
try:
@@ -5517,8 +5580,8 @@ class Forward(ParseElementEnhance):
new_loc, new_peek = prev_loc, prev_peek
# the match did not get better: we are done
if new_loc <= prev_loc:
- if doActions:
- # replace the match for doActions=False as well,
+ if do_actions:
+ # replace the match for do_actions=False as well,
# in case the action did backtrack
prev_loc, prev_result = memo[peek_key] = memo[act_key]
del memo[peek_key], memo[act_key]
@@ -5526,7 +5589,7 @@ class Forward(ParseElementEnhance):
del memo[peek_key]
return prev_loc, prev_peek.copy()
# the match did get better: see if we can improve further
- if doActions:
+ if do_actions:
try:
memo[act_key] = super().parseImpl(instring, loc, True)
except ParseException as e:
@@ -5586,7 +5649,7 @@ class Forward(ParseElementEnhance):
ret <<= self
return ret
- def _setResultsName(self, name, list_all_matches=False):
+ def _setResultsName(self, name, list_all_matches=False) -> ParserElement:
# fmt: off
if (
__diag__.warn_name_set_on_empty_Forward
@@ -5892,7 +5955,9 @@ def trace_parse_action(f: ParseAction) -> ParseAction:
try:
ret = f(*paArgs)
except Exception as exc:
- sys.stderr.write(f"<<leaving {thisFunc} (exception: {exc})\n")
+ sys.stderr.write(
+ f"<<leaving {thisFunc} (exception: {type(exc).__name__}: {exc})\n"
+ )
raise
sys.stderr.write(f"<<leaving {thisFunc} (ret: {ret!r})\n")
return ret
@@ -6070,7 +6135,7 @@ _builtin_exprs: List[ParserElement] = [
v for v in vars().values() if isinstance(v, ParserElement)
]
-# backward compatibility names
+# Compatibility synonyms
# fmt: off
sglQuotedString = sgl_quoted_string
dblQuotedString = dbl_quoted_string
diff --git a/contrib/python/pyparsing/py3/pyparsing/diagram/__init__.py b/contrib/python/pyparsing/py3/pyparsing/diagram/__init__.py
index 700d0b561f..3275adafb6 100644
--- a/contrib/python/pyparsing/py3/pyparsing/diagram/__init__.py
+++ b/contrib/python/pyparsing/py3/pyparsing/diagram/__init__.py
@@ -36,6 +36,7 @@ jinja2_template_source = """\
</head>
<body>
{% endif %}
+<meta charset="UTF-8"/>
{{ body | safe }}
{% for diagram in diagrams %}
<div class="railroad-group">
@@ -89,7 +90,7 @@ class AnnotatedItem(railroad.Group):
"""
def __init__(self, label: str, item):
- super().__init__(item=item, label="[{}]".format(label) if label else label)
+ super().__init__(item=item, label=f"[{label}]")
class EditablePartial(Generic[T]):
@@ -145,7 +146,7 @@ def railroad_to_html(diagrams: List[NamedDiagram], embed=False, **kwargs) -> str
continue
io = StringIO()
try:
- css = kwargs.get('css')
+ css = kwargs.get("css")
diagram.diagram.writeStandalone(io.write, css=css)
except AttributeError:
diagram.diagram.writeSvg(io.write)
@@ -425,9 +426,11 @@ def _apply_diagram_item_enhancements(fn):
element_results_name = element.resultsName
if element_results_name:
# add "*" to indicate if this is a "list all results" name
- element_results_name += "" if element.modalResults else "*"
+ modal_tag = "" if element.modalResults else "*"
ret = EditablePartial.from_call(
- railroad.Group, item=ret, label=element_results_name
+ railroad.Group,
+ item=ret,
+ label=f"{repr(element_results_name)}{modal_tag}",
)
return ret
@@ -534,7 +537,7 @@ def _to_diagram_element(
# (all will have the same name, and resultsName)
if not exprs:
return None
- if len(set((e.name, e.resultsName) for e in exprs)) == 1:
+ if len(set((e.name, e.resultsName) for e in exprs)) == 1 and len(exprs) > 2:
ret = EditablePartial.from_call(
railroad.OneOrMore, item="", repeat=str(len(exprs))
)
@@ -563,7 +566,7 @@ def _to_diagram_element(
if show_groups:
ret = EditablePartial.from_call(AnnotatedItem, label="", item="")
else:
- ret = EditablePartial.from_call(railroad.Group, label="", item="")
+ ret = EditablePartial.from_call(railroad.Sequence, items=[])
elif isinstance(element, pyparsing.TokenConverter):
label = type(element).__name__.lower()
if label == "tokenconverter":
@@ -573,8 +576,36 @@ def _to_diagram_element(
elif isinstance(element, pyparsing.Opt):
ret = EditablePartial.from_call(railroad.Optional, item="")
elif isinstance(element, pyparsing.OneOrMore):
- ret = EditablePartial.from_call(railroad.OneOrMore, item="")
+ if element.not_ender is not None:
+ args = [
+ parent,
+ lookup,
+ vertical,
+ index,
+ name_hint,
+ show_results_names,
+ show_groups,
+ ]
+ return _to_diagram_element(
+ (~element.not_ender.expr + element.expr)[1, ...].set_name(element.name),
+ *args,
+ )
+ ret = EditablePartial.from_call(railroad.OneOrMore, item=None)
elif isinstance(element, pyparsing.ZeroOrMore):
+ if element.not_ender is not None:
+ args = [
+ parent,
+ lookup,
+ vertical,
+ index,
+ name_hint,
+ show_results_names,
+ show_groups,
+ ]
+ return _to_diagram_element(
+ (~element.not_ender.expr + element.expr)[...].set_name(element.name),
+ *args,
+ )
ret = EditablePartial.from_call(railroad.ZeroOrMore, item="")
elif isinstance(element, pyparsing.Group):
ret = EditablePartial.from_call(
diff --git a/contrib/python/pyparsing/py3/pyparsing/exceptions.py b/contrib/python/pyparsing/py3/pyparsing/exceptions.py
index 1aaea56f54..8db34f195a 100644
--- a/contrib/python/pyparsing/py3/pyparsing/exceptions.py
+++ b/contrib/python/pyparsing/py3/pyparsing/exceptions.py
@@ -85,7 +85,7 @@ class ParseBaseException(Exception):
ret = []
if isinstance(exc, ParseBaseException):
ret.append(exc.line)
- ret.append(" " * (exc.column - 1) + "^")
+ ret.append(f"{' ' * (exc.column - 1)}^")
ret.append(f"{type(exc).__name__}: {exc}")
if depth <= 0:
@@ -245,6 +245,7 @@ class ParseBaseException(Exception):
"""
return self.explain_exception(self, depth)
+ # Compatibility synonyms
# fmt: off
markInputline = replaced_by_pep8("markInputline", mark_input_line)
# fmt: on
diff --git a/contrib/python/pyparsing/py3/pyparsing/helpers.py b/contrib/python/pyparsing/py3/pyparsing/helpers.py
index dcfdb8fe4b..d5d14a08d6 100644
--- a/contrib/python/pyparsing/py3/pyparsing/helpers.py
+++ b/contrib/python/pyparsing/py3/pyparsing/helpers.py
@@ -782,9 +782,12 @@ def infix_notation(
# if lpar and rpar are not suppressed, wrap in group
if not (isinstance(lpar, Suppress) and isinstance(rpar, Suppress)):
- lastExpr = base_expr | Group(lpar + ret + rpar)
+ lastExpr = base_expr | Group(lpar + ret + rpar).set_name(
+ f"nested_{base_expr.name}"
+ )
else:
- lastExpr = base_expr | (lpar + ret + rpar)
+ lastExpr = base_expr | (lpar + ret + rpar).set_name(f"nested_{base_expr.name}")
+ root_expr = lastExpr
arity: int
rightLeftAssoc: opAssoc
@@ -855,6 +858,7 @@ def infix_notation(
thisExpr <<= (matchExpr | lastExpr).setName(term_name)
lastExpr = thisExpr
ret <<= lastExpr
+ root_expr.set_name("base_expr")
return ret
@@ -1049,7 +1053,7 @@ def delimited_list(
)
-# pre-PEP8 compatible names
+# Compatibility synonyms
# fmt: off
opAssoc = OpAssoc
anyOpenTag = any_open_tag
diff --git a/contrib/python/pyparsing/py3/pyparsing/results.py b/contrib/python/pyparsing/py3/pyparsing/results.py
index 3e5fe2089b..3bb7c948e0 100644
--- a/contrib/python/pyparsing/py3/pyparsing/results.py
+++ b/contrib/python/pyparsing/py3/pyparsing/results.py
@@ -4,12 +4,14 @@ from collections.abc import (
Mapping,
MutableSequence,
Iterator,
- Sequence,
- Container,
+ Iterable,
)
import pprint
from typing import Tuple, Any, Dict, Set, List
+from .util import replaced_by_pep8
+
+
str_type: Tuple[type, ...] = (str, bytes)
_generator_type = type((_ for _ in ()))
@@ -573,20 +575,20 @@ class ParseResults:
# replace values with copies if they are of known mutable types
for i, obj in enumerate(self._toklist):
if isinstance(obj, ParseResults):
- self._toklist[i] = obj.deepcopy()
+ ret._toklist[i] = obj.deepcopy()
elif isinstance(obj, (str, bytes)):
pass
elif isinstance(obj, MutableMapping):
- self._toklist[i] = dest = type(obj)()
+ ret._toklist[i] = dest = type(obj)()
for k, v in obj.items():
dest[k] = v.deepcopy() if isinstance(v, ParseResults) else v
- elif isinstance(obj, Container):
- self._toklist[i] = type(obj)(
+ elif isinstance(obj, Iterable):
+ ret._toklist[i] = type(obj)(
v.deepcopy() if isinstance(v, ParseResults) else v for v in obj
)
return ret
- def get_name(self):
+ def get_name(self) -> str:
r"""
Returns the results name for this token expression. Useful when several
different expressions might match at a particular location.
diff --git a/contrib/python/pyparsing/py3/pyparsing/unicode.py b/contrib/python/pyparsing/py3/pyparsing/unicode.py
index 426b8b238c..0e3e06572b 100644
--- a/contrib/python/pyparsing/py3/pyparsing/unicode.py
+++ b/contrib/python/pyparsing/py3/pyparsing/unicode.py
@@ -53,51 +53,51 @@ class unicode_set:
_ranges: UnicodeRangeList = []
@_lazyclassproperty
- def _chars_for_ranges(cls):
- ret = []
+ def _chars_for_ranges(cls) -> List[str]:
+ ret: List[int] = []
for cc in cls.__mro__:
if cc is unicode_set:
break
for rr in getattr(cc, "_ranges", ()):
ret.extend(range(rr[0], rr[-1] + 1))
- return [chr(c) for c in sorted(set(ret))]
+ return sorted(chr(c) for c in set(ret))
@_lazyclassproperty
- def printables(cls):
+ def printables(cls) -> str:
"""all non-whitespace characters in this range"""
return "".join(filterfalse(str.isspace, cls._chars_for_ranges))
@_lazyclassproperty
- def alphas(cls):
+ def alphas(cls) -> str:
"""all alphabetic characters in this range"""
return "".join(filter(str.isalpha, cls._chars_for_ranges))
@_lazyclassproperty
- def nums(cls):
+ def nums(cls) -> str:
"""all numeric digit characters in this range"""
return "".join(filter(str.isdigit, cls._chars_for_ranges))
@_lazyclassproperty
- def alphanums(cls):
+ def alphanums(cls) -> str:
"""all alphanumeric characters in this range"""
return cls.alphas + cls.nums
@_lazyclassproperty
- def identchars(cls):
+ def identchars(cls) -> str:
"""all characters in this range that are valid identifier characters, plus underscore '_'"""
return "".join(
sorted(
- set(
- "".join(filter(str.isidentifier, cls._chars_for_ranges))
- + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµº"
- + "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ"
- + "_"
+ set(filter(str.isidentifier, cls._chars_for_ranges))
+ | set(
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµº"
+ "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ"
+ "_"
)
)
)
@_lazyclassproperty
- def identbodychars(cls):
+ def identbodychars(cls) -> str:
"""
all characters in this range that are valid identifier body characters,
plus the digits 0-9, and · (Unicode MIDDLE DOT)
@@ -105,7 +105,9 @@ class unicode_set:
identifier_chars = set(
c for c in cls._chars_for_ranges if ("_" + c).isidentifier()
)
- return "".join(sorted(identifier_chars | set(cls.identchars + "0123456789·")))
+ return "".join(
+ sorted(identifier_chars | set(cls.identchars) | set("0123456789·"))
+ )
@_lazyclassproperty
def identifier(cls):
diff --git a/contrib/python/pyparsing/py3/pyparsing/util.py b/contrib/python/pyparsing/py3/pyparsing/util.py
index 4ae018a963..94837fea0f 100644
--- a/contrib/python/pyparsing/py3/pyparsing/util.py
+++ b/contrib/python/pyparsing/py3/pyparsing/util.py
@@ -246,7 +246,7 @@ def replaced_by_pep8(compat_name: str, fn: C) -> C:
# (Presence of 'self' arg in signature is used by explain_exception() methods, so we take
# some extra steps to add it if present in decorated function.)
- if "self" == list(inspect.signature(fn).parameters)[0]:
+ if ["self"] == list(inspect.signature(fn).parameters)[:1]:
@wraps(fn)
def _inner(self, *args, **kwargs):
diff --git a/contrib/python/pyparsing/py3/ya.make b/contrib/python/pyparsing/py3/ya.make
index 9df0a0f5fa..c5575db221 100644
--- a/contrib/python/pyparsing/py3/ya.make
+++ b/contrib/python/pyparsing/py3/ya.make
@@ -4,7 +4,7 @@ PY3_LIBRARY()
PROVIDES(pyparsing)
-VERSION(3.1.2)
+VERSION(3.1.4)
LICENSE(MIT)