Merged birkenfeld/sphinx into default

This commit is contained in:
Rob Ruana 2014-01-19 12:31:07 -05:00
commit 4c782604ed
38 changed files with 659 additions and 290 deletions

40
CHANGES
View File

@ -1,28 +1,39 @@
Release 1.3 (in development)
============================
Change support versions
-----------------------
* Drop Python-2.5, 3.1 (support code was completely removed)
Incompatible changes
--------------------
* Dropped support for Python 2.5 and 3.1.
* Removed the ``sphinx.ext.oldcmarkup`` extension.
* The deprecated config values ``exclude_trees``, ``exclude_dirnames`` and
``unused_docs`` have been removed.
* A new node, ``sphinx.addnodes.literal_strong``, has been added, for text that
should appear literally (i.e. no smart quotes) in strong font. Custom writers
will have to be adapted to handle this node.
New features
------------
* PR#202: Allow "." and "~" prefixed references in ``:param:`` doc fields
for Python.
* PR#184: Add :confval:`autodoc_mock_imports`, allowing to mock imports of
external modules that need not be present when autodocumenting.
* #925: Allow list-typed config values to be provided on the command line,
like ``-D key=val1,val2``.
* #668: Allow line numbering of ``code-block`` and ``literalinclude`` directives
to start at an arbitrary line number, with a new ``lineno-start`` option.
* PR#172: The :rst:dir:`code-block` and :rst:dir:`literalinclude` directives now
can have a ``filename`` option that shows a filename before the code in the
output.
* Prompt for the document language in sphinx-quickstart.
Bugs fixed
@ -126,6 +137,23 @@ Bugs fixed
* #1285: Avoid name clashes between C domain objects and section titles.
* #848: Always take the newest code in incremental rebuilds with the
:mod:`sphinx.ext.viewcode` extension.
* #979, #1266: Fix exclude handling in ``sphinx-apidoc``.
* #1302: Fix regression in :mod:`sphinx.ext.inheritance_diagram` when
documenting classes that can't be pickled.
* #1316: Remove hard-coded ``font-face`` resources from epub theme.
* #1329: Fix traceback with empty translation msgstr in .po files.
* #1300: Fix references not working in translated documents in some instances.
* #1283: Fix a bug in the detection of changed files that would try to access
doctrees of deleted documents.
Documentation
-------------
@ -377,6 +405,8 @@ Features added
reference documentation in doc directory provides a ``sphinx.pot`` file with
message strings from ``doc/_templates/*.html`` when using ``make gettext``.
- PR#61,#703: Add support for non-ASCII filename handling.
* Other builders:
- Added the Docutils-native XML and pseudo-XML builders. See

View File

@ -4,157 +4,15 @@
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = python ../sphinx-build.py
PAPER =
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
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 xml \
pseudoxml
SPHINXPROJ = sphinx
SOURCEDIR = .
BUILDDIR = _build
# Has to be explicit, otherwise we don't get "make" without targets right.
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files called index.html in directories"
@echo " singlehtml to make one big HTML file"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " pickle to make pickle files"
@echo " json to make json files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make Qt help files and project"
@echo " devhelp to make Devhelp files and project"
@echo " epub to make an epub file"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run pdflatex"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview over all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
clean:
rm -rf _build/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
@echo
@echo "Build finished. The HTML pages are in _build/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) _build/dirhtml
@echo
@echo "Build finished. The HTML pages are in _build/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) _build/singlehtml
@echo
@echo "Build finished. The HTML page is in _build/singlehtml."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) _build/text
@echo
@echo "Build finished."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) _build/man
@echo
@echo "Build finished."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
@echo
@echo "Build finished."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json
@echo
@echo "Build finished."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in _build/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) _build/qthelp
@echo
@echo "Build finished; now you can run qcollectiongenerator with the" \
".qhcp project file in build/qthelp."
@echo "# qcollectiongenerator _build/qthelp/Sphinx.qhcp"
@echo "To view the help collection:"
@echo "# assistant -collectionFile _build/qthelp/Sphinx.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) _build/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/sphinx"
@echo "# ln -s _build/devhelp $$HOME/.local/share/devhelp/sphinx"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) _build/epub
@echo
@echo "Build finished. The epub file is in _build/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
@echo
@echo "Build finished; the LaTeX files are in _build/latex."
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
"run these through (pdf)latex."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
@echo "Running LaTeX files through pdflatex..."
make -C _build/latex all-pdf
@echo "pdflatex finished; the PDF files are in _build/latex."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) _build/locale
@echo
@echo "Build finished. The message catalogs are in _build/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
@echo
@echo "The overview file is in _build/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in _build/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) _build/doctest
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) _build/texinfo
@echo
@echo "Build finished. The Texinfo files are in _build/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) _build/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C _build/texinfo info
@echo "makeinfo finished; the Info files are in _build/texinfo."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) _build/xml
@echo
@echo "Build finished. The XML files are in _build/XML."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) _build/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in _build/pseudoxml."
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%:
$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View File

@ -45,7 +45,8 @@ Important points to note:
* There is a special object named ``tags`` available in the config file.
It can be used to query and change the tags (see :ref:`tags`). Use
``tags.has('tag')`` to query, ``tags.add('tag')`` and ``tags.remove('tag')``
to change.
to change. Only tags set via the ``-t`` command-line option or via
``tags.add('tag')`` can be queried using ``tags.has('tag')``.
General configuration
@ -113,38 +114,6 @@ General configuration
.. versionadded:: 1.0
.. confval:: unused_docs
A list of document names that are present, but not currently included in the
toctree. Use this setting to suppress the warning that is normally emitted
in that case.
.. deprecated:: 1.0
Use :confval:`exclude_patterns` or :ref:`metadata` instead.
.. confval:: exclude_trees
A list of directory paths, relative to the source directory, that are to be
recursively excluded from the search for source files, that is, their
subdirectories won't be searched too. The default is ``[]``.
.. versionadded:: 0.4
.. deprecated:: 1.0
Use :confval:`exclude_patterns` instead.
.. confval:: exclude_dirnames
A list of directory names that are to be excluded from any recursive
operation Sphinx performs (e.g. searching for source files or copying static
files). This is useful, for example, to exclude version-control-specific
directories like ``'CVS'``. The default is ``[]``.
.. versionadded:: 0.5
.. deprecated:: 1.0
Use :confval:`exclude_patterns` instead.
.. confval:: templates_path
A list of paths that contain extra templates (or templates that overwrite

View File

@ -195,6 +195,12 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
.. versionadded:: 1.2
* Add a list of modules in the :confval:`autodoc_mock_imports` to prevent
import errors to halt the building process when some external dependencies
are not importable at build time.
.. versionadded:: 1.3
.. rst:directive:: autofunction
autodata
@ -335,6 +341,14 @@ There are also new config values that you can set:
.. versionadded:: 1.1
.. confval:: autodoc_mock_imports
This value contains a list of modules to be mocked up. This is useful when
some external dependencies are not met at build time and break the building
process.
.. versionadded:: 1.3
Docstring preprocessing
-----------------------

View File

@ -188,6 +188,25 @@ Includes
The ``prepend`` and ``append`` options, as well as ``tab-width``.
Showing a file name
^^^^^^^^^^^^^^^^^^^
.. versionadded:: 1.3
A ``filename`` option can be given to show that name before the code block. For
example::
.. code-block:: python
:filename: this.py
print 'Explicit is better than implicit.'
:rst:dir:`literalinclude` also supports the ``filename`` option, with the
additional feature that if you leave the value empty, the shown filename will be
exactly the one given as an argument.
.. rubric:: Footnotes
.. [1] There is a standard ``.. include`` directive, but it raises errors if the

View File

@ -11,5 +11,8 @@
import sys
if __name__ == '__main__':
from sphinx import main
from sphinx import main, make_main
if sys.argv[1:2] == ['-M']:
sys.exit(make_main(sys.argv))
else:
sys.exit(main(sys.argv))

View File

@ -81,5 +81,11 @@ def main(argv=sys.argv):
return cmdline.main(argv)
def make_main(argv=sys.argv):
"""Sphinx build "make mode" entry."""
from sphinx import make_mode
return make_mode.run_make_mode(argv[2:])
if __name__ == '__main__':
sys.exit(main(sys.argv))

View File

@ -173,9 +173,6 @@ def recurse_tree(rootpath, excludes, opts):
Look for every file in the directory tree and create the corresponding
ReST files.
"""
# use absolute path for root, as relative paths like '../../foo' cause
# 'if "/." in root ...' to filter out *all* modules otherwise
rootpath = path.normpath(path.abspath(rootpath))
# check if the base directory is a package and get its name
if INITPY in os.listdir(rootpath):
root_package = rootpath.split(path.sep)[-1]
@ -185,13 +182,12 @@ def recurse_tree(rootpath, excludes, opts):
toplevels = []
followlinks = getattr(opts, 'followlinks', False)
includeprivate = getattr(opts, 'includeprivate', False)
for root, subs, files in os.walk(rootpath, followlinks=followlinks):
if is_excluded(root, excludes):
del subs[:]
continue
# document only Python module files
# document only Python module files (that aren't excluded)
py_files = sorted(f for f in files
if path.splitext(f)[1] in PY_SUFFIXES)
if path.splitext(f)[1] in PY_SUFFIXES and
not is_excluded(path.join(root, f), excludes))
is_pkg = INITPY in py_files
if is_pkg:
py_files.remove(INITPY)
@ -200,8 +196,14 @@ def recurse_tree(rootpath, excludes, opts):
# only accept non-package at toplevel
del subs[:]
continue
# remove hidden ('.') and private ('_') directories
subs[:] = sorted(sub for sub in subs if sub[0] not in ['.', '_'])
# remove hidden ('.') and private ('_') directories, as well as
# excluded dirs
if includeprivate:
exclude_prefixes = ('.',)
else:
exclude_prefixes = ('.', '_')
subs[:] = sorted(sub for sub in subs if not sub.startswith(exclude_prefixes)
and not is_excluded(path.join(root, sub), excludes))
if is_pkg:
# we are in a package with something to document
@ -225,47 +227,35 @@ def recurse_tree(rootpath, excludes, opts):
def normalize_excludes(rootpath, excludes):
"""
Normalize the excluded directory list:
* must be either an absolute path or start with rootpath,
* otherwise it is joined with rootpath
* with trailing slash
"""
f_excludes = []
for exclude in excludes:
if not path.isabs(exclude) and not exclude.startswith(rootpath):
exclude = path.join(rootpath, exclude)
f_excludes.append(path.normpath(exclude) + path.sep)
return f_excludes
"""Normalize the excluded directory list."""
return [path.normpath(path.abspath(exclude)) for exclude in excludes]
def is_excluded(root, excludes):
"""
Check if the directory is in the exclude list.
"""Check if the directory is in the exclude list.
Note: by having trailing slashes, we avoid common prefix issues, like
e.g. an exlude "foo" also accidentally excluding "foobar".
"""
sep = path.sep
if not root.endswith(sep):
root += sep
root = path.normpath(root)
for exclude in excludes:
if root.startswith(exclude):
if root == exclude:
return True
return False
def main(argv=sys.argv):
"""
Parse and check the command line arguments.
"""
"""Parse and check the command line arguments."""
parser = optparse.OptionParser(
usage="""\
usage: %prog [options] -o <output_path> <module_path> [exclude_paths, ...]
usage: %prog [options] -o <output_path> <module_path> [exclude_path, ...]
Look recursively in <module_path> for Python modules and packages and create
one reST file with automodule directives per package in the <output_path>.
The <exclude_path>s can be files and/or directories that will be excluded
from generation.
Note: By default this script will not overwrite already created files.""")
parser.add_option('-o', '--output-dir', action='store', dest='destdir',
@ -327,6 +317,7 @@ Note: By default this script will not overwrite already created files.""")
if not path.isdir(opts.destdir):
if not opts.dryrun:
os.makedirs(opts.destdir)
rootpath = path.normpath(path.abspath(rootpath))
excludes = normalize_excludes(rootpath, excludes)
modules = recurse_tree(rootpath, excludes, opts)
if opts.full:

View File

@ -265,6 +265,12 @@ class Builder(object):
self.info(bold('no targets are out of date.'))
return
# filter "docnames" (list of outdated files) by the updated
# found_docs of the environment; this will remove docs that
# have since been removed
if docnames != ['__all__']:
docnames = set(docnames) & self.env.found_docs
# another indirection to support builders that don't build
# files individually
self.write(docnames, list(updated_docnames), method)
@ -289,6 +295,7 @@ class Builder(object):
docnames = set(build_docnames) | set(updated_docnames)
else:
docnames = set(build_docnames)
self.app.debug('docnames to write: %s', ', '.join(sorted(docnames)))
# add all toctree-containing files that may have changed
for docname in list(docnames):

View File

@ -579,10 +579,7 @@ class StandaloneHTMLBuilder(Builder):
# then, copy over all user-supplied static files
staticentries = [path.join(self.confdir, spath)
for spath in self.config.html_static_path]
matchers = compile_matchers(
self.config.exclude_patterns +
['**/' + d for d in self.config.exclude_dirnames]
)
matchers = compile_matchers(self.config.exclude_patterns)
for entry in staticentries:
if not path.exists(entry):
self.warn('html_static_path entry %r does not exist' % entry)

