Skip to content

Commit

Permalink
Merge branch '3.0.x' into 7418_case_insensitive_glossary_dup_warning
Browse files Browse the repository at this point in the history
  • Loading branch information
tk0miya committed Apr 9, 2020
2 parents a5dadeb + 9bb204d commit 0d359fa
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Expand Up @@ -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
--------
Expand Down
81 changes: 72 additions & 9 deletions sphinx/domains/cpp.py
Expand Up @@ -4300,18 +4300,73 @@ def merge_with(self, other: "Symbol", docnames: List[str],
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:
Expand All @@ -4326,10 +4381,14 @@ def merge_with(self, other: "Symbol", docnames: List[str],
# 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":
Expand Down Expand Up @@ -7116,7 +7175,6 @@ def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None:
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)
Expand All @@ -7130,6 +7188,11 @@ def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None:
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,
Expand Down
13 changes: 11 additions & 2 deletions sphinx/util/inspect.py
Expand Up @@ -17,7 +17,7 @@
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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 0d359fa

Please sign in to comment.