diff options
author | Rob Ruana <rob@relentlessidiot.com> | 2014-01-19 12:31:07 -0500 |
---|---|---|
committer | Rob Ruana <rob@relentlessidiot.com> | 2014-01-19 12:31:07 -0500 |
commit | a8b06aa17015396b9bd5accb5cca4644f69f307d (patch) | |
tree | d38b9d2e011dccc1a319674799b499b2f31ffece | |
parent | 49b952d84136ef89132de8d48b4b937b816f0c22 (diff) | |
parent | 2a8cf7c7781a4554adbcb4bae6bec2a40bfc156d (diff) | |
download | sphinx-a8b06aa17015396b9bd5accb5cca4644f69f307d.tar.gz |
Merged birkenfeld/sphinx into default
38 files changed, 659 insertions, 290 deletions
@@ -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 diff --git a/doc/Makefile b/doc/Makefile index 831c12c5..8bc59724 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -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" - -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." + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -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) diff --git a/doc/config.rst b/doc/config.rst index 181ef2a4..aa34ad40 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -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 diff --git a/doc/ext/autodoc.rst b/doc/ext/autodoc.rst index c92fe0c4..94b05423 100644 --- a/doc/ext/autodoc.rst +++ b/doc/ext/autodoc.rst @@ -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 ----------------------- diff --git a/doc/markup/code.rst b/doc/markup/code.rst index 6e707e00..e9f8f1da 100644 --- a/doc/markup/code.rst +++ b/doc/markup/code.rst @@ -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 diff --git a/sphinx-build.py b/sphinx-build.py index 6737d072..54bdb529 100755 --- a/sphinx-build.py +++ b/sphinx-build.py @@ -11,5 +11,8 @@ import sys if __name__ == '__main__': - from sphinx import main - sys.exit(main(sys.argv)) + from sphinx import main, make_main + if sys.argv[1:2] == ['-M']: + sys.exit(make_main(sys.argv)) + else: + sys.exit(main(sys.argv)) diff --git a/sphinx/__init__.py b/sphinx/__init__.py index 2551526f..c1e9e38d 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -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)) diff --git a/sphinx/apidoc.py b/sphinx/apidoc.py index c3054662..7e95cdae 100644 --- a/sphinx/apidoc.py +++ b/sphinx/apidoc.py @@ -65,7 +65,7 @@ def write_file(name, text, opts): def format_heading(level, text): """Create a heading of <level> [1, 2 or 3 supported].""" - underlining = ['=', '-', '~', ][level-1] * len(text) + underlining = ['=', '-', '~', ][level - 1] * len(text) return '%s\n%s\n\n' % (text, underlining) @@ -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: diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py index c153d121..f1280a0b 100644 --- a/sphinx/builders/__init__.py +++ b/sphinx/builders/__init__.py @@ -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): diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index b6ebf926..d715607e 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -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) diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py index 2d7146c3..fdb47dec 100644 --- a/sphinx/cmdline.py +++ b/sphinx/cmdline.py @@ -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']) - allopts = set(opt[0] for opt in opts) - if '-h' in allopts or '--help' in allopts: - usage(argv) - print >>sys.stderr - 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 + 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/>.' + 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: diff --git a/sphinx/config.py b/sphinx/config.py index df74e914..ace5f2a6 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -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'), diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py index 7b1acfd5..6900ea6b 100644 --- a/sphinx/directives/code.py +++ b/sphinx/directives/code.py @@ -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 diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index 377130b8..d44c9cd7 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -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',)), diff --git a/sphinx/environment.py b/sphinx/environment.py index a319ef3c..09f76bf2 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -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( diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py index 571f36cb..86837ff8 100644 --- a/sphinx/ext/autodoc.py +++ b/sphinx/ext/autodoc.py @@ -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') diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py index 800e9ca8..32bb96d3 100644 --- a/sphinx/ext/graphviz.py +++ b/sphinx/ext/graphviz.py @@ -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 diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py index 2d1d6e30..fd973544 100644 --- a/sphinx/ext/inheritance_diagram.py +++ b/sphinx/ext/inheritance_diagram.py @@ -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))) diff --git a/sphinx/ext/viewcode.py b/sphinx/ext/viewcode.py index 962b543b..36fb47d2 100644 --- a/sphinx/ext/viewcode.py +++ b/sphinx/ext/viewcode.py @@ -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 + try: + analyzer = ModuleAnalyzer.for_module(modname) + except Exception: + env._viewcode_modules[modname] = False + return + 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() - if not isinstance(analyzer.code, unicode): - code = analyzer.code.decode(analyzer.encoding) - else: - code = analyzer.code 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 = [''] diff --git a/sphinx/make_mode.py b/sphinx/make_mode.py new file mode 100644 index 00000000..24de6b28 --- /dev/null +++ b/sphinx/make_mode.py @@ -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]) diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py index 3e32f35b..fd358532 100644 --- a/sphinx/quickstart.py +++ b/sphinx/quickstart.py @@ -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): diff --git a/sphinx/setup_command.py b/sphinx/setup_command.py index 07cd520c..7999bf59 100644 --- a/sphinx/setup_command.py +++ b/sphinx/setup_command.py @@ -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() diff --git a/sphinx/texinputs/Makefile b/sphinx/texinputs/Makefile index 6b87ad88..5e6030c0 100644 --- a/sphinx/texinputs/Makefile +++ b/sphinx/texinputs/Makefile @@ -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 diff --git a/sphinx/themes/agogo/static/agogo.css_t b/sphinx/themes/agogo/static/agogo.css_t index 3fb81178..4c7eb378 100644 --- a/sphinx/themes/agogo/static/agogo.css_t +++ b/sphinx/themes/agogo/static/agogo.css_t @@ -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; +} diff --git a/sphinx/themes/basic/static/basic.css_t b/sphinx/themes/basic/static/basic.css_t index d54e7f4e..a3255ebd 100644 --- a/sphinx/themes/basic/static/basic.css_t +++ b/sphinx/themes/basic/static/basic.css_t @@ -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; diff --git a/sphinx/themes/basic/static/doctools.js b/sphinx/themes/basic/static/doctools.js index 8614442e..2036e5f5 100644 --- a/sphinx/themes/basic/static/doctools.js +++ b/sphinx/themes/basic/static/doctools.js @@ -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'); diff --git a/sphinx/themes/default/static/default.css_t b/sphinx/themes/default/static/default.css_t index 5db77108..cdc1b782 100644 --- a/sphinx/themes/default/static/default.css_t +++ b/sphinx/themes/default/static/default.css_t @@ -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; +} diff --git a/sphinx/themes/epub/static/epub.css b/sphinx/themes/epub/static/epub.css index 3f4664f6..6c8ff5e7 100644 --- a/sphinx/themes/epub/static/epub.css +++ b/sphinx/themes/epub/static/epub.css @@ -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"); } - +*/
\ No newline at end of file diff --git a/sphinx/themes/nature/static/nature.css_t b/sphinx/themes/nature/static/nature.css_t index 3c492034..e4f4d2ed 100644 --- a/sphinx/themes/nature/static/nature.css_t +++ b/sphinx/themes/nature/static/nature.css_t @@ -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; +} diff --git a/sphinx/themes/pyramid/static/pyramid.css_t b/sphinx/themes/pyramid/static/pyramid.css_t index c4e94908..c724a493 100644 --- a/sphinx/themes/pyramid/static/pyramid.css_t +++ b/sphinx/themes/pyramid/static/pyramid.css_t @@ -340,3 +340,8 @@ tt.xref { font-weight: normal; font-style: normal; } + +div.code-block-filename { + background-color: #ddd; + color: #222; +} diff --git a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t index af498257..1d7c5796 100644 --- a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t +++ b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t @@ -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; +} diff --git a/sphinx/themes/traditional/static/traditional.css_t b/sphinx/themes/traditional/static/traditional.css_t index fff411ef..cbea798c 100644 --- a/sphinx/themes/traditional/static/traditional.css_t +++ b/sphinx/themes/traditional/static/traditional.css_t @@ -698,3 +698,7 @@ div.viewcode-block:target { margin: -1px -10px; padding: 0 10px; } + +div.code-block-filename { + background-color: #cceeff; +} diff --git a/sphinx/transforms.py b/sphinx/transforms.py index 35e9d297..e44a3d3e 100644 --- a/sphinx/transforms.py +++ b/sphinx/transforms.py @@ -195,7 +195,10 @@ class Locale(Transform): patch = new_document(source, settings) CustomLocaleReporter(node.source, node.line).set_reporter(patch) parser.parse(msgstr, patch) - patch = patch[0] + 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) - patch = patch[0] + 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 diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index 308e1f5b..61b905f6 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -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 diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 5429bcbb..61aa5828 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -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, diff --git a/tests/root/autodoc.txt b/tests/root/autodoc.txt index d4b3404c..aa0dffba 100644 --- a/tests/root/autodoc.txt +++ b/tests/root/autodoc.txt @@ -45,3 +45,5 @@ Just testing a few autodoc possibilities... :members: ca1, ia1 Specific members (2 total) + +.. automodule:: autodoc_missing_imports diff --git a/tests/root/autodoc_missing_imports.py b/tests/root/autodoc_missing_imports.py new file mode 100644 index 00000000..7a717345 --- /dev/null +++ b/tests/root/autodoc_missing_imports.py @@ -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.""" diff --git a/tests/root/conf.py b/tests/root/conf.py index 9cc536ba..af984e5e 100644 --- a/tests/root/conf.py +++ b/tests/root/conf.py @@ -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') |