docs: def py_bisect(f, a, b, args=(), xtol=_xtol, rtol=_rtol, maxiter=_iter,
                ytol=None, full_output=False, disp=True):
      '''Port of SciPy's C bisect routine.
      '''
      fa = f(a, *args)
      fb = f(b, *args)
      if fa*fb > 0.0:
          raise ValueError("f(a) and f(b) must have different signs") 
      elif fa == 0.0:
          return a
      elif fb == 0.0:
          return b
  
      dm = b - a
      iterations = 0.0
      
      for i in range(maxiter):
          dm *= 0.5
          xm = a + dm
          fm = f(xm, *args)
          if fm*fa >= 0.0:
              a = xm
          abs_dm = fabs(dm)
          
          if fm == 0.0:
              return xm
          elif ytol is not None:
              if (abs_dm < xtol + rtol*abs_dm) and abs(fm) < ytol:
                  return xm
          elif (abs_dm < xtol + rtol*abs_dm):
              return xm
      raise UnconvergedError("Failed to converge after %d iterations" %maxiter)