sphinx-contrib / matlabdomain

A Sphinx extension for documenting Matlab code
http://sphinxcontrib-matlabdomain.readthedocs.io/
Other
70 stars 45 forks source link

Parser does not ignore a comment line on the top of a file and fails #58

Closed Ganimed closed 6 years ago

Ganimed commented 6 years ago

This is a fork from issue #57 to split up two different problems.

As I have mentioned in the previous discussion, I was testing what will happen when a simple comment is set on the top of the file (before function or defclass). The result was that the parser does not ignore the comment and causes that matlabdomain will crash with following unhandled exception:

Exception occurred:
  File "/usr/local/lib/python2.7/dist-packages/sphinxcontrib/mat_types.py", line 1104, in for_module
    obj = cls.for_folder(mod.path, modname)
AttributeError: 'module' object has no attribute 'path'

This will happen when .. autoclass:: or .. autofunction:: will be called with the corresponding class or function name.

Here is the corresponding log:

# Sphinx version: 1.6.6
# Python version: 2.7.12 (CPython)
# Docutils version: 0.14 
# Jinja2 version: 2.10
# Last messages:
#   Running Sphinx v1.6.6
#   loading pickled environment...
#   not yet created
#   building [mo]: targets for 0 po files that are out of date
#   building [html]: targets for 4 source files that are out of date
#   updating environment:
#   4 added, 0 changed, 0 removed
#   reading sources... [ 25%] _sources/documentation
#   reading sources... [ 50%] _sources/wbm/modules
# Loaded extensions:
#   sphinx.ext.mathjax (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/mathjax.pyc
#   sphinx.ext.viewcode (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/viewcode.pyc
#   sphinx.ext.napoleon (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/napoleon/__init__.pyc
#   sphinx.ext.autodoc (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/autodoc.pyc
#   sphinxcontrib.matlab (unknown version) from /usr/local/lib/python2.7/dist-packages/sphinxcontrib/matlab.pyc
#   sphinx.ext.graphviz (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/graphviz.pyc
#   alabaster (0.7.10) from /usr/local/lib/python2.7/dist-packages/alabaster/__init__.pyc
#   sphinx.ext.ifconfig (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/ifconfig.pyc
#   sphinx.ext.githubpages (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/githubpages.pyc
#   sphinxcontrib.plantuml (unknown version) from /usr/local/lib/python2.7/dist-packages/sphinxcontrib/plantuml.pyc
#   sphinx.ext.autosummary (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/autosummary/__init__.pyc
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/sphinx/cmdline.py", line 306, in main
    app.build(opts.force_all, filenames)
  File "/usr/local/lib/python2.7/dist-packages/sphinx/application.py", line 339, in build
    self.builder.build_update()
  File "/usr/local/lib/python2.7/dist-packages/sphinx/builders/__init__.py", line 329, in build_update
    'out of date' % len(to_build))
  File "/usr/local/lib/python2.7/dist-packages/sphinx/builders/__init__.py", line 342, in build
    updated_docnames = set(self.env.update(self.config, self.srcdir, self.doctreedir))
  File "/usr/local/lib/python2.7/dist-packages/sphinx/environment/__init__.py", line 601, in update
    self._read_serial(docnames, self.app)
  File "/usr/local/lib/python2.7/dist-packages/sphinx/environment/__init__.py", line 621, in _read_serial
    self.read_doc(docname, app)
  File "/usr/local/lib/python2.7/dist-packages/sphinx/environment/__init__.py", line 758, in read_doc
    pub.publish()
  File "/usr/local/lib/python2.7/dist-packages/docutils/core.py", line 217, in publish
    self.settings)
  File "/usr/local/lib/python2.7/dist-packages/sphinx/io.py", line 74, in read
    self.parse()
  File "/usr/local/lib/python2.7/dist-packages/docutils/readers/__init__.py", line 78, in parse
    self.parser.parse(self.input, document)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/__init__.py", line 191, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 171, in run
    input_source=document['source'])
  File "/usr/local/lib/python2.7/dist-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/usr/local/lib/python2.7/dist-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2753, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 395, in new_subsection
    node=section_node, match_titles=True)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
    node=node, match_titles=match_titles)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/usr/local/lib/python2.7/dist-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/usr/local/lib/python2.7/dist-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2328, in explicit_markup
    self.explicit_list(blank_finish)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2358, in explicit_list
    match_titles=self.state_machine.match_titles)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 319, in nested_list_parse
    node=node, match_titles=match_titles)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/usr/local/lib/python2.7/dist-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/usr/local/lib/python2.7/dist-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2631, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2338, in explicit_construct
    return method(self, expmatch)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2081, in directive
    directive_class, match, type_name, option_presets)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2130, in run_directive
    result = directive_instance.run()
  File "/usr/local/lib/python2.7/dist-packages/sphinx/ext/autodoc.py", line 1843, in run
    documenter.generate(more_content=self.content)
  File "/usr/local/lib/python2.7/dist-packages/sphinxcontrib/mat_documenters.py", line 416, in generate
    self.analyzer = MatModuleAnalyzer.for_module(self.real_modname)
  File "/usr/local/lib/python2.7/dist-packages/sphinxcontrib/mat_types.py", line 1104, in for_module
    obj = cls.for_folder(mod.path, modname)
AttributeError: 'module' object has no attribute 'path'

So I have studied your code in mat_types.py and found a simple solution for this error that would kill 2 birds with one stone. I added in MatObject a simple function that removes any comment line or empty line above a class or function. This will be done after the file was read and before the code string will be parsed. This leads to, that no exception will be raised and at the same time it allows to write some comments or a long comment header outside of a class or function that should be ignored by the matlabdomain.

Currently, I have not tested this with a script file. But for class-files and function-files works this solution well.

But the decision is up to you if want or like this kind of solution.

joeced commented 6 years ago

Sounds like an okay solution to me. Make a pull request, so I can review the code. A pull request will also run the current test suite.

Ganimed commented 6 years ago

I have some difficulties with making a pull request. I.e. I made my changes locally in an own local branch called "remove_comment_header". But how can I make a pull request with this local branch?

joeced commented 6 years ago

I'm not an git expert :). What I normally do (like 2-3 times) is to fork the project to my own github account, and push the changes to this fork. From there it is easy to make a pull request.

Ganimed commented 6 years ago

Thank's for the hint, I'm also not a git-expert. ;)

joeced commented 6 years ago

Fixed in 4abc42e3210758028709819aad7fccc885deb677