Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pyparsing/results.py: 50%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# results.py
3from __future__ import annotations
5import collections
6from collections.abc import (
7 MutableMapping,
8 Mapping,
9 MutableSequence,
10 Iterator,
11 Iterable,
12)
13import pprint
14from typing import Any
16from .util import deprecate_argument, _is_iterable, _flatten
19str_type: tuple[type, ...] = (str, bytes)
20_generator_type = type((_ for _ in ()))
21NULL_SLICE: slice = slice(None)
24class _ParseResultsWithOffset:
25 __slots__ = ["tup"]
27 def __init__(self, p1: ParseResults, p2: int) -> None:
28 self.tup: tuple[ParseResults, int] = (p1, p2)
30 def __getitem__(self, i):
31 return self.tup[i]
33 def __getstate__(self):
34 return self.tup
36 def __setstate__(self, state):
37 self.tup = state
40class ParseResults:
41 """Structured parse results, to provide multiple means of access to
42 the parsed data:
44 - as a list (``len(results)``)
45 - by list index (``results[0], results[1]``, etc.)
46 - by attribute (``results.<results_name>`` - see :class:`ParserElement.set_results_name`)
48 Example:
50 .. testcode::
52 integer = Word(nums)
53 date_str = (integer.set_results_name("year") + '/'
54 + integer.set_results_name("month") + '/'
55 + integer.set_results_name("day"))
56 # equivalent form:
57 # date_str = (integer("year") + '/'
58 # + integer("month") + '/'
59 # + integer("day"))
61 # parse_string returns a ParseResults object
62 result = date_str.parse_string("1999/12/31")
64 def test(s, fn=repr):
65 print(f"{s} -> {fn(eval(s))}")
67 test("list(result)")
68 test("result[0]")
69 test("result['month']")
70 test("result.day")
71 test("'month' in result")
72 test("'minutes' in result")
73 test("result.dump()", str)
75 prints:
77 .. testoutput::
79 list(result) -> ['1999', '/', '12', '/', '31']
80 result[0] -> '1999'
81 result['month'] -> '12'
82 result.day -> '31'
83 'month' in result -> True
84 'minutes' in result -> False
85 result.dump() -> ['1999', '/', '12', '/', '31']
86 - day: '31'
87 - month: '12'
88 - year: '1999'
90 """
92 _null_values: tuple[Any, ...] = (None, [], ())
94 _name: str
95 _parent: ParseResults
96 _all_names: set[str]
97 _modal: bool
98 _toklist: list[Any]
99 _tokdict: dict[str, Any]
101 __slots__ = (
102 "_name",
103 "_parent",
104 "_all_names",
105 "_modal",
106 "_toklist",
107 "_tokdict",
108 )
110 class List(list):
111 """
112 Simple wrapper class to distinguish parsed list results that should be preserved
113 as actual Python lists, instead of being converted to :class:`ParseResults`:
115 .. testcode::
117 import pyparsing as pp
118 ppc = pp.common
120 LBRACK, RBRACK, LPAR, RPAR = pp.Suppress.using_each("[]()")
121 element = pp.Forward()
122 item = ppc.integer
123 item_list = pp.DelimitedList(element)
124 element_list = LBRACK + item_list + RBRACK | LPAR + item_list + RPAR
125 element <<= item | element_list
127 # add parse action to convert from ParseResults
128 # to actual Python collection types
129 @element_list.add_parse_action
130 def as_python_list(t):
131 return pp.ParseResults.List(t.as_list())
133 element.run_tests('''
134 100
135 [2,3,4]
136 [[2, 1],3,4]
137 [(2, 1),3,4]
138 (2,3,4)
139 ([2, 3], 4)
140 ''', post_parse=lambda s, r: (r[0], type(r[0]))
141 )
143 prints:
145 .. testoutput::
146 :options: +NORMALIZE_WHITESPACE
149 100
150 (100, <class 'int'>)
152 [2,3,4]
153 ([2, 3, 4], <class 'list'>)
155 [[2, 1],3,4]
156 ([[2, 1], 3, 4], <class 'list'>)
158 [(2, 1),3,4]
159 ([[2, 1], 3, 4], <class 'list'>)
161 (2,3,4)
162 ([2, 3, 4], <class 'list'>)
164 ([2, 3], 4)
165 ([[2, 3], 4], <class 'list'>)
167 (Used internally by :class:`Group` when `aslist=True`.)
168 """
170 def __new__(cls, contained=None):
171 if contained is None:
172 contained = []
174 if not isinstance(contained, list):
175 raise TypeError(
176 f"{cls.__name__} may only be constructed with a list, not {type(contained).__name__}"
177 )
179 return list.__new__(cls)
181 def __new__(cls, toklist=None, name=None, **kwargs):
182 if isinstance(toklist, ParseResults):
183 return toklist
184 self = object.__new__(cls)
185 self._name = None
186 self._parent = None
187 self._all_names = set()
189 if toklist is None:
190 self._toklist = []
191 elif isinstance(toklist, (list, _generator_type)):
192 self._toklist = (
193 [toklist[:]]
194 if isinstance(toklist, ParseResults.List)
195 else list(toklist)
196 )
197 else:
198 self._toklist = [toklist]
199 self._tokdict = dict()
200 return self
202 # Performance tuning: we construct a *lot* of these, so keep this
203 # constructor as small and fast as possible
204 def __init__(
205 self,
206 toklist=None,
207 name=None,
208 aslist=True,
209 modal=True,
210 isinstance=isinstance,
211 **kwargs,
212 ) -> None:
213 asList = deprecate_argument(kwargs, "asList", True, new_name="aslist")
215 asList = asList and aslist
216 self._tokdict: dict[str, _ParseResultsWithOffset]
217 self._modal = modal
219 if name is None or name == "":
220 return
222 if isinstance(name, int):
223 name = str(name)
225 if not modal:
226 self._all_names = {name}
228 self._name = name
230 if toklist in self._null_values:
231 return
233 if isinstance(toklist, (str_type, type)):
234 toklist = [toklist]
236 if asList:
237 if isinstance(toklist, ParseResults):
238 self[name] = _ParseResultsWithOffset(ParseResults(toklist._toklist), 0)
239 else:
240 self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]), 0)
241 self[name]._name = name
242 return
244 try:
245 self[name] = toklist[0]
246 except (KeyError, TypeError, IndexError):
247 if toklist is not self:
248 self[name] = toklist
249 else:
250 self._name = name
252 def __getitem__(self, i):
253 if isinstance(i, (int, slice)):
254 return self._toklist[i]
256 if i not in self._all_names:
257 return self._tokdict[i][-1][0]
259 return ParseResults([v[0] for v in self._tokdict[i]])
261 def __setitem__(self, k, v, isinstance=isinstance):
262 if isinstance(v, _ParseResultsWithOffset):
263 self._tokdict[k] = self._tokdict.get(k, list()) + [v]
264 sub = v[0]
265 elif isinstance(k, (int, slice)):
266 self._toklist[k] = v
267 sub = v
268 else:
269 self._tokdict[k] = self._tokdict.get(k, []) + [
270 _ParseResultsWithOffset(v, 0)
271 ]
272 sub = v
273 if isinstance(sub, ParseResults):
274 sub._parent = self
276 def __delitem__(self, i):
277 if not isinstance(i, (int, slice)):
278 del self._tokdict[i]
279 return
281 # slight optimization if del results[:]
282 if i == NULL_SLICE:
283 self._toklist.clear()
284 return
286 mylen = len(self._toklist)
287 del self._toklist[i]
289 # convert int to slice
290 if isinstance(i, int):
291 if i < 0:
292 i += mylen
293 i = slice(i, i + 1)
294 # get removed indices
295 removed = list(range(*i.indices(mylen)))
296 removed.reverse()
297 # fixup indices in token dictionary
298 for occurrences in self._tokdict.values():
299 for j in removed:
300 for k, (value, position) in enumerate(occurrences):
301 occurrences[k] = _ParseResultsWithOffset(
302 value, position - (position > j)
303 )
305 def __contains__(self, k) -> bool:
306 return k in self._tokdict
308 def __len__(self) -> int:
309 return len(self._toklist)
311 def __bool__(self) -> bool:
312 return not not (self._toklist or self._tokdict)
314 def __iter__(self) -> Iterator:
315 return iter(self._toklist)
317 def __reversed__(self) -> Iterator:
318 return iter(self._toklist[::-1])
320 def keys(self):
321 return iter(self._tokdict)
323 def values(self):
324 return (self[k] for k in self.keys())
326 def items(self):
327 return ((k, self[k]) for k in self.keys())
329 def haskeys(self) -> bool:
330 """
331 Since ``keys()`` returns an iterator, this method is helpful in bypassing
332 code that looks for the existence of any defined results names."""
333 return not not self._tokdict
335 def pop(self, *args, **kwargs):
336 """
337 Removes and returns item at specified index (default= ``last``).
338 Supports both ``list`` and ``dict`` semantics for ``pop()``. If
339 passed no argument or an integer argument, it will use ``list``
340 semantics and pop tokens from the list of parsed tokens. If passed
341 a non-integer argument (most likely a string), it will use ``dict``
342 semantics and pop the corresponding value from any defined results
343 names. A second default return value argument is supported, just as in
344 ``dict.pop()``.
346 Example:
348 .. doctest::
350 >>> numlist = Word(nums)[...]
351 >>> print(numlist.parse_string("0 123 321"))
352 ['0', '123', '321']
354 >>> def remove_first(tokens):
355 ... tokens.pop(0)
356 ...
357 >>> numlist.add_parse_action(remove_first)
358 [W:(0-9)]...
359 >>> print(numlist.parse_string("0 123 321"))
360 ['123', '321']
362 >>> label = Word(alphas)
363 >>> patt = label("LABEL") + Word(nums)[1, ...]
364 >>> print(patt.parse_string("AAB 123 321").dump())
365 ['AAB', '123', '321']
366 - LABEL: 'AAB'
368 >>> # Use pop() in a parse action to remove named result
369 >>> # (note that corresponding value is not
370 >>> # removed from list form of results)
371 >>> def remove_LABEL(tokens):
372 ... tokens.pop("LABEL")
373 ... return tokens
374 ...
375 >>> patt.add_parse_action(remove_LABEL)
376 {W:(A-Za-z) {W:(0-9)}...}
377 >>> print(patt.parse_string("AAB 123 321").dump())
378 ['AAB', '123', '321']
380 """
381 if not args:
382 args = [-1]
383 for k, v in kwargs.items():
384 if k == "default":
385 args = (args[0], v)
386 else:
387 raise TypeError(f"pop() got an unexpected keyword argument {k!r}")
388 if isinstance(args[0], int) or len(args) == 1 or args[0] in self:
389 index = args[0]
390 ret = self[index]
391 del self[index]
392 return ret
393 else:
394 defaultvalue = args[1]
395 return defaultvalue
397 def get(self, key, default_value=None):
398 """
399 Returns named result matching the given key, or if there is no
400 such name, then returns the given ``default_value`` or ``None`` if no
401 ``default_value`` is specified.
403 Similar to ``dict.get()``.
405 Example:
407 .. doctest::
409 >>> integer = Word(nums)
410 >>> date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
412 >>> result = date_str.parse_string("1999/12/31")
413 >>> result.get("year")
414 '1999'
415 >>> result.get("hour", "not specified")
416 'not specified'
417 >>> result.get("hour")
419 """
420 if key in self:
421 return self[key]
422 else:
423 return default_value
425 def insert(self, index, ins_string):
426 """
427 Inserts new element at location index in the list of parsed tokens.
429 Similar to ``list.insert()``.
431 Example:
433 .. doctest::
435 >>> numlist = Word(nums)[...]
436 >>> print(numlist.parse_string("0 123 321"))
437 ['0', '123', '321']
439 >>> # use a parse action to insert the parse location
440 >>> # in the front of the parsed results
441 >>> def insert_locn(locn, tokens):
442 ... tokens.insert(0, locn)
443 ...
444 >>> numlist.add_parse_action(insert_locn)
445 [W:(0-9)]...
446 >>> print(numlist.parse_string("0 123 321"))
447 [0, '0', '123', '321']
449 """
450 self._toklist.insert(index, ins_string)
451 # fixup indices in token dictionary
452 for occurrences in self._tokdict.values():
453 for k, (value, position) in enumerate(occurrences):
454 occurrences[k] = _ParseResultsWithOffset(
455 value, position + (position > index)
456 )
458 def append(self, item):
459 """
460 Add single element to end of ``ParseResults`` list of elements.
462 Example:
464 .. doctest::
466 >>> numlist = Word(nums)[...]
467 >>> print(numlist.parse_string("0 123 321"))
468 ['0', '123', '321']
470 >>> # use a parse action to compute the sum of the parsed integers,
471 >>> # and add it to the end
472 >>> def append_sum(tokens):
473 ... tokens.append(sum(map(int, tokens)))
474 ...
475 >>> numlist.add_parse_action(append_sum)
476 [W:(0-9)]...
477 >>> print(numlist.parse_string("0 123 321"))
478 ['0', '123', '321', 444]
479 """
480 self._toklist.append(item)
482 def extend(self, itemseq):
483 """
484 Add sequence of elements to end of :class:`ParseResults` list of elements.
486 Example:
488 .. testcode::
490 patt = Word(alphas)[1, ...]
492 # use a parse action to append the reverse of the matched strings,
493 # to make a palindrome
494 def make_palindrome(tokens):
495 tokens.extend(reversed([t[::-1] for t in tokens]))
496 return ''.join(tokens)
498 patt.add_parse_action(make_palindrome)
499 print(patt.parse_string("lskdj sdlkjf lksd"))
501 prints:
503 .. testoutput::
505 ['lskdjsdlkjflksddsklfjkldsjdksl']
506 """
507 if isinstance(itemseq, ParseResults):
508 self.__iadd__(itemseq)
509 else:
510 self._toklist.extend(itemseq)
512 def clear(self):
513 """
514 Clear all elements and results names.
515 """
516 del self._toklist[:]
517 self._tokdict.clear()
519 def __getattr__(self, name):
520 try:
521 return self[name]
522 except KeyError:
523 if name.startswith("__"):
524 raise AttributeError(name)
525 return ""
527 def __add__(self, other: ParseResults) -> ParseResults:
528 ret = self.copy()
529 ret += other
530 return ret
532 def __iadd__(self, other: ParseResults) -> ParseResults:
533 if not other:
534 return self
536 if other._tokdict:
537 offset = len(self._toklist)
538 addoffset = lambda a: offset if a < 0 else a + offset
539 otheritems = other._tokdict.items()
540 otherdictitems = [
541 (k, _ParseResultsWithOffset(v[0], addoffset(v[1])))
542 for k, vlist in otheritems
543 for v in vlist
544 ]
545 for k, v in otherdictitems:
546 self[k] = v
547 if isinstance(v[0], ParseResults):
548 v[0]._parent = self
550 self._toklist += other._toklist
551 self._all_names |= other._all_names
552 return self
554 def __radd__(self, other) -> ParseResults:
555 if isinstance(other, int) and other == 0:
556 # useful for merging many ParseResults using sum() builtin
557 return self.copy()
558 else:
559 # this may raise a TypeError - so be it
560 return other + self
562 def __repr__(self) -> str:
563 return f"{type(self).__name__}({self._toklist!r}, {self.as_dict()})"
565 def __str__(self) -> str:
566 return (
567 "["
568 + ", ".join(
569 [
570 str(i) if isinstance(i, ParseResults) else repr(i)
571 for i in self._toklist
572 ]
573 )
574 + "]"
575 )
577 def _asStringList(self, sep=""):
578 out = []
579 for item in self._toklist:
580 if out and sep:
581 out.append(sep)
582 if isinstance(item, ParseResults):
583 out += item._asStringList()
584 else:
585 out.append(str(item))
586 return out
588 def as_list(self, *, flatten: bool = False) -> list:
589 """
590 Returns the parse results as a nested list of matching tokens, all converted to strings.
591 If ``flatten`` is True, all the nesting levels in the returned list are collapsed.
593 Example:
595 .. doctest::
597 >>> patt = Word(alphas)[1, ...]
598 >>> result = patt.parse_string("sldkj lsdkj sldkj")
599 >>> # even though the result prints in string-like form,
600 >>> # it is actually a pyparsing ParseResults
601 >>> type(result)
602 <class 'pyparsing.results.ParseResults'>
603 >>> print(result)
604 ['sldkj', 'lsdkj', 'sldkj']
606 .. doctest::
608 >>> # Use as_list() to create an actual list
609 >>> result_list = result.as_list()
610 >>> type(result_list)
611 <class 'list'>
612 >>> print(result_list)
613 ['sldkj', 'lsdkj', 'sldkj']
615 .. versionchanged:: 3.2.0
616 New ``flatten`` argument.
617 """
619 if flatten:
620 return [*_flatten(self)]
621 else:
622 return [
623 res.as_list() if isinstance(res, ParseResults) else res
624 for res in self._toklist
625 ]
627 def as_dict(self) -> dict:
628 """
629 Returns the named parse results as a nested dictionary.
631 Example:
633 .. doctest::
635 >>> integer = pp.Word(pp.nums)
636 >>> date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
638 >>> result = date_str.parse_string('1999/12/31')
639 >>> type(result)
640 <class 'pyparsing.results.ParseResults'>
641 >>> result
642 ParseResults(['1999', '/', '12', '/', '31'], {'year': '1999', 'month': '12', 'day': '31'})
644 >>> result_dict = result.as_dict()
645 >>> type(result_dict)
646 <class 'dict'>
647 >>> result_dict
648 {'year': '1999', 'month': '12', 'day': '31'}
650 >>> # even though a ParseResults supports dict-like access,
651 >>> # sometime you just need to have a dict
652 >>> import json
653 >>> print(json.dumps(result))
654 Traceback (most recent call last):
655 TypeError: Object of type ParseResults is not JSON serializable
656 >>> print(json.dumps(result.as_dict()))
657 {"year": "1999", "month": "12", "day": "31"}
658 """
660 def to_item(obj):
661 if isinstance(obj, ParseResults):
662 return obj.as_dict() if obj.haskeys() else [to_item(v) for v in obj]
663 else:
664 return obj
666 return dict((k, to_item(v)) for k, v in self.items())
668 def copy(self) -> ParseResults:
669 """
670 Returns a new shallow copy of a :class:`ParseResults` object.
671 :class:`ParseResults` items contained within the source are
672 shared with the copy. Use :meth:`ParseResults.deepcopy` to
673 create a copy with its own separate content values.
674 """
675 ret: ParseResults = object.__new__(ParseResults)
676 ret._toklist = self._toklist[:]
677 ret._tokdict = {**self._tokdict}
678 ret._parent = self._parent
679 ret._all_names = {*self._all_names}
680 ret._name = self._name
681 ret._modal = self._modal
682 return ret
684 def deepcopy(self) -> ParseResults:
685 """
686 Returns a new deep copy of a :class:`ParseResults` object.
688 .. versionadded:: 3.1.0
689 """
690 ret = self.copy()
691 # replace values with copies if they are of known mutable types
692 for i, obj in enumerate(self._toklist):
693 if isinstance(obj, ParseResults):
694 ret._toklist[i] = obj.deepcopy()
695 elif isinstance(obj, (str, bytes)):
696 pass
697 elif isinstance(obj, MutableMapping):
698 ret._toklist[i] = dest = type(obj)()
699 for k, v in obj.items():
700 dest[k] = v.deepcopy() if isinstance(v, ParseResults) else v
701 elif isinstance(obj, Iterable):
702 ret._toklist[i] = type(obj)(
703 v.deepcopy() if isinstance(v, ParseResults) else v for v in obj # type: ignore[call-arg]
704 )
705 return ret
707 def get_name(self) -> str | None:
708 r"""
709 Returns the results name for this token expression.
711 Useful when several different expressions might match
712 at a particular location.
714 Example:
716 .. testcode::
718 integer = Word(nums)
719 ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d")
720 house_number_expr = Suppress('#') + Word(nums, alphanums)
721 user_data = (Group(house_number_expr)("house_number")
722 | Group(ssn_expr)("ssn")
723 | Group(integer)("age"))
724 user_info = user_data[1, ...]
726 result = user_info.parse_string("22 111-22-3333 #221B")
727 for item in result:
728 print(item.get_name(), ':', item[0])
730 prints:
732 .. testoutput::
734 age : 22
735 ssn : 111-22-3333
736 house_number : 221B
738 """
739 if self._name:
740 return self._name
741 elif self._parent:
742 par: ParseResults = self._parent
743 parent_tokdict_items = par._tokdict.items()
744 return next(
745 (
746 k
747 for k, vlist in parent_tokdict_items
748 for v, loc in vlist
749 if v is self
750 ),
751 None,
752 )
753 elif (
754 len(self) == 1
755 and len(self._tokdict) == 1
756 and next(iter(self._tokdict.values()))[0][1] in (0, -1)
757 ):
758 return next(iter(self._tokdict.keys()))
759 else:
760 return None
762 def dump(self, indent="", full=True, include_list=True, _depth=0) -> str:
763 """
764 Diagnostic method for listing out the contents of
765 a :class:`ParseResults`. Accepts an optional ``indent`` argument so
766 that this string can be embedded in a nested display of other data.
768 Example:
770 .. testcode::
772 integer = Word(nums)
773 date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
775 result = date_str.parse_string('1999/12/31')
776 print(result.dump())
778 prints:
780 .. testoutput::
782 ['1999', '/', '12', '/', '31']
783 - day: '31'
784 - month: '12'
785 - year: '1999'
786 """
787 out = []
788 NL = "\n"
789 out.append(indent + str(self.as_list()) if include_list else "")
791 if not full:
792 return "".join(out)
794 if self.haskeys():
795 items = sorted((str(k), v) for k, v in self.items())
796 for k, v in items:
797 if out:
798 out.append(NL)
799 out.append(f"{indent}{(' ' * _depth)}- {k}: ")
800 if not isinstance(v, ParseResults):
801 out.append(repr(v))
802 continue
804 if not v:
805 out.append(str(v))
806 continue
808 out.append(
809 v.dump(
810 indent=indent,
811 full=full,
812 include_list=include_list,
813 _depth=_depth + 1,
814 )
815 )
816 if not any(isinstance(vv, ParseResults) for vv in self):
817 return "".join(out)
819 v = self
820 incr = " "
821 nl = "\n"
822 for i, vv in enumerate(v):
823 if isinstance(vv, ParseResults):
824 vv_dump = vv.dump(
825 indent=indent,
826 full=full,
827 include_list=include_list,
828 _depth=_depth + 1,
829 )
830 out.append(
831 f"{nl}{indent}{incr * _depth}[{i}]:{nl}{indent}{incr * (_depth + 1)}{vv_dump}"
832 )
833 else:
834 out.append(
835 f"{nl}{indent}{incr * _depth}[{i}]:{nl}{indent}{incr * (_depth + 1)}{vv}"
836 )
838 return "".join(out)
840 def pprint(self, *args, **kwargs):
841 """
842 Pretty-printer for parsed results as a list, using the
843 `pprint <https://docs.python.org/3/library/pprint.html>`_ module.
844 Accepts additional positional or keyword args as defined for
845 `pprint.pprint <https://docs.python.org/3/library/pprint.html#pprint.pprint>`_ .
847 Example:
849 .. testcode::
851 ident = Word(alphas, alphanums)
852 num = Word(nums)
853 func = Forward()
854 term = ident | num | Group('(' + func + ')')
855 func <<= ident + Group(Optional(DelimitedList(term)))
856 result = func.parse_string("fna a,b,(fnb c,d,200),100")
857 result.pprint(width=40)
859 prints:
861 .. testoutput::
863 ['fna',
864 ['a',
865 'b',
866 ['(', 'fnb', ['c', 'd', '200'], ')'],
867 '100']]
868 """
869 pprint.pprint(self.as_list(), *args, **kwargs)
871 # add support for pickle protocol
872 def __getstate__(self):
873 return (
874 self._toklist,
875 (
876 self._tokdict.copy(),
877 None,
878 self._all_names,
879 self._name,
880 ),
881 )
883 def __setstate__(self, state):
884 self._toklist, (self._tokdict, par, inAccumNames, self._name) = state
885 self._all_names = set(inAccumNames)
886 self._parent = None
888 def __getnewargs__(self):
889 return self._toklist, self._name
891 def __dir__(self):
892 return dir(type(self)) + list(self.keys())
894 @classmethod
895 def from_dict(cls, other, name=None) -> ParseResults:
896 """
897 Helper classmethod to construct a :class:`ParseResults` from a ``dict``, preserving the
898 name-value relations as results names. If an optional ``name`` argument is
899 given, a nested :class:`ParseResults` will be returned.
900 """
901 ret = cls([])
902 for k, v in other.items():
903 if isinstance(v, Mapping):
904 ret += cls.from_dict(v, name=k)
905 else:
906 ret += cls([v], name=k, aslist=_is_iterable(v))
907 if name is not None:
908 ret = cls([ret], name=name)
909 return ret
911 asList = as_list
912 """
913 .. deprecated:: 3.0.0
914 use :meth:`as_list`
915 """
916 asDict = as_dict
917 """
918 .. deprecated:: 3.0.0
919 use :meth:`as_dict`
920 """
921 getName = get_name
922 """
923 .. deprecated:: 3.0.0
924 use :meth:`get_name`
925 """
928MutableMapping.register(ParseResults)
929MutableSequence.register(ParseResults)