| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928 |
- # results.py
- from __future__ import annotations
- import collections
- from collections.abc import (
- MutableMapping,
- Mapping,
- MutableSequence,
- Iterator,
- Iterable,
- )
- import pprint
- from typing import Any
- from .util import deprecate_argument, _is_iterable, _flatten
- str_type: tuple[type, ...] = (str, bytes)
- _generator_type = type((_ for _ in ()))
- NULL_SLICE: slice = slice(None)
- class _ParseResultsWithOffset:
- tup: tuple[ParseResults, int]
- __slots__ = ["tup"]
- def __init__(self, p1: ParseResults, p2: int) -> None:
- self.tup: tuple[ParseResults, int] = (p1, p2)
- def __getitem__(self, i):
- return self.tup[i]
- def __getstate__(self):
- return self.tup
- def __setstate__(self, *args):
- self.tup = args[0]
- class ParseResults:
- """Structured parse results, to provide multiple means of access to
- the parsed data:
- - as a list (``len(results)``)
- - by list index (``results[0], results[1]``, etc.)
- - by attribute (``results.<results_name>`` - see :class:`ParserElement.set_results_name`)
- Example:
- .. testcode::
- integer = Word(nums)
- date_str = (integer.set_results_name("year") + '/'
- + integer.set_results_name("month") + '/'
- + integer.set_results_name("day"))
- # equivalent form:
- # date_str = (integer("year") + '/'
- # + integer("month") + '/'
- # + integer("day"))
- # parse_string returns a ParseResults object
- result = date_str.parse_string("1999/12/31")
- def test(s, fn=repr):
- print(f"{s} -> {fn(eval(s))}")
- test("list(result)")
- test("result[0]")
- test("result['month']")
- test("result.day")
- test("'month' in result")
- test("'minutes' in result")
- test("result.dump()", str)
- prints:
- .. testoutput::
- list(result) -> ['1999', '/', '12', '/', '31']
- result[0] -> '1999'
- result['month'] -> '12'
- result.day -> '31'
- 'month' in result -> True
- 'minutes' in result -> False
- result.dump() -> ['1999', '/', '12', '/', '31']
- - day: '31'
- - month: '12'
- - year: '1999'
- """
- _null_values: tuple[Any, ...] = (None, [], ())
- _name: str
- _parent: ParseResults
- _all_names: set[str]
- _modal: bool
- _toklist: list[Any]
- _tokdict: dict[str, Any]
- __slots__ = (
- "_name",
- "_parent",
- "_all_names",
- "_modal",
- "_toklist",
- "_tokdict",
- )
- class List(list):
- """
- Simple wrapper class to distinguish parsed list results that should be preserved
- as actual Python lists, instead of being converted to :class:`ParseResults`:
- .. testcode::
- import pyparsing as pp
- ppc = pp.common
- LBRACK, RBRACK, LPAR, RPAR = pp.Suppress.using_each("[]()")
- element = pp.Forward()
- item = ppc.integer
- item_list = pp.DelimitedList(element)
- element_list = LBRACK + item_list + RBRACK | LPAR + item_list + RPAR
- element <<= item | element_list
- # add parse action to convert from ParseResults
- # to actual Python collection types
- @element_list.add_parse_action
- def as_python_list(t):
- return pp.ParseResults.List(t.as_list())
- element.run_tests('''
- 100
- [2,3,4]
- [[2, 1],3,4]
- [(2, 1),3,4]
- (2,3,4)
- ([2, 3], 4)
- ''', post_parse=lambda s, r: (r[0], type(r[0]))
- )
- prints:
- .. testoutput::
- :options: +NORMALIZE_WHITESPACE
- 100
- (100, <class 'int'>)
- [2,3,4]
- ([2, 3, 4], <class 'list'>)
- [[2, 1],3,4]
- ([[2, 1], 3, 4], <class 'list'>)
- [(2, 1),3,4]
- ([[2, 1], 3, 4], <class 'list'>)
- (2,3,4)
- ([2, 3, 4], <class 'list'>)
- ([2, 3], 4)
- ([[2, 3], 4], <class 'list'>)
- (Used internally by :class:`Group` when `aslist=True`.)
- """
- def __new__(cls, contained=None):
- if contained is None:
- contained = []
- if not isinstance(contained, list):
- raise TypeError(
- f"{cls.__name__} may only be constructed with a list, not {type(contained).__name__}"
- )
- return list.__new__(cls)
- def __new__(cls, toklist=None, name=None, **kwargs):
- if isinstance(toklist, ParseResults):
- return toklist
- self = object.__new__(cls)
- self._name = None
- self._parent = None
- self._all_names = set()
- if toklist is None:
- self._toklist = []
- elif isinstance(toklist, (list, _generator_type)):
- self._toklist = (
- [toklist[:]]
- if isinstance(toklist, ParseResults.List)
- else list(toklist)
- )
- else:
- self._toklist = [toklist]
- self._tokdict = dict()
- return self
- # Performance tuning: we construct a *lot* of these, so keep this
- # constructor as small and fast as possible
- def __init__(
- self,
- toklist=None,
- name=None,
- aslist=True,
- modal=True,
- isinstance=isinstance,
- **kwargs,
- ) -> None:
- asList = deprecate_argument(kwargs, "asList", True, new_name="aslist")
- asList = asList and aslist
- self._tokdict: dict[str, _ParseResultsWithOffset]
- self._modal = modal
- if name is None or name == "":
- return
- if isinstance(name, int):
- name = str(name)
- if not modal:
- self._all_names = {name}
- self._name = name
- if toklist in self._null_values:
- return
- if isinstance(toklist, (str_type, type)):
- toklist = [toklist]
- if asList:
- if isinstance(toklist, ParseResults):
- self[name] = _ParseResultsWithOffset(ParseResults(toklist._toklist), 0)
- else:
- self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]), 0)
- self[name]._name = name
- return
- try:
- self[name] = toklist[0]
- except (KeyError, TypeError, IndexError):
- if toklist is not self:
- self[name] = toklist
- else:
- self._name = name
- def __getitem__(self, i):
- if isinstance(i, (int, slice)):
- return self._toklist[i]
- if i not in self._all_names:
- return self._tokdict[i][-1][0]
- return ParseResults([v[0] for v in self._tokdict[i]])
- def __setitem__(self, k, v, isinstance=isinstance):
- if isinstance(v, _ParseResultsWithOffset):
- self._tokdict[k] = self._tokdict.get(k, list()) + [v]
- sub = v[0]
- elif isinstance(k, (int, slice)):
- self._toklist[k] = v
- sub = v
- else:
- self._tokdict[k] = self._tokdict.get(k, []) + [
- _ParseResultsWithOffset(v, 0)
- ]
- sub = v
- if isinstance(sub, ParseResults):
- sub._parent = self
- def __delitem__(self, i):
- if not isinstance(i, (int, slice)):
- del self._tokdict[i]
- return
- # slight optimization if del results[:]
- if i == NULL_SLICE:
- self._toklist.clear()
- return
- mylen = len(self._toklist)
- del self._toklist[i]
- # convert int to slice
- if isinstance(i, int):
- if i < 0:
- i += mylen
- i = slice(i, i + 1)
- # get removed indices
- removed = list(range(*i.indices(mylen)))
- removed.reverse()
- # fixup indices in token dictionary
- for occurrences in self._tokdict.values():
- for j in removed:
- for k, (value, position) in enumerate(occurrences):
- occurrences[k] = _ParseResultsWithOffset(
- value, position - (position > j)
- )
- def __contains__(self, k) -> bool:
- return k in self._tokdict
- def __len__(self) -> int:
- return len(self._toklist)
- def __bool__(self) -> bool:
- return not not (self._toklist or self._tokdict)
- def __iter__(self) -> Iterator:
- return iter(self._toklist)
- def __reversed__(self) -> Iterator:
- return iter(self._toklist[::-1])
- def keys(self):
- return iter(self._tokdict)
- def values(self):
- return (self[k] for k in self.keys())
- def items(self):
- return ((k, self[k]) for k in self.keys())
- def haskeys(self) -> bool:
- """
- Since ``keys()`` returns an iterator, this method is helpful in bypassing
- code that looks for the existence of any defined results names."""
- return not not self._tokdict
- def pop(self, *args, **kwargs):
- """
- Removes and returns item at specified index (default= ``last``).
- Supports both ``list`` and ``dict`` semantics for ``pop()``. If
- passed no argument or an integer argument, it will use ``list``
- semantics and pop tokens from the list of parsed tokens. If passed
- a non-integer argument (most likely a string), it will use ``dict``
- semantics and pop the corresponding value from any defined results
- names. A second default return value argument is supported, just as in
- ``dict.pop()``.
- Example:
- .. doctest::
- >>> numlist = Word(nums)[...]
- >>> print(numlist.parse_string("0 123 321"))
- ['0', '123', '321']
- >>> def remove_first(tokens):
- ... tokens.pop(0)
- ...
- >>> numlist.add_parse_action(remove_first)
- [W:(0-9)]...
- >>> print(numlist.parse_string("0 123 321"))
- ['123', '321']
- >>> label = Word(alphas)
- >>> patt = label("LABEL") + Word(nums)[1, ...]
- >>> print(patt.parse_string("AAB 123 321").dump())
- ['AAB', '123', '321']
- - LABEL: 'AAB'
- >>> # Use pop() in a parse action to remove named result
- >>> # (note that corresponding value is not
- >>> # removed from list form of results)
- >>> def remove_LABEL(tokens):
- ... tokens.pop("LABEL")
- ... return tokens
- ...
- >>> patt.add_parse_action(remove_LABEL)
- {W:(A-Za-z) {W:(0-9)}...}
- >>> print(patt.parse_string("AAB 123 321").dump())
- ['AAB', '123', '321']
- """
- if not args:
- args = [-1]
- for k, v in kwargs.items():
- if k == "default":
- args = (args[0], v)
- else:
- raise TypeError(f"pop() got an unexpected keyword argument {k!r}")
- if isinstance(args[0], int) or len(args) == 1 or args[0] in self:
- index = args[0]
- ret = self[index]
- del self[index]
- return ret
- else:
- defaultvalue = args[1]
- return defaultvalue
- def get(self, key, default_value=None):
- """
- Returns named result matching the given key, or if there is no
- such name, then returns the given ``default_value`` or ``None`` if no
- ``default_value`` is specified.
- Similar to ``dict.get()``.
- Example:
- .. doctest::
- >>> integer = Word(nums)
- >>> date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
- >>> result = date_str.parse_string("1999/12/31")
- >>> result.get("year")
- '1999'
- >>> result.get("hour", "not specified")
- 'not specified'
- >>> result.get("hour")
- """
- if key in self:
- return self[key]
- else:
- return default_value
- def insert(self, index, ins_string):
- """
- Inserts new element at location index in the list of parsed tokens.
- Similar to ``list.insert()``.
- Example:
- .. doctest::
- >>> numlist = Word(nums)[...]
- >>> print(numlist.parse_string("0 123 321"))
- ['0', '123', '321']
- >>> # use a parse action to insert the parse location
- >>> # in the front of the parsed results
- >>> def insert_locn(locn, tokens):
- ... tokens.insert(0, locn)
- ...
- >>> numlist.add_parse_action(insert_locn)
- [W:(0-9)]...
- >>> print(numlist.parse_string("0 123 321"))
- [0, '0', '123', '321']
- """
- self._toklist.insert(index, ins_string)
- # fixup indices in token dictionary
- for occurrences in self._tokdict.values():
- for k, (value, position) in enumerate(occurrences):
- occurrences[k] = _ParseResultsWithOffset(
- value, position + (position > index)
- )
- def append(self, item):
- """
- Add single element to end of ``ParseResults`` list of elements.
- Example:
- .. doctest::
- >>> numlist = Word(nums)[...]
- >>> print(numlist.parse_string("0 123 321"))
- ['0', '123', '321']
- >>> # use a parse action to compute the sum of the parsed integers,
- >>> # and add it to the end
- >>> def append_sum(tokens):
- ... tokens.append(sum(map(int, tokens)))
- ...
- >>> numlist.add_parse_action(append_sum)
- [W:(0-9)]...
- >>> print(numlist.parse_string("0 123 321"))
- ['0', '123', '321', 444]
- """
- self._toklist.append(item)
- def extend(self, itemseq):
- """
- Add sequence of elements to end of :class:`ParseResults` list of elements.
- Example:
- .. testcode::
- patt = Word(alphas)[1, ...]
- # use a parse action to append the reverse of the matched strings,
- # to make a palindrome
- def make_palindrome(tokens):
- tokens.extend(reversed([t[::-1] for t in tokens]))
- return ''.join(tokens)
- patt.add_parse_action(make_palindrome)
- print(patt.parse_string("lskdj sdlkjf lksd"))
- prints:
- .. testoutput::
- ['lskdjsdlkjflksddsklfjkldsjdksl']
- """
- if isinstance(itemseq, ParseResults):
- self.__iadd__(itemseq)
- else:
- self._toklist.extend(itemseq)
- def clear(self):
- """
- Clear all elements and results names.
- """
- del self._toklist[:]
- self._tokdict.clear()
- def __getattr__(self, name):
- try:
- return self[name]
- except KeyError:
- if name.startswith("__"):
- raise AttributeError(name)
- return ""
- def __add__(self, other: ParseResults) -> ParseResults:
- ret = self.copy()
- ret += other
- return ret
- def __iadd__(self, other: ParseResults) -> ParseResults:
- if not other:
- return self
- if other._tokdict:
- offset = len(self._toklist)
- addoffset = lambda a: offset if a < 0 else a + offset
- otheritems = other._tokdict.items()
- otherdictitems = [
- (k, _ParseResultsWithOffset(v[0], addoffset(v[1])))
- for k, vlist in otheritems
- for v in vlist
- ]
- for k, v in otherdictitems:
- self[k] = v
- if isinstance(v[0], ParseResults):
- v[0]._parent = self
- self._toklist += other._toklist
- self._all_names |= other._all_names
- return self
- def __radd__(self, other) -> ParseResults:
- if isinstance(other, int) and other == 0:
- # useful for merging many ParseResults using sum() builtin
- return self.copy()
- else:
- # this may raise a TypeError - so be it
- return other + self
- def __repr__(self) -> str:
- return f"{type(self).__name__}({self._toklist!r}, {self.as_dict()})"
- def __str__(self) -> str:
- return (
- "["
- + ", ".join(
- [
- str(i) if isinstance(i, ParseResults) else repr(i)
- for i in self._toklist
- ]
- )
- + "]"
- )
- def _asStringList(self, sep=""):
- out = []
- for item in self._toklist:
- if out and sep:
- out.append(sep)
- if isinstance(item, ParseResults):
- out += item._asStringList()
- else:
- out.append(str(item))
- return out
- def as_list(self, *, flatten: bool = False) -> list:
- """
- Returns the parse results as a nested list of matching tokens, all converted to strings.
- If ``flatten`` is True, all the nesting levels in the returned list are collapsed.
- Example:
- .. doctest::
- >>> patt = Word(alphas)[1, ...]
- >>> result = patt.parse_string("sldkj lsdkj sldkj")
- >>> # even though the result prints in string-like form,
- >>> # it is actually a pyparsing ParseResults
- >>> type(result)
- <class 'pyparsing.results.ParseResults'>
- >>> print(result)
- ['sldkj', 'lsdkj', 'sldkj']
- .. doctest::
- >>> # Use as_list() to create an actual list
- >>> result_list = result.as_list()
- >>> type(result_list)
- <class 'list'>
- >>> print(result_list)
- ['sldkj', 'lsdkj', 'sldkj']
- .. versionchanged:: 3.2.0
- New ``flatten`` argument.
- """
- if flatten:
- return [*_flatten(self)]
- else:
- return [
- res.as_list() if isinstance(res, ParseResults) else res
- for res in self._toklist
- ]
- def as_dict(self) -> dict:
- """
- Returns the named parse results as a nested dictionary.
- Example:
- .. doctest::
- >>> integer = pp.Word(pp.nums)
- >>> date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
- >>> result = date_str.parse_string('1999/12/31')
- >>> type(result)
- <class 'pyparsing.results.ParseResults'>
- >>> result
- ParseResults(['1999', '/', '12', '/', '31'], {'year': '1999', 'month': '12', 'day': '31'})
- >>> result_dict = result.as_dict()
- >>> type(result_dict)
- <class 'dict'>
- >>> result_dict
- {'year': '1999', 'month': '12', 'day': '31'}
- >>> # even though a ParseResults supports dict-like access,
- >>> # sometime you just need to have a dict
- >>> import json
- >>> print(json.dumps(result))
- Traceback (most recent call last):
- TypeError: Object of type ParseResults is not JSON serializable
- >>> print(json.dumps(result.as_dict()))
- {"year": "1999", "month": "12", "day": "31"}
- """
- def to_item(obj):
- if isinstance(obj, ParseResults):
- return obj.as_dict() if obj.haskeys() else [to_item(v) for v in obj]
- else:
- return obj
- return dict((k, to_item(v)) for k, v in self.items())
- def copy(self) -> ParseResults:
- """
- Returns a new shallow copy of a :class:`ParseResults` object.
- :class:`ParseResults` items contained within the source are
- shared with the copy. Use :meth:`ParseResults.deepcopy` to
- create a copy with its own separate content values.
- """
- ret = ParseResults(self._toklist)
- ret._tokdict = self._tokdict.copy()
- ret._parent = self._parent
- ret._all_names |= self._all_names
- ret._name = self._name
- return ret
- def deepcopy(self) -> ParseResults:
- """
- Returns a new deep copy of a :class:`ParseResults` object.
- .. versionadded:: 3.1.0
- """
- ret = self.copy()
- # replace values with copies if they are of known mutable types
- for i, obj in enumerate(self._toklist):
- if isinstance(obj, ParseResults):
- ret._toklist[i] = obj.deepcopy()
- elif isinstance(obj, (str, bytes)):
- pass
- elif isinstance(obj, MutableMapping):
- 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, Iterable):
- ret._toklist[i] = type(obj)(
- v.deepcopy() if isinstance(v, ParseResults) else v for v in obj # type: ignore[call-arg]
- )
- return ret
- def get_name(self) -> str | None:
- r"""
- Returns the results name for this token expression.
- Useful when several different expressions might match
- at a particular location.
- Example:
- .. testcode::
- integer = Word(nums)
- ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d")
- house_number_expr = Suppress('#') + Word(nums, alphanums)
- user_data = (Group(house_number_expr)("house_number")
- | Group(ssn_expr)("ssn")
- | Group(integer)("age"))
- user_info = user_data[1, ...]
- result = user_info.parse_string("22 111-22-3333 #221B")
- for item in result:
- print(item.get_name(), ':', item[0])
- prints:
- .. testoutput::
- age : 22
- ssn : 111-22-3333
- house_number : 221B
- """
- if self._name:
- return self._name
- elif self._parent:
- par: ParseResults = self._parent
- parent_tokdict_items = par._tokdict.items()
- return next(
- (
- k
- for k, vlist in parent_tokdict_items
- for v, loc in vlist
- if v is self
- ),
- None,
- )
- elif (
- len(self) == 1
- and len(self._tokdict) == 1
- and next(iter(self._tokdict.values()))[0][1] in (0, -1)
- ):
- return next(iter(self._tokdict.keys()))
- else:
- return None
- def dump(self, indent="", full=True, include_list=True, _depth=0) -> str:
- """
- Diagnostic method for listing out the contents of
- a :class:`ParseResults`. Accepts an optional ``indent`` argument so
- that this string can be embedded in a nested display of other data.
- Example:
- .. testcode::
- integer = Word(nums)
- date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
- result = date_str.parse_string('1999/12/31')
- print(result.dump())
- prints:
- .. testoutput::
- ['1999', '/', '12', '/', '31']
- - day: '31'
- - month: '12'
- - year: '1999'
- """
- out = []
- NL = "\n"
- out.append(indent + str(self.as_list()) if include_list else "")
- if not full:
- return "".join(out)
- if self.haskeys():
- items = sorted((str(k), v) for k, v in self.items())
- for k, v in items:
- if out:
- out.append(NL)
- out.append(f"{indent}{(' ' * _depth)}- {k}: ")
- if not isinstance(v, ParseResults):
- out.append(repr(v))
- continue
- if not v:
- out.append(str(v))
- continue
- out.append(
- v.dump(
- indent=indent,
- full=full,
- include_list=include_list,
- _depth=_depth + 1,
- )
- )
- if not any(isinstance(vv, ParseResults) for vv in self):
- return "".join(out)
- v = self
- incr = " "
- nl = "\n"
- for i, vv in enumerate(v):
- if isinstance(vv, ParseResults):
- vv_dump = vv.dump(
- indent=indent,
- full=full,
- include_list=include_list,
- _depth=_depth + 1,
- )
- out.append(
- f"{nl}{indent}{incr * _depth}[{i}]:{nl}{indent}{incr * (_depth + 1)}{vv_dump}"
- )
- else:
- out.append(
- f"{nl}{indent}{incr * _depth}[{i}]:{nl}{indent}{incr * (_depth + 1)}{vv}"
- )
- return "".join(out)
- def pprint(self, *args, **kwargs):
- """
- Pretty-printer for parsed results as a list, using the
- `pprint <https://docs.python.org/3/library/pprint.html>`_ module.
- Accepts additional positional or keyword args as defined for
- `pprint.pprint <https://docs.python.org/3/library/pprint.html#pprint.pprint>`_ .
- Example:
- .. testcode::
- ident = Word(alphas, alphanums)
- num = Word(nums)
- func = Forward()
- term = ident | num | Group('(' + func + ')')
- func <<= ident + Group(Optional(DelimitedList(term)))
- result = func.parse_string("fna a,b,(fnb c,d,200),100")
- result.pprint(width=40)
- prints:
- .. testoutput::
- ['fna',
- ['a',
- 'b',
- ['(', 'fnb', ['c', 'd', '200'], ')'],
- '100']]
- """
- pprint.pprint(self.as_list(), *args, **kwargs)
- # add support for pickle protocol
- def __getstate__(self):
- return (
- self._toklist,
- (
- self._tokdict.copy(),
- None,
- self._all_names,
- self._name,
- ),
- )
- def __setstate__(self, state):
- self._toklist, (self._tokdict, par, inAccumNames, self._name) = state
- self._all_names = set(inAccumNames)
- self._parent = None
- def __getnewargs__(self):
- return self._toklist, self._name
- def __dir__(self):
- return dir(type(self)) + list(self.keys())
- @classmethod
- def from_dict(cls, other, name=None) -> ParseResults:
- """
- Helper classmethod to construct a :class:`ParseResults` from a ``dict``, preserving the
- name-value relations as results names. If an optional ``name`` argument is
- given, a nested :class:`ParseResults` will be returned.
- """
- ret = cls([])
- for k, v in other.items():
- if isinstance(v, Mapping):
- ret += cls.from_dict(v, name=k)
- else:
- ret += cls([v], name=k, aslist=_is_iterable(v))
- if name is not None:
- ret = cls([ret], name=name)
- return ret
- asList = as_list
- """
- .. deprecated:: 3.0.0
- use :meth:`as_list`
- """
- asDict = as_dict
- """
- .. deprecated:: 3.0.0
- use :meth:`as_dict`
- """
- getName = get_name
- """
- .. deprecated:: 3.0.0
- use :meth:`get_name`
- """
- MutableMapping.register(ParseResults)
- MutableSequence.register(ParseResults)
|