mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch '3.x'
This commit is contained in:
commit
2c7d64b94c
24
CHANGES
24
CHANGES
@ -62,6 +62,7 @@ Features added
|
||||
sidebar
|
||||
* #7484: html theme: Avoid clashes between sidebar and other blocks
|
||||
* #7476: html theme: Relbar breadcrumb should contain current page
|
||||
* #7506: html theme: A canonical URL is not escaped
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
@ -69,7 +70,7 @@ Bugs fixed
|
||||
Testing
|
||||
--------
|
||||
|
||||
Release 3.0.2 (in development)
|
||||
Release 3.0.3 (in development)
|
||||
==============================
|
||||
|
||||
Dependencies
|
||||
@ -84,6 +85,18 @@ Deprecated
|
||||
Features added
|
||||
--------------
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
Testing
|
||||
--------
|
||||
|
||||
Release 3.0.2 (released Apr 19, 2020)
|
||||
=====================================
|
||||
|
||||
Features added
|
||||
--------------
|
||||
|
||||
* C, parse attributes and add :confval:`c_id_attributes`
|
||||
and :confval:`c_paren_attributes` to support user-defined attributes.
|
||||
|
||||
@ -91,11 +104,14 @@ Bugs fixed
|
||||
----------
|
||||
|
||||
* #7461: py domain: fails with IndexError for empty tuple in type annotation
|
||||
* #7510: py domain: keyword-only arguments are documented as having a default of
|
||||
None
|
||||
* #7418: std domain: :rst:role:`term` role could not match case-insensitively
|
||||
* #7461: autodoc: empty tuple in type annotation is not shown correctly
|
||||
* #7479: autodoc: Sphinx builds has been slower since 3.0.0 on mocking
|
||||
* C++, fix spacing issue in east-const declarations.
|
||||
|
||||
Testing
|
||||
--------
|
||||
* #7414: LaTeX: Xindy language options were incorrect
|
||||
* sphinx crashes with ImportError on python3.5.1
|
||||
|
||||
Release 3.0.1 (released Apr 11, 2020)
|
||||
=====================================
|
||||
|
@ -26,7 +26,7 @@ modindex_common_prefix = ['sphinx.']
|
||||
html_static_path = ['_static']
|
||||
html_sidebars = {'index': ['indexsidebar.html', 'searchbox.html']}
|
||||
html_additional_pages = {'index': 'index.html'}
|
||||
html_use_opensearch = 'http://sphinx-doc.org'
|
||||
html_use_opensearch = 'https://www.sphinx-doc.org/en/master'
|
||||
html_baseurl = 'https://www.sphinx-doc.org/en/master/'
|
||||
|
||||
htmlhelp_basename = 'Sphinxdoc'
|
||||
|
@ -52,6 +52,7 @@ if __version__.endswith('+'):
|
||||
__version__ = __version__[:-1] # remove '+' for PEP-440 version spec.
|
||||
try:
|
||||
ret = subprocess.run(['git', 'show', '-s', '--pretty=format:%h'],
|
||||
cwd=package_dir,
|
||||
stdout=PIPE, stderr=PIPE, encoding='ascii')
|
||||
if ret.stdout:
|
||||
__display_version__ += '/' + ret.stdout.strip()
|
||||
|
@ -54,13 +54,13 @@ XINDY_LANG_OPTIONS = {
|
||||
'hr': '-L croatian -C utf8 ',
|
||||
'cs': '-L czech -C utf8 ',
|
||||
'da': '-L danish -C utf8 ',
|
||||
'nl': '-L dutch -C ij-as-ij-utf8 ',
|
||||
'nl': '-L dutch-ij-as-ij -C utf8 ',
|
||||
'en': '-L english -C utf8 ',
|
||||
'eo': '-L esperanto -C utf8 ',
|
||||
'et': '-L estonian -C utf8 ',
|
||||
'fi': '-L finnish -C utf8 ',
|
||||
'fr': '-L french -C utf8 ',
|
||||
'de': '-L german -C din5007-utf8 ',
|
||||
'de': '-L german-din5007 -C utf8 ',
|
||||
'is': '-L icelandic -C utf8 ',
|
||||
'it': '-L italian -C utf8 ',
|
||||
'la': '-L latin -C utf8 ',
|
||||
@ -73,9 +73,9 @@ XINDY_LANG_OPTIONS = {
|
||||
'pl': '-L polish -C utf8 ',
|
||||
'pt': '-L portuguese -C utf8 ',
|
||||
'ro': '-L romanian -C utf8 ',
|
||||
'sk': '-L slovak -C small-utf8 ', # there is also slovak-large
|
||||
'sk': '-L slovak-small -C utf8 ', # there is also slovak-large
|
||||
'sl': '-L slovenian -C utf8 ',
|
||||
'es': '-L spanish -C modern-utf8 ', # there is also spanish-traditional
|
||||
'es': '-L spanish-modern -C utf8 ', # there is also spanish-traditional
|
||||
'sv': '-L swedish -C utf8 ',
|
||||
'tr': '-L turkish -C utf8 ',
|
||||
'hsb': '-L upper-sorbian -C utf8 ',
|
||||
@ -86,7 +86,7 @@ XINDY_LANG_OPTIONS = {
|
||||
'be': '-L belarusian -C utf8 ',
|
||||
'bg': '-L bulgarian -C utf8 ',
|
||||
'mk': '-L macedonian -C utf8 ',
|
||||
'mn': '-L mongolian -C cyrillic-utf8 ',
|
||||
'mn': '-L mongolian-cyrillic -C utf8 ',
|
||||
'ru': '-L russian -C utf8 ',
|
||||
'sr': '-L serbian -C utf8 ',
|
||||
'sh-cyrl': '-L serbian -C utf8 ',
|
||||
@ -96,7 +96,7 @@ XINDY_LANG_OPTIONS = {
|
||||
# can work only with xelatex/lualatex, not supported by texindy+pdflatex
|
||||
'el': '-L greek -C utf8 ',
|
||||
# FIXME, not compatible with [:2] slice but does Sphinx support Greek ?
|
||||
'el-polyton': '-L greek -C polytonic-utf8 ',
|
||||
'el-polyton': '-L greek-polytonic -C utf8 ',
|
||||
}
|
||||
|
||||
XINDY_CYRILLIC_SCRIPTS = [
|
||||
|
@ -29,13 +29,13 @@ class RemovedInSphinx60Warning(PendingDeprecationWarning):
|
||||
RemovedInNextVersionWarning = RemovedInSphinx40Warning
|
||||
|
||||
|
||||
def deprecated_alias(modname: str, objects: Dict, warning: Type[Warning]) -> None:
|
||||
def deprecated_alias(modname: str, objects: Dict, warning: "Type[Warning]") -> None:
|
||||
module = import_module(modname)
|
||||
sys.modules[modname] = _ModuleWrapper(module, modname, objects, warning) # type: ignore
|
||||
|
||||
|
||||
class _ModuleWrapper:
|
||||
def __init__(self, module: Any, modname: str, objects: Dict, warning: Type[Warning]
|
||||
def __init__(self, module: Any, modname: str, objects: Dict, warning: "Type[Warning]"
|
||||
) -> None:
|
||||
self._module = module
|
||||
self._modname = modname
|
||||
@ -55,7 +55,7 @@ class _ModuleWrapper:
|
||||
class DeprecatedDict(dict):
|
||||
"""A deprecated dict which warns on each access."""
|
||||
|
||||
def __init__(self, data: Dict, message: str, warning: Type[Warning]) -> None:
|
||||
def __init__(self, data: Dict, message: str, warning: "Type[Warning]") -> None:
|
||||
self.message = message
|
||||
self.warning = warning
|
||||
super().__init__(data)
|
||||
|
@ -787,6 +787,8 @@ class StandardDomain(Domain):
|
||||
RemovedInSphinx40Warning)
|
||||
domain = env.get_domain('citation')
|
||||
return domain.resolve_xref(env, fromdocname, builder, typ, target, node, contnode)
|
||||
elif typ == 'term':
|
||||
resolver = self._resolve_term_xref
|
||||
else:
|
||||
resolver = self._resolve_obj_xref
|
||||
|
||||
@ -921,6 +923,28 @@ class StandardDomain(Domain):
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
|
||||
def _resolve_term_xref(self, env: "BuildEnvironment", fromdocname: str,
|
||||
builder: "Builder", typ: str, target: str,
|
||||
node: pending_xref, contnode: Element) -> Element:
|
||||
result = self._resolve_obj_xref(env, fromdocname, builder, typ,
|
||||
target, node, contnode)
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
for objtype, term in self.objects:
|
||||
if objtype == 'term' and term.lower() == target.lower():
|
||||
docname, labelid = self.objects[objtype, term]
|
||||
logger.warning(__('term %s not found in case sensitive match.'
|
||||
'made a reference to %s instead.'),
|
||||
target, term, location=node, type='ref', subtype='term')
|
||||
break
|
||||
else:
|
||||
docname, labelid = '', ''
|
||||
if not docname:
|
||||
return None
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
|
||||
def _resolve_obj_xref(self, env: "BuildEnvironment", fromdocname: str,
|
||||
builder: "Builder", typ: str, target: str,
|
||||
node: pending_xref, contnode: Element) -> Element:
|
||||
|
@ -577,7 +577,10 @@ class Documenter:
|
||||
isprivate = membername.startswith('_')
|
||||
|
||||
keep = False
|
||||
if want_all and membername.startswith('__') and \
|
||||
if getattr(member, '__sphinx_mock__', False):
|
||||
# mocked module or object
|
||||
keep = False
|
||||
elif want_all and membername.startswith('__') and \
|
||||
membername.endswith('__') and len(membername) > 4:
|
||||
# special __methods__
|
||||
if self.options.special_members is ALL:
|
||||
|
@ -25,6 +25,7 @@ class _MockObject:
|
||||
"""Used by autodoc_mock_imports."""
|
||||
|
||||
__display_name__ = '_MockObject'
|
||||
__sphinx_mock__ = True
|
||||
|
||||
def __new__(cls, *args: Any, **kwargs: Any) -> Any:
|
||||
if len(args) == 3 and isinstance(args[1], tuple):
|
||||
@ -78,6 +79,7 @@ def _make_subclass(name: str, module: str, superclass: Any = _MockObject,
|
||||
class _MockModule(ModuleType):
|
||||
"""Used by autodoc_mock_imports."""
|
||||
__file__ = os.devnull
|
||||
__sphinx_mock__ = True
|
||||
|
||||
def __init__(self, name: str) -> None:
|
||||
super().__init__(name)
|
||||
|
@ -79,7 +79,7 @@ class SphinxBaseReader(standalone.Reader):
|
||||
self._app = app # hold application object only for compatibility
|
||||
self._env = app.env
|
||||
|
||||
def get_transforms(self) -> List[Type[Transform]]:
|
||||
def get_transforms(self) -> List["Type[Transform]"]:
|
||||
transforms = super().get_transforms() + self.transforms
|
||||
|
||||
# remove transforms which is not needed for Sphinx
|
||||
|
@ -76,7 +76,7 @@ class XRefRole(ReferenceRole):
|
||||
innernodeclass = nodes.literal # type: Type[TextElement]
|
||||
|
||||
def __init__(self, fix_parens: bool = False, lowercase: bool = False,
|
||||
nodeclass: Type[Element] = None, innernodeclass: Type[TextElement] = None,
|
||||
nodeclass: "Type[Element]" = None, innernodeclass: "Type[TextElement]" = None,
|
||||
warn_dangling: bool = False) -> None:
|
||||
self.fix_parens = fix_parens
|
||||
self.lowercase = lowercase
|
||||
|
@ -132,7 +132,7 @@
|
||||
{{- script() }}
|
||||
{%- endblock %}
|
||||
{%- if pageurl %}
|
||||
<link rel="canonical" href="{{ pageurl }}" />
|
||||
<link rel="canonical" href="{{ pageurl|e }}" />
|
||||
{%- endif %}
|
||||
{%- if use_opensearch %}
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
|
@ -527,7 +527,7 @@ def signature_from_str(signature: str) -> inspect.Signature:
|
||||
annotation=annotation))
|
||||
|
||||
for i, arg in enumerate(args.kwonlyargs):
|
||||
default = ast_unparse(args.kw_defaults[i])
|
||||
default = ast_unparse(args.kw_defaults[i]) or Parameter.empty
|
||||
annotation = ast_unparse(arg.annotation) or Parameter.empty
|
||||
params.append(Parameter(arg.arg, Parameter.KEYWORD_ONLY, default=default,
|
||||
annotation=annotation))
|
||||
|
@ -344,9 +344,7 @@ def test_pyfunction_signature_full_py38(app):
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree[1][0][1],
|
||||
[desc_parameterlist, ([desc_parameter, nodes.inline, "*"],
|
||||
[desc_parameter, ([desc_sig_name, "a"],
|
||||
[desc_sig_operator, "="],
|
||||
[nodes.inline, "None"])])])
|
||||
[desc_parameter, desc_sig_name, "a"])])
|
||||
|
||||
# case: separator in the middle
|
||||
text = ".. py:function:: hello(a, /, b, *, c)"
|
||||
@ -356,9 +354,7 @@ def test_pyfunction_signature_full_py38(app):
|
||||
[desc_parameter, desc_sig_operator, "/"],
|
||||
[desc_parameter, desc_sig_name, "b"],
|
||||
[desc_parameter, desc_sig_operator, "*"],
|
||||
[desc_parameter, ([desc_sig_name, "c"],
|
||||
[desc_sig_operator, "="],
|
||||
[nodes.inline, "None"])])])
|
||||
[desc_parameter, desc_sig_name, "c"])])
|
||||
|
||||
# case: separator in the middle (2)
|
||||
text = ".. py:function:: hello(a, /, *, b)"
|
||||
@ -367,9 +363,7 @@ def test_pyfunction_signature_full_py38(app):
|
||||
[desc_parameterlist, ([desc_parameter, desc_sig_name, "a"],
|
||||
[desc_parameter, desc_sig_operator, "/"],
|
||||
[desc_parameter, desc_sig_operator, "*"],
|
||||
[desc_parameter, ([desc_sig_name, "b"],
|
||||
[desc_sig_operator, "="],
|
||||
[nodes.inline, "None"])])])
|
||||
[desc_parameter, desc_sig_name, "b"])])
|
||||
|
||||
# case: separator at tail
|
||||
text = ".. py:function:: hello(a, /)"
|
||||
|
@ -140,12 +140,23 @@ def test_glossary(app):
|
||||
[nodes.definition, nodes.paragraph, "description"])
|
||||
|
||||
# index
|
||||
objects = list(app.env.get_domain("std").get_objects())
|
||||
domain = app.env.get_domain("std")
|
||||
objects = list(domain.get_objects())
|
||||
assert ("term1", "term1", "term", "index", "term-term1", -1) in objects
|
||||
assert ("TERM2", "TERM2", "term", "index", "term-TERM2", -1) in objects
|
||||
assert ("term3", "term3", "term", "index", "term-term3", -1) in objects
|
||||
assert ("term4", "term4", "term", "index", "term-term4", -1) in objects
|
||||
|
||||
# term reference (case sensitive)
|
||||
refnode = domain.resolve_xref(app.env, 'index', app.builder, 'term', 'term1',
|
||||
pending_xref(), nodes.paragraph())
|
||||
assert_node(refnode, nodes.reference, refid="term-term1")
|
||||
|
||||
# term reference (case insensitive)
|
||||
refnode = domain.resolve_xref(app.env, 'index', app.builder, 'term', 'term2',
|
||||
pending_xref(), nodes.paragraph())
|
||||
assert_node(refnode, nodes.reference, refid="term-TERM2")
|
||||
|
||||
|
||||
def test_glossary_warning(app, status, warning):
|
||||
# empty line between terms
|
||||
|
@ -317,6 +317,15 @@ def test_signature_from_str_complex_annotations():
|
||||
assert sig.return_annotation == 'Callable[[int, int], int]'
|
||||
|
||||
|
||||
def test_signature_from_str_kwonly_args():
|
||||
sig = inspect.signature_from_str('(a, *, b)')
|
||||
assert list(sig.parameters.keys()) == ['a', 'b']
|
||||
assert sig.parameters['a'].kind == Parameter.POSITIONAL_OR_KEYWORD
|
||||
assert sig.parameters['a'].default == Parameter.empty
|
||||
assert sig.parameters['b'].kind == Parameter.KEYWORD_ONLY
|
||||
assert sig.parameters['b'].default == Parameter.empty
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 8),
|
||||
reason='python-3.8 or above is required')
|
||||
def test_signature_from_str_positionaly_only_args():
|
||||
|
Loading…
Reference in New Issue
Block a user