1

Is there a way to have a module attribute value documented by Sphinx to be truncated:

Let's define a module attribute:

import numpy as np

MY_MODULE_ATTRIBUTE = np.linspace(-10, 10, 64)
"""
Defines a very ugly *sphinx* rendered module member.
"""

The output will be something like that (You can scroll for very long on the right):

foo module

foo.hello.MY_MODULE_ATTRIBUTE = array([-10. , -9.68253968, -9.36507937, -9.04761905, -8.73015873, -8.41269841, -8.0952381 , -7.77777778, -7.46031746, -7.14285714, -6.82539683, -6.50793651, -6.19047619, -5.87301587, -5.55555556, -5.23809524, -4.92063492, -4.6031746 , -4.28571429, -3.96825397, -3.65079365, -3.33333333, -3.01587302, -2.6984127 , -2.38095238, -2.06349206, -1.74603175, -1.42857143, -1.11111111, -0.79365079, -0.47619048, -0.15873016, 0.15873016, 0.47619048, 0.79365079, 1.11111111, 1.42857143, 1.74603175, 2.06349206, 2.38095238, 2.6984127 , 3.01587302, 3.33333333, 3.65079365, 3.96825397, 4.28571429, 4.6031746 , 4.92063492, 5.23809524, 5.55555556, 5.87301587, 6.19047619, 6.50793651, 6.82539683, 7.14285714, 7.46031746, 7.77777778, 8.0952381 , 8.41269841, 8.73015873, 9.04761905, 9.36507937, 9.68253968, 10. ])
Defines a very ugly sphinx rendered module member.

Which will either wrap or stretch in a very very ugly fashion. Something nicer would be of that kind:

foo module

foo.hello.MY_MODULE_ATTRIBUTE = array([-10. , -9.68253968, ..., 9.68253968, 10. ])
Defines a very ugly sphinx rendered module member.
Kel Solaar
  • 3,660
  • 1
  • 23
  • 29

2 Answers2

3

The attribute value is output by the add_directive_header() method of Sphinx's DataDocumenter class. This monkey patch can be used to truncate it:

from sphinx.ext.autodoc import DataDocumenter, ModuleLevelDocumenter, SUPPRESS
from sphinx.util.inspect import safe_repr

def add_directive_header(self, sig):
    ModuleLevelDocumenter.add_directive_header(self, sig)
    if not self.options.annotation:
        try:
            objrepr = safe_repr(self.object)

            # PATCH: truncate the value if longer than 50 characters
            if len(objrepr) > 50:                  
                objrepr = objrepr[:50] + "..." 

        except ValueError:
            pass
        else:
            self.add_line(u'   :annotation: = ' + objrepr, '<autodoc>')
    elif self.options.annotation is SUPPRESS:
        pass
    else:
        self.add_line(u'   :annotation: %s' % self.options.annotation,
                      '<autodoc>')

DataDocumenter.add_directive_header = add_directive_header

Just add the code above to conf.py.

mzjn
  • 48,958
  • 13
  • 128
  • 248
  • 1
    Last night, I came up monkey patching the **DataDocumenter.import_object** and altering directly the object value. Your proposal is way better! – Kel Solaar Aug 06 '14 at 15:36
  • In Sphinx 1.3, the `safe_repr` function is replaced by `object_description`. – mzjn Mar 25 '15 at 17:48
0

Since I didn't specified in which context / output I wanted that truncation to happen, I found a CSS solution for the html output:

.ellipsis {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

I would rather prefer that to be done at the source if possible, so that the fix is available for any kind of output.

Edit:

I came across this: http://sphinx-doc.org/ext/autodoc.html#event-autodoc-process-signature It should do what I need, I managed to replace all my signatures with it. When I have a proper code I will push it here.

Kel Solaar
  • 3,660
  • 1
  • 23
  • 29
  • It's unfortunately not possible to do what I wanted with the **autodoc-process-docstring** event, the object value is not alterable at that level. – Kel Solaar Aug 06 '14 at 15:38