View File

@ -42,6 +42,7 @@ General options
-d <path> path for the cached environment and doctree files
(default: outdir/.doctrees)
-j <N> build in parallel with N processes where possible
-M <builder> "make" mode -- used by Makefile, like "sphinx-build -M html"
Build configuration options
^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -82,19 +83,28 @@ def main(argv):
# Windows' poor cmd box doesn't understand ANSI sequences
nocolor()
# parse options
try:
opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:nNEqQWw:PThvj:',
['help', 'version'])
except getopt.error, err:
usage(argv, 'Error: %s' % err)
return 1
# handle basic options
allopts = set(opt[0] for opt in opts)
# help and version options
if '-h' in allopts or '--help' in allopts:
usage(argv)
print >>sys.stderr
print >>sys.stderr, 'For more information, see '\
'<http://sphinx-doc.org/>.'
print >>sys.stderr, 'For more information, see <http://sphinx-doc.org/>.'
return 0
if '--version' in allopts:
print 'Sphinx (sphinx-build) %s' % __version__
return 0
# get paths (first and second positional argument)
try:
srcdir = confdir = abspath(args[0])
if not path.isdir(srcdir):
print >>sys.stderr, 'Error: Cannot find source directory `%s\'.' % (
@ -103,12 +113,9 @@ def main(argv):
if not path.isfile(path.join(srcdir, 'conf.py')) and \
'-c' not in allopts and '-C' not in allopts:
print >>sys.stderr, ('Error: Source directory doesn\'t '
'contain conf.py file.')
'contain a conf.py file.')
return 1
outdir = abspath(args[1])
except getopt.error, err:
usage(argv, 'Error: %s' % err)
return 1
except IndexError:
usage(argv, 'Error: Insufficient arguments.')
return 1
@ -118,6 +125,7 @@ def main(argv):
'encoding (%r).' % fs_encoding)
return 1
# handle remaining filename arguments
filenames = args[2:]
err = 0
for filename in filenames:

