mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
getargspec moved to sphinx.util.inspect
This commit is contained in:
commit
0964f4f993
10
CHANGES
10
CHANGES
@ -5,6 +5,10 @@ Release 1.1 (in development)
|
||||
|
||||
* Added a Texinfo builder.
|
||||
|
||||
* Incompatibility: The :rst:dir:`py:module` directive doesn't output
|
||||
its ``platform`` option value anymore. (It was the only thing that
|
||||
the directive did output, and therefore quite inconsistent.)
|
||||
|
||||
* Added i18n support for content, a ``gettext`` builder and
|
||||
related utilities.
|
||||
|
||||
@ -85,6 +89,12 @@ Release 1.1 (in development)
|
||||
Release 1.0.7 (in development)
|
||||
==============================
|
||||
|
||||
* #572: Show warnings by default when reference labels cannot be
|
||||
found.
|
||||
|
||||
* #536: Include line number when complaining about missing reference
|
||||
targets in nitpicky mode.
|
||||
|
||||
* #590: Fix inline display of graphviz diagrams in LaTeX output.
|
||||
|
||||
* #589: Build using app.build() in setup command.
|
||||
|
@ -8,8 +8,9 @@ PAPER =
|
||||
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) \
|
||||
$(SPHINXOPTS) $(O) .
|
||||
ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) \
|
||||
$(SPHINXOPTS) $(O) .
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(O) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml text man pickle json htmlhelp \
|
||||
qthelp devhelp epub latex latexpdf changes linkcheck doctest
|
||||
@ -116,7 +117,7 @@ latexpdf:
|
||||
@echo "pdflatex finished; the PDF files are in _build/latex."
|
||||
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(ALLSPHINXOPTS) _build/locale
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) _build/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in _build/locale."
|
||||
|
||||
|
@ -240,7 +240,7 @@ Note that a direct PDF builder using ReportLab is available in `rst2pdf
|
||||
|
||||
.. versionadded:: 0.5
|
||||
|
||||
.. module:: sphinx.builders.intl
|
||||
.. module:: sphinx.builders.gettext
|
||||
.. class:: MessageCatalogBuilder
|
||||
|
||||
This builder produces gettext-style message catalos. Each top-level file or
|
||||
|
@ -32,7 +32,7 @@ task to split up paragraphs which are too large as there is no sane automated
|
||||
way to do that.
|
||||
|
||||
After Sphinx successfully ran the
|
||||
:class:`~sphinx.builders.intl.MessageCatalogBuilder` you will find a collection
|
||||
:class:`~sphinx.builders.gettext.MessageCatalogBuilder` you will find a collection
|
||||
of ``.pot`` files in your output directory. These are **catalog templates**
|
||||
and contain messages in your original language *only*.
|
||||
|
||||
|
@ -179,7 +179,7 @@ These themes are:
|
||||
*nosidebar*.
|
||||
|
||||
* **pyramid** -- A theme from the Pyramid web framework project, designed by
|
||||
Blais Laflamme. THere are currently no options beyond *nosidebar*.
|
||||
Blaise Laflamme. THere are currently no options beyond *nosidebar*.
|
||||
|
||||
* **haiku** -- A theme without sidebar inspired by the `Haiku OS user guide
|
||||
<http://www.haiku-os.org/docs/userguide/en/contents.html>`_. The following
|
||||
|
@ -31,9 +31,12 @@ class Builder(object):
|
||||
name = ''
|
||||
# builder's output format, or '' if no document output is produced
|
||||
format = ''
|
||||
# doctree versioning method
|
||||
versioning_method = 'none'
|
||||
|
||||
def __init__(self, app):
|
||||
self.env = app.env
|
||||
self.env.set_versioning_method(self.versioning_method)
|
||||
self.srcdir = app.srcdir
|
||||
self.confdir = app.confdir
|
||||
self.outdir = app.outdir
|
||||
@ -330,5 +333,5 @@ BUILTIN_BUILDERS = {
|
||||
'changes': ('changes', 'ChangesBuilder'),
|
||||
'linkcheck': ('linkcheck', 'CheckExternalLinksBuilder'),
|
||||
'websupport': ('websupport', 'WebSupportBuilder'),
|
||||
'gettext': ('intl', 'MessageCatalogBuilder'),
|
||||
'gettext': ('gettext', 'MessageCatalogBuilder'),
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
sphinx.builders.intl
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
sphinx.builders.gettext
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The MessageCatalogBuilder class.
|
||||
|
||||
@ -48,6 +48,7 @@ class I18nBuilder(Builder):
|
||||
General i18n builder.
|
||||
"""
|
||||
name = 'i18n'
|
||||
versioning_method = 'text'
|
||||
|
||||
def init(self):
|
||||
Builder.init(self)
|
@ -26,6 +26,7 @@ class WebSupportBuilder(PickleHTMLBuilder):
|
||||
Builds documents for the web support package.
|
||||
"""
|
||||
name = 'websupport'
|
||||
versioning_method = 'commentable'
|
||||
|
||||
def init(self):
|
||||
PickleHTMLBuilder.init(self)
|
||||
|
@ -131,6 +131,8 @@ class Domain(object):
|
||||
roles = {}
|
||||
#: a list of Index subclasses
|
||||
indices = []
|
||||
#: role name -> a warning message if reference is missing
|
||||
dangling_warnings = {}
|
||||
|
||||
#: data value for a fresh environment
|
||||
initial_data = {}
|
||||
|
@ -1090,13 +1090,15 @@ class CPPDomain(Domain):
|
||||
contnode, name)
|
||||
|
||||
parser = DefinitionParser(target)
|
||||
# XXX: warn?
|
||||
try:
|
||||
expr = parser.parse_type().get_name()
|
||||
parser.skip_ws()
|
||||
if not parser.eof or expr is None:
|
||||
return None
|
||||
raise DefinitionError('')
|
||||
except DefinitionError:
|
||||
refdoc = node.get('refdoc', fromdocname)
|
||||
env.warn(refdoc, 'unparseable C++ definition: %r' % target,
|
||||
node.line)
|
||||
return None
|
||||
|
||||
parent = node['cpp:parent']
|
||||
|
@ -419,15 +419,8 @@ class PyModule(Directive):
|
||||
targetnode = nodes.target('', '', ids=['module-' + modname], ismod=True)
|
||||
self.state.document.note_explicit_target(targetnode)
|
||||
ret = [targetnode]
|
||||
# XXX this behavior of the module directive is a mess...
|
||||
if 'platform' in self.options:
|
||||
platform = self.options['platform']
|
||||
node = nodes.paragraph()
|
||||
node += nodes.emphasis('', _('Platforms: '))
|
||||
node += nodes.Text(platform, platform)
|
||||
ret.append(node)
|
||||
# the synopsis isn't printed; in fact, it is only used in the
|
||||
# modindex currently
|
||||
# the platform and synopsis aren't printed; in fact, they are only used
|
||||
# in the modindex currently
|
||||
if not noindex:
|
||||
indextext = _('%s (module)') % modname
|
||||
inode = addnodes.index(entries=[('single', indextext,
|
||||
|
@ -411,11 +411,13 @@ class StandardDomain(Domain):
|
||||
# links to tokens in grammar productions
|
||||
'token': XRefRole(),
|
||||
# links to terms in glossary
|
||||
'term': XRefRole(lowercase=True, innernodeclass=nodes.emphasis),
|
||||
'term': XRefRole(lowercase=True, innernodeclass=nodes.emphasis,
|
||||
warn_dangling=True),
|
||||
# links to headings or arbitrary labels
|
||||
'ref': XRefRole(lowercase=True, innernodeclass=nodes.emphasis),
|
||||
'ref': XRefRole(lowercase=True, innernodeclass=nodes.emphasis,
|
||||
warn_dangling=True),
|
||||
# links to labels, without a different title
|
||||
'keyword': XRefRole(),
|
||||
'keyword': XRefRole(warn_dangling=True),
|
||||
}
|
||||
|
||||
initial_data = {
|
||||
@ -433,6 +435,13 @@ class StandardDomain(Domain):
|
||||
},
|
||||
}
|
||||
|
||||
dangling_warnings = {
|
||||
'term': 'term not in glossary: %(target)s',
|
||||
'ref': 'undefined label: %(target)s (if the link has no caption '
|
||||
'the label must precede a section header)',
|
||||
'keyword': 'unknown keyword: %(target)s',
|
||||
}
|
||||
|
||||
def clear_doc(self, docname):
|
||||
for key, (fn, _) in self.data['progoptions'].items():
|
||||
if fn == docname:
|
||||
@ -490,27 +499,16 @@ class StandardDomain(Domain):
|
||||
def resolve_xref(self, env, fromdocname, builder,
|
||||
typ, target, node, contnode):
|
||||
if typ == 'ref':
|
||||
#refdoc = node.get('refdoc', fromdocname)
|
||||
if node['refexplicit']:
|
||||
# reference to anonymous label; the reference uses
|
||||
# the supplied link caption
|
||||
docname, labelid = self.data['anonlabels'].get(target, ('',''))
|
||||
sectname = node.astext()
|
||||
# XXX warn somehow if not resolved by intersphinx
|
||||
#if not docname:
|
||||
# env.warn(refdoc, 'undefined label: %s' %
|
||||
# target, node.line)
|
||||
else:
|
||||
# reference to named label; the final node will
|
||||
# contain the section name after the label
|
||||
docname, labelid, sectname = self.data['labels'].get(target,
|
||||
('','',''))
|
||||
# XXX warn somehow if not resolved by intersphinx
|
||||
#if not docname:
|
||||
# env.warn(refdoc,
|
||||
# 'undefined label: %s' % target + ' -- if you '
|
||||
# 'don\'t give a link caption the label must '
|
||||
# 'precede a section header.', node.line)
|
||||
if not docname:
|
||||
return None
|
||||
newnode = nodes.reference('', '', internal=True)
|
||||
@ -534,20 +532,17 @@ class StandardDomain(Domain):
|
||||
# keywords are oddballs: they are referenced by named labels
|
||||
docname, labelid, _ = self.data['labels'].get(target, ('','',''))
|
||||
if not docname:
|
||||
#env.warn(refdoc, 'unknown keyword: %s' % target)
|
||||
return None
|
||||
else:
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
elif typ == 'option':
|
||||
progname = node['refprogram']
|
||||
docname, labelid = self.data['progoptions'].get((progname, target),
|
||||
('', ''))
|
||||
if not docname:
|
||||
return None
|
||||
else:
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
else:
|
||||
objtypes = self.objtypes_for_role(typ) or []
|
||||
for objtype in objtypes:
|
||||
@ -557,13 +552,9 @@ class StandardDomain(Domain):
|
||||
else:
|
||||
docname, labelid = '', ''
|
||||
if not docname:
|
||||
if typ == 'term':
|
||||
env.warn(node.get('refdoc', fromdocname),
|
||||
'term not in glossary: %s' % target, node.line)
|
||||
return None
|
||||
else:
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
|
||||
def get_objects(self):
|
||||
for (prog, option), info in self.data['progoptions'].iteritems():
|
||||
|
@ -43,6 +43,7 @@ from sphinx.util.nodes import clean_astext, make_refnode, extract_messages
|
||||
from sphinx.util.osutil import movefile, SEP, ustrftime
|
||||
from sphinx.util.matching import compile_matchers
|
||||
from sphinx.util.pycompat import all, class_types
|
||||
from sphinx.util.websupport import is_commentable
|
||||
from sphinx.errors import SphinxError, ExtensionError
|
||||
from sphinx.locale import _, init as init_locale
|
||||
from sphinx.versioning import add_uids, merge_doctrees
|
||||
@ -68,7 +69,7 @@ default_settings = {
|
||||
|
||||
# This is increased every time an environment attribute is added
|
||||
# or changed to properly invalidate pickle files.
|
||||
ENV_VERSION = 39
|
||||
ENV_VERSION = 40
|
||||
|
||||
|
||||
default_substitutions = set([
|
||||
@ -79,6 +80,12 @@ default_substitutions = set([
|
||||
|
||||
dummy_reporter = Reporter('', 4, 4)
|
||||
|
||||
versioning_conditions = {
|
||||
'none': False,
|
||||
'text': nodes.TextElement,
|
||||
'commentable': is_commentable,
|
||||
}
|
||||
|
||||
|
||||
class WarningStream(object):
|
||||
def __init__(self, warnfunc):
|
||||
@ -182,7 +189,8 @@ class CitationReferences(Transform):
|
||||
for citnode in self.document.traverse(nodes.citation_reference):
|
||||
cittext = citnode.astext()
|
||||
refnode = addnodes.pending_xref(cittext, reftype='citation',
|
||||
reftarget=cittext)
|
||||
reftarget=cittext, refwarn=True)
|
||||
refnode.line = citnode.line or citnode.parent.line
|
||||
refnode += nodes.Text('[' + cittext + ']')
|
||||
citnode.parent.replace(citnode, refnode)
|
||||
|
||||
@ -313,6 +321,9 @@ class BuildEnvironment:
|
||||
self.srcdir = srcdir
|
||||
self.config = config
|
||||
|
||||
# the method of doctree versioning; see set_versioning_method
|
||||
self.versioning_condition = None
|
||||
|
||||
# the application object; only set while update() runs
|
||||
self.app = None
|
||||
|
||||
@ -380,6 +391,23 @@ class BuildEnvironment:
|
||||
self._warnfunc = func
|
||||
self.settings['warning_stream'] = WarningStream(func)
|
||||
|
||||
def set_versioning_method(self, method):
|
||||
"""This sets the doctree versioning method for this environment.
|
||||
|
||||
Versioning methods are a builder property; only builders with the same
|
||||
versioning method can share the same doctree directory. Therefore, we
|
||||
raise an exception if the user tries to use an environment with an
|
||||
incompatible versioning method.
|
||||
"""
|
||||
if method not in versioning_conditions:
|
||||
raise ValueError('invalid versioning method: %r' % method)
|
||||
condition = versioning_conditions[method]
|
||||
if self.versioning_condition not in (None, condition):
|
||||
raise SphinxError('This environment is incompatible with the '
|
||||
'selected builder, please choose another '
|
||||
'doctree directory.')
|
||||
self.versioning_condition = condition
|
||||
|
||||
def warn(self, docname, msg, lineno=None):
|
||||
# strange argument order is due to backwards compatibility
|
||||
self._warnfunc(msg, (docname, lineno))
|
||||
@ -754,25 +782,24 @@ class BuildEnvironment:
|
||||
# store time of build, for outdated files detection
|
||||
self.all_docs[docname] = time.time()
|
||||
|
||||
# get old doctree
|
||||
old_doctree_path = self.doc2path(docname, self.doctreedir, '.doctree')
|
||||
try:
|
||||
f = open(old_doctree_path, 'rb')
|
||||
if self.versioning_condition:
|
||||
# get old doctree
|
||||
try:
|
||||
old_doctree = pickle.load(f)
|
||||
finally:
|
||||
f.close()
|
||||
old_doctree.settings.env = self
|
||||
old_doctree.reporter = Reporter(self.doc2path(docname), 2, 5,
|
||||
stream=WarningStream(self._warnfunc))
|
||||
except EnvironmentError:
|
||||
old_doctree = None
|
||||
f = open(self.doc2path(docname,
|
||||
self.doctreedir, '.doctree'), 'rb')
|
||||
try:
|
||||
old_doctree = pickle.load(f)
|
||||
finally:
|
||||
f.close()
|
||||
except EnvironmentError:
|
||||
old_doctree = None
|
||||
|
||||
# add uids for versioning
|
||||
if old_doctree is None:
|
||||
list(add_uids(doctree, nodes.TextElement))
|
||||
else:
|
||||
list(merge_doctrees(old_doctree, doctree, nodes.TextElement))
|
||||
# add uids for versioning
|
||||
if old_doctree is None:
|
||||
list(add_uids(doctree, self.versioning_condition))
|
||||
else:
|
||||
list(merge_doctrees(
|
||||
old_doctree, doctree, self.versioning_condition))
|
||||
|
||||
# make it picklable
|
||||
doctree.reporter = None
|
||||
@ -1385,10 +1412,10 @@ class BuildEnvironment:
|
||||
typ = node['reftype']
|
||||
target = node['reftarget']
|
||||
refdoc = node.get('refdoc', fromdocname)
|
||||
warned = False
|
||||
domain = None
|
||||
|
||||
try:
|
||||
if node.has_key('refdomain') and node['refdomain']:
|
||||
if 'refdomain' in node and node['refdomain']:
|
||||
# let the domain try to resolve the reference
|
||||
try:
|
||||
domain = self.domains[node['refdomain']]
|
||||
@ -1401,11 +1428,7 @@ class BuildEnvironment:
|
||||
# directly reference to document by source name;
|
||||
# can be absolute or relative
|
||||
docname = docname_join(refdoc, target)
|
||||
if docname not in self.all_docs:
|
||||
self.warn(refdoc,
|
||||
'unknown document: %s' % docname, node.line)
|
||||
warned = True
|
||||
else:
|
||||
if docname in self.all_docs:
|
||||
if node['refexplicit']:
|
||||
# reference with explicit title
|
||||
caption = node.astext()
|
||||
@ -1418,11 +1441,7 @@ class BuildEnvironment:
|
||||
newnode.append(innernode)
|
||||
elif typ == 'citation':
|
||||
docname, labelid = self.citations.get(target, ('', ''))
|
||||
if not docname:
|
||||
self.warn(refdoc,
|
||||
'citation not found: %s' % target, node.line)
|
||||
warned = True
|
||||
else:
|
||||
if docname:
|
||||
newnode = make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
# no new node found? try the missing-reference event
|
||||
@ -1430,16 +1449,40 @@ class BuildEnvironment:
|
||||
newnode = builder.app.emit_firstresult(
|
||||
'missing-reference', self, node, contnode)
|
||||
# still not found? warn if in nit-picky mode
|
||||
if newnode is None and not warned and self.config.nitpicky:
|
||||
self.warn(refdoc,
|
||||
'reference target not found: %stype %s, target %s'
|
||||
% (node.get('refdomain') and
|
||||
'domain %s, ' % node['refdomain'] or '',
|
||||
typ, target))
|
||||
if newnode is None:
|
||||
self._warn_missing_reference(
|
||||
fromdocname, typ, target, node, domain)
|
||||
except NoUri:
|
||||
newnode = contnode
|
||||
node.replace_self(newnode or contnode)
|
||||
|
||||
# remove only-nodes that do not belong to our builder
|
||||
self.process_only_nodes(doctree, fromdocname, builder)
|
||||
|
||||
# allow custom references to be resolved
|
||||
builder.app.emit('doctree-resolved', doctree, fromdocname)
|
||||
|
||||
def _warn_missing_reference(self, fromdoc, typ, target, node, domain):
|
||||
warn = node.get('refwarn')
|
||||
if self.config.nitpicky:
|
||||
warn = True # XXX process exceptions here
|
||||
if not warn:
|
||||
return
|
||||
refdoc = node.get('refdoc', fromdoc)
|
||||
if domain and typ in domain.dangling_warnings:
|
||||
msg = domain.dangling_warnings[typ]
|
||||
elif typ == 'doc':
|
||||
msg = 'unknown document: %(target)s'
|
||||
elif typ == 'citation':
|
||||
msg = 'citation not found: %(target)s'
|
||||
elif node.get('refdomain', 'std') != 'std':
|
||||
msg = '%s:%s reference target not found: %%(target)s' % \
|
||||
(node['refdomain'], typ)
|
||||
else:
|
||||
msg = '%s reference target not found: %%(target)s' % typ
|
||||
self.warn(refdoc, msg % {'target': target}, node.line)
|
||||
|
||||
def process_only_nodes(self, doctree, fromdocname, builder):
|
||||
for node in doctree.traverse(addnodes.only):
|
||||
try:
|
||||
ret = builder.tags.eval_condition(node['expr'])
|
||||
@ -1455,9 +1498,6 @@ class BuildEnvironment:
|
||||
# if there is a target node before the only node
|
||||
node.replace_self(nodes.comment())
|
||||
|
||||
# allow custom references to be resolved
|
||||
builder.app.emit('doctree-resolved', doctree, fromdocname)
|
||||
|
||||
def assign_section_numbers(self):
|
||||
"""Assign a section number to each heading under a numbered toctree."""
|
||||
# a list of all docnames whose section numbers changed
|
||||
|
@ -27,7 +27,8 @@ from sphinx.pycode import ModuleAnalyzer, PycodeError
|
||||
from sphinx.application import ExtensionError
|
||||
from sphinx.util.nodes import nested_parse_with_titles
|
||||
from sphinx.util.compat import Directive
|
||||
from sphinx.util.inspect import isdescriptor, safe_getmembers, safe_getattr
|
||||
from sphinx.util.inspect import (getargspec, isdescriptor, safe_getmembers, \
|
||||
safe_getattr)
|
||||
from sphinx.util.pycompat import base_exception, class_types
|
||||
from sphinx.util.docstrings import prepare_docstring
|
||||
|
||||
@ -1284,36 +1285,6 @@ def add_documenter(cls):
|
||||
AutoDirective._registry[cls.objtype] = cls
|
||||
|
||||
|
||||
if sys.version_info >= (2, 5):
|
||||
from functools import partial
|
||||
def getargspec(func):
|
||||
"""Like inspect.getargspec but supports functools.partial as well."""
|
||||
if inspect.ismethod(func):
|
||||
func = func.im_func
|
||||
parts = 0, ()
|
||||
if type(func) is partial:
|
||||
parts = len(func.args), func.keywords.keys()
|
||||
func = func.func
|
||||
if not inspect.isfunction(func):
|
||||
raise TypeError('{!r} is not a Python function'.format(func))
|
||||
args, varargs, varkw = inspect.getargs(func.func_code)
|
||||
func_defaults = func.func_defaults
|
||||
if func_defaults:
|
||||
func_defaults = list(func_defaults)
|
||||
if parts[0]:
|
||||
args = args[parts[0]:]
|
||||
if parts[1]:
|
||||
for arg in parts[1]:
|
||||
i = args.index(arg) - len(args)
|
||||
del args[i]
|
||||
try:
|
||||
del func_defaults[i]
|
||||
except IndexError:
|
||||
pass
|
||||
return inspect.ArgSpec(args, varargs, varkw, func_defaults)
|
||||
else:
|
||||
getargspec = inspect.getargspec
|
||||
|
||||
def setup(app):
|
||||
app.add_autodocumenter(ModuleDocumenter)
|
||||
app.add_autodocumenter(ClassDocumenter)
|
||||
|
@ -361,6 +361,8 @@ PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) \
|
||||
$(SPHINXOPTS) %(rsrcdir)s
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) %(rsrcdir)s
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp \
|
||||
epub latex latexpdf text man changes linkcheck doctest gettext
|
||||
@ -483,7 +485,7 @@ info:
|
||||
\t@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext:
|
||||
\t$(SPHINXBUILD) -b gettext $(ALLSPHINXOPTS) $(BUILDDIR)/locale
|
||||
\t$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
\t@echo
|
||||
\t@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
@ -514,8 +516,10 @@ if "%%SPHINXBUILD%%" == "" (
|
||||
)
|
||||
set BUILDDIR=%(rbuilddir)s
|
||||
set ALLSPHINXOPTS=-d %%BUILDDIR%%/doctrees %%SPHINXOPTS%% %(rsrcdir)s
|
||||
set I18NSPHINXOPTS=%%SPHINXOPTS%% %(rsrcdir)s
|
||||
if NOT "%%PAPER%%" == "" (
|
||||
\tset ALLSPHINXOPTS=-D latex_paper_size=%%PAPER%% %%ALLSPHINXOPTS%%
|
||||
\tset I18NSPHINXOPTS=-D latex_paper_size=%%PAPER%% %%I18NSPHINXOPTS%%
|
||||
)
|
||||
|
||||
if "%%1" == "" goto help
|
||||
@ -659,7 +663,7 @@ if "%%1" == "texinfo" (
|
||||
)
|
||||
|
||||
if "%%1" == "gettext" (
|
||||
\t%%SPHINXBUILD%% -b gettext %%ALLSPHINXOPTS%% %%BUILDDIR%%/locale
|
||||
\t%%SPHINXBUILD%% -b gettext %%I18NSPHINXOPTS%% %%BUILDDIR%%/locale
|
||||
\tif errorlevel 1 exit /b 1
|
||||
\techo.
|
||||
\techo.Build finished. The message catalogs are in %%BUILDDIR%%/locale.
|
||||
@ -991,4 +995,3 @@ def main(argv=sys.argv):
|
||||
print
|
||||
print '[Interrupted.]'
|
||||
return
|
||||
|
||||
|
@ -69,9 +69,10 @@ class XRefRole(object):
|
||||
innernodeclass = nodes.literal
|
||||
|
||||
def __init__(self, fix_parens=False, lowercase=False,
|
||||
nodeclass=None, innernodeclass=None):
|
||||
nodeclass=None, innernodeclass=None, warn_dangling=False):
|
||||
self.fix_parens = fix_parens
|
||||
self.lowercase = lowercase
|
||||
self.warn_dangling = warn_dangling
|
||||
if nodeclass is not None:
|
||||
self.nodeclass = nodeclass
|
||||
if innernodeclass is not None:
|
||||
@ -133,6 +134,7 @@ class XRefRole(object):
|
||||
refnode += self.innernodeclass(rawtext, title, classes=classes)
|
||||
# we also need the source document
|
||||
refnode['refdoc'] = env.docname
|
||||
refnode['refwarn'] = self.warn_dangling
|
||||
# result_nodes allow further modification of return values
|
||||
return self.result_nodes(inliner.document, env, refnode, is_ref=True)
|
||||
|
||||
@ -298,7 +300,7 @@ specific_docroles = {
|
||||
# links to download references
|
||||
'download': XRefRole(nodeclass=addnodes.download_reference),
|
||||
# links to documents
|
||||
'doc': XRefRole(),
|
||||
'doc': XRefRole(warn_dangling=True),
|
||||
|
||||
'pep': indexmarkup_role,
|
||||
'rfc': indexmarkup_role,
|
||||
|
@ -9,6 +9,40 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
inspect = __import__('inspect')
|
||||
import sys
|
||||
|
||||
if sys.version_info >= (2, 5):
|
||||
from functools import partial
|
||||
def getargspec(func):
|
||||
"""Like inspect.getargspec but supports functools.partial as well."""
|
||||
if inspect.ismethod(func):
|
||||
func = func.im_func
|
||||
parts = 0, ()
|
||||
if type(func) is partial:
|
||||
parts = len(func.args), func.keywords.keys()
|
||||
func = func.func
|
||||
if not inspect.isfunction(func):
|
||||
raise TypeError('%r is not a Python function' % func)
|
||||
args, varargs, varkw = inspect.getargs(func.func_code)
|
||||
func_defaults = func.func_defaults
|
||||
if func_defaults:
|
||||
func_defaults = list(func_defaults)
|
||||
if parts[0]:
|
||||
args = args[parts[0]:]
|
||||
if parts[1]:
|
||||
for arg in parts[1]:
|
||||
i = args.index(arg) - len(args)
|
||||
del args[i]
|
||||
try:
|
||||
del func_defaults[i]
|
||||
except IndexError:
|
||||
pass
|
||||
return inspect.ArgSpec(args, varargs, varkw, func_defaults)
|
||||
else:
|
||||
getargspec = inspect.getargspec
|
||||
|
||||
|
||||
def isdescriptor(x):
|
||||
"""Check if the object is some kind of descriptor."""
|
||||
for item in '__get__', '__set__', '__delete__':
|
||||
|
@ -11,7 +11,6 @@
|
||||
"""
|
||||
from uuid import uuid4
|
||||
from operator import itemgetter
|
||||
from collections import defaultdict
|
||||
|
||||
from sphinx.util.pycompat import product, zip_longest
|
||||
|
||||
@ -49,7 +48,7 @@ def merge_doctrees(old, new, condition):
|
||||
new_iter = new.traverse(condition)
|
||||
old_nodes = []
|
||||
new_nodes = []
|
||||
ratios = defaultdict(list)
|
||||
ratios = {}
|
||||
seen = set()
|
||||
# compare the nodes each doctree in order
|
||||
for old_node, new_node in zip_longest(old_iter, new_iter):
|
||||
|
Loading…
Reference in New Issue
Block a user