class_docstr: Base effect handler class for the :func:`~pyro.contrib.funsor.to_funsor`
  and :func:`~pyro.contrib.funsor.to_data` primitives.
  Any effect handlers that invoke these primitives internally or wrap
  code that does should inherit from :class:`~NamedMessenger`.
  
  This design ensures that the global name-dim mapping is reset upon handler exit
  rather than potentially persisting until the entire program terminates.
code: def _pyro_to_funsor(msg):
      if len(msg["args"]) == 2:
          raw_value, output = msg["args"]
      else:
          raw_value = msg["args"][0]
          output = msg["kwargs"].setdefault("output", None)
      dim_to_name = msg["kwargs"].setdefault(
          "dim_to_name", OrderedDict()
      )
      dim_type = msg["kwargs"].setdefault("dim_type", DimType.LOCAL)
  
      event_dim = len(output.shape) if output else 0
      try:
          batch_shape = (
              raw_value.batch_shape
          )  # TODO make make this more robust
      except AttributeError:
          full_shape = getattr(raw_value, "shape", ())
          batch_shape = full_shape[: len(full_shape) - event_dim]
  
      batch_dims = tuple(
          dim
          for dim in range(-len(batch_shape), 0)
          if batch_shape[dim] > 1
      )
  
      # interpret all names/dims as requests since we only run this function once
      dim_to_name_request = dim_to_name.copy()
      for dim in batch_dims:
          name = dim_to_name.get(dim, None)
          dim_to_name_request[dim] = (
              name
              if isinstance(name, DimRequest)
              else DimRequest(name, dim_type)
          )
  
      # request and update dim_to_name in-place
      dim_to_name.update(_DIM_STACK.allocate(dim_to_name_request))
  
      msg["stop"] = True
  
imports: from collections import OrderedDict
  from contextlib import ExitStack
  from pyro.contrib.funsor.handlers.runtime import _DIM_STACK, DimRequest, DimType, StackFrame
  from pyro.poutine.reentrant_messenger import ReentrantMessenger
label_desc: Use image node_id 5 for calling the NamedMessenger obj's underlying member method code with example usage: obj._pyro_to_funsor(msg) without return types