7from functools
import lru_cache, wraps
8from typing
import Callable, List, Union, Iterable, TypeVar, cast
11C = TypeVar(
"C", bound=Callable)
15 """Internal class for defining compatibility and debugging flags"""
17 _all_names: List[str] = []
18 _fixed_names: List[str] = []
19 _type_desc =
"configuration"
22 def _set(cls, dname, value):
23 if dname
in cls._fixed_names:
25 f
"{cls.__name__}.{dname} {cls._type_desc} is {str(getattr(cls, dname)).upper()}"
26 f
" and cannot be overridden",
30 if dname
in cls._all_names:
33 raise ValueError(f
"no such {cls._type_desc} {dname!r}")
35 enable =
classmethod(
lambda cls, name: cls._set(name,
True))
36 disable =
classmethod(
lambda cls, name: cls._set(name,
False))
39@lru_cache(maxsize=128)
40def col(loc: int, strg: str) -> int:
42 Returns current column within a string, counting newlines as line separators.
43 The first column is number 1.
45 Note: the default parsing behavior is to expand tabs in the input string
46 before starting the parsing process. See
47 :class:`ParserElement.parse_string` for more
48 information on parsing strings containing ``<TAB>`` s, and suggested
49 methods to maintain a consistent view of the parsed string, the parse
50 location, and line and column positions within the parsed string.
53 return 1
if 0 < loc <
len(s)
and s[loc - 1] ==
"\n" else loc -
s.rfind(
"\n", 0, loc)
56@lru_cache(maxsize=128)
57def lineno(loc: int, strg: str) -> int:
58 """Returns current line number within a string, counting newlines as line separators.
59 The first line is number 1.
61 Note - the default parsing behavior is to expand tabs in the input string
62 before starting the parsing process. See :class:`ParserElement.parse_string`
63 for more information on parsing strings containing ``<TAB>`` s, and
64 suggested methods to maintain a consistent view of the parsed string, the
65 parse location, and line and column positions within the parsed string.
70@lru_cache(maxsize=128)
71def line(loc: int, strg: str) -> str:
73 Returns the line of text containing loc within a string, counting newlines as line separators.
77 return strg[last_cr + 1 : next_cr]
if next_cr >= 0
else strg[last_cr + 1 :]
89 def set_(_, key, value):
105 keyring = [object()] * size
113 def set_(_, key, value):
121 keyring[:] = [object()] * size
131 A memoizing mapping that retains `capacity` deleted items
133 The memo tracks retained items by their access order; once `capacity` items
134 are retained, the least recently used item is discarded.
160 self.
_memory.popitem(last=
False)
170 A memoizing mapping that retains all deleted items
177def _escape_regex_range_chars(s: str) -> str:
186def _collapse_string_to_ranges(
187 s: Union[str, Iterable[str]], re_escape: bool =
True
201 return "\\" + c
if c
in r"\^-][" else c
207 escape_re_range_char = no_escape_re_range_char
210 s =
"".join(sorted(set(s)))
213 first = last = next(chars)
220 sep =
"" if ord(last) ==
ord(first) + 1
else "-"
222 f
"{escape_re_range_char(first)}{sep}{escape_re_range_char(last)}"
230def _flatten(ll: list) -> list:
245 fn =
getattr(fn,
"__func__", fn)
252 def _inner(self, *args, **kwargs):
256 return fn(self, *args, **kwargs)
261 def _inner(*args, **kwargs):
265 return fn(*args, **kwargs)
277 return cast(C, _inner)
280def replaced_by_pep8(fn: C) -> Callable[[Callable], C]:
282 Decorator for pre-PEP8 compatibility synonyms, to link them to the new function.
__setitem__(self, key, value)
C _make_synonym_function(str compat_name, C fn)