python setup.py check --restructuredtext --strict --metadata
fails with:
warning: check: Could not finish the parsing.
if the RST document uses code
or code-block
directives.
This is annoying because the document is valid, but it appears to be invalid
and confuses people. For example, see
https://github.com/ionelmc/pytest-benchmark/pull/4#issuecomment-66940307
Clone a repo that has a README.rst
with code-block
directives in it. E.g.:
$ git clone git@github.com:ionelmc/pytest-benchmark.git
$ cd pytest-benchmark
$ git checkout ab0b08f6fccb06a7909905a8409f8faa8b01e0d8
Observe that it has "code-blocks" in it:
$ grep 'code-block' README.rst .. code-block:: python .. code-block:: python
Observe that RST document is valid, according to rst2html.py
:
$ rst2html.py --halt=1 README.rst > README.html && echo "RST was OK." RST was OK. $ head -n 3 README.html <?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
Observe that python setup.py check --restructuredtext --strict --metadata
fails:
$ python setup.py check --restructuredtext --strict --metadata running check warning: check: Could not finish the parsing. error: Please correct your package. $ echo $? 1
What was expected: python setup.py check --restructuredtext --strict
--metadata
should succeed with no warnings, just as rst2html.py did
, because
README.rst
is a valid RST document.
What actually happened: python setup.py check --restructuredtext --strict
--metadata
prints a warning and an error and fails, unlike rst2html.py
The error is coming from here:
https://github.com/python/cpython/blob/master/Lib/distutils/command/check.py#L142
It's happening because of this line:
https://github.com/python/cpython/blob/master/Lib/distutils/command/check.py#L125
settings = frontend.OptionParser().get_default_values()
If this is changed to:
settings = frontend.OptionParser(components=(Parser,)).get_default_values()
then things work much better (this is how tools/quicktest.py
does it for example)
so this might actually be a bug in distutils, but changing CPython (and maybe PyPy) is a more laborious and slow process, so I'm thinking it might be nice to work around this in docutils, if isn't too much of a burden. Docutils is on a much shorter release cycle than CPython, so changing docutils is a way to get this fix out to users much faster.
Here's a patch to docutils that solves the problem for me:
diff --git a/docutils/frontend.py.2014-12-15-070721 b/docutils/frontend.py index f837c62..7427e15 100644 --- a/docutils/frontend.py.2014-12-15-070721 +++ b/docutils/frontend.py @@ -41,6 +41,7 @@ import docutils import docutils.utils import docutils.nodes from docutils.utils.error_reporting import locale_encoding, ErrorOutput, ErrorString +from docutils.parsers import Parser def store_multiple(option, opt, value, parser, *args, **kwargs): @@ -561,7 +562,20 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): self.version = self.version_template # Make an instance copy (it will be modified): self.relative_path_settings = list(self.relative_path_settings) + from docutils.parsers.rst import Parser self.components = (self,) + tuple(components) + + # distutils.command.check does: + # settings = frontend.OptionParser().get_default_values() + # and as a result is missing important defaults like + # `syntax_highlight`, causing + # `python setup.py check --restructuredtext --strict --metadata` to + # fail with `warning: check: Could not finish the parsing.` if the RST + # document uses `code` or `code-block` directives. + if len(self.components) == 1: + from docutils.parsers.rst import Parser + self.components += (Parser,) + self.populate_from_components(self.components) self.set_defaults_from_dict(defaults or {}) if read_config_files and not self.defaults['_disable_config']:
Attaching
bug_270.patch
, a patch to docutils that fixes this issue ...Last edit: marcman 2014-12-15
After some discussion on the mailing list with David Goodger, I am revising this a bit. He wanted it to check that it was being called by docutils before messing with anything.
I also created a Python issue (and patch) for this:
http://bugs.python.org/issue23063
but it would be nice still to add a workaround to docutils, so that folks don't need Python 3.5 for this to work.
I also created a branch and pull request on GitHub for this, in case folks find that easier to read and pull from:
https://github.com/msabramo/docutils/pull/1
It seems like this is fixed upstream now (no need to wait for 3.5):
http://bugs.python.org/msg234051
Thank you for the report(s), analysis, patch, and patience.