summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--setup.py2
-rw-r--r--sphinx/application.py6
-rw-r--r--sphinx/cmdline.py7
-rw-r--r--sphinx/config.py9
-rw-r--r--sphinx/environment.py4
-rw-r--r--sphinx/ext/autodoc.py10
-rw-r--r--sphinx/ext/doctest.py7
-rw-r--r--sphinx/ext/napoleon/__init__.py7
-rw-r--r--sphinx/ext/napoleon/docstring.py8
-rw-r--r--sphinx/ext/napoleon/iterators.py5
-rw-r--r--sphinx/highlighting.py5
-rw-r--r--sphinx/locale/__init__.py5
-rw-r--r--sphinx/pycode/__init__.py8
-rw-r--r--sphinx/quickstart.py8
-rw-r--r--sphinx/setup_command.py5
-rw-r--r--sphinx/util/__init__.py5
-rw-r--r--sphinx/util/inspect.py13
-rw-r--r--sphinx/util/osutil.py6
-rw-r--r--sphinx/util/pycompat.py31
-rw-r--r--sphinx/versioning.py4
-rwxr-xr-xtests/path.py4
-rw-r--r--tests/roots/test-autosummary/contents.rst12
-rwxr-xr-xtests/run.py5
-rw-r--r--tests/test_application.py10
-rw-r--r--tests/test_autodoc.py6
-rw-r--r--tests/test_build_html.py8
-rw-r--r--tests/test_build_latex.py8
-rw-r--r--tests/test_build_texinfo.py8
-rw-r--r--tests/test_config.py4
-rw-r--r--tests/test_doctest.py5
-rw-r--r--tests/test_docutilsconf.py5
-rw-r--r--tests/test_env.py4
-rw-r--r--tests/test_intersphinx.py11
-rw-r--r--tests/test_intl.py5
-rw-r--r--tests/test_quickstart.py10
-rw-r--r--tests/test_searchadapters.py7
-rw-r--r--tests/test_websupport.py7
-rw-r--r--tests/util.py5
38 files changed, 142 insertions, 137 deletions
diff --git a/setup.py b/setup.py
index a92c93b45..92c489fbb 100644
--- a/setup.py
+++ b/setup.py
@@ -45,7 +45,7 @@ if sys.version_info < (2, 6) or (3, 0) <= sys.version_info < (3, 2):
print('ERROR: Sphinx requires at least Python 2.6 or 3.2 to run.')
sys.exit(1)
-requires = ['Pygments>=1.2', 'docutils>=0.10', 'snowballstemmer>=1.1']
+requires = ['six', 'Pygments>=1.2', 'docutils>=0.10', 'snowballstemmer>=1.1']
if (3, 0) <= sys.version_info < (3, 3):
requires.append('Jinja2>=2.3,<2.7')
diff --git a/sphinx/application.py b/sphinx/application.py
index 89d1d7869..4b1177156 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -18,8 +18,8 @@ import types
import posixpath
import traceback
from os import path
-from cStringIO import StringIO
+import six
from docutils import nodes
from docutils.parsers.rst import convert_directive_function, \
directives, roles
@@ -84,14 +84,14 @@ class Sphinx(object):
self.parallel = parallel
if status is None:
- self._status = StringIO()
+ self._status = six.cStringIO()
self.quiet = True
else:
self._status = status
self.quiet = False
if warning is None:
- self._warning = StringIO()
+ self._warning = six.cStringIO()
else:
self._warning = warning
self._warncount = 0
diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py
index 07551e67e..377f2385e 100644
--- a/sphinx/cmdline.py
+++ b/sphinx/cmdline.py
@@ -16,6 +16,7 @@ import getopt
import traceback
from os import path
+import six
from docutils.utils import SystemMessage
from sphinx import __version__
@@ -24,7 +25,7 @@ from sphinx.application import Sphinx
from sphinx.util import Tee, format_exception_cut_frames, save_traceback
from sphinx.util.console import red, nocolor, color_terminal
from sphinx.util.osutil import abspath, fs_encoding
-from sphinx.util.pycompat import terminal_safe, bytes
+from sphinx.util.pycompat import terminal_safe
def usage(argv, msg=None):
@@ -183,7 +184,7 @@ def main(argv):
print('Error: -D option argument must be in the form name=value.',
file=sys.stderr)
return 1
- if likely_encoding and isinstance(val, bytes):
+ if likely_encoding and isinstance(val, six.binary_type):
try:
val = val.decode(likely_encoding)
except UnicodeError:
@@ -199,7 +200,7 @@ def main(argv):
try:
val = int(val)
except ValueError:
- if likely_encoding and isinstance(val, bytes):
+ if likely_encoding and isinstance(val, six.binary_type):
try:
val = val.decode(likely_encoding)
except UnicodeError:
diff --git a/sphinx/config.py b/sphinx/config.py
index 527ea453d..6cbbd6410 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -11,18 +11,19 @@
import os
import re
-import sys
from os import path
+import six
+
from sphinx.errors import ConfigError
from sphinx.locale import l_
from sphinx.util.osutil import make_filename
-from sphinx.util.pycompat import bytes, b, execfile_
+from sphinx.util.pycompat import b, execfile_
nonascii_re = re.compile(b(r'[\x80-\xff]'))
CONFIG_SYNTAX_ERROR = "There is a syntax error in your configuration file: %s"
-if sys.version_info >= (3, 0):
+if six.PY3:
CONFIG_SYNTAX_ERROR += "\nDid you change the syntax from 2.x to 3.x?"
class Config(object):
@@ -243,7 +244,7 @@ class Config(object):
# check all string values for non-ASCII characters in bytestrings,
# since that can result in UnicodeErrors all over the place
for name, value in self._raw_config.iteritems():
- if isinstance(value, bytes) and nonascii_re.search(value):
+ if isinstance(value, six.binary_type) and nonascii_re.search(value):
warn('the config value %r is set to a string with non-ASCII '
'characters; this can lead to Unicode errors occurring. '
'Please use Unicode strings, e.g. %r.' % (name, u'Content')
diff --git a/sphinx/environment.py b/sphinx/environment.py
index a0fb87dad..195ae724b 100644
--- a/sphinx/environment.py
+++ b/sphinx/environment.py
@@ -23,6 +23,7 @@ from os import path
from glob import glob
from itertools import izip, groupby
+import six
from docutils import nodes
from docutils.io import FileInput, NullOutput
from docutils.core import Publisher
@@ -39,7 +40,6 @@ from sphinx.util import url_re, get_matching_docs, docname_join, split_into, \
from sphinx.util.nodes import clean_astext, make_refnode, WarningStream
from sphinx.util.osutil import SEP, fs_encoding, find_catalog_files
from sphinx.util.matching import compile_matchers
-from sphinx.util.pycompat import class_types
from sphinx.util.websupport import is_commentable
from sphinx.errors import SphinxError, ExtensionError
from sphinx.locale import _
@@ -140,7 +140,7 @@ class BuildEnvironment:
if key.startswith('_') or \
isinstance(val, types.ModuleType) or \
isinstance(val, types.FunctionType) or \
- isinstance(val, class_types):
+ isinstance(val, six.class_types):
del self.config[key]
try:
pickle.dump(self, picklefile, pickle.HIGHEST_PROTOCOL)
diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py
index a79849aef..1fc2a3db3 100644
--- a/sphinx/ext/autodoc.py
+++ b/sphinx/ext/autodoc.py
@@ -17,6 +17,7 @@ import inspect
import traceback
from types import FunctionType, BuiltinFunctionType, MethodType
+import six
from docutils import nodes
from docutils.utils import assemble_option_dict
from docutils.statemachine import ViewList
@@ -29,7 +30,6 @@ 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 class_types
from sphinx.util.docstrings import prepare_docstring
@@ -1028,7 +1028,7 @@ class ClassDocumenter(ModuleLevelDocumenter):
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
- return isinstance(member, class_types)
+ return isinstance(member, six.class_types)
def import_object(self):
ret = ModuleLevelDocumenter.import_object(self)
@@ -1162,7 +1162,7 @@ class ExceptionDocumenter(ClassDocumenter):
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
- return isinstance(member, class_types) and \
+ return isinstance(member, six.class_types) and \
issubclass(member, BaseException)
@@ -1212,7 +1212,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter):
return inspect.isroutine(member) and \
not isinstance(parent, ModuleDocumenter)
- if sys.version_info >= (3, 0):
+ if six.PY3:
def import_object(self):
ret = ClassLevelDocumenter.import_object(self)
obj_from_parent = self.parent.__dict__.get(self.object_name)
@@ -1282,7 +1282,7 @@ class AttributeDocumenter(ClassLevelDocumenter):
"instancemethod")
return isdatadesc or (not isinstance(parent, ModuleDocumenter)
and not inspect.isroutine(member)
- and not isinstance(member, class_types))
+ and not isinstance(member, six.class_types))
def document_members(self, all_members=False):
pass
diff --git a/sphinx/ext/doctest.py b/sphinx/ext/doctest.py
index ef27dc119..6484677ca 100644
--- a/sphinx/ext/doctest.py
+++ b/sphinx/ext/doctest.py
@@ -14,11 +14,11 @@ import re
import sys
import time
import codecs
-import StringIO
from os import path
# circumvent relative import
doctest = __import__('doctest')
+import six
from docutils import nodes
from docutils.parsers.rst import directives
@@ -27,7 +27,6 @@ from sphinx.util import force_decode
from sphinx.util.nodes import set_source_info
from sphinx.util.compat import Directive
from sphinx.util.console import bold
-from sphinx.util.pycompat import bytes
blankline_re = re.compile(r'^\s*<BLANKLINE>', re.MULTILINE)
doctestopt_re = re.compile(r'#\s*doctest:.+$', re.MULTILINE)
@@ -158,7 +157,7 @@ class TestCode(object):
class SphinxDocTestRunner(doctest.DocTestRunner):
def summarize(self, out, verbose=None):
- string_io = StringIO.StringIO()
+ string_io = six.StringIO()
old_stdout = sys.stdout
sys.stdout = string_io
try:
@@ -233,7 +232,7 @@ Results of doctest builder run on %s
self.info(text, nonl=True)
if self.app.quiet:
self.warn(text)
- if isinstance(text, bytes):
+ if isinstance(text, six.binary_type):
text = force_decode(text, None)
self.outfile.write(text)
diff --git a/sphinx/ext/napoleon/__init__.py b/sphinx/ext/napoleon/__init__.py
index 96ca81a56..c6fd3c349 100644
--- a/sphinx/ext/napoleon/__init__.py
+++ b/sphinx/ext/napoleon/__init__.py
@@ -10,6 +10,9 @@
"""
import sys
+
+import six
+
from sphinx.ext.napoleon.docstring import GoogleDocstring, NumpyDocstring
@@ -346,12 +349,12 @@ def _skip_member(app, what, name, obj, skip, options):
if name != '__weakref__' and name != '__init__' and has_doc and is_member:
cls_is_owner = False
if what == 'class' or what == 'exception':
- if sys.version_info[0] < 3:
+ if six.PY2:
cls = getattr(obj, 'im_class', getattr(obj, '__objclass__',
None))
cls_is_owner = (cls and hasattr(cls, name) and
name in cls.__dict__)
- elif sys.version_info[1] >= 3:
+ elif sys.version_info >= (3, 3):
qualname = getattr(obj, '__qualname__', '')
cls_path, _, _ = qualname.rpartition('.')
if cls_path:
diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py
index 2819ffe34..dea55c629 100644
--- a/sphinx/ext/napoleon/docstring.py
+++ b/sphinx/ext/napoleon/docstring.py
@@ -14,11 +14,13 @@
import collections
import inspect
import re
-import sys
+
+import six
+
from sphinx.ext.napoleon.iterators import modify_iter
-if sys.version_info[0] >= 3:
+if six.PY3:
basestring = str
xrange = range
@@ -160,7 +162,7 @@ class GoogleDocstring(object):
UTF-8 encoded version of the docstring.
"""
- if sys.version_info[0] >= 3:
+ if six.PY3:
return self.__unicode__()
else:
return self.__unicode__().encode('utf8')
diff --git a/sphinx/ext/napoleon/iterators.py b/sphinx/ext/napoleon/iterators.py
index 2f1904dab..7db350b77 100644
--- a/sphinx/ext/napoleon/iterators.py
+++ b/sphinx/ext/napoleon/iterators.py
@@ -12,10 +12,11 @@
"""
import collections
-import sys
+import six
-if sys.version_info[0] >= 3:
+
+if six.PY3:
callable = lambda o: hasattr(o, '__call__')
diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py
index b5779ab42..6e5ada6f5 100644
--- a/sphinx/highlighting.py
+++ b/sphinx/highlighting.py
@@ -9,7 +9,6 @@
:license: BSD, see LICENSE for details.
"""
-import sys
import re
import textwrap
@@ -19,6 +18,8 @@ except ImportError:
# parser is not available on Jython
parser = None
+import six
+
from sphinx.util.pycompat import htmlescape
from sphinx.util.texescape import tex_hl_escape_map_new
from sphinx.ext import doctest
@@ -131,7 +132,7 @@ 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 sys.version_info < (3, 0) and isinstance(src, unicode):
+ if six.PY2 and isinstance(src, unicode):
# Non-ASCII chars will only occur in string literals
# and comments. If we wanted to give them to the parser
# correctly, we'd have to find out the correct source
diff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py
index b76aab1f7..fc2ffedb6 100644
--- a/sphinx/locale/__init__.py
+++ b/sphinx/locale/__init__.py
@@ -9,10 +9,11 @@
:license: BSD, see LICENSE for details.
"""
-import sys
import gettext
import UserString
+import six
+
class _TranslationProxy(UserString.UserString, object):
"""
@@ -183,7 +184,7 @@ pairindextypes = {
translators = {}
-if sys.version_info >= (3, 0):
+if six.PY3:
def _(message):
return translators['sphinx'].gettext(message)
else:
diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py
index b735fb31b..53223d250 100644
--- a/sphinx/pycode/__init__.py
+++ b/sphinx/pycode/__init__.py
@@ -13,12 +13,14 @@ from __future__ import print_function
import sys
from os import path
+import six
+
from sphinx import package_dir
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 StringIO, BytesIO, TextIOWrapper
+from sphinx.util.pycompat import TextIOWrapper
from sphinx.util.docstrings import prepare_docstring, prepare_commentdoc
@@ -174,8 +176,8 @@ class ModuleAnalyzer(object):
@classmethod
def for_string(cls, string, modname, srcname='<string>'):
if isinstance(string, bytes):
- return cls(BytesIO(string), modname, srcname)
- return cls(StringIO(string), modname, srcname, decoded=True)
+ return cls(six.BytesIO(string), modname, srcname)
+ return cls(six.StringIO(string), modname, srcname, decoded=True)
@classmethod
def for_file(cls, filename, modname):
diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py
index e480923d5..180066e00 100644
--- a/sphinx/quickstart.py
+++ b/sphinx/quickstart.py
@@ -16,6 +16,8 @@ from io import open
TERM_ENCODING = getattr(sys.stdin, 'encoding', None)
+import six
+
#try to import readline, unix specific enhancement
try:
import readline
@@ -44,7 +46,7 @@ except NameError:
PROMPT_PREFIX = '> '
-if sys.version_info >= (3, 0):
+if six.PY3:
# prevents that the file is checked for being written in Python 2.x syntax
QUICKSTART_CONF = u'#!/usr/bin/env python3\n'
else:
@@ -997,7 +999,7 @@ def do_prompt(d, key, text, default=None, validator=nonempty):
prompt = PROMPT_PREFIX + '%s [%s]: ' % (text, default)
else:
prompt = PROMPT_PREFIX + text + ': '
- if sys.version_info < (3, 0):
+ if six.PY2:
# for Python 2.x, try to get a Unicode string out of it
if prompt.encode('ascii', 'replace').decode('ascii', 'replace') \
!= prompt:
@@ -1037,7 +1039,7 @@ def do_prompt(d, key, text, default=None, validator=nonempty):
d[key] = x
-if sys.version_info >= (3, 0):
+if six.PY3:
# remove Unicode literal prefixes
def _convert_python_source(source, rex=re.compile(r"[uU]('.*?')")):
return rex.sub('\\1', source)
diff --git a/sphinx/setup_command.py b/sphinx/setup_command.py
index deb8ceabc..029a44c24 100644
--- a/sphinx/setup_command.py
+++ b/sphinx/setup_command.py
@@ -16,10 +16,11 @@ from __future__ import print_function
import sys
import os
import types
-from StringIO import StringIO
from distutils.cmd import Command
from distutils.errors import DistutilsOptionError
+import six
+
from sphinx.application import Sphinx
from sphinx.util.console import darkred, nocolor, color_terminal
from sphinx.util.osutil import abspath
@@ -141,7 +142,7 @@ class BuildDoc(Command):
# Windows' poor cmd box doesn't understand ANSI sequences
nocolor()
if not self.verbose:
- status_stream = StringIO()
+ status_stream = six.StringIO()
else:
status_stream = sys.stdout
confoverrides = {}
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index 06c6ce244..3c9366a17 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -12,7 +12,6 @@
import os
import re
import sys
-import shutil
import fnmatch
import tempfile
import posixpath
@@ -22,6 +21,7 @@ from os import path
from codecs import open, BOM_UTF8
from collections import deque
+import six
import docutils
from docutils.utils import relative_path
@@ -29,7 +29,6 @@ import jinja2
import sphinx
from sphinx.errors import PycodeError
-from sphinx.util.pycompat import bytes
# import other utilities; partly for backwards compatibility, so don't
# prune unused ones indiscriminately
@@ -336,7 +335,7 @@ def parselinenos(spec, total):
def force_decode(string, encoding):
"""Forcibly get a unicode string out of a bytestring."""
- if isinstance(string, bytes):
+ if isinstance(string, six.binary_type):
try:
if encoding:
string = string.decode(encoding)
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index e71328744..7cf0be38a 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -9,17 +9,16 @@
:license: BSD, see LICENSE for details.
"""
-import sys
-
# this imports the standard library inspect module without resorting to
# relatively import this module
inspect = __import__('inspect')
+import six
+
from sphinx.util import force_decode
-from sphinx.util.pycompat import bytes, builtins
-if sys.version_info >= (3, 0):
+if six.PY3:
from functools import partial
def getargspec(func):
"""Like inspect.getargspec but supports functools.partial as well."""
@@ -129,7 +128,7 @@ def safe_repr(object):
s = repr(object)
except Exception:
raise ValueError
- if isinstance(s, bytes):
+ if isinstance(s, six.binary_type):
return force_decode(s, None).replace('\n', ' ')
return s.replace('\n', ' ')
@@ -146,6 +145,6 @@ def is_builtin_class_method(obj, attr_name):
classes = [c for c in inspect.getmro(obj) if attr_name in c.__dict__]
cls = classes[0] if classes else object
- if not hasattr(builtins, safe_getattr(cls, '__name__', '')):
+ if not hasattr(six.moves.builtins, safe_getattr(cls, '__name__', '')):
return False
- return getattr(builtins, safe_getattr(cls, '__name__', '')) is cls
+ return getattr(six.moves.builtins, safe_getattr(cls, '__name__', '')) is cls
diff --git a/sphinx/util/osutil.py b/sphinx/util/osutil.py
index 496a2a41f..00cc1ae31 100644
--- a/sphinx/util/osutil.py
+++ b/sphinx/util/osutil.py
@@ -20,6 +20,8 @@ import shutil
import gettext
from os import path
+import six
+
# Errnos that we need.
EEXIST = getattr(errno, 'EEXIST', 0)
ENOENT = getattr(errno, 'ENOENT', 0)
@@ -147,7 +149,7 @@ no_fn_re = re.compile(r'[^a-zA-Z0-9_-]')
def make_filename(string):
return no_fn_re.sub('', string) or 'sphinx'
-if sys.version_info < (3, 0):
+if six.PY2:
# strftime for unicode strings
def ustrftime(format, *args):
# if a locale is set, the time strings are encoded in the encoding
@@ -187,7 +189,7 @@ def find_catalog_files(docname, srcdir, locale_dirs, lang, compaction):
fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
-if sys.version_info < (3, 0):
+if six.PY2:
bytes = str
else:
bytes = bytes
diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py
index 8cc7c5de4..8d1b3d061 100644
--- a/sphinx/util/pycompat.py
+++ b/sphinx/util/pycompat.py
@@ -12,20 +12,19 @@
import sys
import codecs
+import six
+
# ------------------------------------------------------------------------------
# Python 2/3 compatibility
-if sys.version_info >= (3, 0):
+if six.PY3:
# Python 3
- class_types = (type,)
# the ubiquitous "bytes" helper functions
def b(s):
return s.encode('utf-8')
- bytes = bytes
# prefix for Unicode strings
u = ''
- # StringIO/BytesIO classes
- from io import StringIO, BytesIO, TextIOWrapper
+ from io import TextIOWrapper
# safely encode a string for printing to the terminal
def terminal_safe(s):
return s.encode('ascii', 'backslashreplace').decode('ascii')
@@ -47,18 +46,12 @@ 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
- import builtins
+ from html import escape as htmlescape # >= Python 3.2
else:
# Python 2
- from types import ClassType
- class_types = (type, ClassType)
b = str
- bytes = str
u = 'u'
- from StringIO import StringIO
- BytesIO = StringIO
# no need to refactor on 2.x versions
convert_with_2to3 = None
def TextIOWrapper(stream, encoding):
@@ -68,11 +61,9 @@ else:
return s.encode('ascii', 'backslashreplace')
# some kind of default system encoding; should be used with a lenient
# error handler
- import locale
- sys_encoding = locale.getpreferredencoding()
+ sys_encoding = __import__('locale').getpreferredencoding()
# use Python 3 name
- from itertools import izip_longest as zip_longest
- import __builtin__ as builtins
+ from cgi import escape as htmlescape # 2.6, 2.7
def execfile_(filepath, _globals):
@@ -101,10 +92,4 @@ def execfile_(filepath, _globals):
code = compile(source, filepath_enc, 'exec')
else:
raise
- exec code in _globals
-
-
-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
+ six.exec_(code, _globals)
diff --git a/sphinx/versioning.py b/sphinx/versioning.py
index a41de0f09..8cc618e8d 100644
--- a/sphinx/versioning.py
+++ b/sphinx/versioning.py
@@ -13,7 +13,7 @@ from uuid import uuid4
from operator import itemgetter
from itertools import product
-from sphinx.util.pycompat import zip_longest
+import six
# anything below that ratio is considered equal/changed
@@ -52,7 +52,7 @@ def merge_doctrees(old, new, condition):
ratios = {}
seen = set()
# compare the nodes each doctree in order
- for old_node, new_node in zip_longest(old_iter, new_iter):
+ for old_node, new_node in six.moves.zip_longest(old_iter, new_iter):
if old_node is None:
new_nodes.append(new_node)
continue
diff --git a/tests/path.py b/tests/path.py
index f40e7b043..860e65e18 100755
--- a/tests/path.py
+++ b/tests/path.py
@@ -12,6 +12,8 @@ import sys
import shutil
from codecs import open
+import six
+
FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding()
@@ -20,7 +22,7 @@ class path(unicode):
"""
Represents a path which behaves like a string.
"""
- if sys.version_info < (3, 0):
+ if six.PY2:
def __new__(cls, s, encoding=FILESYSTEMENCODING, errors='strict'):
if isinstance(s, str):
s = s.decode(encoding, errors)
diff --git a/tests/roots/test-autosummary/contents.rst b/tests/roots/test-autosummary/contents.rst
index 3f16af998..32390a32e 100644
--- a/tests/roots/test-autosummary/contents.rst
+++ b/tests/roots/test-autosummary/contents.rst
@@ -1,6 +1,6 @@
-
-.. autosummary::
- :nosignatures:
- :toctree:
-
- dummy_module
+
+.. autosummary::
+ :nosignatures:
+ :toctree:
+
+ dummy_module
diff --git a/tests/run.py b/tests/run.py
index 7d51100d9..8d2a828a0 100755
--- a/tests/run.py
+++ b/tests/run.py
@@ -15,6 +15,9 @@ import sys
from os import path, chdir, listdir, environ
import shutil
+import six
+
+
testroot = path.dirname(__file__) or '.'
if 'BUILD_TEST_PATH' in environ:
# for tox testing
@@ -26,7 +29,7 @@ else:
shutil.rmtree(newroot, ignore_errors=True)
-if sys.version_info >= (3, 0):
+if six.PY3:
print('Copying and converting sources to build/lib/tests...')
from distutils.util import copydir_run_2to3
copydir_run_2to3(testroot, newroot)
diff --git a/tests/test_application.py b/tests/test_application.py
index 3d464eb59..d8c52b246 100644
--- a/tests/test_application.py
+++ b/tests/test_application.py
@@ -9,9 +9,9 @@
:license: BSD, see LICENSE for details.
"""
-from StringIO import StringIO
-
+import six
from docutils import nodes
+
from sphinx.application import ExtensionError
from sphinx.domains import Domain
@@ -49,7 +49,7 @@ def test_emit_with_nonascii_name_node(app):
def test_output():
- status, warnings = StringIO(), StringIO()
+ status, warnings = six.StringIO(), six.StringIO()
app = TestApp(status=status, warning=warnings)
try:
status.truncate(0) # __init__ writes to status
@@ -70,7 +70,7 @@ def test_output():
def test_extensions():
- status, warnings = StringIO(), StringIO()
+ status, warnings = six.StringIO(), six.StringIO()
app = TestApp(status=status, warning=warnings)
try:
app.setup_extension('shutil')
@@ -85,7 +85,7 @@ def test_domain_override():
name = 'foo'
class C(Domain):
name = 'foo'
- status, warnings = StringIO(), StringIO()
+ status, warnings = six.StringIO(), six.StringIO()
app = TestApp(status=status, warning=warnings)
try:
# No domain know named foo.
diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py
index 30de8790f..7b6c017e3 100644
--- a/tests/test_autodoc.py
+++ b/tests/test_autodoc.py
@@ -10,13 +10,11 @@
:license: BSD, see LICENSE for details.
"""
-import sys
-from StringIO import StringIO
-
# "raises" imported for usage by autodoc
from util import TestApp, Struct, raises
from nose.tools import with_setup
+import six
from docutils.statemachine import ViewList
from sphinx.ext.autodoc import AutoDirective, add_documenter, \
@@ -811,7 +809,7 @@ class Class(Base):
u"""should be documented as well - süß"""
# initialized to any class imported from another module
- mdocattr = StringIO()
+ mdocattr = six.StringIO()
"""should be documented as well - süß"""
roger = _funky_classmethod("roger", 2, 3, 4)
diff --git a/tests/test_build_html.py b/tests/test_build_html.py
index f4b8c21c2..8fb5313ee 100644
--- a/tests/test_build_html.py
+++ b/tests/test_build_html.py
@@ -11,9 +11,9 @@
import os
import re
-import sys
import htmlentitydefs
-from StringIO import StringIO
+
+import six
try:
import pygments
@@ -29,7 +29,7 @@ def teardown_module():
(test_root / '_build').rmtree(True)
-html_warnfile = StringIO()
+html_warnfile = six.StringIO()
ENV_WARNINGS = """\
%(root)s/autodoc_fodder.py:docstring of autodoc_fodder\\.MarkupError:2: \
@@ -54,7 +54,7 @@ None:\\d+: WARNING: citation not found: missing
%(root)s/markup.txt:: WARNING: invalid pair index entry u'keyword; '
"""
-if sys.version_info >= (3, 0):
+if six.PY3:
ENV_WARNINGS = remove_unicode_literals(ENV_WARNINGS)
HTML_WARNINGS = remove_unicode_literals(HTML_WARNINGS)
diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py
index 0b2d89645..0a2a6421f 100644
--- a/tests/test_build_latex.py
+++ b/tests/test_build_latex.py
@@ -12,10 +12,10 @@ from __future__ import print_function
import os
import re
-import sys
-from StringIO import StringIO
from subprocess import Popen, PIPE
+import six
+
from sphinx.writers.latex import LaTeXTranslator
from util import test_root, SkipTest, remove_unicode_literals, with_app
@@ -26,7 +26,7 @@ def teardown_module():
(test_root / '_build').rmtree(True)
-latex_warnfile = StringIO()
+latex_warnfile = six.StringIO()
LATEX_WARNINGS = ENV_WARNINGS + """\
None:None: WARNING: citation not found: missing
@@ -35,7 +35,7 @@ WARNING: invalid pair index entry u''
WARNING: invalid pair index entry u'keyword; '
"""
-if sys.version_info >= (3, 0):
+if six.PY3:
LATEX_WARNINGS = remove_unicode_literals(LATEX_WARNINGS)
diff --git a/tests/test_build_texinfo.py b/tests/test_build_texinfo.py
index 2dcce7ed1..3cb30a2d5 100644
--- a/tests/test_build_texinfo.py
+++ b/tests/test_build_texinfo.py
@@ -12,10 +12,10 @@ from __future__ import print_function
import os
import re
-import sys
-from StringIO import StringIO
from subprocess import Popen, PIPE
+import six
+
from sphinx.writers.texinfo import TexinfoTranslator
from util import test_root, SkipTest, remove_unicode_literals, with_app
@@ -26,7 +26,7 @@ def teardown_module():
(test_root / '_build').rmtree(True)
-texinfo_warnfile = StringIO()
+texinfo_warnfile = six.StringIO()
TEXINFO_WARNINGS = ENV_WARNINGS + """\
None:None: WARNING: citation not found: missing
@@ -34,7 +34,7 @@ None:None: WARNING: no matching candidate for image URI u'foo.\\*'
None:None: WARNING: no matching candidate for image URI u'svgimg.\\*'
"""
-if sys.version_info >= (3, 0):
+if six.PY3:
TEXINFO_WARNINGS = remove_unicode_literals(TEXINFO_WARNINGS)
diff --git a/tests/test_config.py b/tests/test_config.py
index db9a2a010..f69a2185a 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -9,7 +9,7 @@
:copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
-import sys
+import six
from util import TestApp, with_app, with_tempdir, raises, raises_msg
@@ -101,7 +101,7 @@ def test_errors_warnings(dir):
# test the warning for bytestrings with non-ascii content
# bytestrings with non-ascii content are a syntax error in python3 so we
# skip the test there
- if sys.version_info >= (3, 0):
+ if six.PY3:
return
(dir / 'conf.py').write_text(
u'# -*- coding: latin-1\nproject = "fooä"\n', encoding='latin-1')
diff --git a/tests/test_doctest.py b/tests/test_doctest.py
index ba720041b..d90a5be82 100644
--- a/tests/test_doctest.py
+++ b/tests/test_doctest.py
@@ -11,12 +11,13 @@
from __future__ import print_function
import sys
-import StringIO
+
+import six
from util import with_app
-status = StringIO.StringIO()
+status = six.StringIO()
cleanup_called = 0
@with_app(buildername='doctest', status=status)
diff --git a/tests/test_docutilsconf.py b/tests/test_docutilsconf.py
index fcfef13b3..edd72be8a 100644
--- a/tests/test_docutilsconf.py
+++ b/tests/test_docutilsconf.py
@@ -11,13 +11,14 @@
import os
import re
-from StringIO import StringIO
from functools import wraps
+import six
+
from util import test_roots, TestApp
-html_warnfile = StringIO()
+html_warnfile = six.StringIO()
root = test_roots / 'test-docutilsconf'
diff --git a/tests/test_env.py b/tests/test_env.py
index eaaa212f8..10dd9c8a1 100644
--- a/tests/test_env.py
+++ b/tests/test_env.py
@@ -8,7 +8,7 @@
:copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
-import sys
+import six
from util import TestApp, remove_unicode_literals, path
@@ -57,7 +57,7 @@ def test_images():
htmlbuilder.imgpath = 'dummy'
htmlbuilder.post_process_images(tree)
image_uri_message = "no matching candidate for image URI u'foo.*'"
- if sys.version_info >= (3, 0):
+ if six.PY3:
image_uri_message = remove_unicode_literals(image_uri_message)
assert image_uri_message in app._warning.content[-1]
assert set(htmlbuilder.images.keys()) == \
diff --git a/tests/test_intersphinx.py b/tests/test_intersphinx.py
index d342590d7..9ed9fe688 100644
--- a/tests/test_intersphinx.py
+++ b/tests/test_intersphinx.py
@@ -11,11 +11,8 @@
import zlib
import posixpath
-try:
- from io import BytesIO
-except ImportError:
- from cStringIO import StringIO as BytesIO
+import six
from docutils import nodes
from sphinx import addnodes
@@ -48,7 +45,7 @@ a term std:term -1 glossary.html#term-a-term -
def test_read_inventory_v1():
- f = BytesIO(inventory_v1)
+ f = six.BytesIO(inventory_v1)
f.readline()
invdata = read_inventory_v1(f, '/util', posixpath.join)
assert invdata['py:module']['module'] == \
@@ -58,12 +55,12 @@ def test_read_inventory_v1():
def test_read_inventory_v2():
- f = BytesIO(inventory_v2)
+ f = six.BytesIO(inventory_v2)
f.readline()
invdata1 = read_inventory_v2(f, '/util', posixpath.join)
# try again with a small buffer size to test the chunking algorithm
- f = BytesIO(inventory_v2)
+ f = six.BytesIO(inventory_v2)
f.readline()
invdata2 = read_inventory_v2(f, '/util', posixpath.join, bufsize=5)
diff --git a/tests/test_intl.py b/tests/test_intl.py
index 56c88bd67..64f584fbb 100644
--- a/tests/test_intl.py
+++ b/tests/test_intl.py
@@ -13,14 +13,15 @@ from __future__ import print_function
import os
import re
-from StringIO import StringIO
from subprocess import Popen, PIPE
from xml.etree import ElementTree
+import six
+
from util import test_roots, path, with_app, SkipTest
-warnfile = StringIO()
+warnfile = six.StringIO()
root = test_roots / 'test-intl'
doctreedir = root / '_build' / 'doctree'
diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py
index ef29a2b06..f729f570f 100644
--- a/tests/test_quickstart.py
+++ b/tests/test_quickstart.py
@@ -11,8 +11,8 @@
import sys
import time
-from StringIO import StringIO
-import tempfile
+
+import six
from util import raises, with_tempdir, with_app, SkipTest
@@ -22,7 +22,7 @@ from sphinx.util.console import nocolor, coloron
from sphinx.util.pycompat import execfile_
-warnfile = StringIO()
+warnfile = six.StringIO()
def setup_module():
@@ -35,7 +35,7 @@ def mock_raw_input(answers, needanswer=False):
raise AssertionError('answer for %r missing and no default '
'present' % prompt)
called.add(prompt)
- if sys.version_info < (3, 0):
+ if six.PY2:
prompt = str(prompt) # Python2.x raw_input emulation
# `raw_input` encode `prompt` by default encoding to print.
else:
@@ -264,7 +264,7 @@ def test_quickstart_and_build(tempdir):
(tempdir / '_build' / 'html'), #outdir
(tempdir / '_build' / '.doctree'), #doctreedir
'html', #buildername
- status=StringIO(),
+ status=six.StringIO(),
warning=warnfile)
app.builder.build_all()
warnings = warnfile.getvalue()
diff --git a/tests/test_searchadapters.py b/tests/test_searchadapters.py
index 81d7c1784..1aebcd9f0 100644
--- a/tests/test_searchadapters.py
+++ b/tests/test_searchadapters.py
@@ -10,7 +10,8 @@
"""
import os
-from StringIO import StringIO
+
+import six
from sphinx.websupport import WebSupport
@@ -31,8 +32,8 @@ def search_adapter_helper(adapter):
clear_builddir()
settings = {'builddir': os.path.join(test_root, 'websupport'),
- 'status': StringIO(),
- 'warning': StringIO()}
+ 'status': six.StringIO(),
+ 'warning': six.StringIO()}
settings.update({'srcdir': test_root,
'search': adapter})
support = WebSupport(**settings)
diff --git a/tests/test_websupport.py b/tests/test_websupport.py
index bcb756755..7c7a4f0f3 100644
--- a/tests/test_websupport.py
+++ b/tests/test_websupport.py
@@ -10,9 +10,10 @@
"""
import os
-from StringIO import StringIO
from functools import wraps
+import six
+
from sphinx.websupport import WebSupport
from sphinx.websupport.errors import DocumentNotFoundError, \
CommentNotAllowedError, UserNotAuthorizedError
@@ -30,8 +31,8 @@ from util import test_root, raises, skip_if
default_settings = {'builddir': os.path.join(test_root, 'websupport'),
- 'status': StringIO(),
- 'warning': StringIO()}
+ 'status': six.StringIO(),
+ 'warning': six.StringIO()}
def teardown_module():
(test_root / 'generated').rmtree(True)
diff --git a/tests/util.py b/tests/util.py
index 8c4ff3dff..5eb879f58 100644
--- a/tests/util.py
+++ b/tests/util.py
@@ -8,12 +8,13 @@
"""
import sys
-import StringIO
import tempfile
import shutil
import re
from functools import wraps
+import six
+
from sphinx import application
from sphinx.theming import Theme
from sphinx.ext.autodoc import AutoDirective
@@ -162,7 +163,7 @@ class TestApp(application.Sphinx):
if confoverrides is None:
confoverrides = {}
if status is None:
- status = StringIO.StringIO()
+ status = six.StringIO()
if warning is None:
warning = ListOutput('stderr')
if freshenv is None: