mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch '3.0.x' into 7435_typehints_not_suppressed_for_class
This commit is contained in:
commit
a6dcbc7b6a
6
CHANGES
6
CHANGES
@ -7,6 +7,8 @@ Dependencies
|
|||||||
Incompatible changes
|
Incompatible changes
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
* #7418: std domain: :rst:dir:`term` role becomes case sensitive
|
||||||
|
|
||||||
Deprecated
|
Deprecated
|
||||||
----------
|
----------
|
||||||
|
|
||||||
@ -17,8 +19,12 @@ Bugs fixed
|
|||||||
----------
|
----------
|
||||||
|
|
||||||
* #7428: py domain: a reference to class ``None`` emits a nitpicky warning
|
* #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
|
||||||
* #7435: autodoc: ``autodoc_typehints='description'`` doesn't suppress typehints
|
* #7435: autodoc: ``autodoc_typehints='description'`` doesn't suppress typehints
|
||||||
in signature for classes/methods
|
in signature for classes/methods
|
||||||
|
* #7423: crashed when giving a non-string object to logger
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
--------
|
--------
|
||||||
|
@ -27,7 +27,7 @@ Discovery of builders by entry point
|
|||||||
|
|
||||||
.. versionadded:: 1.6
|
.. versionadded:: 1.6
|
||||||
|
|
||||||
:term:`Builder` extensions can be discovered by means of `entry points`_ so
|
:term:`builder` extensions can be discovered by means of `entry points`_ so
|
||||||
that they do not have to be listed in the :confval:`extensions` configuration
|
that they do not have to be listed in the :confval:`extensions` configuration
|
||||||
value.
|
value.
|
||||||
|
|
||||||
|
@ -4300,18 +4300,73 @@ class Symbol:
|
|||||||
Symbol.debug_indent += 1
|
Symbol.debug_indent += 1
|
||||||
Symbol.debug_print("merge_with:")
|
Symbol.debug_print("merge_with:")
|
||||||
assert other is not None
|
assert other is not None
|
||||||
for otherChild in other._children:
|
|
||||||
ourChild = self._find_first_named_symbol(
|
def unconditionalAdd(self, otherChild):
|
||||||
identOrOp=otherChild.identOrOp,
|
|
||||||
templateParams=otherChild.templateParams,
|
|
||||||
templateArgs=otherChild.templateArgs,
|
|
||||||
templateShorthand=False, matchSelf=False,
|
|
||||||
recurseInAnon=False, correctPrimaryTemplateArgs=False)
|
|
||||||
if ourChild is None:
|
|
||||||
# TODO: hmm, should we prune by docnames?
|
# TODO: hmm, should we prune by docnames?
|
||||||
self._children.append(otherChild)
|
self._children.append(otherChild)
|
||||||
otherChild.parent = self
|
otherChild.parent = self
|
||||||
otherChild._assert_invariants()
|
otherChild._assert_invariants()
|
||||||
|
|
||||||
|
if Symbol.debug_lookup:
|
||||||
|
Symbol.debug_indent += 1
|
||||||
|
for otherChild in other._children:
|
||||||
|
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,
|
||||||
|
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:
|
||||||
|
unconditionalAdd(self, otherChild)
|
||||||
continue
|
continue
|
||||||
if otherChild.declaration and otherChild.docname in docnames:
|
if otherChild.declaration and otherChild.docname in docnames:
|
||||||
if not ourChild.declaration:
|
if not ourChild.declaration:
|
||||||
@ -4326,10 +4381,14 @@ class Symbol:
|
|||||||
# Both have declarations, and in the same docname.
|
# Both have declarations, and in the same docname.
|
||||||
# This can apparently happen, it should be safe to
|
# This can apparently happen, it should be safe to
|
||||||
# just ignore it, right?
|
# 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)
|
ourChild.merge_with(otherChild, docnames, env)
|
||||||
if Symbol.debug_lookup:
|
if Symbol.debug_lookup:
|
||||||
Symbol.debug_indent -= 1
|
Symbol.debug_indent -= 2
|
||||||
|
|
||||||
def add_name(self, nestedName: ASTNestedName,
|
def add_name(self, nestedName: ASTNestedName,
|
||||||
templatePrefix: ASTTemplateDeclarationPrefix = None) -> "Symbol":
|
templatePrefix: ASTTemplateDeclarationPrefix = None) -> "Symbol":
|
||||||
@ -7116,7 +7175,6 @@ class CPPDomain(Domain):
|
|||||||
print("\tother:")
|
print("\tother:")
|
||||||
print(otherdata['root_symbol'].dump(1))
|
print(otherdata['root_symbol'].dump(1))
|
||||||
print("\tother end")
|
print("\tother end")
|
||||||
print("merge_domaindata end")
|
|
||||||
|
|
||||||
self.data['root_symbol'].merge_with(otherdata['root_symbol'],
|
self.data['root_symbol'].merge_with(otherdata['root_symbol'],
|
||||||
docnames, self.env)
|
docnames, self.env)
|
||||||
@ -7130,6 +7188,11 @@ class CPPDomain(Domain):
|
|||||||
logger.warning(msg, location=docname)
|
logger.warning(msg, location=docname)
|
||||||
else:
|
else:
|
||||||
ourNames[name] = docname
|
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,
|
def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
|
||||||
typ: str, target: str, node: pending_xref,
|
typ: str, target: str, node: pending_xref,
|
||||||
|
@ -305,7 +305,7 @@ def make_glossary_term(env: "BuildEnvironment", textnodes: Iterable[Node], index
|
|||||||
term['ids'].append(node_id)
|
term['ids'].append(node_id)
|
||||||
|
|
||||||
std = cast(StandardDomain, env.get_domain('std'))
|
std = cast(StandardDomain, env.get_domain('std'))
|
||||||
std.note_object('term', termtext.lower(), node_id, location=term)
|
std.note_object('term', termtext, node_id, location=term)
|
||||||
|
|
||||||
# add an index entry too
|
# add an index entry too
|
||||||
indexnode = addnodes.index()
|
indexnode = addnodes.index()
|
||||||
@ -565,7 +565,7 @@ class StandardDomain(Domain):
|
|||||||
# links to tokens in grammar productions
|
# links to tokens in grammar productions
|
||||||
'token': TokenXRefRole(),
|
'token': TokenXRefRole(),
|
||||||
# links to terms in glossary
|
# links to terms in glossary
|
||||||
'term': XRefRole(lowercase=True, innernodeclass=nodes.inline,
|
'term': XRefRole(innernodeclass=nodes.inline,
|
||||||
warn_dangling=True),
|
warn_dangling=True),
|
||||||
# links to headings or arbitrary labels
|
# links to headings or arbitrary labels
|
||||||
'ref': XRefRole(lowercase=True, innernodeclass=nodes.inline,
|
'ref': XRefRole(lowercase=True, innernodeclass=nodes.inline,
|
||||||
|
@ -17,7 +17,7 @@ import typing
|
|||||||
import warnings
|
import warnings
|
||||||
from functools import partial, partialmethod
|
from functools import partial, partialmethod
|
||||||
from inspect import ( # NOQA
|
from inspect import ( # NOQA
|
||||||
Parameter, isclass, ismethod, ismethoddescriptor, unwrap
|
Parameter, isclass, ismethod, ismethoddescriptor
|
||||||
)
|
)
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from typing import Any, Callable, Mapping, List, Tuple
|
from typing import Any, Callable, Mapping, List, Tuple
|
||||||
@ -116,6 +116,15 @@ def getargspec(func: Callable) -> Any:
|
|||||||
kwonlyargs, kwdefaults, annotations)
|
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:
|
def unwrap_all(obj: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
Get an original object from wrapped object (unwrapping partials, wrapped
|
Get an original object from wrapped object (unwrapping partials, wrapped
|
||||||
@ -217,7 +226,7 @@ def isattributedescriptor(obj: Any) -> bool:
|
|||||||
return True
|
return True
|
||||||
elif isdescriptor(obj):
|
elif isdescriptor(obj):
|
||||||
# non data descriptor
|
# non data descriptor
|
||||||
unwrapped = inspect.unwrap(obj)
|
unwrapped = unwrap(obj)
|
||||||
if isfunction(unwrapped) or isbuiltin(unwrapped) or inspect.ismethod(unwrapped):
|
if isfunction(unwrapped) or isbuiltin(unwrapped) or inspect.ismethod(unwrapped):
|
||||||
# attribute must not be either function, builtin and method
|
# attribute must not be either function, builtin and method
|
||||||
return False
|
return False
|
||||||
|
@ -412,7 +412,7 @@ class WarningIsErrorFilter(logging.Filter):
|
|||||||
message = record.msg # use record.msg itself
|
message = record.msg # use record.msg itself
|
||||||
|
|
||||||
if location:
|
if location:
|
||||||
raise SphinxWarning(location + ":" + message)
|
raise SphinxWarning(location + ":" + str(message))
|
||||||
else:
|
else:
|
||||||
raise SphinxWarning(message)
|
raise SphinxWarning(message)
|
||||||
else:
|
else:
|
||||||
|
@ -99,7 +99,7 @@ def test_glossary(app):
|
|||||||
text = (".. glossary::\n"
|
text = (".. glossary::\n"
|
||||||
"\n"
|
"\n"
|
||||||
" term1\n"
|
" term1\n"
|
||||||
" term2\n"
|
" TERM2\n"
|
||||||
" description\n"
|
" description\n"
|
||||||
"\n"
|
"\n"
|
||||||
" term3 : classifier\n"
|
" term3 : classifier\n"
|
||||||
@ -114,7 +114,7 @@ def test_glossary(app):
|
|||||||
assert_node(doctree, (
|
assert_node(doctree, (
|
||||||
[glossary, definition_list, ([definition_list_item, ([term, ("term1",
|
[glossary, definition_list, ([definition_list_item, ([term, ("term1",
|
||||||
index)],
|
index)],
|
||||||
[term, ("term2",
|
[term, ("TERM2",
|
||||||
index)],
|
index)],
|
||||||
definition)],
|
definition)],
|
||||||
[definition_list_item, ([term, ("term3",
|
[definition_list_item, ([term, ("term3",
|
||||||
@ -127,7 +127,7 @@ def test_glossary(app):
|
|||||||
assert_node(doctree[0][0][0][0][1],
|
assert_node(doctree[0][0][0][0][1],
|
||||||
entries=[("single", "term1", "term-term1", "main", None)])
|
entries=[("single", "term1", "term-term1", "main", None)])
|
||||||
assert_node(doctree[0][0][0][1][1],
|
assert_node(doctree[0][0][0][1][1],
|
||||||
entries=[("single", "term2", "term-term2", "main", None)])
|
entries=[("single", "TERM2", "term-TERM2", "main", None)])
|
||||||
assert_node(doctree[0][0][0][2],
|
assert_node(doctree[0][0][0][2],
|
||||||
[definition, nodes.paragraph, "description"])
|
[definition, nodes.paragraph, "description"])
|
||||||
assert_node(doctree[0][0][1][0][1],
|
assert_node(doctree[0][0][1][0][1],
|
||||||
@ -143,7 +143,7 @@ def test_glossary(app):
|
|||||||
# index
|
# index
|
||||||
objects = list(app.env.get_domain("std").get_objects())
|
objects = list(app.env.get_domain("std").get_objects())
|
||||||
assert ("term1", "term1", "term", "index", "term-term1", -1) in objects
|
assert ("term1", "term1", "term", "index", "term-term1", -1) in objects
|
||||||
assert ("term2", "term2", "term", "index", "term-term2", -1) in objects
|
assert ("TERM2", "TERM2", "term", "index", "term-TERM2", -1) in objects
|
||||||
assert ("term3", "term3", "term", "index", "term-term3", -1) in objects
|
assert ("term3", "term3", "term", "index", "term-term3", -1) in objects
|
||||||
assert ("term4", "term4", "term", "index", "term-term4", -1) in objects
|
assert ("term4", "term4", "term", "index", "term-term4", -1) in objects
|
||||||
|
|
||||||
|
@ -48,6 +48,14 @@ def test_info_and_warning(app, status, warning):
|
|||||||
assert 'message5' in warning.getvalue()
|
assert 'message5' in warning.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
def test_Exception(app, status, warning):
|
||||||
|
logging.setup(app, status, warning)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
logger.info(Exception)
|
||||||
|
assert "<class 'Exception'>" in status.getvalue()
|
||||||
|
|
||||||
|
|
||||||
def test_verbosity_filter(app, status, warning):
|
def test_verbosity_filter(app, status, warning):
|
||||||
# verbosity = 0: INFO
|
# verbosity = 0: INFO
|
||||||
app.verbosity = 0
|
app.verbosity = 0
|
||||||
|
Loading…
Reference in New Issue
Block a user