Closes #22537: Make sphinx extensions compatible with Python 2 or 3, like in the 3.x branches
diff --git a/Doc/conf.py b/Doc/conf.py
index 4051a56..8bf52f7 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -59,6 +59,9 @@
# unit titles (such as .. function::).
add_module_names = True
+# Require Sphinx 1.2 for build.
+needs_sphinx = '1.2'
+
# Options for HTML output
# -----------------------
diff --git a/Doc/tools/patchlevel.py b/Doc/tools/patchlevel.py
index 082858e..b070d60 100644
--- a/Doc/tools/patchlevel.py
+++ b/Doc/tools/patchlevel.py
@@ -68,4 +68,4 @@
return version, release
if __name__ == '__main__':
- print get_header_version_info('.')[1]
+ print(get_header_version_info('.')[1])
diff --git a/Doc/tools/pyspecific.py b/Doc/tools/pyspecific.py
index 30178eb..8f0d090 100644
--- a/Doc/tools/pyspecific.py
+++ b/Doc/tools/pyspecific.py
@@ -5,7 +5,7 @@
Sphinx extension with Python doc-specific markup.
- :copyright: 2008-2013 by Georg Brandl.
+ :copyright: 2008-2014 by Georg Brandl.
:license: Python license.
"""
@@ -14,11 +14,10 @@
from docutils import nodes, utils
-import sphinx
from sphinx.util.nodes import split_explicit_title
+from sphinx.util.compat import Directive
from sphinx.writers.html import HTMLTranslator
from sphinx.writers.latex import LaTeXTranslator
-from sphinx.locale import versionlabels
# monkey-patch reST parser to disable alphabetic and roman enumerated lists
from docutils.parsers.rst.states import Body
@@ -27,18 +26,6 @@
Body.enum.converters['lowerroman'] = \
Body.enum.converters['upperroman'] = lambda x: None
-if sphinx.__version__[:3] < '1.2':
- # monkey-patch HTML translator to give versionmodified paragraphs a class
- def new_visit_versionmodified(self, node):
- self.body.append(self.starttag(node, 'p', CLASS=node['type']))
- text = versionlabels[node['type']] % node['version']
- if len(node):
- text += ': '
- else:
- text += '.'
- self.body.append('<span class="versionmodified">%s</span>' % text)
- HTMLTranslator.visit_versionmodified = new_visit_versionmodified
-
# monkey-patch HTML and LaTeX translators to keep doctest blocks in the
# doctest docs themselves
orig_visit_literal_block = HTMLTranslator.visit_literal_block
@@ -88,8 +75,6 @@
# Support for marking up implementation details
-from sphinx.util.compat import Directive
-
class ImplementationDetail(Directive):
has_content = True
@@ -140,41 +125,6 @@
return PyClassmember.run(self)
-# Support for documenting version of removal in deprecations
-
-from sphinx.locale import versionlabels
-from sphinx.util.compat import Directive
-
-versionlabels['deprecated-removed'] = \
- 'Deprecated since version %s, will be removed in version %s'
-
-class DeprecatedRemoved(Directive):
- has_content = True
- required_arguments = 2
- optional_arguments = 1
- final_argument_whitespace = True
- option_spec = {}
-
- def run(self):
- node = addnodes.versionmodified()
- node.document = self.state.document
- node['type'] = 'deprecated-removed'
- version = (self.arguments[0], self.arguments[1])
- node['version'] = version
- if len(self.arguments) == 3:
- inodes, messages = self.state.inline_text(self.arguments[2],
- self.lineno+1)
- node.extend(inodes)
- if self.content:
- self.state.nested_parse(self.content, self.content_offset, node)
- ret = [node] + messages
- else:
- ret = [node]
- env = self.state.document.settings.env
- env.note_versionchange('deprecated', version[0], node, self.lineno)
- return ret
-
-
# Support for building "topic help" for pydoc
pydoc_topic_labels = [
@@ -231,13 +181,14 @@
document.append(doctree.ids[labelid])
destination = StringOutput(encoding='utf-8')
writer.write(document, destination)
- self.topics[label] = str(writer.output)
+ self.topics[label] = writer.output
def finish(self):
- f = open(path.join(self.outdir, 'topics.py'), 'w')
+ f = open(path.join(self.outdir, 'topics.py'), 'wb')
try:
- f.write('# Autogenerated by Sphinx on %s\n' % asctime())
- f.write('topics = ' + pformat(self.topics) + '\n')
+ f.write('# -*- coding: utf-8 -*-\n'.encode('utf-8'))
+ f.write(('# Autogenerated by Sphinx on %s\n' % asctime()).encode('utf-8'))
+ f.write(('topics = ' + pformat(self.topics) + '\n').encode('utf-8'))
finally:
f.close()
@@ -295,7 +246,6 @@
app.add_role('issue', issue_role)
app.add_role('source', source_role)
app.add_directive('impl-detail', ImplementationDetail)
- app.add_directive('deprecated-removed', DeprecatedRemoved)
app.add_builder(PydocTopicsBuilder)
app.add_builder(suspicious.CheckSuspiciousMarkupBuilder)
app.add_description_unit('opcode', 'opcode', '%s (opcode)',
diff --git a/Doc/tools/suspicious.py b/Doc/tools/suspicious.py
index e397560..ee87733 100644
--- a/Doc/tools/suspicious.py
+++ b/Doc/tools/suspicious.py
@@ -49,13 +49,15 @@
from docutils import nodes
from sphinx.builders import Builder
-detect_all = re.compile(ur'''
+detect_all = re.compile(r'''
::(?=[^=])| # two :: (but NOT ::=)
:[a-zA-Z][a-zA-Z0-9]+| # :foo
`| # ` (seldom used by itself)
(?<!\.)\.\.[ \t]*\w+: # .. foo: (but NOT ... else:)
''', re.UNICODE | re.VERBOSE).finditer
+py3 = sys.version_info >= (3, 0)
+
class Rule:
def __init__(self, docname, lineno, issue, line):
@@ -147,7 +149,11 @@
if not self.any_issue: self.info()
self.any_issue = True
self.write_log_entry(lineno, issue, text)
- self.warn('[%s:%d] "%s" found in "%-.120s"' % (
+ if py3:
+ self.warn('[%s:%d] "%s" found in "%-.120s"' %
+ (self.docname, lineno, issue, text))
+ else:
+ self.warn('[%s:%d] "%s" found in "%-.120s"' % (
self.docname.encode(sys.getdefaultencoding(),'replace'),
lineno,
issue.encode(sys.getdefaultencoding(),'replace'),
@@ -155,13 +161,19 @@
self.app.statuscode = 1
def write_log_entry(self, lineno, issue, text):
- f = open(self.log_file_name, 'ab')
- writer = csv.writer(f, dialect)
- writer.writerow([self.docname.encode('utf-8'),
- lineno,
- issue.encode('utf-8'),
- text.strip().encode('utf-8')])
- f.close()
+ if py3:
+ f = open(self.log_file_name, 'a')
+ writer = csv.writer(f, dialect)
+ writer.writerow([self.docname, lineno, issue, text.strip()])
+ f.close()
+ else:
+ f = open(self.log_file_name, 'ab')
+ writer = csv.writer(f, dialect)
+ writer.writerow([self.docname.encode('utf-8'),
+ lineno,
+ issue.encode('utf-8'),
+ text.strip().encode('utf-8')])
+ f.close()
def load_rules(self, filename):
"""Load database of previously ignored issues.
@@ -171,18 +183,26 @@
"""
self.info("loading ignore rules... ", nonl=1)
self.rules = rules = []
- try: f = open(filename, 'rb')
- except IOError: return
+ try:
+ if py3:
+ f = open(filename, 'r')
+ else:
+ f = open(filename, 'rb')
+ except IOError:
+ return
for i, row in enumerate(csv.reader(f)):
if len(row) != 4:
raise ValueError(
"wrong format in %s, line %d: %s" % (filename, i+1, row))
docname, lineno, issue, text = row
- docname = docname.decode('utf-8')
- if lineno: lineno = int(lineno)
- else: lineno = None
- issue = issue.decode('utf-8')
- text = text.decode('utf-8')
+ if lineno:
+ lineno = int(lineno)
+ else:
+ lineno = None
+ if not py3:
+ docname = docname.decode('utf-8')
+ issue = issue.decode('utf-8')
+ text = text.decode('utf-8')
rule = Rule(docname, lineno, issue, text)
rules.append(rule)
f.close()