View File

@ -51,10 +51,6 @@ class Config(object):
source_suffix = ('.rst', 'env'),
source_encoding = ('utf-8-sig', 'env'),
exclude_patterns = ([], 'env'),
# the next three are all deprecated now
unused_docs = ([], 'env'),
exclude_trees = ([], 'env'),
exclude_dirnames = ([], 'env'),
default_role = (None, 'env'),
add_function_parentheses = (True, 'env'),
add_module_names = (True, 'env'),

View File

@ -58,6 +58,7 @@ class CodeBlock(Directive):
'linenos': directives.flag,
'lineno-start': int,
'emphasize-lines': directives.unchanged_required,
'filename': directives.unchanged_required,
}
def run(self):
@ -76,6 +77,9 @@ class CodeBlock(Directive):
literal = nodes.literal_block(code, code)
literal['language'] = self.arguments[0]
filename = self.options.get('filename')
if filename:
literal['filename'] = filename
literal['linenos'] = 'linenos' in self.options or \
'lineno-start' in self.options
extra_args = literal['highlight_args'] = {}
@ -111,6 +115,7 @@ class LiteralInclude(Directive):
'prepend': directives.unchanged_required,
'append': directives.unchanged_required,
'emphasize-lines': directives.unchanged_required,
'filename': directives.unchanged,
}
def run(self):
@ -212,6 +217,11 @@ class LiteralInclude(Directive):
retnode['language'] = self.options['language']
retnode['linenos'] = 'linenos' in self.options or \
'lineno-start' in self.options
filename = self.options.get('filename')
if filename is not None:
if not filename:
filename = self.arguments[0]
retnode['filename'] = filename
extra_args = retnode['highlight_args'] = {}
if hl_lines is not None:
extra_args['hl_lines'] = hl_lines

