summaryrefslogtreecommitdiff
path: root/sphinx
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2014-01-19 17:41:41 +0100
committerGeorg Brandl <georg@python.org>2014-01-19 17:41:41 +0100
commita003cdbd2fcf73e24670568facda9bd6c5a73e76 (patch)
treeb227753b9b0a0bb70b412176a186e0e07c99c26c /sphinx
parentdbefc55b2fac1e0f531af7d5f4de51aeef65bcf2 (diff)
parent647512528f59c24781ed4043bab0d811e97ef3a7 (diff)
downloadsphinx-a003cdbd2fcf73e24670568facda9bd6c5a73e76.tar.gz
merge with stable
Diffstat (limited to 'sphinx')
-rw-r--r--sphinx/__init__.py11
-rw-r--r--sphinx/addnodes.py5
-rw-r--r--sphinx/application.py6
-rw-r--r--sphinx/builders/epub.py8
-rw-r--r--sphinx/builders/html.py12
-rw-r--r--sphinx/builders/linkcheck.py3
-rw-r--r--sphinx/cmdline.py13
-rw-r--r--sphinx/config.py33
-rw-r--r--sphinx/directives/code.py29
-rw-r--r--sphinx/domains/python.py19
-rw-r--r--sphinx/ext/autodoc.py37
-rw-r--r--sphinx/ext/oldcmarkup.py67
-rw-r--r--sphinx/ext/todo.py1
-rw-r--r--sphinx/highlighting.py18
-rw-r--r--sphinx/pycode/__init__.py2
-rw-r--r--sphinx/pycode/pgen2/parse.c89
-rw-r--r--sphinx/quickstart.py22
-rw-r--r--sphinx/roles.py6
-rw-r--r--sphinx/texinputs/Makefile28
-rw-r--r--sphinx/themes/agogo/layout.html50
-rw-r--r--sphinx/themes/agogo/static/agogo.css_t7
-rw-r--r--sphinx/themes/basic/layout.html10
-rw-r--r--sphinx/themes/basic/searchbox.html2
-rw-r--r--sphinx/themes/basic/sourcelink.html12
-rw-r--r--sphinx/themes/basic/static/basic.css_t14
-rw-r--r--sphinx/themes/default/static/default.css_t5
-rw-r--r--sphinx/themes/haiku/layout.html6
-rw-r--r--sphinx/themes/nature/static/nature.css_t6
-rw-r--r--sphinx/themes/pyramid/layout.html2
-rw-r--r--sphinx/themes/pyramid/static/pyramid.css_t5
-rw-r--r--sphinx/themes/scrolls/layout.html4
-rw-r--r--sphinx/themes/sphinxdoc/static/sphinxdoc.css_t6
-rw-r--r--sphinx/themes/traditional/static/traditional.css_t4
-rw-r--r--sphinx/transforms.py1
-rw-r--r--sphinx/util/docfields.py6
-rw-r--r--sphinx/util/inspect.py9
-rw-r--r--sphinx/util/jsonimpl.py20
-rw-r--r--sphinx/util/osutil.py9
-rw-r--r--sphinx/util/pycompat.py185
-rw-r--r--sphinx/versioning.py3
-rw-r--r--sphinx/writers/html.py16
-rw-r--r--sphinx/writers/latex.py13
-rw-r--r--sphinx/writers/manpage.py5
-rw-r--r--sphinx/writers/texinfo.py5
-rw-r--r--sphinx/writers/text.py5
45 files changed, 331 insertions, 488 deletions
diff --git a/sphinx/__init__.py b/sphinx/__init__.py
index 8a1b97f7..c1e9e38d 100644
--- a/sphinx/__init__.py
+++ b/sphinx/__init__.py
@@ -15,12 +15,12 @@
import sys
from os import path
-__version__ = '1.2+'
-__released__ = '1.2' # used when Sphinx builds its own docs
+__version__ = '1.3a0'
+__released__ = '1.3a0' # used when Sphinx builds its own docs
# version info for better programmatic use
# possible values for 3rd element: 'alpha', 'beta', 'rc', 'final'
# 'final' has 0 as the last element
-version_info = (1, 2, 0, 'final', 0)
+version_info = (1, 3, 0, 'alpha', 0)
package_dir = path.abspath(path.dirname(__file__))
@@ -42,8 +42,9 @@ if '+' in __version__ or 'pre' in __version__:
def main(argv=sys.argv):
"""Sphinx build "main" command-line entry."""
- if sys.version_info[:3] < (2, 5, 0):
- sys.stderr.write('Error: Sphinx requires at least Python 2.5 to run.\n')
+ if (sys.version_info[:3] < (2, 6, 0) or
+ (3, 0, 0) <= sys.version_info[:3] < (3, 2, 0)):
+ sys.stderr.write('Error: Sphinx requires at least Python 2.6 to run.\n')
return 1
try:
from sphinx import cmdline
diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py
index d8dca2ce..e3f6d7d6 100644
--- a/sphinx/addnodes.py
+++ b/sphinx/addnodes.py
@@ -168,6 +168,11 @@ class literal_emphasis(nodes.emphasis):
applied (e.g. smartypants for HTML output).
"""
+class literal_strong(nodes.strong):
+ """Node that behaves like `strong`, but further text processors are not
+ applied (e.g. smartypants for HTML output).
+ """
+
class abbreviation(nodes.Inline, nodes.TextElement):
"""Node for abbreviations with explanations."""
diff --git a/sphinx/application.py b/sphinx/application.py
index ceb7c32c..6b86b181 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -15,6 +15,7 @@ import os
import sys
import types
import posixpath
+import traceback
from os import path
from cStringIO import StringIO
@@ -112,8 +113,6 @@ class Sphinx(object):
if self.confdir is None:
self.confdir = self.srcdir
- # backwards compatibility: activate old C markup
- self.setup_extension('sphinx.ext.oldcmarkup')
# load all user-given extension modules
for extension in self.config.extensions:
self.setup_extension(extension)
@@ -122,7 +121,7 @@ class Sphinx(object):
self.config.setup(self)
# now that we know all config values, collect them from conf.py
- self.config.init_values()
+ self.config.init_values(self.warn)
# check the Sphinx version if requested
if self.config.needs_sphinx and \
@@ -282,6 +281,7 @@ class Sphinx(object):
try:
mod = __import__(extension, None, None, ['setup'])
except ImportError, err:
+ self.verbose('Original exception:\n' + traceback.format_exc())
raise ExtensionError('Could not import extension %s' % extension,
err)
if not hasattr(mod, 'setup'):
diff --git a/sphinx/builders/epub.py b/sphinx/builders/epub.py
index 1dfcc704..35061b79 100644
--- a/sphinx/builders/epub.py
+++ b/sphinx/builders/epub.py
@@ -12,7 +12,6 @@
import os
import re
-import sys
import time
import codecs
import zipfile
@@ -750,12 +749,5 @@ class EpubBuilder(StandaloneHTMLBuilder):
zipfile.ZIP_STORED)
for file in projectfiles:
fp = path.join(outdir, file)
- if sys.version_info < (2, 6):
- # When zipile.ZipFile.write call with unicode filename, ZipFile
- # encode filename to 'utf-8' (only after Python-2.6).
- if isinstance(file, unicode):
- # OEBPS Container Format (OCF) 2.0.1 specification require
- # "File Names MUST be UTF-8 encoded".
- file = file.encode('utf-8')
epub.write(fp, file, zipfile.ZIP_DEFLATED)
epub.close()
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index dd62e2ba..b6ebf926 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -16,11 +16,7 @@ import codecs
import posixpath
import cPickle as pickle
from os import path
-try:
- from hashlib import md5
-except ImportError:
- # 2.4 compatibility
- from md5 import md5
+from hashlib import md5
from docutils import nodes
from docutils.io import DocTreeInput, StringOutput
@@ -35,7 +31,7 @@ from sphinx.util.osutil import SEP, os_path, relative_uri, ensuredir, \
movefile, ustrftime, copyfile
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.matching import patmatch, compile_matchers
-from sphinx.util.pycompat import any, b
+from sphinx.util.pycompat import b
from sphinx.errors import SphinxError
from sphinx.locale import _
from sphinx.search import js_index
@@ -1098,8 +1094,4 @@ class JSONHTMLBuilder(SerializingHTMLBuilder):
searchindex_filename = 'searchindex.json'
def init(self):
- if jsonimpl.json is None:
- raise SphinxError(
- 'The module simplejson (or json in Python >= 2.6) '
- 'is not available. The JSONHTMLBuilder builder will not work.')
SerializingHTMLBuilder.init(self)
diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py
index 6cbe361b..171e68d5 100644
--- a/sphinx/builders/linkcheck.py
+++ b/sphinx/builders/linkcheck.py
@@ -10,7 +10,6 @@
"""
import re
-import sys
import Queue
import socket
import threading
@@ -110,7 +109,7 @@ class CheckExternalLinksBuilder(Builder):
def check_thread(self):
kwargs = {}
- if sys.version_info > (2, 5) and self.app.config.linkcheck_timeout:
+ if self.app.config.linkcheck_timeout:
kwargs['timeout'] = self.app.config.linkcheck_timeout
def check():
diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py
index f4a09e16..fdb47dec 100644
--- a/sphinx/cmdline.py
+++ b/sphinx/cmdline.py
@@ -181,14 +181,11 @@ def main(argv):
print >>sys.stderr, ('Error: -D option argument must be '
'in the form name=value.')
return 1
- try:
- val = int(val)
- except ValueError:
- if likely_encoding and isinstance(val, bytes):
- try:
- val = val.decode(likely_encoding)
- except UnicodeError:
- pass
+ if likely_encoding and isinstance(val, bytes):
+ try:
+ val = val.decode(likely_encoding)
+ except UnicodeError:
+ pass
confoverrides[key] = val
elif opt == '-A':
try:
diff --git a/sphinx/config.py b/sphinx/config.py
index 8b15bdf3..df74e914 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -214,8 +214,11 @@ class Config(object):
self.overrides = overrides
self.values = Config.config_values.copy()
config = {}
- if "extensions" in overrides:
- config["extensions"] = overrides["extensions"]
+ if 'extensions' in overrides:
+ if isinstance(overrides['extensions'], (str, unicode)):
+ config['extensions'] = overrides.pop('extensions').split(',')
+ else:
+ config['extensions'] = overrides.pop('extensions')
if dirname is not None:
config_file = path.join(dirname, filename)
config['__file__'] = config_file
@@ -248,12 +251,36 @@ class Config(object):
'Please use Unicode strings, e.g. %r.' % (name, u'Content')
)
- def init_values(self):
+ def init_values(self, warn):
config = self._raw_config
for valname, value in self.overrides.iteritems():
if '.' in valname:
realvalname, key = valname.split('.', 1)
config.setdefault(realvalname, {})[key] = value
+ continue
+ elif valname not in self.values:
+ warn('unknown config value %r in override, ignoring' % valname)
+ continue
+ defvalue = self.values[valname][0]
+ if isinstance(value, (str, unicode)):
+ if isinstance(defvalue, dict):
+ warn('cannot override dictionary config setting %r, '
+ 'ignoring (use %r to set individual elements)' %
+ (valname, valname + '.key=value'))
+ continue
+ elif isinstance(defvalue, list):
+ config[valname] = value.split(',')
+ elif isinstance(defvalue, (int, long)):
+ try:
+ config[valname] = int(value)
+ except ValueError:
+ warn('invalid number %r for config value %r, ignoring'
+ % (value, valname))
+ elif defvalue is not None and not isinstance(defvalue, (str, unicode)):
+ warn('cannot override config setting %r with unsupported type, '
+ 'ignoring' % valname)
+ else:
+ config[valname] = value
else:
config[valname] = value
for name in config:
diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py
index 4d43e5ff..6900ea6b 100644
--- a/sphinx/directives/code.py
+++ b/sphinx/directives/code.py
@@ -56,7 +56,9 @@ class CodeBlock(Directive):
final_argument_whitespace = False
option_spec = {
'linenos': directives.flag,
+ 'lineno-start': int,
'emphasize-lines': directives.unchanged_required,
+ 'filename': directives.unchanged_required,
}
def run(self):
@@ -75,9 +77,16 @@ class CodeBlock(Directive):
literal = nodes.literal_block(code, code)
literal['language'] = self.arguments[0]
- literal['linenos'] = 'linenos' in self.options
+ 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'] = {}
if hl_lines is not None:
- literal['highlight_args'] = {'hl_lines': hl_lines}
+ extra_args['hl_lines'] = hl_lines
+ if 'lineno-start' in self.options:
+ extra_args['linenostart'] = self.options['lineno-start']
set_source_info(self, literal)
return [literal]
@@ -95,6 +104,7 @@ class LiteralInclude(Directive):
final_argument_whitespace = True
option_spec = {
'linenos': directives.flag,
+ 'lineno-start': int,
'tab-width': int,
'language': directives.unchanged_required,
'encoding': directives.encoding,
@@ -105,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):
@@ -204,10 +215,18 @@ class LiteralInclude(Directive):
set_source_info(self, retnode)
if self.options.get('language', ''):
retnode['language'] = self.options['language']
- if 'linenos' in self.options:
- retnode['linenos'] = True
+ 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:
- retnode['highlight_args'] = {'hl_lines': hl_lines}
+ extra_args['hl_lines'] = hl_lines
+ if 'lineno-start' in self.options:
+ extra_args['linenostart'] = self.options['lineno-start']
env.note_dependency(rel_filename)
return [retnode]
diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py
index a7ed7557..6714e838 100644
--- a/sphinx/domains/python.py
+++ b/sphinx/domains/python.py
@@ -81,6 +81,23 @@ def _pseudo_parse_arglist(signode, arglist):
signode += paramlist
+# This override allows our inline type specifiers to behave like :class: link
+# when it comes to handling "." and "~" prefixes.
+class PyTypedField(TypedField):
+ def make_xref(self, rolename, domain, target, innernode=nodes.emphasis):
+ result = super(PyTypedField, self).make_xref(rolename, domain, target,
+ innernode)
+ if target.startswith('.'):
+ result['reftarget'] = target[1:]
+ result['refspecific'] = True
+ result[0][0] = nodes.Text(target[1:])
+ if target.startswith('~'):
+ result['reftarget'] = target[1:]
+ title = target.split('.')[-1]
+ result[0][0] = nodes.Text(title)
+ return result
+
+
class PyObject(ObjectDescription):
"""
Description of a general Python object.
@@ -92,7 +109,7 @@ class PyObject(ObjectDescription):
}
doc_field_types = [
- TypedField('parameter', label=l_('Parameters'),
+ PyTypedField('parameter', label=l_('Parameters'),
names=('param', 'parameter', 'arg', 'argument',
'keyword', 'kwarg', 'kwparam'),
typerolename='obj', typenames=('paramtype', 'type'),
diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py
index c454641b..86837ff8 100644
--- a/sphinx/ext/autodoc.py
+++ b/sphinx/ext/autodoc.py
@@ -29,7 +29,7 @@ from sphinx.util.nodes import nested_parse_with_titles
from sphinx.util.compat import Directive
from sphinx.util.inspect import getargspec, isdescriptor, safe_getmembers, \
safe_getattr, safe_repr, is_builtin_class_method
-from sphinx.util.pycompat import base_exception, class_types
+from sphinx.util.pycompat import class_types
from sphinx.util.docstrings import prepare_docstring
@@ -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]
@@ -1130,7 +1162,7 @@ class ExceptionDocumenter(ClassDocumenter):
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
return isinstance(member, class_types) and \
- issubclass(member, base_exception)
+ issubclass(member, BaseException)
class DataDocumenter(ModuleLevelDocumenter):
@@ -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/oldcmarkup.py b/sphinx/ext/oldcmarkup.py
deleted file mode 100644
index aa10246b..00000000
--- a/sphinx/ext/oldcmarkup.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- sphinx.ext.oldcmarkup
- ~~~~~~~~~~~~~~~~~~~~~
-
- Extension for compatibility with old C markup (directives and roles).
-
- :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
- :license: BSD, see LICENSE for details.
-"""
-
-from docutils.parsers.rst import directives
-
-from sphinx.util.compat import Directive
-
-_warned_oldcmarkup = False
-WARNING_MSG = 'using old C markup; please migrate to new-style markup ' \
- '(e.g. c:function instead of cfunction), see ' \
- 'http://sphinx-doc.org/domains.html'
-
-
-class OldCDirective(Directive):
- has_content = True
- required_arguments = 1
- optional_arguments = 0
- final_argument_whitespace = True
- option_spec = {
- 'noindex': directives.flag,
- 'module': directives.unchanged,
- }
-
- def run(self):
- env = self.state.document.settings.env
- if not env.app._oldcmarkup_warned:
- self.state_machine.reporter.warning(WARNING_MSG, line=self.lineno)
- env.app._oldcmarkup_warned = True
- newname = 'c:' + self.name[1:]
- newdir = env.lookup_domain_element('directive', newname)[0]
- return newdir(newname, self.arguments, self.options,
- self.content, self.lineno, self.content_offset,
- self.block_text, self.state, self.state_machine).run()
-
-
-def old_crole(typ, rawtext, text, lineno, inliner, options={}, content=[]):
- env = inliner.document.settings.env
- if not typ:
- typ = env.config.default_role
- if not env.app._oldcmarkup_warned:
- inliner.reporter.warning(WARNING_MSG, line=lineno)
- env.app._oldcmarkup_warned = True
- newtyp = 'c:' + typ[1:]
- newrole = env.lookup_domain_element('role', newtyp)[0]
- return newrole(newtyp, rawtext, text, lineno, inliner, options, content)
-
-
-def setup(app):
- app._oldcmarkup_warned = False
- app.add_directive('cfunction', OldCDirective)
- app.add_directive('cmember', OldCDirective)
- app.add_directive('cmacro', OldCDirective)
- app.add_directive('ctype', OldCDirective)
- app.add_directive('cvar', OldCDirective)
- app.add_role('cdata', old_crole)
- app.add_role('cfunc', old_crole)
- app.add_role('cmacro', old_crole)
- app.add_role('ctype', old_crole)
- app.add_role('cmember', old_crole)
diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py
index de5d2b9f..253ae07d 100644
--- a/sphinx/ext/todo.py
+++ b/sphinx/ext/todo.py
@@ -171,4 +171,3 @@ def setup(app):
app.connect('doctree-read', process_todos)
app.connect('doctree-resolved', process_todo_nodes)
app.connect('env-purge-doc', purge_todos)
-
diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py
index 2c95dec0..c30c9ef3 100644
--- a/sphinx/highlighting.py
+++ b/sphinx/highlighting.py
@@ -63,12 +63,6 @@ _LATEX_STYLES = r'''
\newcommand\PYGZcb{\char`\}}
'''
-parsing_exceptions = (SyntaxError, UnicodeEncodeError)
-if sys.version_info < (2, 5):
- # Python <= 2.4 raises MemoryError when parsing an
- # invalid encoding cookie
- parsing_exceptions += MemoryError,
-
class PygmentsBridge(object):
# Set these attributes if you want to have different Pygments formatters
@@ -131,10 +125,6 @@ class PygmentsBridge(object):
# lines beginning with "..." are probably placeholders for suite
src = re.sub(r"(?m)^(\s*)" + mark + "(.)", r"\1"+ mark + r"# \2", src)
- # if we're using 2.5, use the with statement
- if sys.version_info >= (2, 5):
- src = 'from __future__ import with_statement\n' + src
-
if sys.version_info < (3, 0) and isinstance(src, unicode):
# Non-ASCII chars will only occur in string literals
# and comments. If we wanted to give them to the parser
@@ -143,18 +133,12 @@ class PygmentsBridge(object):
# just replace all non-ASCII characters.
src = src.encode('ascii', 'replace')
- if (3, 0) <= sys.version_info < (3, 2):
- # Python 3.1 can't process '\r' as linesep.
- # `parser.suite("print('hello')\r\n")` cause error.
- if '\r\n' in src:
- src = src.replace('\r\n', '\n')
-
if parser is None:
return True
try:
parser.suite(src)
- except parsing_exceptions:
+ except (SyntaxError, UnicodeEncodeError):
return False
else:
return True
diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py
index 2c0708f9..54e79da6 100644
--- a/sphinx/pycode/__init__.py
+++ b/sphinx/pycode/__init__.py
@@ -17,7 +17,7 @@ from sphinx.errors import PycodeError
from sphinx.pycode import nodes
from sphinx.pycode.pgen2 import driver, token, tokenize, parse, literals
from sphinx.util import get_module_source, detect_encoding
-from sphinx.util.pycompat import next, StringIO, BytesIO, TextIOWrapper
+from sphinx.util.pycompat import StringIO, BytesIO, TextIOWrapper
from sphinx.util.docstrings import prepare_docstring, prepare_commentdoc
diff --git a/sphinx/pycode/pgen2/parse.c b/sphinx/pycode/pgen2/parse.c
index e09f5058..96fa6c8b 100644
--- a/sphinx/pycode/pgen2/parse.c
+++ b/sphinx/pycode/pgen2/parse.c
@@ -353,95 +353,6 @@ static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name); /*proto*/
-#if PY_VERSION_HEX < 0x02050000
-#ifndef PyAnySet_CheckExact
-
-#define PyAnySet_CheckExact(ob) \
- ((ob)->ob_type == &PySet_Type || \
- (ob)->ob_type == &PyFrozenSet_Type)
-
-#define PySet_New(iterable) \
- PyObject_CallFunctionObjArgs((PyObject *)&PySet_Type, (iterable), NULL)
-
-#define Pyx_PyFrozenSet_New(iterable) \
- PyObject_CallFunctionObjArgs((PyObject *)&PyFrozenSet_Type, (iterable), NULL)
-
-#define PySet_Size(anyset) \
- PyObject_Size((anyset))
-
-#define PySet_Contains(anyset, key) \
- PySequence_Contains((anyset), (key))
-
-#define PySet_Pop(set) \
- PyObject_CallMethod(set, (char *)"pop", NULL)
-
-static INLINE int PySet_Clear(PyObject *set) {
- PyObject *ret = PyObject_CallMethod(set, (char *)"clear", NULL);
- if (!ret) return -1;
- Py_DECREF(ret); return 0;
-}
-
-static INLINE int PySet_Discard(PyObject *set, PyObject *key) {
- PyObject *ret = PyObject_CallMethod(set, (char *)"discard", (char *)"O", key);
- if (!ret) return -1;
- Py_DECREF(ret); return 0;
-}
-
-static INLINE int PySet_Add(PyObject *set, PyObject *key) {
- PyObject *ret = PyObject_CallMethod(set, (char *)"add", (char *)"O", key);
- if (!ret) return -1;
- Py_DECREF(ret); return 0;
-}
-
-#endif /* PyAnySet_CheckExact (<= Py2.4) */
-
-#if PY_VERSION_HEX < 0x02040000
-#ifndef Py_SETOBJECT_H
-#define Py_SETOBJECT_H
-
-static PyTypeObject *__Pyx_PySet_Type = NULL;
-static PyTypeObject *__Pyx_PyFrozenSet_Type = NULL;
-
-#define PySet_Type (*__Pyx_PySet_Type)
-#define PyFrozenSet_Type (*__Pyx_PyFrozenSet_Type)
-
-#define PyAnySet_Check(ob) \
- (PyAnySet_CheckExact(ob) || \
- PyType_IsSubtype((ob)->ob_type, &PySet_Type) || \
- PyType_IsSubtype((ob)->ob_type, &PyFrozenSet_Type))
-
-#define PyFrozenSet_CheckExact(ob) ((ob)->ob_type == &PyFrozenSet_Type)
-
-static int __Pyx_Py23SetsImport(void) {
- PyObject *sets=0, *Set=0, *ImmutableSet=0;
-
- sets = PyImport_ImportModule((char *)"sets");
- if (!sets) goto bad;
- Set = PyObject_GetAttrString(sets, (char *)"Set");
- if (!Set) goto bad;
- ImmutableSet = PyObject_GetAttrString(sets, (char *)"ImmutableSet");
- if (!ImmutableSet) goto bad;
- Py_DECREF(sets);
-
- __Pyx_PySet_Type = (PyTypeObject*) Set;
- __Pyx_PyFrozenSet_Type = (PyTypeObject*) ImmutableSet;
-
- return 0;
-
- bad:
- Py_XDECREF(sets);
- Py_XDECREF(Set);
- Py_XDECREF(ImmutableSet);
- return -1;
-}
-
-#else
-static int __Pyx_Py23SetsImport(void) { return 0; }
-#endif /* !Py_SETOBJECT_H */
-#endif /* < Py2.4 */
-#endif /* < Py2.5 */
-
-
static INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
PyObject *r;
if (!j) return NULL;
diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py
index d9449f74..fd358532 100644
--- a/sphinx/quickstart.py
+++ b/sphinx/quickstart.py
@@ -11,6 +11,7 @@
import sys, os, time, re
from os import path
+from io import open
TERM_ENCODING = getattr(sys.stdin, 'encoding', None)
@@ -21,7 +22,6 @@ from sphinx.util.osutil import make_filename
from sphinx.util.console import purple, bold, red, turquoise, \
nocolor, color_terminal
from sphinx.util import texescape
-from sphinx.util.pycompat import open
# function to get input from terminal -- overridden by the test suite
try:
@@ -99,7 +99,10 @@ release = '%(release_str)s'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
-#language = None
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = %(language)r
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
@@ -320,7 +323,7 @@ epub_copyright = u'%(copyright_str)s'
#epub_theme = 'epub'
# The language of the text. It defaults to the language option
-# or en if the language is not set.
+# or 'en' if the language is not set.
#epub_language = ''
# The scheme of the identifier. Typical schemes are ISBN or URL.
@@ -1018,6 +1021,7 @@ def ask_user(d):
* author: author names
* version: version of project
* release: release of project
+ * language: document language
* suffix: source file suffix
* master: master document name
* epub: use epub (bool)
@@ -1084,6 +1088,18 @@ just set both to the same value.'''
if 'release' not in d:
do_prompt(d, 'release', 'Project release', d['version'])
+ if 'language' not in d:
+ print '''
+If the documents are to be written in a language other than English,
+you can select a language here by its language code. Sphinx will then
+translate text that it generates into that language.
+
+For a list of supported codes, see
+http://sphinx-doc.org/config.html#confval-language.'''
+ do_prompt(d, 'language', 'Project language', 'en')
+ if d['language'] == 'en':
+ d['language'] = None
+
if 'suffix' not in d:
print '''
The file name suffix for source files. Commonly, this is either ".txt"
diff --git a/sphinx/roles.py b/sphinx/roles.py
index 6703b6b8..3b858588 100644
--- a/sphinx/roles.py
+++ b/sphinx/roles.py
@@ -22,15 +22,15 @@ from sphinx.util.nodes import split_explicit_title, process_index_entry, \
generic_docroles = {
- 'command' : nodes.strong,
+ 'command' : addnodes.literal_strong,
'dfn' : nodes.emphasis,
'kbd' : nodes.literal,
'mailheader' : addnodes.literal_emphasis,
- 'makevar' : nodes.strong,
+ 'makevar' : addnodes.literal_strong,
'manpage' : addnodes.literal_emphasis,
'mimetype' : addnodes.literal_emphasis,
'newsgroup' : addnodes.literal_emphasis,
- 'program' : nodes.strong, # XXX should be an x-ref
+ 'program' : addnodes.literal_strong, # XXX should be an x-ref
'regexp' : nodes.literal,
}
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/layout.html b/sphinx/themes/agogo/layout.html
index fde19dbc..f2ddb217 100644
--- a/sphinx/themes/agogo/layout.html
+++ b/sphinx/themes/agogo/layout.html
@@ -11,7 +11,7 @@
{%- extends "basic/layout.html" %}
{% block header %}
- <div class="header-wrapper">
+ <div class="header-wrapper" role="banner">
<div class="header">
{%- if logo %}
<p class="logo"><a href="{{ pathto(master_doc) }}">
@@ -22,7 +22,7 @@
<div class="headertitle"><a
href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a></div>
{%- endblock %}
- <div class="rel">
+ <div class="rel" role="navigation" aria-label="related navigation">
{%- for rellink in rellinks|reverse %}
<a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags|e }}"
{{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
@@ -47,16 +47,18 @@
{{ toctree() }}
{%- endblock %}
{%- block sidebarsearch %}
- <h3 style="margin-top: 1.5em;">{{ _('Search') }}</h3>
- <form class="search" action="{{ pathto('search') }}" method="get">
- <input type="text" name="q" />
- <input type="submit" value="{{ _('Go') }}" />
- <input type="hidden" name="check_keywords" value="yes" />
- <input type="hidden" name="area" value="default" />
- </form>
- <p class="searchtip" style="font-size: 90%">
- {{ _('Enter search terms or a module, class or function name.') }}
- </p>
+ <div role="search">
+ <h3 style="margin-top: 1.5em;">{{ _('Search') }}</h3>
+ <form class="search" action="{{ pathto('search') }}" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="{{ _('Go') }}" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ {{ _('Enter search terms or a module, class or function name.') }}
+ </p>
+ </div>
{%- endblock %}
</div>
<div class="clearer"></div>
@@ -68,16 +70,20 @@
<div class="footer-wrapper">
<div class="footer">
<div class="left">
- {%- for rellink in rellinks|reverse %}
- <a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags|e }}"
- {{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
- {%- if not loop.last %}{{ reldelim2 }}{% endif %}
- {%- endfor %}
- {%- if show_source and has_source and sourcename %}
- <br/>
- <a href="{{ pathto('_sources/' + sourcename, true)|e }}"
- rel="nofollow">{{ _('Show Source') }}</a>
- {%- endif %}
+ <div role="navigation" aria-label="related navigaton">
+ {%- for rellink in rellinks|reverse %}
+ <a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags|e }}"
+ {{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
+ {%- if not loop.last %}{{ reldelim2 }}{% endif %}
+ {%- endfor %}
+ </div>
+ <div role="note" aria-label="source link">
+ {%- if show_source and has_source and sourcename %}
+ <br/>
+ <a href="{{ pathto('_sources/' + sourcename, true)|e }}"
+ rel="nofollow">{{ _('Show Source') }}</a>
+ {%- endif %}
+ </div>
</div>
<div class="right">
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/layout.html b/sphinx/themes/basic/layout.html
index 9e4e39a1..68a070b3 100644
--- a/sphinx/themes/basic/layout.html
+++ b/sphinx/themes/basic/layout.html
@@ -25,7 +25,7 @@
{%- endif %}
{%- macro relbar() %}
- <div class="related">
+ <div class="related" role="navigation" aria-label="related navigation">
<h3>{{ _('Navigation') }}</h3>
<ul>
{%- for rellink in rellinks %}
@@ -47,7 +47,7 @@
{%- macro sidebar() %}
{%- if render_sidebar %}
- <div class="sphinxsidebar">
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
{%- block sidebarlogo %}
{%- if logo %}
@@ -152,7 +152,7 @@
{%- endblock %}
{%- block extrahead %} {% endblock %}
</head>
- <body>
+ <body role="document">
{%- block header %}{% endblock %}
{%- block relbar1 %}{{ relbar() }}{% endblock %}
@@ -166,7 +166,7 @@
{%- if render_sidebar %}
<div class="bodywrapper">
{%- endif %}
- <div class="body">
+ <div class="body" role="main">
{% block body %} {% endblock %}
</div>
{%- if render_sidebar %}
@@ -183,7 +183,7 @@
{%- block relbar2 %}{{ relbar() }}{% endblock %}
{%- block footer %}
- <div class="footer">
+ <div class="footer" role="contentinfo">
{%- if show_copyright %}
{%- if hasdoc('copyright') %}
{% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
diff --git a/sphinx/themes/basic/searchbox.html b/sphinx/themes/basic/searchbox.html
index 609aac83..0a573c32 100644
--- a/sphinx/themes/basic/searchbox.html
+++ b/sphinx/themes/basic/searchbox.html
@@ -8,7 +8,7 @@
:license: BSD, see LICENSE for details.
#}
{%- if pagename != "search" %}
-<div id="searchbox" style="display: none">
+<div id="searchbox" style="display: none" role="search">
<h3>{{ _('Quick search') }}</h3>
<form class="search" action="{{ pathto('search') }}" method="get">
<input type="text" name="q" />
diff --git a/sphinx/themes/basic/sourcelink.html b/sphinx/themes/basic/sourcelink.html
index 08232efc..fbbae064 100644
--- a/sphinx/themes/basic/sourcelink.html
+++ b/sphinx/themes/basic/sourcelink.html
@@ -8,9 +8,11 @@
:license: BSD, see LICENSE for details.
#}
{%- if show_source and has_source and sourcename %}
- <h3>{{ _('This Page') }}</h3>
- <ul class="this-page-menu">
- <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
- rel="nofollow">{{ _('Show Source') }}</a></li>
- </ul>
+ <div role="note" aria-label="source link">
+ <h3>{{ _('This Page') }}</h3>
+ <ul class="this-page-menu">
+ <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
+ rel="nofollow">{{ _('Show Source') }}</a></li>
+ </ul>
+ </div>
{%- endif %}
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/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/haiku/layout.html b/sphinx/themes/haiku/layout.html
index 0c6b41e7..a98d89c6 100644
--- a/sphinx/themes/haiku/layout.html
+++ b/sphinx/themes/haiku/layout.html
@@ -32,7 +32,7 @@
{% endmacro %}
{% block content %}
- <div class="header">
+ <div class="header" role="banner">
{%- block haikuheader %}
{%- if theme_full_logo != "false" %}
<a href="{{ pathto('index') }}">
@@ -48,7 +48,7 @@
{%- endif %}
{%- endblock %}
</div>
- <div class="topnav">
+ <div class="topnav" role="navigation" aria-label="top navigation">
{{ nav() }}
</div>
<div class="content">
@@ -60,7 +60,7 @@
{%- endif %}#}
{% block body %}{% endblock %}
</div>
- <div class="bottomnav">
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
{{ nav() }}
</div>
{% endblock %}
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/layout.html b/sphinx/themes/pyramid/layout.html
index 8780ceae..318a3662 100644
--- a/sphinx/themes/pyramid/layout.html
+++ b/sphinx/themes/pyramid/layout.html
@@ -10,7 +10,7 @@
{% block header %}
{%- if logo %}
-<div class="header">
+<div class="header" role="banner">
<div class="logo">
<a href="{{ pathto(master_doc) }}">
<img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/>
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/scrolls/layout.html b/sphinx/themes/scrolls/layout.html
index 48e5e4e4..0961808e 100644
--- a/sphinx/themes/scrolls/layout.html
+++ b/sphinx/themes/scrolls/layout.html
@@ -20,7 +20,7 @@
<h1 class="heading"><a href="{{ pathto('index') }}"
title="back to the documentation overview"><span>{{ title|striptags|e }}</span></a></h1>
</div>
- <div class="relnav">
+ <div class="relnav" role="navigation" aria-label="related navigation">
{%- if prev %}
<a href="{{ prev.link|e }}">&laquo; {{ prev.title }}</a> |
{%- endif %}
@@ -31,7 +31,7 @@
</div>
<div id="contentwrapper">
{%- if display_toc %}
- <div id="toc">
+ <div id="toc" role="navigation" aria-label="table of contents navigation">
<h3>{{ _('Table Of Contents') }}</h3>
{{ toc }}
</div>
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 53bbadb0..e44a3d3e 100644
--- a/sphinx/transforms.py
+++ b/sphinx/transforms.py
@@ -23,7 +23,6 @@ from sphinx.util import split_index_msg
from sphinx.util.nodes import traverse_translatable_index, extract_messages
from sphinx.util.osutil import ustrftime, find_catalog
from sphinx.util.compat import docutils_version
-from sphinx.util.pycompat import all
from sphinx.domains.std import (
make_term_from_paragraph_node,
make_termnodes_from_paragraph_node,
diff --git a/sphinx/util/docfields.py b/sphinx/util/docfields.py
index 6fd8ba95..150bf3a1 100644
--- a/sphinx/util/docfields.py
+++ b/sphinx/util/docfields.py
@@ -99,7 +99,8 @@ class GroupedField(Field):
return Field.make_field(self, types, domain, items[0])
for fieldarg, content in items:
par = nodes.paragraph()
- par += self.make_xref(self.rolename, domain, fieldarg, nodes.strong)
+ par += self.make_xref(self.rolename, domain, fieldarg,
+ addnodes.literal_strong)
par += nodes.Text(' -- ')
par += content
listnode += nodes.list_item('', par)
@@ -137,7 +138,8 @@ class TypedField(GroupedField):
def make_field(self, types, domain, items):
def handle_item(fieldarg, content):
par = nodes.paragraph()
- par += self.make_xref(self.rolename, domain, fieldarg, nodes.strong)
+ par += self.make_xref(self.rolename, domain, fieldarg,
+ addnodes.literal_strong)
if fieldarg in types:
par += nodes.Text(' (')
# NOTE: using .pop() here to prevent a single type node to be
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index 61061a9a..c7556d05 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -55,7 +55,7 @@ if sys.version_info >= (3, 0):
raise TypeError('%r is not a Python function' % func)
return inspect.getfullargspec(func)
-elif sys.version_info >= (2, 5):
+else: # 2.6, 2.7
from functools import partial
def getargspec(func):
"""Like inspect.getargspec but supports functools.partial as well."""
@@ -86,12 +86,7 @@ elif sys.version_info >= (2, 5):
del func_defaults[i]
except IndexError:
pass
- if sys.version_info >= (2, 6):
- return inspect.ArgSpec(args, varargs, varkw, func_defaults)
- else:
- return (args, varargs, varkw, func_defaults)
-else:
- getargspec = inspect.getargspec
+ return inspect.ArgSpec(args, varargs, varkw, func_defaults)
def isdescriptor(x):
diff --git a/sphinx/util/jsonimpl.py b/sphinx/util/jsonimpl.py
index aa0ea825..de846b24 100644
--- a/sphinx/util/jsonimpl.py
+++ b/sphinx/util/jsonimpl.py
@@ -10,27 +10,15 @@
"""
import UserString
+import json
-try:
- import json
- # json-py's json module has no JSONEncoder; this will raise AttributeError
- # if json-py is imported instead of the built-in json module
- JSONEncoder = json.JSONEncoder
-except (ImportError, AttributeError):
- try:
- import simplejson as json
- JSONEncoder = json.JSONEncoder
- except ImportError:
- json = None
- JSONEncoder = object
-
-
-class SphinxJSONEncoder(JSONEncoder):
+
+class SphinxJSONEncoder(json.JSONEncoder):
"""JSONEncoder subclass that forces translation proxies."""
def default(self, obj):
if isinstance(obj, UserString.UserString):
return unicode(obj)
- return JSONEncoder.default(self, obj)
+ return json.JSONEncoder.default(self, obj)
def dump(obj, fp, *args, **kwds):
diff --git a/sphinx/util/osutil.py b/sphinx/util/osutil.py
index 87717771..a5c461a6 100644
--- a/sphinx/util/osutil.py
+++ b/sphinx/util/osutil.py
@@ -69,6 +69,9 @@ def ensuredir(path):
raise
+# This function is same as os.walk of Python2.6, 2.7, 3.2, 3.3 except a
+# customization that check UnicodeError.
+# The customization obstacle to replace the function with the os.walk.
def walk(top, topdown=True, followlinks=False):
"""Backport of os.walk from 2.6, where the *followlinks* argument was
added.
@@ -155,9 +158,8 @@ else:
def safe_relpath(path, start=None):
- from sphinx.util.pycompat import relpath
try:
- return relpath(path, start)
+ return os.path.relpath(path, start)
except ValueError:
return path
@@ -171,14 +173,13 @@ def find_catalog(docname, compaction):
def find_catalog_files(docname, srcdir, locale_dirs, lang, compaction):
- from sphinx.util.pycompat import relpath
if not(lang and locale_dirs):
return []
domain = find_catalog(docname, compaction)
files = [gettext.find(domain, path.join(srcdir, dir_), [lang])
for dir_ in locale_dirs]
- files = [relpath(f, srcdir) for f in files if f]
+ files = [path.relpath(f, srcdir) for f in files if f]
return files
diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py
index 1e5ea314..9941dc0c 100644
--- a/sphinx/util/pycompat.py
+++ b/sphinx/util/pycompat.py
@@ -11,7 +11,6 @@
import sys
import codecs
-import encodings
# ------------------------------------------------------------------------------
# Python 2/3 compatibility
@@ -48,6 +47,7 @@ if sys.version_info >= (3, 0):
# try to match ParseError details with SyntaxError details
raise SyntaxError(err.msg, (filepath, lineno, offset, err.value))
return unicode(tree)
+ from itertools import zip_longest # Python 3 name
else:
# Python 2
@@ -69,6 +69,8 @@ else:
# error handler
import locale
sys_encoding = locale.getpreferredencoding()
+ # use Python 3 name
+ from itertools import izip_longest as zip_longest
def execfile_(filepath, _globals):
@@ -81,8 +83,8 @@ def execfile_(filepath, _globals):
finally:
f.close()
- # py25,py26,py31 accept only LF eol instead of CRLF
- if sys.version_info[:2] in ((2, 5), (2, 6), (3, 1)):
+ # py26 accept only LF eol instead of CRLF
+ if sys.version_info[:2] == (2, 6):
source = source.replace(b('\r\n'), b('\n'))
# compile to a code object, handle syntax errors
@@ -100,178 +102,7 @@ def execfile_(filepath, _globals):
exec code in _globals
-try:
- from html import escape as htmlescape
-except ImportError:
+if sys.version_info >= (3, 2):
+ from html import escape as htmlescape # >= Python 3.2
+else: # 2.6, 2.7, 3.1
from cgi import escape as htmlescape
-
-# ------------------------------------------------------------------------------
-# Missing builtins and itertools in Python < 2.6
-
-if sys.version_info >= (2, 6):
- # Python >= 2.6
- next = next
-
- from itertools import product
- try:
- from itertools import zip_longest # Python 3 name
- except ImportError:
- from itertools import izip_longest as zip_longest
-
- import os
- relpath = os.path.relpath
- del os
-
- import io
- open = io.open
-
-else:
- # Python < 2.6
- from itertools import izip, repeat, chain
-
- # this is on Python 2, where the method is called "next" (it is refactored
- # to __next__ by 2to3, but in that case never executed)
- def next(iterator):
- return iterator.next()
-
- # These replacement functions have been taken from the Python 2.6
- # itertools documentation.
- def product(*args, **kwargs):
- pools = map(tuple, args) * kwargs.get('repeat', 1)
- result = [[]]
- for pool in pools:
- result = [x + [y] for x in result for y in pool]
- for prod in result:
- yield tuple(prod)
-
- def zip_longest(*args, **kwds):
- # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
- fillvalue = kwds.get('fillvalue')
- def sentinel(counter = ([fillvalue]*(len(args)-1)).pop):
- yield counter() # yields the fillvalue, or raises IndexError
- fillers = repeat(fillvalue)
- iters = [chain(it, sentinel(), fillers) for it in args]
- try:
- for tup in izip(*iters):
- yield tup
- except IndexError:
- pass
-
- from os.path import curdir
- def relpath(path, start=curdir):
- """Return a relative version of a path"""
- from os.path import sep, abspath, commonprefix, join, pardir
-
- if not path:
- raise ValueError("no path specified")
-
- start_list = abspath(start).split(sep)
- path_list = abspath(path).split(sep)
-
- # Work out how much of the filepath is shared by start and path.
- i = len(commonprefix([start_list, path_list]))
-
- rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
- if not rel_list:
- return start
- return join(*rel_list)
- del curdir
-
- from types import MethodType
- def open(filename, mode='r', *args, **kw):
- newline = kw.pop('newline', None)
- mode = mode.replace('t', '')
- f = codecs.open(filename, mode, *args, **kw)
- if newline is not None:
- f._write = f.write
- def write(self, text):
- text = text.replace(u'\r\n', u'\n').replace(u'\n', newline)
- self._write(text)
- f.write = MethodType(write, f)
- return f
-
-
-# ------------------------------------------------------------------------------
-# Missing builtins and codecs in Python < 2.5
-
-if sys.version_info >= (2, 5):
- # Python >= 2.5
- base_exception = BaseException
- any = any
- all = all
-
-else:
- # Python 2.4
- base_exception = Exception
-
- def all(gen):
- for i in gen:
- if not i:
- return False
- return True
-
- def any(gen):
- for i in gen:
- if i:
- return True
- return False
-
- # Python 2.4 doesn't know the utf-8-sig encoding, so deliver it here
-
- def my_search_function(encoding):
- norm_encoding = encodings.normalize_encoding(encoding)
- if norm_encoding != 'utf_8_sig':
- return None
- return (encode, decode, StreamReader, StreamWriter)
-
- codecs.register(my_search_function)
-
- # begin code copied from utf_8_sig.py in Python 2.6
-
- def encode(input, errors='strict'):
- return (codecs.BOM_UTF8 +
- codecs.utf_8_encode(input, errors)[0], len(input))
-
- def decode(input, errors='strict'):
- prefix = 0
- if input[:3] == codecs.BOM_UTF8:
- input = input[3:]
- prefix = 3
- (output, consumed) = codecs.utf_8_decode(input, errors, True)
- return (output, consumed+prefix)
-
- class StreamWriter(codecs.StreamWriter):
- def reset(self):
- codecs.StreamWriter.reset(self)
- try:
- del self.encode
- except AttributeError:
- pass
-
- def encode(self, input, errors='strict'):
- self.encode = codecs.utf_8_encode
- return encode(input, errors)
-
- class StreamReader(codecs.StreamReader):
- def reset(self):
- codecs.StreamReader.reset(self)
- try:
- del self.decode
- except AttributeError:
- pass
-
- def decode(self, input, errors='strict'):
- if len(input) < 3:
- if codecs.BOM_UTF8.startswith(input):
- # not enough data to decide if this is a BOM
- # => try again on the next call
- return (u"", 0)
- elif input[:3] == codecs.BOM_UTF8:
- self.decode = codecs.utf_8_decode
- (output, consumed) = codecs.utf_8_decode(input[3:],errors)
- return (output, consumed+3)
- # (else) no BOM present
- self.decode = codecs.utf_8_decode
- return codecs.utf_8_decode(input, errors)
-
- # end code copied from utf_8_sig.py
diff --git a/sphinx/versioning.py b/sphinx/versioning.py
index a16751bb..ccab41d4 100644
--- a/sphinx/versioning.py
+++ b/sphinx/versioning.py
@@ -11,8 +11,9 @@
"""
from uuid import uuid4
from operator import itemgetter
+from itertools import product
-from sphinx.util.pycompat import product, zip_longest, all
+from sphinx.util.pycompat import zip_longest
# anything below that ratio is considered equal/changed
diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py
index 41663a0c..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
@@ -508,6 +511,11 @@ class HTMLTranslator(BaseTranslator):
def depart_literal_emphasis(self, node):
return self.depart_emphasis(node)
+ def visit_literal_strong(self, node):
+ return self.visit_strong(node)
+ def depart_literal_strong(self, node):
+ return self.depart_strong(node)
+
def visit_abbreviation(self, node):
attrs = {}
if node.hasattr('explanation'):
@@ -618,6 +626,14 @@ class SmartyPantsHTMLTranslator(HTMLTranslator):
self.depart_emphasis(node)
self.no_smarty -= 1
+ def visit_literal_strong(self, node):
+ self.no_smarty += 1
+ self.visit_strong(node)
+
+ def depart_literal_strong(self, node):
+ self.depart_strong(node)
+ self.no_smarty -= 1
+
def visit_desc_signature(self, node):
self.no_smarty += 1
HTMLTranslator.visit_desc_signature(self, node)
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index 3c1a50f8..61aa5828 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -25,7 +25,6 @@ from sphinx.errors import SphinxError
from sphinx.locale import admonitionlabels, _
from sphinx.util import split_into
from sphinx.util.osutil import ustrftime
-from sphinx.util.pycompat import any
from sphinx.util.texescape import tex_escape_map, tex_replace_map
from sphinx.util.smartypants import educate_quotes_latex
@@ -1247,6 +1246,13 @@ class LaTeXTranslator(nodes.NodeVisitor):
def depart_strong(self, node):
self.body.append('}')
+ def visit_literal_strong(self, node):
+ self.body.append(r'\textbf{\texttt{')
+ self.no_contractions += 1
+ def depart_literal_strong(self, node):
+ self.body.append('}}')
+ self.no_contractions -= 1
+
def visit_abbreviation(self, node):
abbr = node.astext()
self.body.append(r'\textsc{')
@@ -1331,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/sphinx/writers/manpage.py b/sphinx/writers/manpage.py
index bc4da17a..0aa0058c 100644
--- a/sphinx/writers/manpage.py
+++ b/sphinx/writers/manpage.py
@@ -304,6 +304,11 @@ class ManualPageTranslator(BaseTranslator):
def depart_literal_emphasis(self, node):
return self.depart_emphasis(node)
+ def visit_literal_strong(self, node):
+ return self.visit_strong(node)
+ def depart_literal_strong(self, node):
+ return self.depart_strong(node)
+
def visit_abbreviation(self, node):
pass
def depart_abbreviation(self, node):
diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py
index 7b70485a..a930a525 100644
--- a/sphinx/writers/texinfo.py
+++ b/sphinx/writers/texinfo.py
@@ -1207,6 +1207,11 @@ class TexinfoTranslator(nodes.NodeVisitor):
def depart_literal_emphasis(self, node):
self.body.append('}')
+ def visit_literal_strong(self, node):
+ self.body.append('@code{')
+ def depart_literal_strong(self, node):
+ self.body.append('}')
+
def visit_index(self, node):
# terminate the line but don't prevent paragraph breaks
if isinstance(node.parent, nodes.paragraph):
diff --git a/sphinx/writers/text.py b/sphinx/writers/text.py
index 57a40b29..a174bc26 100644
--- a/sphinx/writers/text.py
+++ b/sphinx/writers/text.py
@@ -762,6 +762,11 @@ class TextTranslator(nodes.NodeVisitor):
def depart_strong(self, node):
self.add_text('**')
+ def visit_literal_strong(self, node):
+ self.add_text('**')
+ def depart_literal_strong(self, node):
+ self.add_text('**')
+
def visit_abbreviation(self, node):
self.add_text('')
def depart_abbreviation(self, node):