mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch 'stable'
This commit is contained in:
commit
aa6dfb8b41
2
CHANGES
2
CHANGES
@ -163,6 +163,7 @@ Bugs fixed
|
|||||||
rendered as code
|
rendered as code
|
||||||
* #2665, #2607: Link names in C++ docfields, and make it possible for other domains.
|
* #2665, #2607: Link names in C++ docfields, and make it possible for other domains.
|
||||||
* #3542: C++, fix parsing error of non-type template argument with template.
|
* #3542: C++, fix parsing error of non-type template argument with template.
|
||||||
|
* #3065, #3520: python domain fails to recognize nested class
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
--------
|
--------
|
||||||
@ -200,6 +201,7 @@ Bugs fixed
|
|||||||
* #3450:   is appeared in EPUB docs
|
* #3450:   is appeared in EPUB docs
|
||||||
* #3418: Search button is misaligned in nature and pyramid theme
|
* #3418: Search button is misaligned in nature and pyramid theme
|
||||||
* #3421: Could not translate a caption of tables
|
* #3421: Could not translate a caption of tables
|
||||||
|
* #3552: linkcheck raises UnboundLocalError
|
||||||
|
|
||||||
Release 1.5.2 (released Jan 22, 2017)
|
Release 1.5.2 (released Jan 22, 2017)
|
||||||
=====================================
|
=====================================
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
.. highlight:: console
|
||||||
|
|
||||||
Sphinx Developer's Guide
|
Sphinx Developer's Guide
|
||||||
========================
|
========================
|
||||||
|
|
||||||
@ -129,8 +131,8 @@ These are the basic steps needed to start developing on Sphinx.
|
|||||||
|
|
||||||
* Run code style checks and type checks (type checks require mypy)::
|
* Run code style checks and type checks (type checks require mypy)::
|
||||||
|
|
||||||
make style-check
|
make style-check
|
||||||
make type-check
|
make type-check
|
||||||
|
|
||||||
* Run the unit tests under different Python environments using
|
* Run the unit tests under different Python environments using
|
||||||
:program:`tox`::
|
:program:`tox`::
|
||||||
@ -274,14 +276,12 @@ Debugging Tips
|
|||||||
* Set the debugging options in the `Docutils configuration file
|
* Set the debugging options in the `Docutils configuration file
|
||||||
<http://docutils.sourceforge.net/docs/user/config.html>`_.
|
<http://docutils.sourceforge.net/docs/user/config.html>`_.
|
||||||
|
|
||||||
* JavaScript stemming algorithms in `sphinx/search/*.py` (except `en.py`) are
|
* JavaScript stemming algorithms in ``sphinx/search/*.py`` (except ``en.py``) are
|
||||||
generated by this
|
generated by this
|
||||||
`modified snowballcode generator <https://github.com/shibukawa/snowball>`_.
|
`modified snowballcode generator <https://github.com/shibukawa/snowball>`_.
|
||||||
Generated `JSX <http://jsx.github.io/>`_ files are
|
Generated `JSX <http://jsx.github.io/>`_ files are
|
||||||
in `this repository <https://github.com/shibukawa/snowball-stemmer.jsx>`_.
|
in `this repository <https://github.com/shibukawa/snowball-stemmer.jsx>`_.
|
||||||
You can get the resulting JavaScript files using the following command:
|
You can get the resulting JavaScript files using the following command::
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ npm install
|
$ npm install
|
||||||
$ node_modules/.bin/grunt build # -> dest/*.global.js
|
$ node_modules/.bin/grunt build # -> dest/*.global.js
|
||||||
|
@ -438,14 +438,6 @@ Let us now list some macros from the package file
|
|||||||
the new macros are wrappers of the formerly hard-coded ``\texttt``,
|
the new macros are wrappers of the formerly hard-coded ``\texttt``,
|
||||||
``\emph``, ... The default definitions can be found in
|
``\emph``, ... The default definitions can be found in
|
||||||
:file:`sphinx.sty`.
|
:file:`sphinx.sty`.
|
||||||
- macros for directional double quotes: pairs of straight double quote ``"``
|
|
||||||
in reST source are converted into LaTeX mark-up
|
|
||||||
``\sphinxquotedblleft{}`` and ``\sphinxquotedblright{}`` which default to
|
|
||||||
`````\ ````` and ``''`` (i.e. the TeX mark-up for directional double
|
|
||||||
quotes via font ligaturing mechanism.)
|
|
||||||
|
|
||||||
.. versionadded:: 1.5.4
|
|
||||||
Formerly, produced TeX was directly with `````\ ````` and ``''``.
|
|
||||||
- paragraph level environments: for each admonition type ``<foo>``, the
|
- paragraph level environments: for each admonition type ``<foo>``, the
|
||||||
used environment is named ``sphinx<foo>``. They may be ``\renewenvironment``
|
used environment is named ``sphinx<foo>``. They may be ``\renewenvironment``
|
||||||
'd individually, and must then be defined with one argument (it is the heading
|
'd individually, and must then be defined with one argument (it is the heading
|
||||||
|
@ -182,7 +182,9 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
# history contains any redirects, get last
|
# history contains any redirects, get last
|
||||||
if response.history:
|
if response.history:
|
||||||
code = response.history[-1].status_code
|
code = response.history[-1].status_code
|
||||||
return 'redirected', new_url, code
|
return 'redirected', new_url, code
|
||||||
|
else:
|
||||||
|
return 'redirected', new_url, 0
|
||||||
|
|
||||||
def check():
|
def check():
|
||||||
# type: () -> Tuple[unicode, unicode, int]
|
# type: () -> Tuple[unicode, unicode, int]
|
||||||
|
@ -163,6 +163,9 @@ class PyTypedField(PyXrefMixin, TypedField):
|
|||||||
class PyObject(ObjectDescription):
|
class PyObject(ObjectDescription):
|
||||||
"""
|
"""
|
||||||
Description of a general Python object.
|
Description of a general Python object.
|
||||||
|
|
||||||
|
:cvar allow_nesting: Class is an object that allows for nested namespaces
|
||||||
|
:vartype allow_nesting: bool
|
||||||
"""
|
"""
|
||||||
option_spec = {
|
option_spec = {
|
||||||
'noindex': directives.flag,
|
'noindex': directives.flag,
|
||||||
@ -189,6 +192,8 @@ class PyObject(ObjectDescription):
|
|||||||
names=('rtype',), bodyrolename='obj'),
|
names=('rtype',), bodyrolename='obj'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
allow_nesting = False
|
||||||
|
|
||||||
def get_signature_prefix(self, sig):
|
def get_signature_prefix(self, sig):
|
||||||
# type: (unicode) -> unicode
|
# type: (unicode) -> unicode
|
||||||
"""May return a prefix to put before the object name in the
|
"""May return a prefix to put before the object name in the
|
||||||
@ -316,13 +321,54 @@ class PyObject(ObjectDescription):
|
|||||||
|
|
||||||
def before_content(self):
|
def before_content(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
# needed for automatic qualification of members (reset in subclasses)
|
"""Handle object nesting before content
|
||||||
self.clsname_set = False
|
|
||||||
|
:py:class:`PyObject` represents Python language constructs. For
|
||||||
|
constructs that are nestable, such as a Python classes, this method will
|
||||||
|
build up a stack of the nesting heirarchy so that it can be later
|
||||||
|
de-nested correctly, in :py:meth:`after_content`.
|
||||||
|
|
||||||
|
For constructs that aren't nestable, the stack is bypassed, and instead
|
||||||
|
only the most recent object is tracked. This object prefix name will be
|
||||||
|
removed with :py:meth:`after_content`.
|
||||||
|
"""
|
||||||
|
if self.names:
|
||||||
|
# fullname and name_prefix come from the `handle_signature` method.
|
||||||
|
# fullname represents the full object name that is constructed using
|
||||||
|
# object nesting and explicit prefixes. `name_prefix` is the
|
||||||
|
# explicit prefix given in a signature
|
||||||
|
(fullname, name_prefix) = self.names[-1]
|
||||||
|
if self.allow_nesting:
|
||||||
|
prefix = fullname
|
||||||
|
elif name_prefix:
|
||||||
|
prefix = name_prefix.strip('.')
|
||||||
|
else:
|
||||||
|
prefix = None
|
||||||
|
if prefix:
|
||||||
|
self.env.ref_context['py:class'] = prefix
|
||||||
|
if self.allow_nesting:
|
||||||
|
classes = self.env.ref_context.setdefault('py:classes', [])
|
||||||
|
classes.append(prefix)
|
||||||
|
|
||||||
def after_content(self):
|
def after_content(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
if self.clsname_set:
|
"""Handle object de-nesting after content
|
||||||
self.env.ref_context.pop('py:class', None)
|
|
||||||
|
If this class is a nestable object, removing the last nested class prefix
|
||||||
|
ends further nesting in the object.
|
||||||
|
|
||||||
|
If this class is not a nestable object, the list of classes should not
|
||||||
|
be altered as we didn't affect the nesting levels in
|
||||||
|
:py:meth:`before_content`.
|
||||||
|
"""
|
||||||
|
classes = self.env.ref_context.setdefault('py:classes', [])
|
||||||
|
if self.allow_nesting:
|
||||||
|
try:
|
||||||
|
classes.pop()
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
self.env.ref_context['py:class'] = (classes[-1] if len(classes) > 0
|
||||||
|
else None)
|
||||||
|
|
||||||
|
|
||||||
class PyModulelevel(PyObject):
|
class PyModulelevel(PyObject):
|
||||||
@ -353,6 +399,8 @@ class PyClasslike(PyObject):
|
|||||||
Description of a class-like object (classes, interfaces, exceptions).
|
Description of a class-like object (classes, interfaces, exceptions).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
allow_nesting = True
|
||||||
|
|
||||||
def get_signature_prefix(self, sig):
|
def get_signature_prefix(self, sig):
|
||||||
# type: (unicode) -> unicode
|
# type: (unicode) -> unicode
|
||||||
return self.objtype + ' '
|
return self.objtype + ' '
|
||||||
@ -368,13 +416,6 @@ class PyClasslike(PyObject):
|
|||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def before_content(self):
|
|
||||||
# type: () -> None
|
|
||||||
PyObject.before_content(self)
|
|
||||||
if self.names:
|
|
||||||
self.env.ref_context['py:class'] = self.names[0][0]
|
|
||||||
self.clsname_set = True
|
|
||||||
|
|
||||||
|
|
||||||
class PyClassmember(PyObject):
|
class PyClassmember(PyObject):
|
||||||
"""
|
"""
|
||||||
@ -450,14 +491,6 @@ class PyClassmember(PyObject):
|
|||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def before_content(self):
|
|
||||||
# type: () -> None
|
|
||||||
PyObject.before_content(self)
|
|
||||||
lastname = self.names and self.names[-1][1]
|
|
||||||
if lastname and not self.env.ref_context.get('py:class'):
|
|
||||||
self.env.ref_context['py:class'] = lastname.strip('.')
|
|
||||||
self.clsname_set = True
|
|
||||||
|
|
||||||
|
|
||||||
class PyDecoratorMixin(object):
|
class PyDecoratorMixin(object):
|
||||||
"""
|
"""
|
||||||
|
@ -36,30 +36,34 @@ except ImportError:
|
|||||||
# for requests < 2.4.0
|
# for requests < 2.4.0
|
||||||
InsecureRequestWarning = None
|
InsecureRequestWarning = None
|
||||||
|
|
||||||
# try to load requests[security]
|
# try to load requests[security] (but only if SSL is available)
|
||||||
try:
|
try:
|
||||||
pkg_resources.require(['requests[security]'])
|
|
||||||
except (pkg_resources.DistributionNotFound,
|
|
||||||
pkg_resources.VersionConflict):
|
|
||||||
import ssl
|
import ssl
|
||||||
if not getattr(ssl, 'HAS_SNI', False):
|
except ImportError:
|
||||||
# don't complain on each url processed about the SSL issue
|
pass
|
||||||
requests.packages.urllib3.disable_warnings(
|
else:
|
||||||
requests.packages.urllib3.exceptions.InsecurePlatformWarning)
|
try:
|
||||||
|
pkg_resources.require(['requests[security]'])
|
||||||
|
except (pkg_resources.DistributionNotFound,
|
||||||
|
pkg_resources.VersionConflict):
|
||||||
|
if not getattr(ssl, 'HAS_SNI', False):
|
||||||
|
# don't complain on each url processed about the SSL issue
|
||||||
|
requests.packages.urllib3.disable_warnings(
|
||||||
|
requests.packages.urllib3.exceptions.InsecurePlatformWarning)
|
||||||
|
warnings.warn(
|
||||||
|
'Some links may return broken results due to being unable to '
|
||||||
|
'check the Server Name Indication (SNI) in the returned SSL cert '
|
||||||
|
'against the hostname in the url requested. Recommended to '
|
||||||
|
'install "requests[security]" as a dependency or upgrade to '
|
||||||
|
'a python version with SNI support (Python 3 and Python 2.7.9+).'
|
||||||
|
)
|
||||||
|
except pkg_resources.UnknownExtra:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
'Some links may return broken results due to being unable to '
|
'Some links may return broken results due to being unable to '
|
||||||
'check the Server Name Indication (SNI) in the returned SSL cert '
|
'check the Server Name Indication (SNI) in the returned SSL cert '
|
||||||
'against the hostname in the url requested. Recommended to '
|
'against the hostname in the url requested. Recommended to '
|
||||||
'install "requests[security]" as a dependency or upgrade to '
|
'install requests-2.4.1+.'
|
||||||
'a python version with SNI support (Python 3 and Python 2.7.9+).'
|
|
||||||
)
|
)
|
||||||
except pkg_resources.UnknownExtra:
|
|
||||||
warnings.warn(
|
|
||||||
'Some links may return broken results due to being unable to '
|
|
||||||
'check the Server Name Indication (SNI) in the returned SSL cert '
|
|
||||||
'against the hostname in the url requested. Recommended to '
|
|
||||||
'install requests-2.4.1+.'
|
|
||||||
)
|
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
|
@ -82,8 +82,8 @@ def test_domain_py_xrefs(app, status, warning):
|
|||||||
u'subchild_2', u'meth')
|
u'subchild_2', u'meth')
|
||||||
assert_refnode(refnodes[8], None, u'NestedParentA.NestedChildA',
|
assert_refnode(refnodes[8], None, u'NestedParentA.NestedChildA',
|
||||||
u'NestedParentA.child_1', u'meth')
|
u'NestedParentA.child_1', u'meth')
|
||||||
assert_refnode(refnodes[9], None, None, u'NestedChildA.subchild_1',
|
assert_refnode(refnodes[9], None, u'NestedParentA',
|
||||||
u'meth')
|
u'NestedChildA.subchild_1', u'meth')
|
||||||
assert_refnode(refnodes[10], None, u'NestedParentB', u'child_1', u'meth')
|
assert_refnode(refnodes[10], None, u'NestedParentB', u'child_1', u'meth')
|
||||||
assert_refnode(refnodes[11], None, u'NestedParentB', u'NestedParentB',
|
assert_refnode(refnodes[11], None, u'NestedParentB', u'NestedParentB',
|
||||||
u'class')
|
u'class')
|
||||||
@ -125,6 +125,7 @@ def test_domain_py_objects(app, status, warning):
|
|||||||
assert objects['module_a.submodule.ModTopLevel'] == ('module', 'class')
|
assert objects['module_a.submodule.ModTopLevel'] == ('module', 'class')
|
||||||
assert objects['module_a.submodule.ModTopLevel.mod_child_1'] == ('module', 'method')
|
assert objects['module_a.submodule.ModTopLevel.mod_child_1'] == ('module', 'method')
|
||||||
assert objects['module_a.submodule.ModTopLevel.mod_child_2'] == ('module', 'method')
|
assert objects['module_a.submodule.ModTopLevel.mod_child_2'] == ('module', 'method')
|
||||||
|
assert 'ModTopLevel.ModNoModule' not in objects
|
||||||
assert objects['ModNoModule'] == ('module', 'class')
|
assert objects['ModNoModule'] == ('module', 'class')
|
||||||
assert objects['module_b.submodule.ModTopLevel'] == ('module', 'class')
|
assert objects['module_b.submodule.ModTopLevel'] == ('module', 'class')
|
||||||
|
|
||||||
@ -136,7 +137,7 @@ def test_domain_py_objects(app, status, warning):
|
|||||||
assert objects['NestedParentA.NestedChildA'] == ('roles', 'class')
|
assert objects['NestedParentA.NestedChildA'] == ('roles', 'class')
|
||||||
assert objects['NestedParentA.NestedChildA.subchild_1'] == ('roles', 'method')
|
assert objects['NestedParentA.NestedChildA.subchild_1'] == ('roles', 'method')
|
||||||
assert objects['NestedParentA.NestedChildA.subchild_2'] == ('roles', 'method')
|
assert objects['NestedParentA.NestedChildA.subchild_2'] == ('roles', 'method')
|
||||||
assert objects['child_2'] == ('roles', 'method')
|
assert objects['NestedParentA.child_2'] == ('roles', 'method')
|
||||||
assert objects['NestedParentB'] == ('roles', 'class')
|
assert objects['NestedParentB'] == ('roles', 'class')
|
||||||
assert objects['NestedParentB.child_1'] == ('roles', 'method')
|
assert objects['NestedParentB.child_1'] == ('roles', 'method')
|
||||||
|
|
||||||
|
@ -97,9 +97,9 @@ def verify_re_latex(app, parse):
|
|||||||
def verify_re(verify_re_html, verify_re_latex):
|
def verify_re(verify_re_html, verify_re_latex):
|
||||||
def verify_re_(rst, html_expected, latex_expected):
|
def verify_re_(rst, html_expected, latex_expected):
|
||||||
if html_expected:
|
if html_expected:
|
||||||
return verify_re_html(rst, html_expected)
|
verify_re_html(rst, html_expected)
|
||||||
if latex_expected:
|
if latex_expected:
|
||||||
return verify_re_latex(rst, latex_expected)
|
verify_re_latex(rst, latex_expected)
|
||||||
return verify_re_
|
return verify_re_
|
||||||
|
|
||||||
|
|
||||||
@ -107,9 +107,9 @@ def verify_re(verify_re_html, verify_re_latex):
|
|||||||
def verify(verify_re_html, verify_re_latex):
|
def verify(verify_re_html, verify_re_latex):
|
||||||
def verify_(rst, html_expected, latex_expected):
|
def verify_(rst, html_expected, latex_expected):
|
||||||
if html_expected:
|
if html_expected:
|
||||||
return verify_re_html(rst, re.escape(html_expected) + '$')
|
verify_re_html(rst, re.escape(html_expected) + '$')
|
||||||
if latex_expected:
|
if latex_expected:
|
||||||
return verify_re_latex(rst, re.escape(latex_expected) + '$')
|
verify_re_latex(rst, re.escape(latex_expected) + '$')
|
||||||
return verify_
|
return verify_
|
||||||
|
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ def get_verifier(verify, verify_re):
|
|||||||
'verify',
|
'verify',
|
||||||
'"John"',
|
'"John"',
|
||||||
'<p>“John”</p>',
|
'<p>“John”</p>',
|
||||||
"``John''",
|
r'\sphinxquotedblleft{}John\sphinxquotedblright{}',
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
# ... but not in literal text
|
# ... but not in literal text
|
||||||
|
Loading…
Reference in New Issue
Block a user