Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-breathe for openSUSE:Factory checked in at 2021-03-02 12:25:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-breathe (Old) and /work/SRC/openSUSE:Factory/.python-breathe.new.2378 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-breathe" Tue Mar 2 12:25:34 2021 rev:12 rq:874949 version:4.27.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-breathe/python-breathe.changes 2020-12-12 20:32:09.513839157 +0100 +++ /work/SRC/openSUSE:Factory/.python-breathe.new.2378/python-breathe.changes 2021-03-02 12:25:36.151324396 +0100 @@ -1,0 +2,19 @@ +Thu Feb 25 03:13:38 UTC 2021 - Steve Kowalik <steven.kowa...@suse.com> + +- Update to 4.27.0: + * Add various specifiers to functions and variables. #628 + * Add multiply inherited class for PHP objects. #630 + * Initial support for table rendering. #632 + * Add rendering of \section, \subsection and \subsubsection. #635 + * Sphinx 3.5 compatibility. #640 + * Fix linking to sections. #639 + * Add table examples to documentation. #638 + * Fix doxygenfile causing duplicate IDs for unspecified sections. #622 + * Fixes for doxygenfunction (friend keyword, friend class, arg checks). #623 + * Add test for ellipsis ('...') in args. #610 + * Sphinx 3.4.x compatibility. #617 + * Adapt friendclass to Doxygen 1.9. #618 + * Add support for \parblock parsing and rendering. #603 + * Allow lookup in doxygenfunction without writing param names. #606 + +------------------------------------------------------------------- Old: ---- v4.24.1.tar.gz New: ---- v4.27.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-breathe.spec ++++++ --- /var/tmp/diff_new_pack.sTBIjm/_old 2021-03-02 12:25:36.823325028 +0100 +++ /var/tmp/diff_new_pack.sTBIjm/_new 2021-03-02 12:25:36.827325032 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-breathe # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %define skip_python2 1 Name: python-breathe -Version: 4.24.1 +Version: 4.27.0 Release: 0 Summary: Sphinx Doxygen renderer License: BSD-3-Clause ++++++ v4.24.1.tar.gz -> v4.27.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/.github/workflows/unit_tests.yml new/breathe-4.27.0/.github/workflows/unit_tests.yml --- old/breathe-4.24.1/.github/workflows/unit_tests.yml 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/.github/workflows/unit_tests.yml 2021-02-16 16:26:15.000000000 +0100 @@ -6,12 +6,15 @@ runs-on: ubuntu-latest strategy: matrix: - python-version: [3.5, 3.6, 3.7, 3.8] + python-version: [3.5, 3.6, 3.7, 3.8, 3.9] sphinx-version: - 3.0.4 - 3.1.2 - - 3.2.0 - - git+https://github.com/sphinx-doc/sphinx.git@3.3.x + - 3.2.1 + - 3.3.1 + - 3.4.3 + - 3.5.0 + - git+https://github.com/sphinx-doc/sphinx.git@3.5.x - git+https://github.com/sphinx-doc/sphinx.git@3.x # master (Sphinx 4) will require at least Python 3.6, so disable it for now #- git+https://github.com/sphinx-doc/sphinx.git@master diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/README.rst new/breathe-4.27.0/README.rst --- old/breathe-4.24.1/README.rst 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/README.rst 2021-02-16 16:26:15.000000000 +0100 @@ -172,6 +172,36 @@ Inspired by `Keepachangelog.com <http://keepachangelog.com/>`__. +- 2021-02-16 - Breathe v4.27.0 + + - Add various specifiers to functions and variables. #628 + - Add multiply inherited class for PHP objects. #630 + - Initial support for table rendering. #632 + - Add rendering of \section, \subsection and \subsubsection. #635 + - Sphinx 3.5 compatibility. #640 + - Fix linking to sections. #639 + - Add table examples to documentation. #638 + +- 2021-01-21 - Breathe v4.26.1 + + - Fix doxygenfile causing duplicate IDs for unspecified sections. #622 + - Fixes for doxygenfunction (friend keyword, friend class, arg checks). #623 + +- 2021-01-08 - Breathe v4.26.0 + + - Add test for ellipsis ('...') in args. #610 + - Sphinx 3.4.x compatibility. #617 + - Adapt friendclass to Doxygen 1.9. #618 + +- 2020-12-16 - Breathe v4.25.1 + + - Addendum to #606, for functions with '...'. #609 + +- 2020-12-15 - Breathe v4.25.0 + + - Add support for \parblock parsing and rendering. #603 + - Allow lookup in doxygenfunction without writing param names. #606 + - 2020-12-01 - Breathe v4.24.1 - Fix anchors on pages generated by Doxygen >= 1.8.17. #602 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/breathe/__init__.py new/breathe-4.27.0/breathe/__init__.py --- old/breathe-4.24.1/breathe/__init__.py 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/breathe/__init__.py 2021-02-16 16:26:15.000000000 +0100 @@ -4,7 +4,7 @@ from sphinx.application import Sphinx -__version__ = '4.24.1' +__version__ = '4.27.0' def setup(app: Sphinx): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/breathe/directives.py new/breathe-4.27.0/breathe/directives.py --- old/breathe-4.24.1/breathe/directives.py 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/breathe/directives.py 2021-02-16 16:26:15.000000000 +0100 @@ -28,7 +28,7 @@ import re import subprocess -from typing import Any, List, Type # noqa +from typing import Any, List, Optional, Type # noqa class NoMatchingFunctionError(BreatheError): @@ -76,13 +76,22 @@ return warning.warn('doxygenfunction: %s' % e) # Extract arguments from the function name. - args = self.parse_args(args) + args = self._parse_args(args) - finder_filter = self.filter_factory.create_function_finder_filter(namespace, function_name) + finder_filter = self.filter_factory.create_function_and_all_friend_finder_filter( + namespace, function_name) # TODO: find a more specific type for the Doxygen nodes - matches = [] # type: List[Any] - finder.filter_(finder_filter, matches) + matchesAll = [] # type: List[Any] + finder.filter_(finder_filter, matchesAll) + matches = [] + for m in matchesAll: + # only take functions and friend functions + # ignore friend classes + node = m[0] + if node.kind == 'friend' and not node.argsstring: + continue + matches.append(m) # Create it ahead of time as it is cheap and it is ugly to declare it for both exception # clauses below @@ -92,43 +101,30 @@ self.lineno, namespace='%s::' % namespace if namespace else '', function=function_name, - args=', '.join(args) + args=str(args) ) try: - node_stack = self.resolve_function(matches, args, project_info) + node_stack = self._resolve_function(matches, args, project_info) except NoMatchingFunctionError: return warning.warn('doxygenfunction: Cannot find function "{namespace}{function}" ' '{tail}') except UnableToResolveFunctionError as error: - message = 'doxygenfunction: Unable to resolve multiple matches for function ' \ - '"{namespace}{function}" with arguments ({args}) {tail}.\n' \ + message = 'doxygenfunction: Unable to resolve function ' \ + '"{namespace}{function}" with arguments {args} {tail}.\n' \ 'Potential matches:\n' - # We want to create a string for the console output and a set of docutils nodes - # for rendering into the final output. We handle the final output as a literal string - # with a txt based list of the options. - literal_text = '' - - # TODO: We're cheating here with the set() as signatures has repeating entries for some - # reason (failures in the matcher_stack code) so we consolidate them by shoving them in - # a set to remove duplicates. Should be fixed! - signatures = '' - for i, entry in enumerate(sorted(set(error.signatures))): - if i: - literal_text += '\n' - # Replace new lines with a new line & enough spacing to reach the appropriate - # alignment for our simple plain text list - literal_text += '- %s' % entry.replace('\n', '\n ') - signatures += ' - %s\n' % entry.replace('\n', '\n ') - block = nodes.literal_block('', '', nodes.Text(literal_text)) + text = '' + for i, entry in enumerate(sorted(error.signatures)): + text += '- %s\n' % entry + block = nodes.literal_block('', '', nodes.Text(text)) formatted_message = warning.format(message) warning_nodes = [ nodes.paragraph("", "", nodes.Text(formatted_message)), block ] result = warning.warn(message, rendered_nodes=warning_nodes, - unformatted_suffix=signatures) + unformatted_suffix=text) return result target_handler = create_target_handler(self.options, project_info, self.state.document) @@ -137,44 +133,29 @@ return self.render(node_stack, project_info, filter_, target_handler, NullMaskFactory(), self.directive_args) - def parse_args(self, function_description): - # Strip off trailing qualifiers - pattern = re.compile(r'''(?<= \)) \s* - (?: = \s* 0)? \s* $ ''', - re.VERBOSE) - - function_description = re.sub(pattern, - '', - function_description) - - paren_index = function_description.find('(') - if paren_index == -1: - return [] - # If it is empty parenthesis, then return empty list as we want empty parenthesis coming - # from the xml file to match the user's function when the user doesn't provide parenthesis - # ie. when there are no args anyway - elif function_description == '()': - return [] - else: - # Parse the function name string, eg. f(int, float) to - # extract the types so we can use them for matching - args = [] - num_open_brackets = -1 - start = paren_index + 1 - for i in range(paren_index, len(function_description)): - c = function_description[i] - if c == '(' or c == '<': - num_open_brackets += 1 - elif c == ')' or c == '>': - num_open_brackets -= 1 - elif c == ',' and num_open_brackets == 0: - args.append(function_description[start:i].strip()) - start = i + 1 - args.append(function_description[start:-1].strip()) - return args + def _parse_args(self, function_description: str) -> Optional[cpp.ASTParametersQualifiers]: + if function_description == '': + return None + + parser = cpp.DefinitionParser(function_description, + location=self.get_source_info(), + config=self.config) + paramQual = parser._parse_parameters_and_qualifiers(paramMode='function') + # now erase the parameter names + for p in paramQual.args: + if p.arg is None: + assert p.ellipsis + continue + declarator = p.arg.type.decl + while hasattr(declarator, 'next'): + declarator = declarator.next # type: ignore + assert hasattr(declarator, 'declId') + declarator.declId = None # type: ignore + p.arg.init = None # type: ignore + return paramQual - def create_function_signature(self, node_stack, project_info, filter_, target_handler, - mask_factory, directive_args): + def _create_function_signature(self, node_stack, project_info, filter_, target_handler, + mask_factory, directive_args) -> str: "Standard render process used by subclasses" try: @@ -192,7 +173,8 @@ return format_parser_error("doxygenclass", e.error, e.filename, self.state, self.lineno, True) except FileIOError as e: - return format_parser_error("doxygenclass", e.error, e.filename, self.state, self.lineno) + return format_parser_error("doxygenclass", e.error, e.filename, self.state, + self.lineno, False) context = RenderContext(node_stack, mask_factory, directive_args) node = node_stack[0] @@ -212,16 +194,12 @@ ast = parser.parse_declaration('function', 'function') return str(ast) - def resolve_function(self, matches, args, project_info): + def _resolve_function(self, matches, args: Optional[cpp.ASTParametersQualifiers], project_info): if not matches: raise NoMatchingFunctionError() - if len(matches) == 1: - return matches[0] - - signatures = [] - - # Iterate over the potential matches + res = [] + candSignatures = [] for entry in matches: text_options = {'no-link': u'', 'outline': u''} @@ -235,20 +213,29 @@ directive_args = self.directive_args[:] directive_args[2] = text_options - signature = self.create_function_signature(entry, project_info, filter_, target_handler, - mask_factory, directive_args) - signatures.append(signature) - - match = re.match(r"([^(]*)(.*)", signature) - match_args = match.group(2) - - # Parse the text to find the arguments - match_args = self.parse_args(match_args) - - # Match them against the arg spec - if args == match_args: - return entry - raise UnableToResolveFunctionError(signatures) + signature = self._create_function_signature(entry, project_info, filter_, + target_handler, + mask_factory, directive_args) + candSignatures.append(signature) + + if args is not None: + match = re.match(r"([^(]*)(.*)", signature) + assert match + _match_args = match.group(2) + + # Parse the text to find the arguments + match_args = self._parse_args(_match_args) + + # Match them against the arg spec + if args != match_args: + continue + + res.append((entry, signature)) + + if len(res) == 1: + return res[0][0] + else: + raise UnableToResolveFunctionError(candSignatures) class _DoxygenClassLikeDirective(BaseDirective): @@ -603,7 +590,7 @@ app.add_config_value("breathe_separate_member_pages", False, 'env') breathe_css = "breathe.css" - if (os.path.exists(os.path.join(app.confdir, "_static", breathe_css))): + if (os.path.exists(os.path.join(app.confdir, "_static", breathe_css))): # type: ignore app.add_stylesheet(breathe_css) def write_file(directory, filename, content): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/breathe/parser/compound.py new/breathe-4.27.0/breathe/parser/compound.py --- old/breathe-4.24.1/breathe/parser/compound.py 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/breathe/parser/compound.py 2021-02-16 16:26:15.000000000 +0100 @@ -1050,12 +1050,35 @@ obj_ = supermod.docAnchorType.factory() obj_.build(child_) self.content.append(obj_) + elif child_.nodeType == Node.ELEMENT_NODE and nodeName_ == "parblock": + obj_ = supermod.docParBlockType.factory() + obj_.build(child_) + self.content.append(obj_) + elif child_.nodeType == Node.ELEMENT_NODE and nodeName_ == "table": + obj_ = supermod.docTableType.factory() + obj_.build(child_) + self.content.append(obj_) supermod.docParaType.subclass = docParaTypeSub # end class docParaTypeSub +class docParBlockTypeSub(supermod.docParBlockType): + + node_type = "docparblock" + + def __init__(self, para=None): + supermod.docParBlockType.__init__(self, para) + + def buildChildren(self, child_, nodeName_): + supermod.docParBlockType.buildChildren(self, child_, nodeName_) + + +supermod.docParBlockType.subclass = docParBlockTypeSub +# end class docParBlockTypeSub + + class docMarkupTypeSub(supermod.docMarkupType): node_type = "docmarkup" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/breathe/parser/compoundsuper.py new/breathe-4.27.0/breathe/parser/compoundsuper.py --- old/breathe-4.24.1/breathe/parser/compoundsuper.py 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/breathe/parser/compoundsuper.py 2021-02-16 16:26:15.000000000 +0100 @@ -2888,6 +2888,10 @@ self.content_ = [] else: self.content_ = content_ + if title is None: + self.title = "" + else: + self.title = title def factory(*args_, **kwargs_): if docSect1Type.subclass: return docSect1Type.subclass(*args_, **kwargs_) @@ -2943,11 +2947,7 @@ def buildChildren(self, child_, nodeName_): if child_.nodeType == Node.ELEMENT_NODE and \ nodeName_ == 'title': - childobj_ = docTitleType.factory() - childobj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, 'title', childobj_) - self.content_.append(obj_) + self.title = child_.childNodes[0].nodeValue elif child_.nodeType == Node.ELEMENT_NODE and \ nodeName_ == 'para': childobj_ = docParaType.factory() @@ -2989,6 +2989,10 @@ self.content_ = [] else: self.content_ = content_ + if title is None: + title = "" + else: + title = title def factory(*args_, **kwargs_): if docSect2Type.subclass: return docSect2Type.subclass(*args_, **kwargs_) @@ -3044,11 +3048,7 @@ def buildChildren(self, child_, nodeName_): if child_.nodeType == Node.ELEMENT_NODE and \ nodeName_ == 'title': - childobj_ = docTitleType.factory() - childobj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, 'title', childobj_) - self.content_.append(obj_) + self.title = child_.childNodes[0].nodeValue elif child_.nodeType == Node.ELEMENT_NODE and \ nodeName_ == 'para': childobj_ = docParaType.factory() @@ -3090,6 +3090,10 @@ self.content_ = [] else: self.content_ = content_ + if title is None: + self.title = "" + else: + self.title = title def factory(*args_, **kwargs_): if docSect3Type.subclass: return docSect3Type.subclass(*args_, **kwargs_) @@ -3145,11 +3149,7 @@ def buildChildren(self, child_, nodeName_): if child_.nodeType == Node.ELEMENT_NODE and \ nodeName_ == 'title': - childobj_ = docTitleType.factory() - childobj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, 'title', childobj_) - self.content_.append(obj_) + self.title = child_.childNodes[0].nodeValue elif child_.nodeType == Node.ELEMENT_NODE and \ nodeName_ == 'para': childobj_ = docParaType.factory() @@ -5682,6 +5682,72 @@ # end class docCharType +class docParBlockType(GeneratedsSuper): + subclass = None + superclass = None + def __init__(self, mixedclass_=None, para=None): + if mixedclass_ is None: + self.mixedclass_ = MixedContainer + else: + self.mixedclass_ = mixedclass_ + if para is None: + self.para = [] + else: + self.para = para + def factory(*args_, **kwargs_): + if docParBlockType.subclass: + return docParBlockType.subclass(*args_, **kwargs_) + else: + return docParBlockType(*args_, **kwargs_) + factory = staticmethod(factory) + def get_para(self): return self.para + def set_para(self, para): self.para = para + def add_para(self, value): self.para.append(value) + def insert_para(self, index, value): self.para[index] = value + def export(self, outfile, level, namespace_='', name_='docParBlockType', namespacedef_=''): + showIndent(outfile, level) + outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) + self.exportAttributes(outfile, level, namespace_, name_='docParBlockType') + if self.hasContent_(): + outfile.write('>\n') + self.exportChildren(outfile, level + 1, namespace_, name_) + showIndent(outfile, level) + outfile.write('</%s%s>\n' % (namespace_, name_)) + else: + outfile.write('/>\n') + def exportAttributes(self, outfile, level, namespace_='', name_='docParBlockType'): + pass + def exportChildren(self, outfile, level, namespace_='', name_='docParBlockType'): + for para_ in self.para: + para_.export(outfile, level, namespace_, name_='para') + def hasContent_(self): + if ( + self.para + ): + return True + else: + return False + def build(self, node_): + attrs = node_.attributes + self.buildAttributes(attrs) + self.valueOf_ = '' + for child_ in node_.childNodes: + nodeName_ = child_.nodeName.split(':')[-1] + self.buildChildren(child_, nodeName_) + def buildAttributes(self, attrs): + pass + def buildChildren(self, child_, nodeName_): + if child_.nodeType == Node.ELEMENT_NODE and \ + nodeName_ == 'para': + obj_ = docParaType.factory() + obj_.build(child_) + obj_ = self.mixedclass_(MixedContainer.CategoryComplex, + MixedContainer.TypeNone, 'para', obj_) + self.para.append(obj_) + +# end class docParBlockType + + class docEmptyType(GeneratedsSuper): subclass = None superclass = None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/breathe/path_handler.py new/breathe-4.27.0/breathe/path_handler.py --- old/breathe-4.24.1/breathe/path_handler.py 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/breathe/path_handler.py 2021-02-16 16:26:15.000000000 +0100 @@ -15,4 +15,4 @@ """ # os.path.join does the appropriate handling if _project_path is an absolute path - return os.path.join(app.confdir, directory, filename) + return os.path.join(app.confdir, directory, filename) # type: ignore diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/breathe/renderer/filter.py new/breathe-4.27.0/breathe/renderer/filter.py --- old/breathe-4.24.1/breathe/renderer/filter.py 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/breathe/renderer/filter.py 2021-02-16 16:26:15.000000000 +0100 @@ -1026,16 +1026,17 @@ return (parent_is_compound & parent_is_file & node_matches) \ | (parent_is_compound & parent_is_not_file & node_matches) - def create_function_finder_filter(self, namespace: str, name: str) -> Filter: + def create_function_and_all_friend_finder_filter(self, namespace: str, name: str) -> Filter: parent = Parent() parent_is_compound = parent.node_type == 'compound' parent_is_group = parent.kind == 'group' function_filter = self.create_member_finder_filter(namespace, name, 'function') + friend_filter = self.create_member_finder_filter(namespace, name, 'friend') # Get matching functions but only ones where the parent is not a group. We want to skip # function entries in groups as we'll find the same functions in a file's xml output # elsewhere and having more than one match is confusing for our logic later on. - return function_filter & ~(parent_is_compound & parent_is_group) + return (function_filter | friend_filter) & ~(parent_is_compound & parent_is_group) def create_enumvalue_finder_filter(self, name: str) -> Filter: """Returns a filter which looks for an enumvalue with the specified name.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/breathe/renderer/sphinxrenderer.py new/breathe-4.27.0/breathe/renderer/sphinxrenderer.py --- old/breathe-4.24.1/breathe/renderer/sphinxrenderer.py 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/breathe/renderer/sphinxrenderer.py 2021-02-16 16:26:15.000000000 +0100 @@ -148,6 +148,26 @@ # ---------------------------------------------------------------------------- +# Create multi-inheritance classes to merge BaseObject from Breathe with +# classes from phpdomain. +# We use capitalization (and the namespace) to differentiate between the two + +if php is not None: + class PHPNamespaceLevel(BaseObject, php.PhpNamespacelevel): + """Description of a PHP item *in* a namespace (not the space itself).""" + pass + + class PHPClassLike(BaseObject, php.PhpClasslike): + pass + + class PHPClassMember(BaseObject, php.PhpClassmember): + pass + + class PHPGlobalLevel(BaseObject, php.PhpGloballevel): + pass + +# ---------------------------------------------------------------------------- + if cs is not None: class CSharpCurrentNamespace(BaseObject, cs.CSharpCurrentNamespace): pass @@ -239,12 +259,13 @@ if php is not None: php_classes = { - 'function': (php.PhpNamespacelevel, 'function'), - 'class': (php.PhpClasslike, 'class'), - 'attr': (php.PhpClassmember, 'attr'), - 'method': (php.PhpClassmember, 'method'), - 'global': (php.PhpGloballevel, 'global'), + 'function': (PHPNamespaceLevel, 'function'), + 'class': (PHPClassLike, 'class'), + 'attr': (PHPClassMember, 'attr'), + 'method': (PHPClassMember, 'method'), + 'global': (PHPGlobalLevel, 'global'), } + php_classes_default = php_classes['class'] # Directive when no matching ones were found if cs is not None: cs_classes = { @@ -291,8 +312,12 @@ else: if arg_0 in ['variable']: arg_0 = 'global' - cls, name = DomainDirectiveFactory.php_classes.get( - arg_0, (php.PhpClasslike, 'class')) + + if arg_0 in DomainDirectiveFactory.php_classes: + cls, name = DomainDirectiveFactory.php_classes[arg_0] # type: ignore + else: + cls, name = DomainDirectiveFactory.php_classes_default # type: ignore + elif cs is not None and domain == 'cs': cls, name = DomainDirectiveFactory.cs_classes[args[0]] # type: ignore else: @@ -1165,13 +1190,13 @@ # Get all sub sections for sectiondef in node.sectiondef: + kind = sectiondef.kind + if section_order is not None and kind not in section_order: + continue child_nodes = self.render(sectiondef) if not child_nodes: # Skip empty section continue - kind = sectiondef.kind - if section_order is not None and kind not in section_order: - continue rst_node = nodes.container(classes=['breathe-sectiondef']) rst_node.document = self.state.document rst_node['objtype'] = kind @@ -1284,6 +1309,9 @@ return [nodes.paragraph("", "", *nodelist)] + def visit_docparblock(self, node) -> List[Node]: + return self.render_iterable(node.para) + def visit_docimage(self, node) -> List[Node]: """Output docutils image node using name attribute from xml as the uri""" @@ -1316,8 +1344,20 @@ print("Warning: does not currently handle 'small' text display") return [creator("", "", *nodelist)] - def visit_docsect1(self, node) -> List[Node]: - return [] + def visit_docsectN(self, node) -> List[Node]: + ''' + Docutils titles are defined by their level inside the document so + the proper structure is only guaranteed by the Doxygen XML. + + Doxygen command mapping to XML element name: + @section == sect1, @subsection == sect2, @subsubsection == sect3 + ''' + section = nodes.section() + section['ids'].append(self.get_refid(node.id)) + section += self.create_doxygen_target(node) + section += nodes.title(node.title, node.title) + section += self.render_iterable(node.content_) + return [section] def visit_docsimplesect(self, node) -> List[Node]: """Other Type documentation such as Warning, Note, Returns, etc""" @@ -1582,9 +1622,39 @@ content = node.term.content_ return self.render_iterable(content) - def visit_docanchor(self, node) -> List[None]: + def visit_docanchor(self, node) -> List[Node]: return self.create_doxygen_target(node) + def visit_docentry(self, node) -> List[Node]: + col = nodes.entry() + col += self.render_iterable(node.para) + if node.thead == 'yes': + col['heading'] = True + return [col] + + def visit_docrow(self, node) -> List[Node]: + row = nodes.row() + cols = self.render_iterable(node.entry) + if all(col.get('heading', False) for col in cols): + elem = nodes.thead() + else: + elem = nodes.tbody() + row += cols + elem += row + return [elem] + + def visit_doctable(self, node) -> List[Node]: + table = nodes.table() + table['classes'] += ['colwidths-auto'] + tgroup = nodes.tgroup(cols=node.cols) + for _ in range(node.cols): + colspec = nodes.colspec() + colspec.attributes['colwidth'] = 'auto' + tgroup += colspec + table += tgroup + tgroup += self.render_iterable(node.row) + return [table] + def visit_mixedcontainer(self, node) -> List[Node]: return self.render_optional(node.getValue()) @@ -1603,12 +1673,25 @@ if dom == 'py': declaration = name + node.get_argsstring() else: - declaration = ' '.join([ - self.create_template_prefix(node), - ''.join(n.astext() for n in self.render(node.get_type())), # type: ignore - name, - node.get_argsstring() - ]) + elements = [self.create_template_prefix(node)] + if node.static == 'yes': + elements.append('static') + if node.inline == 'yes': + elements.append('inline') + if node.kind == 'friend': + elements.append('friend') + if node.virt in ('virtual', 'pure-virtual'): + elements.append('virtual') + if node.explicit == 'yes': + elements.append('explicit') + if 'constexpr' in dir(node): + assert node.constexpr == 'yes' + elements.append('constexpr') + elements.append(''.join(n.astext() + for n in self.render(node.get_type()))) # type: ignore + elements.append(name) + elements.append(node.get_argsstring()) + declaration = ' '.join(elements) nodes = self.handle_declaration(node, declaration) return nodes else: @@ -1753,16 +1836,19 @@ if len(initializer) != 0: options['value'] = initializer else: + elements = [self.create_template_prefix(node)] + if node.static == 'yes': + elements.append('static') + if node.mutable == 'yes': + elements.append('mutable') typename = ''.join(n.astext() for n in self.render(node.get_type())) if dom == 'c' and '::' in typename: typename = typename.replace('::', '.') - declaration = ' '.join([ - self.create_template_prefix(node), - typename, - name, - node.get_argsstring(), - self.make_initializer(node) - ]) + elements.append(typename) + elements.append(name) + elements.append(node.get_argsstring()) + elements.append(self.make_initializer(node)) + declaration = ' '.join(elements) if not dom or dom in ('c', 'cpp', 'py', 'cs'): return self.handle_declaration(node, declaration, options=options) else: @@ -1778,7 +1864,11 @@ desc += signode typ = ''.join(n.astext() for n in self.render(node.get_type())) # type: ignore - assert typ in ("friend class", "friend struct") + # in Doxygen < 1.9 the 'friend' part is there, but afterwards not + # https://github.com/michaeljones/breathe/issues/616 + assert typ in ("friend class", "friend struct", "class", "struct") + if not typ.startswith('friend '): + typ = 'friend ' + typ signode += addnodes.desc_annotation(typ, typ) signode += nodes.Text(' ') # expr = cpp.CPPExprRole(asCode=False) @@ -1934,10 +2024,13 @@ "docreftext": visit_docreftext, "docheading": visit_docheading, "docpara": visit_docpara, + "docparblock": visit_docparblock, "docimage": visit_docimage, "docurllink": visit_docurllink, "docmarkup": visit_docmarkup, - "docsect1": visit_docsect1, + "docsect1": visit_docsectN, + "docsect2": visit_docsectN, + "docsect3": visit_docsectN, "docsimplesect": visit_docsimplesect, "doctitle": visit_doctitle, "docformula": visit_docformula, @@ -1964,6 +2057,9 @@ "docvariablelist": visit_docvariablelist, "docvarlistentry": visit_docvarlistentry, "docanchor": visit_docanchor, + "doctable": visit_doctable, + "docrow": visit_docrow, + "docentry": visit_docentry, } def render(self, node, context: Optional[RenderContext] = None) -> List[Node]: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/documentation/source/conf.py new/breathe-4.27.0/documentation/source/conf.py --- old/breathe-4.24.1/documentation/source/conf.py 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/documentation/source/conf.py 2021-02-16 16:26:15.000000000 +0100 @@ -204,6 +204,7 @@ "programlisting":"../../examples/specific/programlisting/xml/", "image":"../../examples/specific/image/xml/", "lists":"../../examples/specific/lists/xml/", + "tables":"../../examples/specific/tables/xml/", "group":"../../examples/specific/group/xml/", "union":"../../examples/specific/union/xml/", "qtsignalsandslots":"../../examples/specific/qtsignalsandslots/xml/", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/documentation/source/directives.rst new/breathe-4.27.0/documentation/source/directives.rst --- old/breathe-4.24.1/documentation/source/directives.rst 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/documentation/source/directives.rst 2021-02-16 16:26:15.000000000 +0100 @@ -438,6 +438,12 @@ "h" : "cpp", } + You can also use this to enable support for Doxygen XML generated from PHP code:: + + breathe_domain_by_extension = { + "php" : "php", + } + .. confval:: breathe_domain_by_file_pattern Allows you to specify domains for particular files by wildcard syntax. This diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/documentation/source/doxygen.rst new/breathe-4.27.0/documentation/source/doxygen.rst --- old/breathe-4.24.1/documentation/source/doxygen.rst 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/documentation/source/doxygen.rst 2021-02-16 16:26:15.000000000 +0100 @@ -84,6 +84,14 @@ .. doxygenindex:: :path: ../../examples/doxygen/par/xml +Parblock +-------- + +.. cpp:namespace:: @ex_doxygen_parblock + +.. doxygenindex:: + :path: ../../examples/doxygen/parblock/xml + Overload -------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/documentation/source/index.rst new/breathe-4.27.0/documentation/source/index.rst --- old/breathe-4.24.1/documentation/source/index.rst 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/documentation/source/index.rst 2021-02-16 16:26:15.000000000 +0100 @@ -69,6 +69,7 @@ customcss groups lists + tables template Contributing diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/documentation/source/tables.rst new/breathe-4.27.0/documentation/source/tables.rst --- old/breathe-4.24.1/documentation/source/tables.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/breathe-4.27.0/documentation/source/tables.rst 2021-02-16 16:26:15.000000000 +0100 @@ -0,0 +1,89 @@ +Tables +====== + +Breathe has support for tables in the doxygen documentation. They are output as +follows. + +.. cpp:namespace:: @ex_tables_simple + +A simple Markdown syntax table :: + + .. doxygenclass:: Table_1 + :project: tables + +It renders as: + +---- + +.. doxygenclass:: Table_1 + :project: tables + +---- + +.. cpp:namespace:: @ex_tables_aligned + +A Markdown syntax table with alignment :: + + .. doxygenclass:: Table_2 + :project: tables + +It renders as: + +---- + +.. doxygenclass:: Table_2 + :project: tables + +---- + +.. cpp:namespace:: @ex_tables_rowspan + +A Markdown syntax table with rowspan (and alignment) :: + + .. doxygenclass:: Table_3 + :project: tables + +It renders as: + +---- + +.. only:: html + + .. doxygenclass:: Table_3 + :project: tables + +---- + +.. cpp:namespace:: @ex_tables_colspan + +A Markdown syntax table with colspan (and alignment) :: + + .. doxygenclass:: Table_4 + :project: tables + +It renders as: + +---- + +.. only:: html + + .. doxygenclass:: Table_4 + :project: tables + +---- + +.. cpp:namespace:: @ex_tables_doxygen + +A Doxygen syntax table :: + + .. doxygenclass:: Table_5 + :project: tables + +It renders as: + +---- + +.. only:: html + + .. doxygenclass:: Table_5 + :project: tables diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/examples/doxygen/.gitignore new/breathe-4.27.0/examples/doxygen/.gitignore --- old/breathe-4.24.1/examples/doxygen/.gitignore 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/examples/doxygen/.gitignore 2021-02-16 16:26:15.000000000 +0100 @@ -18,6 +18,7 @@ overload page par +parblock pyexample qtstyle relates diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/examples/doxygen/Makefile new/breathe-4.27.0/examples/doxygen/Makefile --- old/breathe-4.24.1/examples/doxygen/Makefile 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/examples/doxygen/Makefile 2021-02-16 16:26:15.000000000 +0100 @@ -27,6 +27,7 @@ relates/xml/index.xml \ author/xml/index.xml \ par/xml/index.xml \ + parblock/xml/index.xml \ overload/xml/index.xml \ example/xml/index.xml \ include/xml/index.xml \ @@ -49,7 +50,7 @@ clean: rm -rf class define enum file func page relates author \ - par overload example include qtstyle jdstyle structcmd \ + par parblock overload example include qtstyle jdstyle structcmd \ autolink tag restypedef afterdoc template tag group diagrams \ memgrp docstring pyexample mux manual interface @@ -80,6 +81,9 @@ par/xml/index.xml: par.cpp par.cfg $(DOXYGEN) par.cfg +parblock/xml/index.xml: parblock.cpp parblock.cfg + $(DOXYGEN) parblock.cfg + overload/xml/index.xml: overload.cpp overload.cfg $(DOXYGEN) overload.cfg @@ -140,4 +144,3 @@ ifneq ($(HAVE_DOT),) $(DOXYGEN) diagrams.cfg endif - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/examples/doxygen/parblock.cfg new/breathe-4.27.0/examples/doxygen/parblock.cfg --- old/breathe-4.24.1/examples/doxygen/parblock.cfg 1970-01-01 01:00:00.000000000 +0100 +++ new/breathe-4.27.0/examples/doxygen/parblock.cfg 2021-02-16 16:26:15.000000000 +0100 @@ -0,0 +1,11 @@ +PROJECT_NAME = "Parblock Command" +OUTPUT_DIRECTORY = parblock +GENERATE_LATEX = NO +GENERATE_MAN = NO +GENERATE_RTF = NO +CASE_SENSE_NAMES = NO +INPUT = parblock.cpp +QUIET = YES +JAVADOC_AUTOBRIEF = YES +GENERATE_HTML = NO +GENERATE_XML = YES diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/examples/doxygen/parblock.cpp new/breathe-4.27.0/examples/doxygen/parblock.cpp --- old/breathe-4.24.1/examples/doxygen/parblock.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/breathe-4.27.0/examples/doxygen/parblock.cpp 2021-02-16 16:26:15.000000000 +0100 @@ -0,0 +1,24 @@ +/*! \class Test15 + * Normal text. + * + * \par A paragraph followed by a paragraph block: + * \parblock + * Contents of the first paragraph in the block. + * + * New paragraph under the same heading. + * \endparblock + * + * \note + * This note consists of three paragraphs in a block. + * \parblock + * This is the first paragraph in the block. + * + * And this is the second paragraph in the block. + * + * And still a third paragraph in the block. + * \endparblock + * + * More normal text. + */ + +class Test15 {}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/examples/specific/Makefile new/breathe-4.27.0/examples/specific/Makefile --- old/breathe-4.24.1/examples/specific/Makefile 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/examples/specific/Makefile 2021-02-16 16:26:15.000000000 +0100 @@ -23,7 +23,7 @@ image name union group struct struct_function qtsignalsandslots lists \ headings links parameters template_class template_class_non_type \ template_function template_type_alias template_specialisation \ - enum define interface xrefsect \ + enum define interface xrefsect tables \ cpp_anon cpp_enum cpp_union cpp_function cpp_friendclass \ cpp_inherited_members cpp_trailing_return_type \ c_file c_struct c_enum c_typedef c_macro c_union diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/examples/specific/tables.cfg new/breathe-4.27.0/examples/specific/tables.cfg --- old/breathe-4.24.1/examples/specific/tables.cfg 1970-01-01 01:00:00.000000000 +0100 +++ new/breathe-4.27.0/examples/specific/tables.cfg 2021-02-16 16:26:15.000000000 +0100 @@ -0,0 +1,11 @@ +PROJECT_NAME = "Tables Option" +OUTPUT_DIRECTORY = tables +GENERATE_LATEX = NO +GENERATE_MAN = NO +GENERATE_RTF = NO +CASE_SENSE_NAMES = NO +INPUT = tables.h +QUIET = YES +JAVADOC_AUTOBRIEF = YES +GENERATE_HTML = NO +GENERATE_XML = YES diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/examples/specific/tables.h new/breathe-4.27.0/examples/specific/tables.h --- old/breathe-4.24.1/examples/specific/tables.h 1970-01-01 01:00:00.000000000 +0100 +++ new/breathe-4.27.0/examples/specific/tables.h 2021-02-16 16:26:15.000000000 +0100 @@ -0,0 +1,96 @@ +/** + * \brief This is a simple Markdown table example. + * + * Following is a simple table using Markdown syntax. + * + * First Header | Second Header + * ------------- | ------------- + * Content Cell | Content Cell + * Content Cell | Content Cell + * + * And this is some more text. + */ +class Table_1 +{ +}; + +/** + * \brief This is a Markdown table with alignment. + * + * Following is a table with alignment using Markdown syntax. + * + * | Right | Center | Left | + * | ----: | :----: | :---- | + * | 10 | 10 | 10 | + * | 1000 | 1000 | 1000 | + * + * And this is some more text. + */ +class Table_2 +{ +}; + +/** + * \brief This is a Markdown table with rowspan and alignment. + * + * Following is a table with rowspan and alignment using Markdown syntax. + * + * | Right | Center | Left | + * | ----: | :----: | :---- | + * | 10 | 10 | 10 | + * | ^ | 1000 | 1000 | + * + * And this is some more text. + */ +class Table_3 +{ +}; + +/** + * \brief This is a Markdown table with colspan and alignment. + * + * Following is a table with colspan and alignment using Markdown syntax. + * + * | Right | Center | Left | + * | ----: | :----: | :---- | + * | 10 | 10 | 10 | + * | 1000 ||| + * + * And this is some more text. + */ +class Table_4 +{ +}; + +/** + * \brief This is a Doxygen table. + * + * Following is a table using Doxygen syntax (and all supported features). + * + * <table> + * <caption id="multi_row">Complex table</caption> + * <tr><th>Column 1 <th>Column 2 <th>Column 3 + * <tr><td rowspan="2">cell row=1+2,col=1<td>cell row=1,col=2<td>cell row=1,col=3 + * <tr><td rowspan="2">cell row=2+3,col=2 <td>cell row=2,col=3 + * <tr><td>cell row=3,col=1 <td rowspan="2">cell row=3+4,col=3 + * <tr><td colspan="2">cell row=4,col=1+2 + * <tr><td>cell row=5,col=1 <td colspan="2">cell row=5,col=2+3 + * <tr><td colspan="2" rowspan="2">cell row=6+7,col=1+2 <td>cell row=6,col=3 + * <tr> <td>cell row=7,col=3 + * <tr><td>cell row=8,col=1 <td>cell row=8,col=2\n + * <table> + * <tr><td>Inner cell row=1,col=1<td>Inner cell row=1,col=2 + * <tr><td>Inner cell row=2,col=1<td>Inner cell row=2,col=2 + * </table> + * <td>cell row=8,col=3 + * <ul> + * <li>Item 1 + * <li>Item 2 + * </ul> + * </table> + * + * And this is some more text. + */ +class Table_5 +{ +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/requirements/production.txt new/breathe-4.27.0/requirements/production.txt --- old/breathe-4.24.1/requirements/production.txt 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/requirements/production.txt 2021-02-16 16:26:15.000000000 +0100 @@ -2,5 +2,5 @@ Jinja2>=2.7.3 MarkupSafe>=0.23 Pygments>=1.6 -Sphinx>=3.0,<3.4 +Sphinx>=3.0,<3.6 six>=1.9.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/setup.py new/breathe-4.27.0/setup.py --- old/breathe-4.24.1/setup.py 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/setup.py 2021-02-16 16:26:15.000000000 +0100 @@ -14,7 +14,7 @@ render `Doxygen <http://www.doxygen.org>`__ xml output. ''' -requires = ['Sphinx>=3.0,<3.4', 'docutils>=0.12', 'six>=1.9'] +requires = ['Sphinx>=3.0,<3.6', 'docutils>=0.12', 'six>=1.9'] if sys.version_info < (3, 5): print('ERROR: Sphinx requires at least Python 3.5 to run.') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/tests/data/arange.xml new/breathe-4.27.0/tests/data/arange.xml --- old/breathe-4.24.1/tests/data/arange.xml 1970-01-01 01:00:00.000000000 +0100 +++ new/breathe-4.27.0/tests/data/arange.xml 2021-02-16 16:26:15.000000000 +0100 @@ -0,0 +1,149 @@ +<sectiondef kind="typedef"> +<memberdef kind="function" id="1" prot="public" static="no" const="yes" explicit="no" inline="no" virt="non-virtual"> + <type><ref refid="classat_1_1_tensor" kindref="compound">Tensor</ref></type> + <definition>Tensor at::arange</definition> + <argsstring>(Scalar end, const TensorOptions &options={})</argsstring> + <name>arange</name> + <param> + <type>Scalar</type> + <declname>end</declname> + </param> + <param> + <type>const TensorOptions &</type> + <declname>options</declname> + <defval>{}</defval> + </param> +</memberdef> +<memberdef kind="function" id="2" prot="public" static="no" const="yes" explicit="no" inline="no" virt="non-virtual"> + <type><ref refid="classat_1_1_tensor" kindref="compound">Tensor</ref></type> + <definition>Tensor at::arange</definition> + <argsstring>(Scalar end, c10::optional< ScalarType > dtype, c10::optional< Layout > layout, c10::optional< Device > device, c10::optional< bool > pin_memory)</argsstring> + <name>arange</name> + <param> + <type>Scalar</type> + <declname>end</declname> + </param> + <param> + <type><ref refid="classc10_1_1optional" kindref="compound">c10::optional</ref>< ScalarType ></type> + <declname>dtype</declname> + </param> + <param> + <type><ref refid="classc10_1_1optional" kindref="compound">c10::optional</ref>< Layout ></type> + <declname>layout</declname> + </param> + <param> + <type><ref refid="classc10_1_1optional" kindref="compound">c10::optional</ref>< Device ></type> + <declname>device</declname> + </param> + <param> + <type><ref refid="classc10_1_1optional" kindref="compound">c10::optional</ref>< bool ></type> + <declname>pin_memory</declname> + </param> +</memberdef> +<memberdef kind="function" id="3" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual"> + <type><ref refid="classat_1_1_tensor" kindref="compound">Tensor</ref></type> + <definition>Tensor at::arange</definition> + <argsstring>(Scalar start, Scalar end, const TensorOptions &options={})</argsstring> + <name>arange</name> + <param> + <type>Scalar</type> + <declname>start</declname> + </param> + <param> + <type>Scalar</type> + <declname>end</declname> + </param> + <param> + <type>const TensorOptions &</type> + <declname>options</declname> + <defval>{}</defval> + </param> +</memberdef> +<memberdef kind="function" id="4" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual"> + <type><ref refid="classat_1_1_tensor" kindref="compound">Tensor</ref></type> + <definition>Tensor at::arange</definition> + <argsstring>(Scalar start, Scalar end, c10::optional< ScalarType > dtype, c10::optional< Layout > layout, c10::optional< Device > device, c10::optional< bool > pin_memory)</argsstring> + <name>arange</name> + <param> + <type>Scalar</type> + <declname>start</declname> + </param> + <param> + <type>Scalar</type> + <declname>end</declname> + </param> + <param> + <type><ref refid="classc10_1_1optional" kindref="compound">c10::optional</ref>< ScalarType ></type> + <declname>dtype</declname> + </param> + <param> + <type><ref refid="classc10_1_1optional" kindref="compound">c10::optional</ref>< Layout ></type> + <declname>layout</declname> + </param> + <param> + <type><ref refid="classc10_1_1optional" kindref="compound">c10::optional</ref>< Device ></type> + <declname>device</declname> + </param> + <param> + <type><ref refid="classc10_1_1optional" kindref="compound">c10::optional</ref>< bool ></type> + <declname>pin_memory</declname> + </param> +</memberdef> +<memberdef kind="function" id="5" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual"> + <type><ref refid="classat_1_1_tensor" kindref="compound">Tensor</ref></type> + <definition>Tensor at::arange</definition> + <argsstring>(Scalar start, Scalar end, Scalar step, const TensorOptions &options={})</argsstring> + <name>range</name> + <param> + <type>Scalar</type> + <declname>start</declname> + </param> + <param> + <type>Scalar</type> + <declname>end</declname> + </param> + <param> + <type>Scalar</type> + <declname>step</declname> + </param> + <param> + <type>const TensorOptions &</type> + <declname>options</declname> + <defval>{}</defval> + </param> +</memberdef> +<memberdef kind="function" id="6" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual"> + <type><ref refid="classat_1_1_tensor" kindref="compound">Tensor</ref></type> + <definition>Tensor at::arange</definition> + <argsstring>(Scalar start, Scalar end, Scalar step, c10::optional< ScalarType > dtype, c10::optional< Layout > layout, c10::optional< Device > device, c10::optional< bool > pin_memory)</argsstring> + <name>range</name> + <param> + <type>Scalar</type> + <declname>start</declname> + </param> + <param> + <type>Scalar</type> + <declname>end</declname> + </param> + <param> + <type>Scalar</type> + <declname>step</declname> + </param> + <param> + <type><ref refid="classc10_1_1optional" kindref="compound">c10::optional</ref>< ScalarType ></type> + <declname>dtype</declname> + </param> + <param> + <type><ref refid="classc10_1_1optional" kindref="compound">c10::optional</ref>< Layout ></type> + <declname>layout</declname> + </param> + <param> + <type><ref refid="classc10_1_1optional" kindref="compound">c10::optional</ref>< Device ></type> + <declname>device</declname> + </param> + <param> + <type><ref refid="classc10_1_1optional" kindref="compound">c10::optional</ref>< bool ></type> + <declname>pin_memory</declname> + </param> +</memberdef> +</sectiondef> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/tests/data/ellipsis.xml new/breathe-4.27.0/tests/data/ellipsis.xml --- old/breathe-4.24.1/tests/data/ellipsis.xml 1970-01-01 01:00:00.000000000 +0100 +++ new/breathe-4.27.0/tests/data/ellipsis.xml 2021-02-16 16:26:15.000000000 +0100 @@ -0,0 +1,20 @@ +<sectiondef kind="typedef"> +<memberdef kind="function" id="0" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual"> + <type>double</type> + <definition>double amici::spline_pos</definition> + <argsstring>(double t, int num,...)</argsstring> + <name>spline_pos</name> + <param> + <type>double</type> + <declname>t</declname> + </param> + <param> + <type>int</type> + <declname>num</declname> + </param> + <param> + <type>...</type> + </param> +</memberdef> +</sectiondef> + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/tests/test_renderer.py new/breathe-4.27.0/tests/test_renderer.py --- old/breathe-4.24.1/tests/test_renderer.py 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/tests/test_renderer.py 2021-02-16 16:26:15.000000000 +0100 @@ -1,3 +1,4 @@ +import os import pytest # type: ignore import sphinx.addnodes @@ -403,3 +404,67 @@ for el in render(app, compound_def, compound_parser=mock_compound_parser, options=['inner'])) + +def get_directive(app): + from breathe.directives import DoxygenFunctionDirective + from breathe.project import ProjectInfoFactory + from breathe.parser import DoxygenParserFactory + from breathe.finder.factory import FinderFactory + from docutils.statemachine import StringList + app.config.breathe_separate_member_pages = False + app.config.breathe_default_project = 'test_project' + app.config.breathe_domain_by_extension = {} + app.config.breathe_domain_by_file_pattern = {} + app.config.breathe_use_project_refids = False + project_info_factory = ProjectInfoFactory(app) + parser_factory = DoxygenParserFactory(app) + finder_factory = FinderFactory(app, parser_factory) + cls_args = ('doxygenclass', ['at::Tensor'], + {'members': '', 'protected-members': None, 'undoc-members': None}, + StringList([], items=[]), + 20, 24, + ('.. doxygenclass:: at::Tensor\n :members:\n' + ' :protected-members:\n :undoc-members:'), + MockState(app), + MockStateMachine(), + ) + return DoxygenFunctionDirective(finder_factory, project_info_factory, parser_factory, *cls_args) + + +def get_matches(datafile): + from breathe.parser.compoundsuper import sectiondefType + from xml.dom import minidom + + argsstrings = [] + with open(os.path.join(os.path.dirname(__file__), 'data', datafile)) as fid: + xml = fid.read() + doc = minidom.parseString(xml) + + sectiondef = sectiondefType.factory() + for child in doc.documentElement.childNodes: + sectiondef.buildChildren(child, 'memberdef') + if getattr(child, 'tagName', None) == 'memberdef': + # Get the argsstring function declaration + argsstrings.append(child.getElementsByTagName('argsstring')[0].childNodes[0].data) + matches = [[m, sectiondef] for m in sectiondef.memberdef] + return argsstrings, matches + + +def test_resolve_overrides(app): + # Test that multiple function overrides works + argsstrings, matches = get_matches('arange.xml') + cls = get_directive(app) + + # Verify that the exact arguments returns one override + for args in argsstrings: + ast_param = cls._parse_args(args) + ret = cls._resolve_function(matches, ast_param, None) + +def test_ellipsis(app): + argsstrings, matches = get_matches('ellipsis.xml') + cls = get_directive(app) + + # Verify that parsing an ellipsis works + ast_param = cls._parse_args(argsstrings[0]) + ret = cls._resolve_function(matches, ast_param, None) + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/breathe-4.24.1/tests/warnings/source/conf.py new/breathe-4.27.0/tests/warnings/source/conf.py --- old/breathe-4.24.1/tests/warnings/source/conf.py 2020-12-01 22:19:50.000000000 +0100 +++ new/breathe-4.27.0/tests/warnings/source/conf.py 2021-02-16 16:26:15.000000000 +0100 @@ -11,6 +11,8 @@ # # All configuration values have a default; values that are commented out # serve to show the default. +# +# mypy: ignore-errors import sys import os