spyder-ide / spyder

Official repository for Spyder - The Scientific Python Development Environment
https://www.spyder-ide.org
MIT License
8.34k stars 1.62k forks source link

Help doesn't get rendered properly when Ctrl+I pressed from the editor #12492

Open ma-sadeghi opened 4 years ago

ma-sadeghi commented 4 years ago

Description

What steps will reproduce the problem?

When pressing Ctrl+I from the editor on a class, the Help tab doesn't get rendered properly, whereas doing the same thing from IPython console seems to work fine. Here are some pictures:

From the editor: image From IPython console: image

And here's the docstrings of the FickianDiffusion class:

@docstr.dedent
class FickianDiffusion(ReactiveTransport):
    r"""
    A class to simulate binary diffusion with reactions

    Parameters
    ----------
    %(ReactiveTransport.parameters)s

    Notes
    -----
    Fickian diffusion in porous materials occurs in the void space, but
    becuase the diffusion is defined to pores it is impacted by the porosity
    and tortuosity of the network.  Thus the total diffusive flux through the
    network is reduced.  This class can be used to simualte diffusion-reaction
    in domains with arbitrarily complex boundary conditions, or it can be used
    to calculate the effective diffusivity of the network by applying
    controlled boundary conditions on opposing faces, calculate the diffusion
    rate, and inverting Fick's first law:

    .. math::

        D_{eff} = N_{A}*L/(A*\Delta C_{A})

    This class includes a method for calculating Deff automatically assuming
    appropriate boundary conditions were applied (``calc_eff_diffusivity``).
    The length and area of the domain should be supplied, but if they are
    not an attempt is made to calculate them.

    """

    def __init__(self, settings={}, **kwargs):
        super().__init__(**kwargs)

We use docrep library to pull sections of the docstrings of the parent class.

Versions

Dependencies


# Mandatory:
atomicwrites >=1.2.0           :  1.3.0 (OK)
chardet >=2.0.0                :  3.0.4 (OK)
cloudpickle >=0.5.0            :  1.3.0 (OK)
diff_match_patch >=20181111    :  20181111 (OK)
intervaltree                   :  None (OK)
IPython >=4.0                  :  7.13.0 (OK)
jedi =0.15.2                   :  0.15.2 (OK)
nbconvert >=4.0                :  5.6.1 (OK)
numpydoc >=0.6.0               :  0.9.2 (OK)
paramiko >=2.4.0               :  2.7.1 (OK)
parso =0.5.2                   :  0.5.2 (OK)
pexpect >=4.4.0                :  4.8.0 (OK)
pickleshare >=0.4              :  0.7.5 (OK)
psutil >=5.3                   :  5.7.0 (OK)
pygments >=2.0                 :  2.6.1 (OK)
pylint >=0.25                  :  2.4.4 (OK)
pyls >=0.31.9;<0.32.0          :  0.31.9 (OK)
qdarkstyle >=2.8               :  2.8 (OK)
qtawesome >=0.5.7              :  0.7.0 (OK)
qtconsole >=4.6.0              :  4.7.2 (OK)
qtpy >=1.5.0                   :  1.9.0 (OK)
rtree >=0.8.3                  :  0.9.3 (OK)
sphinx >=0.6.6                 :  2.4.4 (OK)
spyder_kernels >=1.9.0;<1.10.0 :  1.9.0 (OK)
watchdog                       :  None (OK)
zmq >=17                       :  18.1.1 (OK)

# Optional:
cython >=0.21                  :  0.29.15 (OK)
matplotlib >=2.0.0             :  3.1.3 (OK)
numpy >=1.7                    :  1.18.1 (OK)
pandas >=0.13.1                :  1.0.3 (OK)
scipy >=0.17.0                 :  1.4.1 (OK)
sympy >=0.7.3                  :  1.5.1 (OK)
ccordoba12 commented 4 years ago

We use docrep library to pull sections of the docstrings of the parent class.

This could be the issue here. Could you expand a bit more on how you do that?

ma-sadeghi commented 4 years ago

Here's how docrep works. In this example, the "Parameters" section of do_more method is inherited from do_something method as they're identical. I'm copying from the documentation of docrep package:

In [4]: import docrep

In [5]: docstrings = docrep.DocstringProcessor()

In [6]: @docstrings.get_sectionsf('do_something')
   ...: @docstrings.dedent
   ...: def do_something(a, b):
   ...:     """
   ...:     Add two numbers
   ...: 
   ...:     Parameters
   ...:     ----------
   ...:     a: int
   ...:         The first number
   ...:     b: int
   ...:         The second number
   ...: 
   ...:     Returns
   ...:     -------
   ...:     int
   ...:         `a` + `b`"""
   ...:     return a + b
   ...: 

In [7]: @docstrings.dedent
   ...: def do_more(*args, **kwargs):
   ...:     """
   ...:     Add two numbers and multiply it by 2
   ...: 
   ...:     Parameters
   ...:     ----------
   ...:     %(do_something.parameters)s
   ...: 
   ...:     Returns
   ...:     -------
   ...:     int
   ...:         (`a` + `b`) * 2"""
   ...:     return do_something(*args, **kwargs) * 2
   ...: 

In [8]: help(do_more)
Help on function do_more in module __main__:

do_more(*args, **kwargs)
    Add two numbers and multiply it by 2

    Parameters
    ----------
    a: int
        The first number
    b: int
        The second number

    Returns
    -------
    int
        (`a` + `b`) * 2
ccordoba12 commented 4 years ago

I see. Unfortunately this is not something we can solve here. We'll try to solve it in the upstream project we rely on to get docstrings in the editor, but I can't promise a short term solution.

ma-sadeghi commented 4 years ago

@ccordoba12 Thanks. Just a quick question: how is it that the IPython console gets it right? I assume a different tool is used there?

ccordoba12 commented 4 years ago

how is it that the IPython console gets it right? I assume a different tool is used there?

Yes, that's right. The editor and the IPython console used different ways to introspect code.