Opened 5 years ago

Closed 4 years ago

#30255 closed Bug (fixed)

docutils reports an error rendering view docstring when the first line is not empty

Reported by: Manlio Perillo Owned by: Baptiste Mispelon
Component: contrib.admindocs Version: dev
Severity: Normal Keywords:
Cc: Markus Zapke-Gründemann Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Currently admindoc works correctly only with docstrings where the first line is empty, and all Django docstrings are formatted in this way.
However usually the docstring text starts at the first line, e.g.:

def test():
    """test tests something.
    """

and this cause an error:

Error in "default-role" directive:
no content permitted.

.. default-role:: cmsreference

The culprit is this code in trim_docstring:

indent = min(len(line) - len(line.lstrip()) for line in lines if line.lstrip())

The problem is that the indentation of the first line is 0.

The solution is to skip the first line:

indent = min(len(line) - len(line.lstrip()) for line in lines[1:] if line.lstrip())

Thanks.

Change History (10)

comment:1 by Tim Graham, 5 years ago

Summary: docutils reports an error when the first line in a docstring is not emptydocutils reports an error rendering view docstring when the first line is not empty
Triage Stage: UnreviewedAccepted
Type: UncategorizedBug

Confirmed the patch fixes the issue, although it crashes for some tests with ValueError: min() arg is an empty sequence.

comment:2 by Simon Charette, 5 years ago

We should probably just switch to inspect.cleandoc as it implements the algorithm defined in PEP257.

in reply to:  1 comment:3 by Manlio Perillo, 5 years ago

Replying to Tim Graham:

Confirmed the patch fixes the issue, although it crashes for some tests with ValueError: min() arg is an empty sequence.

Yes, I also found it yesterday. The simple solution is:

indent = min((len(line) - len(line.lstrip()) for line in lines[1:] if line.lstrip()), default=0)

The default argument was added in Python 3.4, so it is safe to use in Django.

comment:4 by Tapasweni Pathak, 5 years ago

Hello folks: Can I PR?

comment:5 by Hasan Ramezani, 5 years ago

Owner: changed from nobody to Hasan Ramezani
Status: newassigned

I couldn't reproduce it on:

  • Python=3.7
  • django=master
  • docutils=0.15.2

@Manlio Perillo, Could you please help me? I am wrong?

Last edited 5 years ago by Hasan Ramezani (previous) (diff)

comment:6 by Markus Zapke-Gründemann, 5 years ago

Cc: Markus Zapke-Gründemann added

comment:7 by Hasan Ramezani, 4 years ago

@Manlio Perillo,
I couldn't reproduce this bug.
Could you please provide more information about this bug?
Python version, docutils version?

It would be good to have a model definition or test case.

Thanks.

comment:8 by Baptiste Mispelon, 4 years ago

Has patch: set
Version: 2.13.0

After a bit of trial and error, I finally managed to reproduce the issue on current master with an up-to-date version of docutils.

The trick was to use a docstring like this: "firstline\n\n second line" and not the one mentioned in the original report.

I took Simon's suggestion from comment 2 and removed trim_docstring in favor of inspect.cleandoc and it fixes the issue.

PR here

comment:9 by Mariusz Felisiak, 4 years ago

Owner: changed from Hasan Ramezani to Baptiste Mispelon
Version: 3.0master

comment:10 by Mariusz Felisiak <felisiak.mariusz@…>, 4 years ago

Resolution: fixed
Status: assignedclosed

In f47ba7e:

Fixed #30255 -- Fixed admindocs errors when rendering docstrings without leading newlines.

Used inspect.cleandoc() which implements PEP-257 instead of an internal
hook.

Note: See TracTickets for help on using tickets.
Back to Top