class_docstr: Given a stochastic function with some sample statements
  and a dictionary of values at names,
  set the return values of those sites equal to the values
  as if they were hard-coded to those values
  and introduce fresh sample sites with the same names
  whose values do not propagate.
  
  Composes freely with :func:`~pyro.poutine.handlers.condition`
  to represent counterfactual distributions over potential outcomes.
  See Single World Intervention Graphs [1] for additional details and theory.
  
  Consider the following Pyro program:
  
      >>> def model(x):
      ...     s = pyro.param("s", torch.tensor(0.5))
      ...     z = pyro.sample("z", dist.Normal(x, s))
      ...     return z ** 2
  
  To intervene with a value for site `z`, we can write
  
      >>> intervened_model = pyro.poutine.do(model, data={"z": torch.tensor(1.)})
  
  This is equivalent to replacing `z = pyro.sample("z", ...)` with
  `z = torch.tensor(1.)`
  and introducing a fresh sample site pyro.sample("z", ...) whose value is not used elsewhere.
  
  References
  
  [1] `Single World Intervention Graphs: A Primer`,
      Thomas Richardson, James Robins
  
  :param fn: a stochastic function (callable containing Pyro primitive calls)
  :param data: a ``dict`` mapping sample site names to interventions
  :returns: stochastic function decorated with a :class:`~pyro.poutine.do_messenger.DoMessenger`
code: def __init__(
      self, data: Dict[str, Union[torch.Tensor, numbers.Number]]
  ) -> None:
      super().__init__()
      self.data = data
      self._intervener_id = str(id(self))
  
file_path: pyro/pyro/poutine/do_messenger.py
imports: import numbers
  import warnings
  from typing import Dict, Union
  import torch
  from pyro.poutine.messenger import Messenger
  from pyro.poutine.runtime import Message, apply_stack
label_desc: Use image node_id 1 to create a new DoMessenger object from inherited base classes: Messenger with example: obj = DoMessenger(data)