# Buggy code
def show_options(solver=None, method=None, disp=True):
    """
    Show documentation for additional options of optimization solvers.

    These are method-specific options that can be supplied through the
    ``options`` dict.

    Parameters
    ----------
    solver : str
        Type of optimization solver. One of 'minimize', 'minimize_scalar',
        'root', or 'linprog'.
    method : str, optional
        If not given, shows all methods of the specified solver. Otherwise,
        show only the options for the specified method. Valid values
        corresponds to methods' names of respective solver (e.g. 'BFGS' for
        'minimize').
    disp : bool, optional
        Whether to print the result rather than returning it.

    Returns
    -------
    text
        Either None (for disp=False) or the text string (disp=True)

    Notes
    -----
    The solver-specific methods are:

    `scipy.optimize.minimize`

    - :ref:`Nelder-Mead <optimize.minimize-neldermead>`
    - :ref:`Powell      <optimize.minimize-powell>`
    - :ref:`CG          <optimize.minimize-cg>`
    - :ref:`BFGS        <optimize.minimize-bfgs>`
    - :ref:`Newton-CG   <optimize.minimize-newtoncg>`
    - :ref:`L-BFGS-B    <optimize.minimize-lbfgsb>`
    - :ref:`TNC         <optimize.minimize-tnc>`
    - :ref:`COBYLA      <optimize.minimize-cobyla>`
    - :ref:`SLSQP       <optimize.minimize-slsqp>`
    - :ref:`dogleg      <optimize.minimize-dogleg>`
    - :ref:`trust-ncg   <optimize.minimize-trustncg>`

    `scipy.optimize.root`

    - :ref:`hybr              <optimize.root-hybr>`
    - :ref:`lm                <optimize.root-lm>`
    - :ref:`broyden1          <optimize.root-broyden1>`
    - :ref:`broyden2          <optimize.root-broyden2>`
    - :ref:`anderson          <optimize.root-anderson>`
    - :ref:`linearmixing      <optimize.root-linearmixing>`
    - :ref:`diagbroyden       <optimize.root-diagbroyden>`
    - :ref:`excitingmixing    <optimize.root-excitingmixing>`
    - :ref:`krylov            <optimize.root-krylov>`
    - :ref:`df-sane           <optimize.root-dfsane>`

    `scipy.optimize.minimize_scalar`

    - :ref:`brent       <optimize.minimize_scalar-brent>`
    - :ref:`golden      <optimize.minimize_scalar-golden>`
    - :ref:`bounded     <optimize.minimize_scalar-bounded>`

    `scipy.optimize.linprog`

    - :ref:`simplex         <optimize.linprog-simplex>`
    - :ref:`interior-point  <optimize.linprog-interior-point>`

    """
    import textwrap

    doc_routines = {
        "minimize": (
            ("bfgs", "scipy.optimize.optimize._minimize_bfgs"),
            ("cg", "scipy.optimize.optimize._minimize_cg"),
            ("cobyla", "scipy.optimize.cobyla._minimize_cobyla"),
            ("dogleg", "scipy.optimize._trustregion_dogleg._minimize_dogleg"),
            ("l-bfgs-b", "scipy.optimize.lbfgsb._minimize_lbfgsb"),
            ("nelder-mead", "scipy.optimize.optimize._minimize_neldermead"),
            ("newtoncg", "scipy.optimize.optimize._minimize_newtoncg"),
            ("powell", "scipy.optimize.optimize._minimize_powell"),
            ("slsqp", "scipy.optimize.slsqp._minimize_slsqp"),
            ("tnc", "scipy.optimize.tnc._minimize_tnc"),
            ("trust-ncg", "scipy.optimize._trustregion_ncg._minimize_trust_ncg"),
        ),
        "root": (
            ("hybr", "scipy.optimize.minpack._root_hybr"),
            ("lm", "scipy.optimize._root._root_leastsq"),
            ("broyden1", "scipy.optimize._root._root_broyden1_doc"),
            ("broyden2", "scipy.optimize._root._root_broyden2_doc"),
            ("anderson", "scipy.optimize._root._root_anderson_doc"),
            ("diagbroyden", "scipy.optimize._root._root_diagbroyden_doc"),
            ("excitingmixing", "scipy.optimize._root._root_excitingmixing_doc"),
            ("linearmixing", "scipy.optimize._root._root_linearmixing_doc"),
            ("krylov", "scipy.optimize._root._root_krylov_doc"),
            ("df-sane", "scipy.optimize._spectral._root_df_sane"),
        ),
        "linprog": (
            ("simplex", "scipy.optimize._linprog._linprog_simplex"),
            ("interior-point", "scipy.optimize._linprog._linprog_ip"),
        ),
        "minimize_scalar": (
            ("brent", "scipy.optimize.optimize._minimize_scalar_brent"),
            ("bounded", "scipy.optimize.optimize._minimize_scalar_bounded"),
            ("golden", "scipy.optimize.optimize._minimize_scalar_golden"),
        ),
    }

    if solver is None:
        text = ["\n\n\n========\n", "minimize\n", "========\n"]
        text.append(show_options("minimize", disp=False))
        text.extend(["\n\n===============\n", "minimize_scalar\n", "===============\n"])
        text.append(show_options("minimize_scalar", disp=False))
        text.extend(["\n\n\n====\n", "root\n", "====\n"])
        text.append(show_options("root", disp=False))
        text.extend(["\n\n\n=======\n", "linprog\n", "=======\n"])
        text.append(show_options("linprog", disp=False))
        text = "".join(text)
    else:
        solver = solver.lower()
        if solver not in doc_routines:
            raise ValueError("Unknown solver %r" % (solver,))

        if method is None:
            text = []
            for name, _ in doc_routines[solver]:
                text.extend(["\n\n" + name, "\n" + "=" * len(name) + "\n\n"])
                text.append(show_options(solver, name, disp=False))
            text = "".join(text)
        else:
            methods = dict(doc_routines[solver])
            if method not in methods:
                raise ValueError("Unknown method %r" % (method,))
            name = methods[method]

            # Import function object
            parts = name.split(".")
            mod_name = ".".join(parts[:-1])
            __import__(mod_name)
            obj = getattr(sys.modules[mod_name], parts[-1])

            # Get doc
            doc = obj.__doc__
            if doc is not None:
                text = textwrap.dedent(doc).strip()
            else:
                text = ""

    if disp:
        print(text)
        return
    else:
        return text


