summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2020-04-09 23:46:50 +0900
committerGitHub <noreply@github.com>2020-04-09 23:46:50 +0900
commit0d359fa30aae05bade0114f31a491216e6d82d54 (patch)
treea6b6ecf62947ed4221c2976d847175c12ba8d128
parenta5dadeb890beca64bb9eabe86e6634c9dd3e1d50 (diff)
parent9bb204dcabe6ba0fc422bf4a45ad0c79c680d90b (diff)
downloadsphinx-git-0d359fa30aae05bade0114f31a491216e6d82d54.tar.gz
Merge branch '3.0.x' into 7418_case_insensitive_glossary_dup_warning
-rw-r--r--CHANGES2
-rw-r--r--sphinx/domains/cpp.py81
-rw-r--r--sphinx/util/inspect.py13
3 files changed, 85 insertions, 11 deletions
diff --git a/CHANGES b/CHANGES
index c9c962380..b12cfd398 100644
--- a/CHANGES
+++ b/CHANGES
@@ -20,6 +20,8 @@ Bugs fixed
* #7428: py domain: a reference to class ``None`` emits a nitpicky warning
* #7418: std domain: duplication warning for glossary terms is case insensitive
+* #7438: C++, fix merging overloaded functions in parallel builds.
+* #7422: autodoc: fails with ValueError when using autodoc_mock_imports
Testing
--------
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index dbb6d1a39..8180384da 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -4300,18 +4300,73 @@ class Symbol:
Symbol.debug_indent += 1
Symbol.debug_print("merge_with:")
assert other is not None
+
+ def unconditionalAdd(self, otherChild):
+ # TODO: hmm, should we prune by docnames?
+ self._children.append(otherChild)
+ otherChild.parent = self
+ otherChild._assert_invariants()
+
+ if Symbol.debug_lookup:
+ Symbol.debug_indent += 1
for otherChild in other._children:
- ourChild = self._find_first_named_symbol(
+ if Symbol.debug_lookup:
+ Symbol.debug_print("otherChild:\n", otherChild.to_string(Symbol.debug_indent))
+ Symbol.debug_indent += 1
+ if otherChild.isRedeclaration:
+ unconditionalAdd(self, otherChild)
+ if Symbol.debug_lookup:
+ Symbol.debug_print("isRedeclaration")
+ Symbol.debug_indent -= 1
+ continue
+ candiateIter = self._find_named_symbols(
identOrOp=otherChild.identOrOp,
templateParams=otherChild.templateParams,
templateArgs=otherChild.templateArgs,
templateShorthand=False, matchSelf=False,
- recurseInAnon=False, correctPrimaryTemplateArgs=False)
+ recurseInAnon=False, correctPrimaryTemplateArgs=False,
+ searchInSiblings=False)
+ candidates = list(candiateIter)
+
+ if Symbol.debug_lookup:
+ Symbol.debug_print("raw candidate symbols:", len(candidates))
+ symbols = [s for s in candidates if not s.isRedeclaration]
+ if Symbol.debug_lookup:
+ Symbol.debug_print("non-duplicate candidate symbols:", len(symbols))
+
+ if len(symbols) == 0:
+ unconditionalAdd(self, otherChild)
+ if Symbol.debug_lookup:
+ Symbol.debug_indent -= 1
+ continue
+
+ ourChild = None
+ if otherChild.declaration is None:
+ if Symbol.debug_lookup:
+ Symbol.debug_print("no declaration in other child")
+ ourChild = symbols[0]
+ else:
+ queryId = otherChild.declaration.get_newest_id()
+ if Symbol.debug_lookup:
+ Symbol.debug_print("queryId: ", queryId)
+ for symbol in symbols:
+ if symbol.declaration is None:
+ if Symbol.debug_lookup:
+ Symbol.debug_print("empty candidate")
+ # if in the end we have non matching, but have an empty one,
+ # then just continue with that
+ ourChild = symbol
+ continue
+ candId = symbol.declaration.get_newest_id()
+ if Symbol.debug_lookup:
+ Symbol.debug_print("candidate:", candId)
+ if candId == queryId:
+ ourChild = symbol
+ break
+ if Symbol.debug_lookup:
+ Symbol.debug_indent -= 1
if ourChild is None:
- # TODO: hmm, should we prune by docnames?
- self._children.append(otherChild)
- otherChild.parent = self
- otherChild._assert_invariants()
+ unconditionalAdd(self, otherChild)
continue
if otherChild.declaration and otherChild.docname in docnames:
if not ourChild.declaration:
@@ -4326,10 +4381,14 @@ class Symbol:
# Both have declarations, and in the same docname.
# This can apparently happen, it should be safe to
# just ignore it, right?
- pass
+ # Hmm, only on duplicate declarations, right?
+ msg = "Internal C++ domain error during symbol merging.\n"
+ msg += "ourChild:\n" + ourChild.to_string(1)
+ msg += "\notherChild:\n" + otherChild.to_string(1)
+ logger.warning(msg, location=otherChild.docname)
ourChild.merge_with(otherChild, docnames, env)
if Symbol.debug_lookup:
- Symbol.debug_indent -= 1
+ Symbol.debug_indent -= 2
def add_name(self, nestedName: ASTNestedName,
templatePrefix: ASTTemplateDeclarationPrefix = None) -> "Symbol":
@@ -7116,7 +7175,6 @@ class CPPDomain(Domain):
print("\tother:")
print(otherdata['root_symbol'].dump(1))
print("\tother end")
- print("merge_domaindata end")
self.data['root_symbol'].merge_with(otherdata['root_symbol'],
docnames, self.env)
@@ -7130,6 +7188,11 @@ class CPPDomain(Domain):
logger.warning(msg, location=docname)
else:
ourNames[name] = docname
+ if Symbol.debug_show_tree:
+ print("\tresult:")
+ print(self.data['root_symbol'].dump(1))
+ print("\tresult end")
+ print("merge_domaindata end")
def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
typ: str, target: str, node: pending_xref,
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index 570ea9df6..64c1568f6 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -17,7 +17,7 @@ import typing
import warnings
from functools import partial, partialmethod
from inspect import ( # NOQA
- Parameter, isclass, ismethod, ismethoddescriptor, unwrap
+ Parameter, isclass, ismethod, ismethoddescriptor
)
from io import StringIO
from typing import Any, Callable, Mapping, List, Tuple
@@ -116,6 +116,15 @@ def getargspec(func: Callable) -> Any:
kwonlyargs, kwdefaults, annotations)
+def unwrap(obj: Any) -> Any:
+ """Get an original object from wrapped object (wrapped functions)."""
+ try:
+ return inspect.unwrap(obj)
+ except ValueError:
+ # might be a mock object
+ return obj
+
+
def unwrap_all(obj: Any) -> Any:
"""
Get an original object from wrapped object (unwrapping partials, wrapped
@@ -217,7 +226,7 @@ def isattributedescriptor(obj: Any) -> bool:
return True
elif isdescriptor(obj):
# non data descriptor
- unwrapped = inspect.unwrap(obj)
+ unwrapped = unwrap(obj)
if isfunction(unwrapped) or isbuiltin(unwrapped) or inspect.ismethod(unwrapped):
# attribute must not be either function, builtin and method
return False