mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #5227 from tk0miya/changeset_domain
refactor: Move repository of changesets to domain from env
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -84,9 +84,11 @@ Deprecated
|
||||
* ``env._read_parallel()`` is deprecated
|
||||
* ``env.write_doctree()`` is deprecated
|
||||
* ``env._nitpick_ignore`` is deprecated
|
||||
* ``env.versionchanges`` is deprecated
|
||||
* ``env.dump()`` is deprecated
|
||||
* ``env.dumps()`` is deprecated
|
||||
* ``env.topickle()`` is deprecated
|
||||
* ``env.note_versionchange()`` is deprecated
|
||||
* ``sphinx.writers.latex.Table.caption_footnotetexts`` is deprecated
|
||||
* ``sphinx.writers.latex.Table.header_footnotetexts`` is deprecated
|
||||
* ``sphinx.writers.latex.LaTeXTranslator.footnotestack`` is deprecated
|
||||
@@ -116,6 +118,7 @@ Deprecated
|
||||
* ``sphinx.ext.mathbase.is_in_section_title()`` is deprecated
|
||||
* ``sphinx.ext.mathbase.MathDomain`` is deprecated
|
||||
* ``sphinx.ext.mathbase.setup_math()`` is deprecated
|
||||
* ``sphinx.directives.other.VersionChanges`` is deprecated
|
||||
* ``sphinx.highlighting.PygmentsBridge.unhighlight()`` is deprecated
|
||||
* ``sphinx.ext.mathbase.get_node_equation_number()`` is deprecated
|
||||
* ``sphinx.ext.mathbase.wrap_displaymath()`` is deprecated
|
||||
|
||||
@@ -131,6 +131,11 @@ The following is a list of deprecated interface.
|
||||
- 4.0
|
||||
- :meth:`~sphinx.application.Sphinx.add_js_file()`
|
||||
|
||||
* - ``sphinx.directives.other.VersionChanges``
|
||||
- 1.8
|
||||
- 3.0
|
||||
- ``sphinx.domains.changeset.VersionChanges``
|
||||
|
||||
* - ``sphinx.highlighting.PygmentsBridge.unhighlight()``
|
||||
- 1.8
|
||||
- 3.0
|
||||
@@ -385,6 +390,11 @@ The following is a list of deprecated interface.
|
||||
- 3.0
|
||||
- :confval:`nitpick_ignore`
|
||||
|
||||
* - ``BuildEnvironment.versionchanges``
|
||||
- 1.8
|
||||
- 3.0
|
||||
- N/A
|
||||
|
||||
* - ``BuildEnvironment.update()``
|
||||
- 1.8
|
||||
- 3.0
|
||||
@@ -410,6 +420,11 @@ The following is a list of deprecated interface.
|
||||
- 3.0
|
||||
- ``Builder.write_doctree()``
|
||||
|
||||
* - ``BuildEnvironment.note_versionchange()``
|
||||
- 1.8
|
||||
- 3.0
|
||||
- ``ChangesDomain.note_changeset()``
|
||||
|
||||
* - ``warn()`` (template helper function)
|
||||
- 1.8
|
||||
- 3.0
|
||||
|
||||
@@ -80,6 +80,7 @@ builtin_extensions = (
|
||||
'sphinx.builders.xml',
|
||||
'sphinx.config',
|
||||
'sphinx.domains.c',
|
||||
'sphinx.domains.changeset',
|
||||
'sphinx.domains.cpp',
|
||||
'sphinx.domains.javascript',
|
||||
'sphinx.domains.math',
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
|
||||
import codecs
|
||||
from os import path
|
||||
from typing import cast
|
||||
|
||||
from six import iteritems
|
||||
|
||||
from sphinx import package_dir
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.domains.changeset import ChangeSetDomain
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.theming import HTMLThemeFactory
|
||||
from sphinx.util import logging
|
||||
@@ -60,6 +62,7 @@ class ChangesBuilder(Builder):
|
||||
def write(self, *ignored):
|
||||
# type: (Any) -> None
|
||||
version = self.config.version
|
||||
domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
|
||||
libchanges = {} # type: Dict[unicode, List[Tuple[unicode, unicode, int]]]
|
||||
apichanges = [] # type: List[Tuple[unicode, unicode, int]]
|
||||
otherchanges = {} # type: Dict[Tuple[unicode, unicode], List[Tuple[unicode, unicode, int]]] # NOQA
|
||||
@@ -67,21 +70,22 @@ class ChangesBuilder(Builder):
|
||||
logger.info(bold(__('no changes in version %s.') % version))
|
||||
return
|
||||
logger.info(bold('writing summary file...'))
|
||||
for type, docname, lineno, module, descname, content in \
|
||||
self.env.versionchanges[version]:
|
||||
if isinstance(descname, tuple):
|
||||
descname = descname[0]
|
||||
ttext = self.typemap[type]
|
||||
context = content.replace('\n', ' ')
|
||||
if descname and docname.startswith('c-api'):
|
||||
for changeset in domain.get_changesets_for(version):
|
||||
if isinstance(changeset.descname, tuple):
|
||||
descname = changeset.descname[0]
|
||||
else:
|
||||
descname = changeset.descname
|
||||
ttext = self.typemap[changeset.type]
|
||||
context = changeset.content.replace('\n', ' ')
|
||||
if descname and changeset.docname.startswith('c-api'):
|
||||
if context:
|
||||
entry = '<b>%s</b>: <i>%s:</i> %s' % (descname, ttext,
|
||||
context)
|
||||
else:
|
||||
entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext)
|
||||
apichanges.append((entry, docname, lineno))
|
||||
elif descname or module:
|
||||
if not module:
|
||||
apichanges.append((entry, changeset.docname, changeset.lineno))
|
||||
elif descname or changeset.module:
|
||||
if not changeset.module:
|
||||
module = _('Builtins')
|
||||
if not descname:
|
||||
descname = _('Module level')
|
||||
@@ -90,15 +94,15 @@ class ChangesBuilder(Builder):
|
||||
context)
|
||||
else:
|
||||
entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext)
|
||||
libchanges.setdefault(module, []).append((entry, docname,
|
||||
lineno))
|
||||
libchanges.setdefault(module, []).append((entry, changeset.docname,
|
||||
changeset.lineno))
|
||||
else:
|
||||
if not context:
|
||||
continue
|
||||
entry = '<i>%s:</i> %s' % (ttext.capitalize(), context)
|
||||
title = self.env.titles[docname].astext()
|
||||
otherchanges.setdefault((docname, title), []).append(
|
||||
(entry, docname, lineno))
|
||||
title = self.env.titles[changeset.docname].astext()
|
||||
otherchanges.setdefault((changeset.docname, title), []).append(
|
||||
(entry, changeset.docname, changeset.lineno))
|
||||
|
||||
ctx = {
|
||||
'project': self.config.project,
|
||||
|
||||
@@ -17,8 +17,8 @@ from docutils.parsers.rst.directives.misc import Class
|
||||
from docutils.parsers.rst.directives.misc import Include as BaseInclude
|
||||
from six.moves import range
|
||||
|
||||
from sphinx import addnodes, locale
|
||||
from sphinx.deprecation import DeprecatedDict, RemovedInSphinx30Warning
|
||||
from sphinx import addnodes
|
||||
from sphinx.domains.changeset import VersionChange # NOQA # for compatibility
|
||||
from sphinx.locale import _
|
||||
from sphinx.util import url_re, docname_join
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
@@ -32,19 +32,6 @@ if False:
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
|
||||
|
||||
versionlabels = {
|
||||
'versionadded': _('New in version %s'),
|
||||
'versionchanged': _('Changed in version %s'),
|
||||
'deprecated': _('Deprecated since version %s'),
|
||||
} # type: Dict[unicode, unicode]
|
||||
|
||||
locale.versionlabels = DeprecatedDict(
|
||||
versionlabels,
|
||||
'sphinx.locale.versionlabels is deprecated. '
|
||||
'Please use sphinx.directives.other.versionlabels instead.',
|
||||
RemovedInSphinx30Warning
|
||||
)
|
||||
|
||||
glob_re = re.compile(r'.*[*?\[].*')
|
||||
|
||||
|
||||
@@ -218,54 +205,6 @@ class Index(SphinxDirective):
|
||||
return [indexnode, targetnode]
|
||||
|
||||
|
||||
class VersionChange(SphinxDirective):
|
||||
"""
|
||||
Directive to describe a change/addition/deprecation in a specific version.
|
||||
"""
|
||||
has_content = True
|
||||
required_arguments = 1
|
||||
optional_arguments = 1
|
||||
final_argument_whitespace = True
|
||||
option_spec = {} # type: Dict
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
node = addnodes.versionmodified()
|
||||
node.document = self.state.document
|
||||
set_source_info(self, node)
|
||||
node['type'] = self.name
|
||||
node['version'] = self.arguments[0]
|
||||
text = versionlabels[self.name] % self.arguments[0]
|
||||
if len(self.arguments) == 2:
|
||||
inodes, messages = self.state.inline_text(self.arguments[1],
|
||||
self.lineno + 1)
|
||||
para = nodes.paragraph(self.arguments[1], '', *inodes, translatable=False)
|
||||
set_source_info(self, para)
|
||||
node.append(para)
|
||||
else:
|
||||
messages = []
|
||||
if self.content:
|
||||
self.state.nested_parse(self.content, self.content_offset, node)
|
||||
if len(node):
|
||||
if isinstance(node[0], nodes.paragraph) and node[0].rawsource:
|
||||
content = nodes.inline(node[0].rawsource, translatable=True)
|
||||
content.source = node[0].source
|
||||
content.line = node[0].line
|
||||
content += node[0].children
|
||||
node[0].replace_self(nodes.paragraph('', '', content, translatable=False))
|
||||
node[0].insert(0, nodes.inline('', '%s: ' % text,
|
||||
classes=['versionmodified']))
|
||||
else:
|
||||
para = nodes.paragraph('', '',
|
||||
nodes.inline('', '%s.' % text,
|
||||
classes=['versionmodified']),
|
||||
translatable=False)
|
||||
node.append(para)
|
||||
# XXX should record node.source as well
|
||||
self.env.note_versionchange(node['type'], node['version'], node, node.line)
|
||||
return [node] + messages
|
||||
|
||||
|
||||
class SeeAlso(BaseAdmonition):
|
||||
"""
|
||||
An admonition mentioning things to look at as reference.
|
||||
@@ -475,9 +414,6 @@ def setup(app):
|
||||
directives.register_directive('moduleauthor', Author)
|
||||
directives.register_directive('codeauthor', Author)
|
||||
directives.register_directive('index', Index)
|
||||
directives.register_directive('deprecated', VersionChange)
|
||||
directives.register_directive('versionadded', VersionChange)
|
||||
directives.register_directive('versionchanged', VersionChange)
|
||||
directives.register_directive('seealso', SeeAlso)
|
||||
directives.register_directive('tabularcolumns', TabularColumns)
|
||||
directives.register_directive('centered', Centered)
|
||||
|
||||
159
sphinx/domains/changeset.py
Normal file
159
sphinx/domains/changeset.py
Normal file
@@ -0,0 +1,159 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
sphinx.domains.changeset
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The changeset domain.
|
||||
|
||||
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from typing import NamedTuple
|
||||
|
||||
from docutils import nodes
|
||||
from six import iteritems
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx import locale
|
||||
from sphinx.deprecation import DeprecatedDict, RemovedInSphinx30Warning
|
||||
from sphinx.domains import Domain
|
||||
from sphinx.locale import _
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
from sphinx.util.nodes import set_source_info
|
||||
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, List # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
|
||||
|
||||
versionlabels = {
|
||||
'versionadded': _('New in version %s'),
|
||||
'versionchanged': _('Changed in version %s'),
|
||||
'deprecated': _('Deprecated since version %s'),
|
||||
} # type: Dict[unicode, unicode]
|
||||
|
||||
locale.versionlabels = DeprecatedDict(
|
||||
versionlabels,
|
||||
'sphinx.locale.versionlabels is deprecated. '
|
||||
'Please use sphinx.domains.changeset.versionlabels instead.',
|
||||
RemovedInSphinx30Warning
|
||||
)
|
||||
|
||||
|
||||
ChangeSet = NamedTuple('ChangeSet', [('type', str),
|
||||
('docname', str),
|
||||
('lineno', int),
|
||||
('module', str),
|
||||
('descname', str),
|
||||
('content', str)])
|
||||
|
||||
|
||||
class VersionChange(SphinxDirective):
|
||||
"""
|
||||
Directive to describe a change/addition/deprecation in a specific version.
|
||||
"""
|
||||
has_content = True
|
||||
required_arguments = 1
|
||||
optional_arguments = 1
|
||||
final_argument_whitespace = True
|
||||
option_spec = {} # type: Dict
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
node = addnodes.versionmodified()
|
||||
node.document = self.state.document
|
||||
set_source_info(self, node)
|
||||
node['type'] = self.name
|
||||
node['version'] = self.arguments[0]
|
||||
text = versionlabels[self.name] % self.arguments[0]
|
||||
if len(self.arguments) == 2:
|
||||
inodes, messages = self.state.inline_text(self.arguments[1],
|
||||
self.lineno + 1)
|
||||
para = nodes.paragraph(self.arguments[1], '', *inodes, translatable=False)
|
||||
set_source_info(self, para)
|
||||
node.append(para)
|
||||
else:
|
||||
messages = []
|
||||
if self.content:
|
||||
self.state.nested_parse(self.content, self.content_offset, node)
|
||||
if len(node):
|
||||
if isinstance(node[0], nodes.paragraph) and node[0].rawsource:
|
||||
content = nodes.inline(node[0].rawsource, translatable=True)
|
||||
content.source = node[0].source
|
||||
content.line = node[0].line
|
||||
content += node[0].children
|
||||
node[0].replace_self(nodes.paragraph('', '', content, translatable=False))
|
||||
node[0].insert(0, nodes.inline('', '%s: ' % text,
|
||||
classes=['versionmodified']))
|
||||
else:
|
||||
para = nodes.paragraph('', '',
|
||||
nodes.inline('', '%s.' % text,
|
||||
classes=['versionmodified']),
|
||||
translatable=False)
|
||||
node.append(para)
|
||||
|
||||
self.env.get_domain('changeset').note_changeset(node) # type: ignore
|
||||
return [node] + messages
|
||||
|
||||
|
||||
class ChangeSetDomain(Domain):
|
||||
"""Domain for changesets."""
|
||||
|
||||
name = 'changeset'
|
||||
label = 'changeset'
|
||||
|
||||
initial_data = {
|
||||
'changes': {}, # version -> list of ChangeSet
|
||||
} # type: Dict
|
||||
|
||||
def clear_doc(self, docname):
|
||||
# type: (unicode) -> None
|
||||
for version, changes in iteritems(self.data['changes']):
|
||||
for changeset in changes[:]:
|
||||
if changeset.docname == docname:
|
||||
changes.remove(changeset)
|
||||
|
||||
def merge_domaindata(self, docnames, otherdata):
|
||||
# type: (List[unicode], Dict) -> None
|
||||
# XXX duplicates?
|
||||
for version, otherchanges in iteritems(otherdata['changes']):
|
||||
changes = self.data['changes'].setdefault(version, [])
|
||||
for changeset in otherchanges:
|
||||
if changeset.docname in docnames:
|
||||
changes.append(changeset)
|
||||
|
||||
def process_doc(self, env, docname, document):
|
||||
# type: (BuildEnvironment, unicode, nodes.Node) -> None
|
||||
pass # nothing to do here. All changesets are registered on calling directive.
|
||||
|
||||
def note_changeset(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
version = node['version']
|
||||
module = self.env.ref_context.get('py:module')
|
||||
objname = self.env.temp_data.get('object')
|
||||
changeset = ChangeSet(node['type'], self.env.docname, node.line, # type: ignore
|
||||
module, objname, node.astext())
|
||||
self.data['changes'].setdefault(version, []).append(changeset)
|
||||
|
||||
def get_changesets_for(self, version):
|
||||
# type: (unicode) -> List[ChangeSet]
|
||||
return self.data['changes'].get(version, [])
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[unicode, Any]
|
||||
app.add_domain(ChangeSetDomain)
|
||||
app.add_directive('deprecated', VersionChange)
|
||||
app.add_directive('versionadded', VersionChange)
|
||||
app.add_directive('versionchanged', VersionChange)
|
||||
|
||||
return {
|
||||
'version': 'builtin',
|
||||
'env_version': 1,
|
||||
'parallel_read_safe': True,
|
||||
'parallel_write_safe': True,
|
||||
}
|
||||
@@ -186,9 +186,6 @@ class BuildEnvironment(object):
|
||||
self.indexentries = {} # type: Dict[unicode, List[Tuple[unicode, unicode, unicode, unicode, unicode]]] # NOQA
|
||||
# docname -> list of
|
||||
# (type, unicode, target, aliasname)
|
||||
self.versionchanges = {} # type: Dict[unicode, List[Tuple[unicode, unicode, int, unicode, unicode, unicode]]] # NOQA
|
||||
# version -> list of (type, docname,
|
||||
# lineno, module, descname, content)
|
||||
|
||||
# these map absolute path -> (docnames, unique filename)
|
||||
self.images = FilenameUniqDict() # type: FilenameUniqDict
|
||||
@@ -321,10 +318,6 @@ class BuildEnvironment(object):
|
||||
self.reread_always.discard(docname)
|
||||
self.included.discard(docname)
|
||||
|
||||
for version, changes in self.versionchanges.items():
|
||||
new = [change for change in changes if change[1] != docname]
|
||||
changes[:] = new
|
||||
|
||||
for domain in self.domains.values():
|
||||
domain.clear_doc(docname)
|
||||
|
||||
@@ -343,10 +336,6 @@ class BuildEnvironment(object):
|
||||
if docname in other.included:
|
||||
self.included.add(docname)
|
||||
|
||||
for version, changes in other.versionchanges.items():
|
||||
self.versionchanges.setdefault(version, []).extend(
|
||||
change for change in changes if change[1] in docnames)
|
||||
|
||||
for domainname, domain in self.domains.items():
|
||||
domain.merge_domaindata(docnames, other.domaindata[domainname])
|
||||
app.emit('env-merge-info', self, docnames, other)
|
||||
@@ -571,13 +560,6 @@ class BuildEnvironment(object):
|
||||
"""
|
||||
self.reread_always.add(self.docname)
|
||||
|
||||
def note_versionchange(self, type, version, node, lineno):
|
||||
# type: (unicode, unicode, nodes.Node, int) -> None
|
||||
self.versionchanges.setdefault(version, []).append(
|
||||
(type, self.temp_data['docname'], lineno,
|
||||
self.ref_context.get('py:module'),
|
||||
self.temp_data.get('object'), node.astext()))
|
||||
|
||||
def note_toctree(self, docname, toctreenode):
|
||||
# type: (unicode, addnodes.toctree) -> None
|
||||
"""Note a TOC tree directive in a document and gather information about
|
||||
@@ -857,3 +839,21 @@ class BuildEnvironment(object):
|
||||
RemovedInSphinx30Warning)
|
||||
with open(filename, 'wb') as f:
|
||||
self.dump(self, f)
|
||||
|
||||
@property
|
||||
def versionchanges(self):
|
||||
# type: () -> Dict[unicode, List[Tuple[unicode, unicode, int, unicode, unicode, unicode]]] # NOQA
|
||||
warnings.warn('env.versionchanges() is deprecated. '
|
||||
'Please use ChangeSetDomain instead.',
|
||||
RemovedInSphinx30Warning)
|
||||
return self.domaindata['changeset']['changes']
|
||||
|
||||
def note_versionchange(self, type, version, node, lineno):
|
||||
# type: (unicode, unicode, nodes.Node, int) -> None
|
||||
warnings.warn('env.note_versionchange() is deprecated. '
|
||||
'Please use ChangeSetDomain.note_changeset() instead.',
|
||||
RemovedInSphinx30Warning)
|
||||
node['type'] = type
|
||||
node['version'] = version
|
||||
node.line = lineno
|
||||
self.get_domain('changeset').note_changeset(node) # type: ignore
|
||||
|
||||
Reference in New Issue
Block a user