# Traceback (ValueError)
In [1]: from scipy.optimize import show_options

In [2]: show_options(solver='minimize', method='Newton-CG')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-2-2ef3b8f5feba> in <module>()
----> 1 show_options(solver='minimize', method='Newton-CG')

~/miniconda3scipy/lib/python3.5/site-packages/scipy-1.1.0.dev0+ecab276-py3.5-macosx-10.6-x86_64.egg/scipy/optimize/optimize.py in show_options(solver, method, disp)
3040             methods = dict(doc_routines[solver])
3041             if method not in methods:
-> 3042                 raise ValueError("Unknown method %r" % (method,))
3043             name = methods[method]
3044

ValueError: Unknown method 'Newton-CG'

# Fixed code
def show_options(solver=None, method=None, disp=True):
    """
    Show documentation for additional options of optimization solvers.

    These are method-specific options that can be supplied through the
    ``options`` dict.

    Parameters
    ----------
    solver : str
        Type of optimization solver. One of 'minimize', 'minimize_scalar',
        'root', or 'linprog'.
    method : str, optional
        If not given, shows all methods of the specified solver. Otherwise,
        show only the options for the specified method. Valid values
        corresponds to methods' names of respective solver (e.g. 'BFGS' for
        'minimize').
    disp : bool, optional
        Whether to print the result rather than returning it.

    Returns
    -------
    text
        Either None (for disp=False) or the text string (disp=True)

    Notes
    -----
    The solver-specific methods are:

    `scipy.optimize.minimize`

    - :ref:`Nelder-Mead <optimize.minimize-neldermead>`
    - :ref:`Powell      <optimize.minimize-powell>`
    - :ref:`CG          <optimize.minimize-cg>`
    - :ref:`BFGS        <optimize.minimize-bfgs>`
    - :ref:`Newton-CG   <optimize.minimize-newtoncg>`
    - :ref:`L-BFGS-B    <optimize.minimize-lbfgsb>`
    - :ref:`TNC         <optimize.minimize-tnc>`
    - :ref:`COBYLA      <optimize.minimize-cobyla>`
    - :ref:`SLSQP       <optimize.minimize-slsqp>`
    - :ref:`dogleg      <optimize.minimize-dogleg>`
    - :ref:`trust-ncg   <optimize.minimize-trustncg>`

    `scipy.optimize.root`

    - :ref:`hybr              <optimize.root-hybr>`
    - :ref:`lm                <optimize.root-lm>`
    - :ref:`broyden1          <optimize.root-broyden1>`
    - :ref:`broyden2          <optimize.root-broyden2>`
    - :ref:`anderson          <optimize.root-anderson>`
    - :ref:`linearmixing      <optimize.root-linearmixing>`
    - :ref:`diagbroyden       <optimize.root-diagbroyden>`
    - :ref:`excitingmixing    <optimize.root-excitingmixing>`
    - :ref:`krylov            <optimize.root-krylov>`
    - :ref:`df-sane           <optimize.root-dfsane>`

    `scipy.optimize.minimize_scalar`

    - :ref:`brent       <optimize.minimize_scalar-brent>`
    - :ref:`golden      <optimize.minimize_scalar-golden>`
    - :ref:`bounded     <optimize.minimize_scalar-bounded>`

    `scipy.optimize.linprog`

    - :ref:`simplex         <optimize.linprog-simplex>`
    - :ref:`interior-point  <optimize.linprog-interior-point>`

    """
    import textwrap

    doc_routines = {
        "minimize": (
            ("bfgs", "scipy.optimize.optimize._minimize_bfgs"),
            ("cg", "scipy.optimize.optimize._minimize_cg"),
            ("cobyla", "scipy.optimize.cobyla._minimize_cobyla"),
            ("dogleg", "scipy.optimize._trustregion_dogleg._minimize_dogleg"),
            ("l-bfgs-b", "scipy.optimize.lbfgsb._minimize_lbfgsb"),
            ("nelder-mead", "scipy.optimize.optimize._minimize_neldermead"),
            ("newton-cg", "scipy.optimize.optimize._minimize_newtoncg"),
            ("powell", "scipy.optimize.optimize._minimize_powell"),
            ("slsqp", "scipy.optimize.slsqp._minimize_slsqp"),
            ("tnc", "scipy.optimize.tnc._minimize_tnc"),
            ("trust-ncg", "scipy.optimize._trustregion_ncg._minimize_trust_ncg"),
        ),
        "root": (
            ("hybr", "scipy.optimize.minpack._root_hybr"),
            ("lm", "scipy.optimize._root._root_leastsq"),
            ("broyden1", "scipy.optimize._root._root_broyden1_doc"),
            ("broyden2", "scipy.optimize._root._root_broyden2_doc"),
            ("anderson", "scipy.optimize._root._root_anderson_doc"),
            ("diagbroyden", "scipy.optimize._root._root_diagbroyden_doc"),
            ("excitingmixing", "scipy.optimize._root._root_excitingmixing_doc"),
            ("linearmixing", "scipy.optimize._root._root_linearmixing_doc"),
            ("krylov", "scipy.optimize._root._root_krylov_doc"),
            ("df-sane", "scipy.optimize._spectral._root_df_sane"),
        ),
        "linprog": (
            ("simplex", "scipy.optimize._linprog._linprog_simplex"),
            ("interior-point", "scipy.optimize._linprog._linprog_ip"),
        ),
        "minimize_scalar": (
            ("brent", "scipy.optimize.optimize._minimize_scalar_brent"),
            ("bounded", "scipy.optimize.optimize._minimize_scalar_bounded"),
            ("golden", "scipy.optimize.optimize._minimize_scalar_golden"),
        ),
    }

    if solver is None:
        text = ["\n\n\n========\n", "minimize\n", "========\n"]
        text.append(show_options("minimize", disp=False))
        text.extend(["\n\n===============\n", "minimize_scalar\n", "===============\n"])
        text.append(show_options("minimize_scalar", disp=False))
        text.extend(["\n\n\n====\n", "root\n", "====\n"])
        text.append(show_options("root", disp=False))
        text.extend(["\n\n\n=======\n", "linprog\n", "=======\n"])
        text.append(show_options("linprog", disp=False))
        text = "".join(text)
    else:
        solver = solver.lower()
        if solver not in doc_routines:
            raise ValueError("Unknown solver %r" % (solver,))

        if method is None:
            text = []
            for name, _ in doc_routines[solver]:
                text.extend(["\n\n" + name, "\n" + "=" * len(name) + "\n\n"])
                text.append(show_options(solver, name, disp=False))
            text = "".join(text)
        else:
            method = method.lower()
            methods = dict(doc_routines[solver])
            if method not in methods:
                raise ValueError("Unknown method %r" % (method,))
            name = methods[method]

            # Import function object
            parts = name.split(".")
            mod_name = ".".join(parts[:-1])
            __import__(mod_name)
            obj = getattr(sys.modules[mod_name], parts[-1])

            # Get doc
            doc = obj.__doc__
            if doc is not None:
                text = textwrap.dedent(doc).strip()
            else:
                text = ""

    if disp:
        print(text)
        return
    else:
        return text