code: def unmunchify(x):
      """Recursively converts a Munch into a dictionary.
  
      >>> b = Munch(foo=Munch(lol=True), hello=42, ponies='are pretty!')
      >>> sorted(unmunchify(b).items())
      [('foo', {'lol': True}), ('hello', 42), ('ponies', 'are pretty!')]
  
      unmunchify will handle intermediary dicts, lists and tuples (as well as
      their subclasses), but ymmv on custom datatypes.
  
      >>> b = Munch(foo=['bar', Munch(lol=True)], hello=42,
      ...         ponies=('are pretty!', Munch(lies='are trouble!')))
      >>> sorted(unmunchify(b).items()) #doctest: +NORMALIZE_WHITESPACE
      [('foo', ['bar', {'lol': True}]), ('hello', 42), ('ponies', ('are pretty!', {'lies': 'are trouble!'}))]
  
      nb. As dicts are not hashable, they cannot be nested in sets/frozensets.
      """
  
      # Munchify x, using `seen` to track object cycles
      seen = dict()
  
      def unmunchify_cycles(obj):
          # If we've already begun unmunchifying obj, just return the already-created unmunchified obj
          try:
              return seen[id(obj)]
          except KeyError:
              pass
  
          # Otherwise, first partly unmunchify obj (but without descending into any lists or dicts) and save that
          seen[id(obj)] = partial = pre_unmunchify(obj)
          # Then finish unmunchifying lists and dicts inside obj (reusing unmunchified obj if cycles are encountered)
          return post_unmunchify(partial, obj)
  
      def pre_unmunchify(obj):
          # Here we return a skeleton of unmunchified obj, which is enough to save for later (in case
          # we need to break cycles) but it needs to filled out in post_unmunchify
          if isinstance(obj, Mapping):
              return dict()
          elif isinstance(obj, list):
              return type(obj)()
          elif isinstance(obj, tuple):
              type_factory = getattr(obj, "_make", type(obj))
              return type_factory(
                  unmunchify_cycles(item) for item in obj
              )
          else:
              return obj
  
      def post_unmunchify(partial, obj):
          # Here we finish unmunchifying the parts of obj that were deferred by pre_unmunchify because they
          # might be involved in a cycle
          if isinstance(obj, Mapping):
              partial.update(
                  (k, unmunchify_cycles(obj[k])) for k in obj.keys()
              )
          elif isinstance(obj, list):
              partial.extend(unmunchify_cycles(v) for v in obj)
          elif isinstance(obj, tuple):
              for value_partial, value in zip(partial, obj):
                  post_unmunchify(value_partial, value)
  
          return partial
  
      return unmunchify_cycles(x)
  
imports: from collections.abc import Mapping
label_desc: Use image node_id 2 for calling a global function with example usage: unmunchify(x) and returns: unmunchify_cycles, post_unmunchify, partial, seen, dict, type, type_factory, obj