[Python-checkins] cpython (2.7): Closes #22537: Make sphinx extensions compatible with Python 2 or 3, like in

georg.brandl python-checkins at python.org
Thu Oct 2 08:27:26 CEST 2014


https://hg.python.org/cpython/rev/fd2530294d50
changeset:   92738:fd2530294d50
branch:      2.7
parent:      92735:1a36d4e8cf4e
user:        Georg Brandl <georg at python.org>
date:        Thu Oct 02 08:26:26 2014 +0200
summary:
  Closes #22537: Make sphinx extensions compatible with Python 2 or 3, like in the 3.x branches

files:
  Doc/conf.py             |   3 +
  Doc/tools/patchlevel.py |   2 +-
  Doc/tools/pyspecific.py |  64 +++-------------------------
  Doc/tools/suspicious.py |  52 ++++++++++++++++-------
  4 files changed, 47 insertions(+), 74 deletions(-)


diff --git a/Doc/conf.py b/Doc/conf.py
--- 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
--- 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
--- 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
--- 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()

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list