class_docstr: Dispatch methods based on type signature
  
  Use ``dispatch`` to add implementations
  
  Examples
  --------
  
  >>> from sympy.multipledispatch import dispatch
  >>> @dispatch(int)
  ... def f(x):
  ...     return x + 1
  
  >>> @dispatch(float)
  ... def f(x): # noqa: F811
  ...     return x - 1
  
  >>> f(3)
  4
  >>> f(3.0)
  2.0
docstr: Add new types/method pair to dispatcher
  
  >>> from sympy.multipledispatch import Dispatcher
  >>> D = Dispatcher('add')
  >>> D.add((int, int), lambda x, y: x + y)
  >>> D.add((float, float), lambda x, y: x + y)
  
  >>> D(1, 2)
  3
  >>> D(1, 2.0)
  Traceback (most recent call last):
  ...
  NotImplementedError: Could not find signature for add: <int, float>
  
  When ``add`` detects a warning it calls the ``on_ambiguity`` callback
  with a dispatcher/itself, and a set of ambiguous type signature pairs
  as inputs.  See ``ambiguity_warn`` for an example.
docstr_tok: ["Add","new","types\/method","pair","to","dispatcher",">",">",">","from","sympy.multipledispatch","import","Dispatcher",">",">",">","D","=","Dispatcher","(","'add","'",")",">",">",">","D.add","(","(","int",",","int",")",",","lambda","x",",","y",":","x","+","y",")",">",">",">","D.add","(","(","float",",","float",")",",","lambda","x",",","y",":","x","+","y",")",">",">",">","D","(","1",",","2",")","3",">",">",">","D","(","1",",","2.0",")","Traceback","(","most","recent","call","last",")",":","...","NotImplementedError",":","Could","not","find","signature","for","add",":","<","int",",","float",">","When","``","add","``","detects","a","warning","it","calls","the","``","on_ambiguity","``","callback","with","a","dispatcher\/itself",",","and","a","set","of","ambiguous","type","signature","pairs","as","inputs",".","See","``","ambiguity_warn","``","for","an","example","."]
code: def add(self, signature, func, on_ambiguity=ambiguity_warn):
      """Add new types/method pair to dispatcher
  
      >>> from sympy.multipledispatch import Dispatcher
      >>> D = Dispatcher('add')
      >>> D.add((int, int), lambda x, y: x + y)
      >>> D.add((float, float), lambda x, y: x + y)
  
      >>> D(1, 2)
      3
      >>> D(1, 2.0)
      Traceback (most recent call last):
      ...
      NotImplementedError: Could not find signature for add: <int, float>
  
      When ``add`` detects a warning it calls the ``on_ambiguity`` callback
      with a dispatcher/itself, and a set of ambiguous type signature pairs
      as inputs.  See ``ambiguity_warn`` for an example.
      """
      # Handle annotations
      if not signature:
          annotations = self.get_func_annotations(func)
          if annotations:
              signature = annotations
  
      # Handle union types
      if any(isinstance(typ, tuple) for typ in signature):
          for typs in expand_tuples(signature):
              self.add(typs, func, on_ambiguity)
          return
  
      for typ in signature:
          if not isinstance(typ, type):
              str_sig = ", ".join(
                  c.__name__ if isinstance(c, type) else str(c)
                  for c in signature
              )
              raise TypeError(
                  "Tried to dispatch on non-type: %s\n"
                  "In signature: <%s>\n"
                  "In function: %s" % (typ, str_sig, self.name)
              )
  
      self.funcs[signature] = func
      self.reorder(on_ambiguity=on_ambiguity)
      self._cache.clear()
  
imports: from __future__ import annotations
  from warnings import warn
  import inspect
  from .conflict import ordering, ambiguities, super_signature, AmbiguityWarning
  from .utils import expand_tuples
  import itertools
label_desc: Use image node_id 5 for calling the Dispatcher obj's underlying member method code with example usage: obj.add(signature, func, on_ambiguity) without return types