Skip to content

Commit

Permalink
Only support Sphinx >= 4 and Python >= 3.6 (#121)
Browse files Browse the repository at this point in the history
* Updated to version 0.12.0.
* Only Sphinx >= 4.0.0 is now supported.
* Only Python >= 3.6 is supported.
* Fixed numerous warnings due to deprecated Sphinx API.
* Fixed issue #101
* CI now tests on Python 3.6, 3.7, 3.8 and 3.9.
  • Loading branch information
joeced authored Jun 15, 2021
1 parent c389858 commit c0607c5
Show file tree
Hide file tree
Showing 24 changed files with 395 additions and 56 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ tests/test_docs/_build/
.pytest_cache/
.vscode/
_build
htmlcov
.coverage

4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
sudo: false
dist: xenial
language: python
python:
- "2.7"
python:
- "3.6"
- "3.7"
- "3.8"
- "3.9"
install:
- pip install tox-travis
script:
Expand Down
19 changes: 19 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
sphinxcontrib-matlabdomain-0.12.0 (2021-06-12)
==============================================

* Only Sphinx >= 4.0.0 is now supported.
* Only Python >= 3.6 is supported.
* Fixed numerous warnings due to `deprecated Sphinx API`_.
* Use ``sphinx.ext.autodoc.directive.DocumenterBridge.record_dependencies``
insted of ``sphinx.ext.autodoc.directive.DocumenterBridge.filename_set``.
* Use ``str.rpartition()`` insted of ``sphinx.util.rpartition()``
* Remove use of ``sphinx.util.force_decode()``.
* Use ``inspect.getmembers()`` insted of
``sphinx.util.inspect.safe_getmembers()``.
* Remove use of encoding argument in ``autodoc.Documenter.get_doc()``.
* Fixed `Issue 101 <https://github.com/sphinx-contrib/matlabdomain/issues/101>`_.
* CI now tests on Python 3.6, 3.7, 3.8 and 3.9.


sphinxcontrib-matlabdomain-0.11.8 (2021-05-12)
==============================================

Expand Down Expand Up @@ -356,3 +373,5 @@ sphinxcontrib-matlabdomain-0.1 (2013-04-25)
* create a Sphinx domain for MATLAB
* override standard domain to remove py modules index
.. _`deprecated Sphinx API`: https://www.sphinx-doc.org/en/master/extdev/deprecated.html
3 changes: 2 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ The Python package must be installed with::

pip install -U sphinxcontrib-matlabdomain

In general, the usage is the same as for documenting Python code.
In general, the usage is the same as for documenting Python code. The package
requires Python >= 3.6 and Sphinx >= 4.0.0.

For a Python 2 compatible version the package must be installed with::

Expand Down
2 changes: 1 addition & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[pytest]
log_print = False
addopts = --show-capture=all
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
with open('README.rst', 'r') as f_readme:
long_desc = f_readme.read()

requires = ['Sphinx<4.0.0>=1.72', 'Pygments>=2.0.1', 'future>=0.16.0']
requires = ['Sphinx>=4.0.0', 'Pygments>=2.0.1', 'future>=0.16.0']

setup(
name='sphinxcontrib-matlabdomain',
Expand Down
15 changes: 5 additions & 10 deletions sphinxcontrib/mat_directives.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from __future__ import unicode_literals
from sphinx.ext.autodoc.directive import AutodocDirective, DummyOptionSpec, DocumenterBridge
from sphinx.ext.autodoc.directive import process_documenter_options, parse_generated_content
from sphinx.util import logging
from sphinx import version_info

logger = logging.getLogger('matlab-domain')
import sphinx.util

logger = sphinx.util.logging.getLogger('matlab-domain')

class MatlabAutodocDirective(AutodocDirective):
"""A directive class for all MATLAB autodoc directives.
Expand Down Expand Up @@ -44,11 +42,8 @@ def run(self):
(self.name, exc), location=(source, lineno))
return []

# generate the output
if version_info[0] >= 2:
params = DocumenterBridge(self.env, reporter, documenter_options, lineno, self.state)
else:
params = DocumenterBridge(self.env, reporter, documenter_options, lineno)
# generate the output
params = DocumenterBridge(self.env, reporter, documenter_options, lineno, self.state)
documenter = doccls(params, self.arguments[0])
documenter.generate(more_content=self.content)
if not params.result:
Expand All @@ -58,7 +53,7 @@ def run(self):

# record all filenames as dependencies -- this will at least
# partially make automatic invalidation possible
for fn in params.filename_set:
for fn in params.record_dependencies:
self.state.document.settings.record_dependencies.add(fn)

result = parse_generated_content(self.state, params.result, documenter)
Expand Down
52 changes: 18 additions & 34 deletions sphinxcontrib/mat_documenters.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,16 @@
MatMethod, MatScript, MatException, MatModuleAnalyzer,
MatApplication, modules)


import re
import sys
import traceback
import inspect

from docutils.statemachine import ViewList

from sphinx.util import rpartition, force_decode
import sphinx.util
from sphinx.locale import _
from sphinx.pycode import PycodeError
# from sphinx.util.nodes import nested_parse_with_titles
# from sphinx.util.inspect import getargspec, isdescriptor, safe_getmembers, \
# safe_getattr, is_builtin_class_method
from sphinx.util.inspect import safe_getmembers, safe_getattr
from sphinx.util import logging
try:
# Sphinx >= 1.3.0
from sphinx.util.inspect import object_description
except ImportError:
# Sphinx < 1.3.0
from sphinx.util.inspect import safe_repr as object_description
from sphinx.util.docstrings import prepare_docstring

from sphinx.ext.autodoc import py_ext_sig_re as mat_ext_sig_re, \
identity, Options, ALL, INSTANCEATTR, members_option, \
members_set_option, SUPPRESS, annotation_option, bool_option, \
Expand All @@ -61,7 +48,7 @@
# TODO: check MRO's for all classes, attributes and methods!!!


logger = logging.getLogger('matlab-domain')
logger = sphinx.util.logging.getLogger('matlab-domain')


class MatlabDocumenter(PyDocumenter):
Expand All @@ -82,7 +69,7 @@ def parse_name(self):
try:
explicit_modname, path, base, args, retann = \
mat_ext_sig_re.match(self.name).groups()
except AttributeError:
except AttributeError:
self.directive.warn('invalid signature for auto%s (%r)' %
(self.objtype, self.name))
return False
Expand Down Expand Up @@ -148,9 +135,8 @@ def import_object(self):
errmsg = '[sphinxcontrib-matlabdomain]: failed to import %s %r' % \
(self.objtype, self.fullname)
errmsg += '; the following exception was raised:\n%s' % \
traceback.format_exc()
logger.debug(errmsg)
self.directive.warn(errmsg)
traceback.format_exc()
logger.warning(errmsg)
self.env.note_reread()
return False

Expand Down Expand Up @@ -222,7 +208,7 @@ def get_object_members(self, want_all):
elif self.options.inherited_members:
# safe_getmembers() uses dir() which pulls in members from all
# base classes
members = safe_getmembers(self.object, attr_getter=self.get_attr)
members = inspect.get_members(self.object, attr_getter=self.get_attr)
else:
# __dict__ contains only the members directly defined in
# the class (but get them via getattr anyway, to e.g. get
Expand Down Expand Up @@ -533,9 +519,9 @@ def generate(self, more_content=None, real_modname=None,
self.analyzer = None
# at least add the module.__file__ as a dependency
if hasattr(self.module, '__file__') and self.module.__file__:
self.directive.filename_set.add(self.module.__file__)
self.directive.record_dependencies.add(self.module.__file__)
else:
self.directive.filename_set.add(self.analyzer.srcname)
self.directive.record_dependencies.add(self.analyzer.srcname)

# check __module__ of object (for members not given explicitly)
if check_module:
Expand Down Expand Up @@ -608,7 +594,7 @@ def get_object_members(self, want_all):
self.directive.warn(
'missing attribute mentioned in :members: or __all__: '
'module %s, attribute %s' % (
safe_getattr(self.object, '__name__', '???'), mname))
sphinx.util.inspect.safe_getattr(self.object, '__name__', '???'), mname))
return False, ret


Expand Down Expand Up @@ -653,7 +639,7 @@ def resolve_name(self, modname, parents, path, base):
# ... if still None, there's no way to know
if mod_cls is None:
return None, []
modname, cls = rpartition(mod_cls, '.')
modname, _, cls = mod_cls.rpartition('.')
parents = [cls]
# if the module name is still missing, get it like above
if not modname:
Expand Down Expand Up @@ -687,7 +673,7 @@ def _find_signature(self, encoding=None):
if not self.objpath or base != self.objpath[-1]:
return
# re-prepare docstring to ignore indentation after signature
docstrings = MatlabDocumenter.get_doc(self, encoding, 2)
docstrings = MatlabDocumenter.get_doc(self, encoding)
doclines = docstrings[0]
# ok, now jump over remaining empty lines and set the remaining
# lines as the new doclines
Expand All @@ -697,11 +683,11 @@ def _find_signature(self, encoding=None):
setattr(self, '__new_doclines', doclines[i:])
return args, retann

def get_doc(self, encoding=None, ignore=1):
def get_doc(self, encoding=None):
lines = getattr(self, '__new_doclines', None)
if lines is not None:
return [lines]
return MatlabDocumenter.get_doc(self, encoding, ignore)
return MatlabDocumenter.get_doc(self, encoding)

def format_signature(self):
if self.args is None and self.env.config.autodoc_docstring_signature:
Expand Down Expand Up @@ -829,7 +815,7 @@ def add_directive_header(self, sig):
if base_class_links:
self.add_line(_(' Bases: %s') % ', '.join(base_class_links), '<autodoc>')

def get_doc(self, encoding=None, ignore=1):
def get_doc(self, encoding=None):
content = self.env.config.autoclass_content

docstrings = []
Expand Down Expand Up @@ -864,14 +850,12 @@ def get_doc(self, encoding=None, ignore=1):
docstrings.append(initdocstring)
doc = []
for docstring in docstrings:
if not isinstance(docstring, str):
docstring = force_decode(docstring, encoding)
doc.append(prepare_docstring(docstring))
doc.append(sphinx.util.docstrings.prepare_docstring(docstring))
return doc

def add_content(self, more_content, no_docstring=False):
if self.doc_as_attr:
classname = safe_getattr(self.object, '__name__', None)
classname = sphinx.util.inspect.safe_getattr(self.object, '__name__', None)
if classname:
content = ViewList(
[_('alias of :class:`%s`') % classname], source='')
Expand Down Expand Up @@ -975,7 +959,7 @@ def add_directive_header(self, sig):
if not self.options.annotation:
if not self._datadescriptor:
try:
objrepr = object_description(self.object.default) # display default
objrepr = sphinx.util.inspect.object_description(self.object.default) # display default
except ValueError:
pass
else:
Expand Down
4 changes: 2 additions & 2 deletions sphinxcontrib/mat_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
import re
import sys
from copy import copy
from sphinx.util import logging
import sphinx.util
from sphinxcontrib.mat_lexer import MatlabLexer
from pygments.token import Token
from zipfile import ZipFile
import xml.etree.ElementTree as ET

logger = logging.getLogger('matlab-domain')
logger = sphinx.util.logging.getLogger('matlab-domain')

modules = {}

Expand Down
10 changes: 6 additions & 4 deletions sphinxcontrib/matlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
from sphinx.directives import ObjectDescription
from sphinx.util.nodes import make_refnode
from sphinx.util.docfields import Field, GroupedField, TypedField
import sphinx.util

logger = sphinx.util.logging.getLogger('matlab-domain')


# REs for MATLAB signatures
Expand Down Expand Up @@ -732,10 +735,9 @@ def resolve_xref(self, env, fromdocname, builder,
if not matches:
return None
elif len(matches) > 1:
env.warn_node(
'more than one target found for cross-reference '
'%r: %s' % (target, ', '.join(match[0] for match in matches)),
node)
logger.warning('[sphinxcontrib-matlabdomain] more than one target found for cross-reference %r: %s',
target, ', '.join(match[0] for match in matches), type='ref', subtype='python', location=node)

name, obj = matches[0]

if obj[1] == 'module':
Expand Down
1 change: 1 addition & 0 deletions tests/roots/test_duplicate_link/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
_build/
20 changes: 20 additions & 0 deletions tests/roots/test_duplicate_link/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = sphinxcontrib-matlabdomain
SOURCEDIR = .
BUILDDIR = _build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
22 changes: 22 additions & 0 deletions tests/roots/test_duplicate_link/_src/+replab/Domain.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
classdef Domain
% Describes a set of elements with a common structure
%
% Those elements can be compared (`.eqv`), and random elements can be produced (`.sample`).

methods % ABSTRACT

function b = eqv(self, t, u)
% Tests domain elements for equality/equivalence
%
% Args:
% t (domain element): First element to test
% u (domain element): Second element to test
%
% Returns:
% logical: True when ``t`` and ``u`` are equivalent, and false otherwise
error('Abstract');
end

end

end
11 changes: 11 additions & 0 deletions tests/roots/test_duplicate_link/_src/+replab/FiniteGroup.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
classdef FiniteGroup < replab.CompactGroup
% Describes a group with a finite number of elements
%
% .. admonition:: Inherited elements
% :class: collapsed
%
% .. method:: eqv
%
% Documentation in :meth:`+replab.Domain.eqv`

end
10 changes: 10 additions & 0 deletions tests/roots/test_duplicate_link/_src/+replab/Group.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
classdef Group < replab.Monoid
% Describes a group
%
% .. admonition:: Inherited elements
% :class: collapsed
%
% .. method:: eqv
%
% Documentation in :meth:`+replab.Domain.eqv`
end
12 changes: 12 additions & 0 deletions tests/roots/test_duplicate_link/_src/+replab/Monoid.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
classdef Monoid < replab.Domain
% Describes a monoid
%
% See https://en.wikipedia.org/wiki/Monoid
%
% .. admonition:: Inherited elements
%
% .. method:: eqv
%
% Documentation in :meth:`+replab.Domain.eqv`

end
Loading

0 comments on commit c0607c5

Please sign in to comment.