View File

@ -537,6 +537,7 @@ class DefinitionParser(object):
'mutable': None,
'const': None,
'typename': None,
'struct': None,
'unsigned': set(('char', 'short', 'int', 'long')),
'signed': set(('char', 'short', 'int', 'long')),
'short': set(('int',)),

View File

@ -333,9 +333,6 @@ class BuildEnvironment:
matchers = compile_matchers(
config.exclude_patterns[:] +
config.html_extra_path +
config.exclude_trees +
[d + config.source_suffix for d in config.unused_docs] +
['**/' + d for d in config.exclude_dirnames] +
['**/_sources', '.#*']
)
self.found_docs = set(get_matching_docs(

View File

@ -70,6 +70,35 @@ class Options(dict):
return None
class _MockModule(object):
"""Used by autodoc_mock_imports."""
def __init__(self, *args, **kwargs):
pass
def __call__(self, *args, **kwargs):
return _MockModule()
@classmethod
def __getattr__(cls, name):
if name in ('__file__', '__path__'):
return '/dev/null'
elif name[0] == name[0].upper():
# Not very good, we assume Uppercase names are classes...
mocktype = type(name, (), {})
mocktype.__module__ = __name__
return mocktype
else:
return _MockModule()
def mock_import(modname):
if '.' in modname:
pkg, _n, mods = modname.rpartition('.')
mock_import(pkg)
mod = _MockModule()
sys.modules[modname] = mod
return mod
ALL = object()
INSTANCEATTR = object()
@ -332,6 +361,9 @@ class Documenter(object):
self.modname, '.'.join(self.objpath))
try:
dbg('[autodoc] import %s', self.modname)
for modname in self.env.config.autodoc_mock_imports:
dbg('[autodoc] adding a mock module %s!', self.modname)
mock_import(modname)
__import__(self.modname)
parent = None
obj = self.module = sys.modules[self.modname]
@ -1453,6 +1485,7 @@ def setup(app):
app.add_config_value('autodoc_member_order', 'alphabetic', True)
app.add_config_value('autodoc_default_flags', [], True)
app.add_config_value('autodoc_docstring_signature', True, True)
app.add_config_value('autodoc_mock_imports', [], True)
app.add_event('autodoc-process-docstring')
app.add_event('autodoc-process-signature')
app.add_event('autodoc-skip-member')

View File

@ -178,6 +178,9 @@ def render_dot(self, code, options, format, prefix='graphviz'):
if p.returncode != 0:
raise GraphvizError('dot exited with error:\n[stderr]\n%s\n'
'[stdout]\n%s' % (stderr, stdout))
if not path.isfile(outfn):
raise GraphvizError('dot did not produce an output file:\n[stderr]\n%s\n'
'[stdout]\n%s' % (stderr, stdout))
return relfn, outfn

View File

@ -154,8 +154,18 @@ class InheritanceGraph(object):
nodename = self.class_name(cls, parts)
fullname = self.class_name(cls, 0)
# Use first line of docstring as tooltip, if available
tooltip = None
try:
if cls.__doc__:
doc = cls.__doc__.strip().split("\n")[0]
if doc:
tooltip = '"%s"' % doc.replace('"', '\\"')
except Exception: # might raise AttributeError for strange classes
pass
baselist = []
all_classes[cls] = (nodename, fullname, baselist)
all_classes[cls] = (nodename, fullname, baselist, tooltip)
for base in cls.__bases__:
if not show_builtins and base in builtins:
continue
@ -168,7 +178,7 @@ class InheritanceGraph(object):
for cls in classes:
recurse(cls)
return all_classes
return all_classes.values()
def class_name(self, cls, parts=0):
"""Given a class object, return a fully-qualified name.
@ -188,7 +198,7 @@ class InheritanceGraph(object):
def get_all_class_names(self):
"""Get all of the class names involved in the graph."""
return [fullname for (_, fullname, _) in self.class_info.values()]
return [fullname for (_, fullname, _, _) in self.class_info]
# These are the default attrs for graphviz
default_graph_attrs = {
@ -241,17 +251,13 @@ class InheritanceGraph(object):
res.append('digraph %s {\n' % name)
res.append(self._format_graph_attrs(g_attrs))
for cls, (name, fullname, bases) in sorted(self.class_info.items()):
for name, fullname, bases, tooltip in sorted(self.class_info):
# Write the node
this_node_attrs = n_attrs.copy()
if fullname in urls:
this_node_attrs['URL'] = '"%s"' % urls[fullname]
# Use first line of docstring as tooltip, if available
if cls.__doc__:
doc = cls.__doc__.strip().split("\n")[0]
if doc:
doc = doc.replace('"', '\\"')
this_node_attrs['tooltip'] = '"%s"' % doc
if tooltip:
this_node_attrs['tooltip'] = tooltip
res.append(' "%s" [%s];\n' %
(name, self._format_node_attrs(this_node_attrs)))

View File

@ -24,17 +24,17 @@ def doctree_read(app, doctree):
def has_tag(modname, fullname, docname):
entry = env._viewcode_modules.get(modname, None)
if entry is None:
try:
analyzer = ModuleAnalyzer.for_module(modname)
except Exception:
env._viewcode_modules[modname] = False
return
analyzer.find_tags()
if not isinstance(analyzer.code, unicode):
code = analyzer.code.decode(analyzer.encoding)
else:
code = analyzer.code
if entry is None or entry[0] != code:
analyzer.find_tags()
entry = code, analyzer.tags, {}
env._viewcode_modules[modname] = entry
elif entry is False:
@ -142,7 +142,7 @@ def collect_pages(app):
if not modnames:
return
app.builder.info(' _modules/index')
app.builder.info(' _modules/index', nonl=True)
html = ['\n']
# the stack logic is needed for using nested lists for submodules
stack = ['']

252
sphinx/make_mode.py Normal file
View File

@ -0,0 +1,252 @@
# -*- coding: utf-8 -*-
"""
sphinx.make_mode
~~~~~~~~~~~~~~~~
sphinx-build -M command-line handling.
This replaces the old, platform-dependent and once-generated content
of Makefile / make.bat.
This is in its own module so that importing it is fast. It should not
import the main Sphinx modules (like sphinx.applications, sphinx.builders).
:copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
import sys
import shutil
from os import path
from subprocess import call
import sphinx
from sphinx.util.console import bold, blue
proj_name = os.getenv('SPHINXPROJ', '<project>')
BUILDERS = [
("", "html", "to make standalone HTML files"),
("", "dirhtml", "to make HTML files named index.html in directories"),
("", "singlehtml","to make a single large HTML file"),
("", "pickle", "to make pickle files"),
("", "json", "to make JSON files"),
("", "htmlhelp", "to make HTML files and a HTML help project"),
("", "qthelp", "to make HTML files and a qthelp project"),
("", "devhelp", "to make HTML files and a Devhelp project"),
("", "epub", "to make an epub"),
("", "latex", "to make LaTeX files, you can set PAPER=a4 or PAPER=letter"),
("posix", "latexpdf", "to make LaTeX files and run them through pdflatex"),
("posix", "latexpdfja","to make LaTeX files and run them through platex/dvipdfmx"),
("", "text", "to make text files"),
("", "man", "to make manual pages"),
("", "texinfo", "to make Texinfo files"),
("posix", "info", "to make Texinfo files and run them through makeinfo"),
("", "gettext", "to make PO message catalogs"),
("", "changes", "to make an overview of all changed/added/deprecated items"),
("", "xml", "to make Docutils-native XML files"),
("", "pseudoxml", "to make pseudoxml-XML files for display purposes"),
("", "linkcheck", "to check all external links for integrity"),
("", "doctest", "to run all doctests embedded in the documentation (if enabled)"),
("", "coverage", "to run coverage check of the documentation (if enabled)"),
]
class Make(object):
def __init__(self, srcdir, builddir, opts):
self.srcdir = srcdir
self.builddir = builddir
self.opts = opts
def builddir_join(self, *comps):
return path.join(self.builddir, *comps)
def build_clean(self):
if not path.exists(self.builddir):
return
elif not path.isdir(self.builddir):
print "Error: %r is not a directory!" % self.builddir
return 1
print "Removing everything under %r..." % self.builddir
for item in os.listdir(self.builddir):
shutil.rmtree(self.builddir_join(item))
def build_help(self):
print bold("Sphinx v%s" % sphinx.__version__)
print "Please use `make %s' where %s is one of" % ((blue('target'),)*2)
for osname, bname, description in BUILDERS:
if not osname or os.name == osname:
print ' %s %s' % (blue(bname.ljust(10)), description)
def build_html(self):
if self.run_generic_build('html') > 0:
return 1
print
print 'Build finished. The HTML pages are in %s.' % self.builddir_join('html')
def build_dirhtml(self):
if self.run_generic_build('dirhtml') > 0:
return 1
print
print 'Build finished. The HTML pages are in %s.' % self.builddir_join('dirhtml')
def build_singlehtml(self):
if self.run_generic_build('singlehtml') > 0:
return 1
print
print 'Build finished. The HTML page is in %s.' % self.builddir_join('singlehtml')
def build_pickle(self):
if self.run_generic_build('pickle') > 0:
return 1
print
print 'Build finished; now you can process the pickle files.'
def build_json(self):
if self.run_generic_build('json') > 0:
return 1
print
print 'Build finished; now you can process the JSON files.'
def build_htmlhelp(self):
if self.run_generic_build('htmlhelp') > 0:
return 1
print
print ('Build finished; now you can run HTML Help Workshop with the '
'.hhp project file in %s.') % self.builddir_join('htmlhelp')
def build_qthelp(self):
if self.run_generic_build('qthelp') > 0:
return 1
print
print ('Build finished; now you can run "qcollectiongenerator" with the '
'.qhcp project file in %s, like this:') % self.builddir_join('qthelp')
print '$ qcollectiongenerator %s.qhcp' % self.builddir_join('qthelp', proj_name)
print 'To view the help file:'
print '$ assistant -collectionFile %s.qhc' % self.builddir_join('qthelp', proj_name)
def build_devhelp(self):
if self.run_generic_build('devhelp') > 0:
return 1
print
print "Build finished."
print "To view the help file:"
print "$ mkdir -p $HOME/.local/share/devhelp/" + proj_name
print "$ ln -s %s $HOME/.local/share/devhelp/%s" % \
(self.builddir_join('devhelp'), proj_name)
print "$ devhelp"
def build_epub(self):
if self.run_generic_build('epub') > 0:
return 1
print
print 'Build finished. The ePub file is in %s.' % self.builddir_join('epub')
def build_latex(self):
if self.run_generic_build('latex') > 0:
return 1
print "Build finished; the LaTeX files are in %s." % self.builddir_join('latex')
if os.name == 'posix':
print "Run `make' in that directory to run these through (pdf)latex"
print "(use `make latexpdf' here to do that automatically)."
def build_latexpdf(self):
if self.run_generic_build('latex') > 0:
return 1
os.system('make -C %s all-pdf' % self.builddir_join('latex'))
def build_latexpdfja(self):
if self.run_generic_build('latex') > 0:
return 1
os.system('make -C %s all-pdf-ja' % self.builddir_join('latex'))
def build_text(self):
if self.run_generic_build('text') > 0:
return 1
print
print 'Build finished. The text files are in %s.' % self.builddir_join('text')
def build_texinfo(self):
if self.run_generic_build('texinfo') > 0:
return 1
print "Build finished; the Texinfo files are in %s." % self.builddir_join('texinfo')
if os.name == 'posix':
print "Run `make' in that directory to run these through makeinfo"
print "(use `make info' here to do that automatically)."
def build_info(self):
if self.run_generic_build('texinfo') > 0:
return 1
os.system('make -C %s info' % self.builddir_join('texinfo'))
def build_gettext(self):
dtdir = self.builddir_join('gettext', '.doctrees')
if self.run_generic_build('gettext', doctreedir=dtdir) > 0:
return 1
print
print 'Build finished. The message catalogs are in %s.' % self.builddir_join('gettext')
def build_changes(self):
if self.run_generic_build('changes') > 0:
return 1
print
print 'Build finished. The overview file is in %s.' % self.builddir_join('changes')
def build_linkcheck(self):
res = self.run_generic_build('linkcheck')
print
print ('Link check complete; look for any errors in the above output '
'or in %s.') % self.builddir_join('linkcheck', 'output.txt')
return res
def build_doctest(self):
res = self.run_generic_build('doctest')
print ("Testing of doctests in the sources finished, look at the "
"results in %s." % self.builddir_join('doctest', 'output.txt'))
return res
def build_coverage(self):
if self.run_generic_build('coverage') > 0:
print "Has the coverage extension been enabled?"
return 1
print
print ("Testing of coverage in the sources finished, look at the "
"results in %s." % self.builddir_join('coverage'))
def build_xml(self):
if self.run_generic_build('xml') > 0:
return 1
print
print 'Build finished. The XML files are in %s.' % self.builddir_join('xml')
def build_pseudoxml(self):
if self.run_generic_build('pseudoxml') > 0:
return 1
print
print 'Build finished. The pseudo-XML files are in %s.' % self.builddir_join('pseudoxml')
def run_generic_build(self, builder, doctreedir=None):
# compatibility with old Makefile
papersize = os.getenv('PAPER', '')
opts = self.opts
if papersize in ('a4', 'letter'):
opts.extend(['-D', 'latex_paper_size=' + papersize])
if doctreedir is None:
doctreedir = self.builddir_join('doctrees')
return call([sys.executable, sys.argv[0], '-b', builder,
'-d', doctreedir, self.srcdir, self.builddir_join(builder)] + opts)
def run_make_mode(args):
if len(args) < 3:
print >>sys.stderr, ('Error: at least 3 arguments (builder, source '
'dir, build dir) are required.')
return 1
make = Make(args[1], args[2], args[3:])
run_method = 'build_' + args[0]
if hasattr(make, run_method):
return getattr(make, run_method)()
return make.run_generic_build(args[0])

View File

@ -840,6 +840,76 @@ if "%%1" == "pseudoxml" (
:end
'''
# This will become the Makefile template for Sphinx 1.5.
MAKEFILE_NEW = u'''\
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = %(project_fn)s
SOURCEDIR = %(rsrcdir)s
BUILDDIR = %(rbuilddir)s
# User-friendly check for sphinx-build.
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error \
The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx \
installed, then set the SPHINXBUILD environment variable to point \
to the full path of the '$(SPHINXBUILD)' executable. Alternatively you \
can add the directory with the executable to your PATH. \
If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Has to be explicit, otherwise we don't get "make" without targets right.
help:
\t@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
# You can add custom targets here.
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%:
\t@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
'''
# This will become the make.bat template for Sphinx 1.5.
BATCHFILE_NEW = u'''\
@ECHO OFF
REM Command file for Sphinx documentation
if "%%SPHINXBUILD%%" == "" (
\tset SPHINXBUILD=sphinx-build
)
set BUILDDIR=%(rbuilddir)s
set SPHINXPROJ=%(project_fn)s
if "%%1" == "" goto help
%%SPHINXBUILD%% 2> nul
if errorlevel 9009 (
\techo.
\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx
\techo.installed, then set the SPHINXBUILD environment variable to point
\techo.to the full path of the 'sphinx-build' executable. Alternatively you
\techo.may add the Sphinx directory to PATH.
\techo.
\techo.If you don't have Sphinx installed, grab it from
\techo.http://sphinx-doc.org/
\texit /b 1
)
%%SPHINXBUILD%% -M %%1 %%BUILDDIR%% %%SPHINXOPTS%%
goto end
:help
%%SPHINXBUILD%% -M help %%BUILDDIR%% %%SPHINXOPTS%%
:end
'''
def mkdir_p(dir):
if path.isdir(dir):

View File

@ -14,6 +14,7 @@
import sys
import os
import types
from StringIO import StringIO
from distutils.cmd import Command
@ -98,6 +99,19 @@ class BuildDoc(Command):
return root
return None
# Overriding distutils' Command._ensure_stringlike which doesn't support
# unicode, causing finalize_options to fail if invoked again. Workaround
# for http://bugs.python.org/issue19570
def _ensure_stringlike(self, option, what, default=None):
val = getattr(self, option)
if val is None:
setattr(self, option, default)
return default
elif not isinstance(val, types.StringTypes):
raise DistutilsOptionError("'%s' must be a %s (got `%s`)"
% (option, what, val))
return val
def finalize_options(self):
if self.source_dir is None:
self.source_dir = self._guess_source_dir()

View File

@ -9,6 +9,10 @@ ARCHIVEPRREFIX =
# Additional LaTeX options
LATEXOPTS =
LATEX = latex
PDFLATEX = pdflatex
MAKEINDEX = makeindex
all: $(ALLPDF)
all-pdf: $(ALLPDF)
all-dvi: $(ALLDVI)
@ -43,20 +47,20 @@ bz2: tar
# The number of LaTeX runs is quite conservative, but I don't expect it
# to get run often, so the little extra time won't hurt.
%.dvi: %.tex
latex $(LATEXOPTS) '$<'
latex $(LATEXOPTS) '$<'
latex $(LATEXOPTS) '$<'
-makeindex -s python.ist '$(basename $<).idx'
latex $(LATEXOPTS) '$<'
latex $(LATEXOPTS) '$<'
$(LATEX) $(LATEXOPTS) '$<'
$(LATEX) $(LATEXOPTS) '$<'
$(LATEX) $(LATEXOPTS) '$<'
-$(MAKEINDEX) -s python.ist '$(basename $<).idx'
$(LATEX) $(LATEXOPTS) '$<'
$(LATEX) $(LATEXOPTS) '$<'
%.pdf: %.tex
pdflatex $(LATEXOPTS) '$<'
pdflatex $(LATEXOPTS) '$<'
pdflatex $(LATEXOPTS) '$<'
-makeindex -s python.ist '$(basename $<).idx'
pdflatex $(LATEXOPTS) '$<'
pdflatex $(LATEXOPTS) '$<'
$(PDFLATEX) $(LATEXOPTS) '$<'
$(PDFLATEX) $(LATEXOPTS) '$<'
$(PDFLATEX) $(LATEXOPTS) '$<'
-$(MAKEINDEX) -s python.ist '$(basename $<).idx'
$(PDFLATEX) $(LATEXOPTS) '$<'
$(PDFLATEX) $(LATEXOPTS) '$<'
clean:
rm -f *.dvi *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla

View File

@ -462,3 +462,10 @@ div.viewcode-block:target {
border-top: 1px solid #ac9;
border-bottom: 1px solid #ac9;
}
div.code-block-filename {
background-color: #ddd;
color: #333;
padding: 2px 5px;
font-size: small;
}

View File

@ -471,6 +471,20 @@ table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
div.code-block-filename {
padding: 2px 5px;
font-size: small;
}
div.code-block-filename tt {
background-color: transparent;
}
div.code-block-filename + pre,
div.code-block-filename + div.highlight > pre {
margin-top: 0;
}
tt.descname {
background-color: transparent;
font-weight: bold;

View File

@ -168,6 +168,9 @@ var Documentation = {
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div.body');
if (!body.length) {
body = $('body');
}
window.setTimeout(function() {
$.each(terms, function() {
body.highlightText(this.toLowerCase(), 'highlighted');

View File

@ -308,3 +308,8 @@ div.viewcode-block:target {
border-top: 1px solid #ac9;
border-bottom: 1px solid #ac9;
}
div.code-block-filename {
color: #efefef;
background-color: #1c4e63;
}

View File

@ -339,7 +339,7 @@ dl.glossary dt {
/* -- code displays --------------------------------------------------------- */
pre {
font-family: "LiberationNarrow", monospace;
font-family: monospace;
overflow: auto;
overflow-y: hidden;
}
@ -360,7 +360,7 @@ table.highlighttable td {
}
tt {
font-family: "LiberationNarrow", monospace;
font-family: monospace;
}
tt.descname {
@ -432,6 +432,7 @@ table .link-target {
/* -- font-face ------------------------------------------------------------- */
/*
@font-face {
font-family: "LiberationNarrow";
font-style: normal;
@ -460,4 +461,4 @@ table .link-target {
src: url("res:///Data/fonts/LiberationNarrow-BoldItalic.otf")
format("opentype");
}
*/

View File

@ -243,3 +243,9 @@ div.viewcode-block:target {
border-top: 1px solid #ac9;
border-bottom: 1px solid #ac9;
}
div.code-block-filename {
background-color: #ddd;
color: #222;
border: 1px solid #C6C9CB;
}

View File

@ -340,3 +340,8 @@ tt.xref {
font-weight: normal;
font-style: normal;
}
div.code-block-filename {
background-color: #ddd;
color: #222;
}

View File

@ -337,3 +337,9 @@ div.viewcode-block:target {
border-top: 1px solid #ac9;
border-bottom: 1px solid #ac9;
}
div.code-block-filename {
background-color: #ddd;
color: #222;
border: 1px solid #ccc;
}

View File

@ -698,3 +698,7 @@ div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
div.code-block-filename {
background-color: #cceeff;
}

View File

@ -195,7 +195,10 @@ class Locale(Transform):
patch = new_document(source, settings)
CustomLocaleReporter(node.source, node.line).set_reporter(patch)
parser.parse(msgstr, patch)
try:
patch = patch[0]
except IndexError: # empty node
pass
# XXX doctest and other block markup
if not isinstance(patch, nodes.paragraph):
continue # skip for now
@ -238,8 +241,7 @@ class Locale(Transform):
self.document.ids.pop(_id, None)
# re-entry with new named section node.
self.document.note_implicit_target(
section_node, section_node)
self.document.note_implicit_target(section_node)
# replace target's refname to new target name
def is_named_target(node):
@ -298,7 +300,10 @@ class Locale(Transform):
patch = new_document(source, settings)
CustomLocaleReporter(node.source, node.line).set_reporter(patch)
parser.parse(msgstr, patch)
try:
patch = patch[0]
except IndexError: # empty node
pass
# XXX doctest and other block markup
if not isinstance(patch, nodes.paragraph):
continue # skip for now

View File

@ -267,6 +267,9 @@ class HTMLTranslator(BaseTranslator):
**highlight_args)
starttag = self.starttag(node, 'div', suffix='',
CLASS='highlight-%s' % lang)
if node.has_key('filename'):
starttag += '<div class="code-block-filename"><tt>%s</tt></div>' % (
node['filename'],)
self.body.append(starttag + highlighted + '</div>\n')
raise nodes.SkipNode

View File

@ -1337,6 +1337,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
highlight_args['force'] = True
if 'linenos' in node:
linenos = node['linenos']
filename = node.get('filename')
if filename:
self.body.append('\n{\\colorbox[rgb]{0.9,0.9,0.9}'
'{\\makebox[\\textwidth][l]'
'{\\small\\texttt{%s}}}}\n' % (filename,))
def warner(msg):
self.builder.warn(msg, (self.curfilestack[-1], node.line))
hlcode = self.highlighter.highlight_block(code, lang, warn=warner,

View File

@ -45,3 +45,5 @@ Just testing a few autodoc possibilities...
:members: ca1, ia1
Specific members (2 total)
.. automodule:: autodoc_missing_imports

View File

@ -0,0 +1,9 @@
import missing_module
from missing_module import missing_name
import missing_package1.missing_module1
from missing_package2 import missing_module2
from missing_package3.missing_module3 import missing_name
class TestAutodoc(object):
"""TestAutodoc docstring."""

View File

@ -23,7 +23,6 @@ copyright = '2010, Georg Brandl & Team'
version = '0.6'
release = '0.6alpha1'
today_fmt = '%B %d, %Y'
# unused_docs = []
exclude_patterns = ['_build', '**/excluded.*']
keep_warnings = True
pygments_style = 'sphinx'
@ -71,6 +70,13 @@ autosummary_generate = ['autosummary']
extlinks = {'issue': ('http://bugs.python.org/issue%s', 'issue '),
'pyurl': ('http://python.org/%s', None)}
autodoc_mock_imports = [
'missing_module',
'missing_package1.missing_module1',
'missing_package2.missing_module2',
'missing_package3.missing_module3',
]
# modify tags from conf.py
tags.add('confpytag')