introduce the six module and reduce sphinx.util.pycompat implementation. refs #1350.

This commit is contained in:
Takayuki Shimizukawa 2014-04-29 11:46:47 +09:00
parent 1e4b390b22
commit 68290a266c
38 changed files with 142 additions and 137 deletions

View File

@ -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.') print('ERROR: Sphinx requires at least Python 2.6 or 3.2 to run.')
sys.exit(1) 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): if (3, 0) <= sys.version_info < (3, 3):
requires.append('Jinja2>=2.3,<2.7') requires.append('Jinja2>=2.3,<2.7')

View File

@ -18,8 +18,8 @@ import types
import posixpath import posixpath
import traceback import traceback
from os import path from os import path
from cStringIO import StringIO
import six
from docutils import nodes from docutils import nodes
from docutils.parsers.rst import convert_directive_function, \ from docutils.parsers.rst import convert_directive_function, \
directives, roles directives, roles
@ -84,14 +84,14 @@ class Sphinx(object):
self.parallel = parallel self.parallel = parallel
if status is None: if status is None:
self._status = StringIO() self._status = six.cStringIO()
self.quiet = True self.quiet = True
else: else:
self._status = status self._status = status
self.quiet = False self.quiet = False
if warning is None: if warning is None:
self._warning = StringIO() self._warning = six.cStringIO()
else: else:
self._warning = warning self._warning = warning
self._warncount = 0 self._warncount = 0

View File

@ -16,6 +16,7 @@ import getopt
import traceback import traceback
from os import path from os import path
import six
from docutils.utils import SystemMessage from docutils.utils import SystemMessage
from sphinx import __version__ 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 import Tee, format_exception_cut_frames, save_traceback
from sphinx.util.console import red, nocolor, color_terminal from sphinx.util.console import red, nocolor, color_terminal
from sphinx.util.osutil import abspath, fs_encoding 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): def usage(argv, msg=None):
@ -183,7 +184,7 @@ def main(argv):
print('Error: -D option argument must be in the form name=value.', print('Error: -D option argument must be in the form name=value.',
file=sys.stderr) file=sys.stderr)
return 1 return 1
if likely_encoding and isinstance(val, bytes): if likely_encoding and isinstance(val, six.binary_type):
try: try:
val = val.decode(likely_encoding) val = val.decode(likely_encoding)
except UnicodeError: except UnicodeError:
@ -199,7 +200,7 @@ def main(argv):
try: try:
val = int(val) val = int(val)
except ValueError: except ValueError:
if likely_encoding and isinstance(val, bytes): if likely_encoding and isinstance(val, six.binary_type):
try: try:
val = val.decode(likely_encoding) val = val.decode(likely_encoding)
except UnicodeError: except UnicodeError:

View File

@ -11,18 +11,19 @@
import os import os
import re import re
import sys
from os import path from os import path
import six
from sphinx.errors import ConfigError from sphinx.errors import ConfigError
from sphinx.locale import l_ from sphinx.locale import l_
from sphinx.util.osutil import make_filename 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]')) nonascii_re = re.compile(b(r'[\x80-\xff]'))
CONFIG_SYNTAX_ERROR = "There is a syntax error in your configuration file: %s" 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?" CONFIG_SYNTAX_ERROR += "\nDid you change the syntax from 2.x to 3.x?"
class Config(object): class Config(object):
@ -243,7 +244,7 @@ class Config(object):
# check all string values for non-ASCII characters in bytestrings, # check all string values for non-ASCII characters in bytestrings,
# since that can result in UnicodeErrors all over the place # since that can result in UnicodeErrors all over the place
for name, value in self._raw_config.iteritems(): 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 ' warn('the config value %r is set to a string with non-ASCII '
'characters; this can lead to Unicode errors occurring. ' 'characters; this can lead to Unicode errors occurring. '
'Please use Unicode strings, e.g. %r.' % (name, u'Content') 'Please use Unicode strings, e.g. %r.' % (name, u'Content')

View File

@ -23,6 +23,7 @@ from os import path
from glob import glob from glob import glob
from itertools import izip, groupby from itertools import izip, groupby
import six
from docutils import nodes from docutils import nodes
from docutils.io import FileInput, NullOutput from docutils.io import FileInput, NullOutput
from docutils.core import Publisher 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.nodes import clean_astext, make_refnode, WarningStream
from sphinx.util.osutil import SEP, fs_encoding, find_catalog_files from sphinx.util.osutil import SEP, fs_encoding, find_catalog_files
from sphinx.util.matching import compile_matchers from sphinx.util.matching import compile_matchers
from sphinx.util.pycompat import class_types
from sphinx.util.websupport import is_commentable from sphinx.util.websupport import is_commentable
from sphinx.errors import SphinxError, ExtensionError from sphinx.errors import SphinxError, ExtensionError
from sphinx.locale import _ from sphinx.locale import _
@ -140,7 +140,7 @@ class BuildEnvironment:
if key.startswith('_') or \ if key.startswith('_') or \
isinstance(val, types.ModuleType) or \ isinstance(val, types.ModuleType) or \
isinstance(val, types.FunctionType) or \ isinstance(val, types.FunctionType) or \
isinstance(val, class_types): isinstance(val, six.class_types):
del self.config[key] del self.config[key]
try: try:
pickle.dump(self, picklefile, pickle.HIGHEST_PROTOCOL) pickle.dump(self, picklefile, pickle.HIGHEST_PROTOCOL)

View File

@ -17,6 +17,7 @@ import inspect
import traceback import traceback
from types import FunctionType, BuiltinFunctionType, MethodType from types import FunctionType, BuiltinFunctionType, MethodType
import six
from docutils import nodes from docutils import nodes
from docutils.utils import assemble_option_dict from docutils.utils import assemble_option_dict
from docutils.statemachine import ViewList 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.compat import Directive
from sphinx.util.inspect import getargspec, isdescriptor, safe_getmembers, \ from sphinx.util.inspect import getargspec, isdescriptor, safe_getmembers, \
safe_getattr, safe_repr, is_builtin_class_method safe_getattr, safe_repr, is_builtin_class_method
from sphinx.util.pycompat import class_types
from sphinx.util.docstrings import prepare_docstring from sphinx.util.docstrings import prepare_docstring
@ -1028,7 +1028,7 @@ class ClassDocumenter(ModuleLevelDocumenter):
@classmethod @classmethod
def can_document_member(cls, member, membername, isattr, parent): def can_document_member(cls, member, membername, isattr, parent):
return isinstance(member, class_types) return isinstance(member, six.class_types)
def import_object(self): def import_object(self):
ret = ModuleLevelDocumenter.import_object(self) ret = ModuleLevelDocumenter.import_object(self)
@ -1162,7 +1162,7 @@ class ExceptionDocumenter(ClassDocumenter):
@classmethod @classmethod
def can_document_member(cls, member, membername, isattr, parent): 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) issubclass(member, BaseException)
@ -1212,7 +1212,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter):
return inspect.isroutine(member) and \ return inspect.isroutine(member) and \
not isinstance(parent, ModuleDocumenter) not isinstance(parent, ModuleDocumenter)
if sys.version_info >= (3, 0): if six.PY3:
def import_object(self): def import_object(self):
ret = ClassLevelDocumenter.import_object(self) ret = ClassLevelDocumenter.import_object(self)
obj_from_parent = self.parent.__dict__.get(self.object_name) obj_from_parent = self.parent.__dict__.get(self.object_name)
@ -1282,7 +1282,7 @@ class AttributeDocumenter(ClassLevelDocumenter):
"instancemethod") "instancemethod")
return isdatadesc or (not isinstance(parent, ModuleDocumenter) return isdatadesc or (not isinstance(parent, ModuleDocumenter)
and not inspect.isroutine(member) 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): def document_members(self, all_members=False):
pass pass

View File

@ -14,11 +14,11 @@ import re
import sys import sys
import time import time
import codecs import codecs
import StringIO
from os import path from os import path
# circumvent relative import # circumvent relative import
doctest = __import__('doctest') doctest = __import__('doctest')
import six
from docutils import nodes from docutils import nodes
from docutils.parsers.rst import directives 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.nodes import set_source_info
from sphinx.util.compat import Directive from sphinx.util.compat import Directive
from sphinx.util.console import bold from sphinx.util.console import bold
from sphinx.util.pycompat import bytes
blankline_re = re.compile(r'^\s*<BLANKLINE>', re.MULTILINE) blankline_re = re.compile(r'^\s*<BLANKLINE>', re.MULTILINE)
doctestopt_re = re.compile(r'#\s*doctest:.+$', re.MULTILINE) doctestopt_re = re.compile(r'#\s*doctest:.+$', re.MULTILINE)
@ -158,7 +157,7 @@ class TestCode(object):
class SphinxDocTestRunner(doctest.DocTestRunner): class SphinxDocTestRunner(doctest.DocTestRunner):
def summarize(self, out, verbose=None): def summarize(self, out, verbose=None):
string_io = StringIO.StringIO() string_io = six.StringIO()
old_stdout = sys.stdout old_stdout = sys.stdout
sys.stdout = string_io sys.stdout = string_io
try: try:
@ -233,7 +232,7 @@ Results of doctest builder run on %s
self.info(text, nonl=True) self.info(text, nonl=True)
if self.app.quiet: if self.app.quiet:
self.warn(text) self.warn(text)
if isinstance(text, bytes): if isinstance(text, six.binary_type):
text = force_decode(text, None) text = force_decode(text, None)
self.outfile.write(text) self.outfile.write(text)

View File

@ -10,6 +10,9 @@
""" """
import sys import sys
import six
from sphinx.ext.napoleon.docstring import GoogleDocstring, NumpyDocstring 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: if name != '__weakref__' and name != '__init__' and has_doc and is_member:
cls_is_owner = False cls_is_owner = False
if what == 'class' or what == 'exception': if what == 'class' or what == 'exception':
if sys.version_info[0] < 3: if six.PY2:
cls = getattr(obj, 'im_class', getattr(obj, '__objclass__', cls = getattr(obj, 'im_class', getattr(obj, '__objclass__',
None)) None))
cls_is_owner = (cls and hasattr(cls, name) and cls_is_owner = (cls and hasattr(cls, name) and
name in cls.__dict__) name in cls.__dict__)
elif sys.version_info[1] >= 3: elif sys.version_info >= (3, 3):
qualname = getattr(obj, '__qualname__', '') qualname = getattr(obj, '__qualname__', '')
cls_path, _, _ = qualname.rpartition('.') cls_path, _, _ = qualname.rpartition('.')
if cls_path: if cls_path:

View File

@ -14,11 +14,13 @@
import collections import collections
import inspect import inspect
import re import re
import sys
import six
from sphinx.ext.napoleon.iterators import modify_iter from sphinx.ext.napoleon.iterators import modify_iter
if sys.version_info[0] >= 3: if six.PY3:
basestring = str basestring = str
xrange = range xrange = range
@ -160,7 +162,7 @@ class GoogleDocstring(object):
UTF-8 encoded version of the docstring. UTF-8 encoded version of the docstring.
""" """
if sys.version_info[0] >= 3: if six.PY3:
return self.__unicode__() return self.__unicode__()
else: else:
return self.__unicode__().encode('utf8') return self.__unicode__().encode('utf8')

View File

@ -12,10 +12,11 @@
""" """
import collections import collections
import sys
import six
if sys.version_info[0] >= 3: if six.PY3:
callable = lambda o: hasattr(o, '__call__') callable = lambda o: hasattr(o, '__call__')

View File

@ -9,7 +9,6 @@
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
import sys
import re import re
import textwrap import textwrap
@ -19,6 +18,8 @@ except ImportError:
# parser is not available on Jython # parser is not available on Jython
parser = None parser = None
import six
from sphinx.util.pycompat import htmlescape from sphinx.util.pycompat import htmlescape
from sphinx.util.texescape import tex_hl_escape_map_new from sphinx.util.texescape import tex_hl_escape_map_new
from sphinx.ext import doctest from sphinx.ext import doctest
@ -131,7 +132,7 @@ class PygmentsBridge(object):
# lines beginning with "..." are probably placeholders for suite # lines beginning with "..." are probably placeholders for suite
src = re.sub(r"(?m)^(\s*)" + mark + "(.)", r"\1"+ mark + r"# \2", src) 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 # Non-ASCII chars will only occur in string literals
# and comments. If we wanted to give them to the parser # and comments. If we wanted to give them to the parser
# correctly, we'd have to find out the correct source # correctly, we'd have to find out the correct source

View File

@ -9,10 +9,11 @@
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
import sys
import gettext import gettext
import UserString import UserString
import six
class _TranslationProxy(UserString.UserString, object): class _TranslationProxy(UserString.UserString, object):
""" """
@ -183,7 +184,7 @@ pairindextypes = {
translators = {} translators = {}
if sys.version_info >= (3, 0): if six.PY3:
def _(message): def _(message):
return translators['sphinx'].gettext(message) return translators['sphinx'].gettext(message)
else: else:

View File

@ -13,12 +13,14 @@ from __future__ import print_function
import sys import sys
from os import path from os import path
import six
from sphinx import package_dir from sphinx import package_dir
from sphinx.errors import PycodeError from sphinx.errors import PycodeError
from sphinx.pycode import nodes from sphinx.pycode import nodes
from sphinx.pycode.pgen2 import driver, token, tokenize, parse, literals from sphinx.pycode.pgen2 import driver, token, tokenize, parse, literals
from sphinx.util import get_module_source, detect_encoding 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 from sphinx.util.docstrings import prepare_docstring, prepare_commentdoc
@ -174,8 +176,8 @@ class ModuleAnalyzer(object):
@classmethod @classmethod
def for_string(cls, string, modname, srcname='<string>'): def for_string(cls, string, modname, srcname='<string>'):
if isinstance(string, bytes): if isinstance(string, bytes):
return cls(BytesIO(string), modname, srcname) return cls(six.BytesIO(string), modname, srcname)
return cls(StringIO(string), modname, srcname, decoded=True) return cls(six.StringIO(string), modname, srcname, decoded=True)
@classmethod @classmethod
def for_file(cls, filename, modname): def for_file(cls, filename, modname):

View File

@ -16,6 +16,8 @@ from io import open
TERM_ENCODING = getattr(sys.stdin, 'encoding', None) TERM_ENCODING = getattr(sys.stdin, 'encoding', None)
import six
#try to import readline, unix specific enhancement #try to import readline, unix specific enhancement
try: try:
import readline import readline
@ -44,7 +46,7 @@ except NameError:
PROMPT_PREFIX = '> ' 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 # prevents that the file is checked for being written in Python 2.x syntax
QUICKSTART_CONF = u'#!/usr/bin/env python3\n' QUICKSTART_CONF = u'#!/usr/bin/env python3\n'
else: else:
@ -997,7 +999,7 @@ def do_prompt(d, key, text, default=None, validator=nonempty):
prompt = PROMPT_PREFIX + '%s [%s]: ' % (text, default) prompt = PROMPT_PREFIX + '%s [%s]: ' % (text, default)
else: else:
prompt = PROMPT_PREFIX + text + ': ' 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 # for Python 2.x, try to get a Unicode string out of it
if prompt.encode('ascii', 'replace').decode('ascii', 'replace') \ if prompt.encode('ascii', 'replace').decode('ascii', 'replace') \
!= prompt: != prompt:
@ -1037,7 +1039,7 @@ def do_prompt(d, key, text, default=None, validator=nonempty):
d[key] = x d[key] = x
if sys.version_info >= (3, 0): if six.PY3:
# remove Unicode literal prefixes # remove Unicode literal prefixes
def _convert_python_source(source, rex=re.compile(r"[uU]('.*?')")): def _convert_python_source(source, rex=re.compile(r"[uU]('.*?')")):
return rex.sub('\\1', source) return rex.sub('\\1', source)

View File

@ -16,10 +16,11 @@ from __future__ import print_function
import sys import sys
import os import os
import types import types
from StringIO import StringIO
from distutils.cmd import Command from distutils.cmd import Command
from distutils.errors import DistutilsOptionError from distutils.errors import DistutilsOptionError
import six
from sphinx.application import Sphinx from sphinx.application import Sphinx
from sphinx.util.console import darkred, nocolor, color_terminal from sphinx.util.console import darkred, nocolor, color_terminal
from sphinx.util.osutil import abspath from sphinx.util.osutil import abspath
@ -141,7 +142,7 @@ class BuildDoc(Command):
# Windows' poor cmd box doesn't understand ANSI sequences # Windows' poor cmd box doesn't understand ANSI sequences
nocolor() nocolor()
if not self.verbose: if not self.verbose:
status_stream = StringIO() status_stream = six.StringIO()
else: else:
status_stream = sys.stdout status_stream = sys.stdout
confoverrides = {} confoverrides = {}

View File

@ -12,7 +12,6 @@
import os import os
import re import re
import sys import sys
import shutil
import fnmatch import fnmatch
import tempfile import tempfile
import posixpath import posixpath
@ -22,6 +21,7 @@ from os import path
from codecs import open, BOM_UTF8 from codecs import open, BOM_UTF8
from collections import deque from collections import deque
import six
import docutils import docutils
from docutils.utils import relative_path from docutils.utils import relative_path
@ -29,7 +29,6 @@ import jinja2
import sphinx import sphinx
from sphinx.errors import PycodeError from sphinx.errors import PycodeError
from sphinx.util.pycompat import bytes
# import other utilities; partly for backwards compatibility, so don't # import other utilities; partly for backwards compatibility, so don't
# prune unused ones indiscriminately # prune unused ones indiscriminately
@ -336,7 +335,7 @@ def parselinenos(spec, total):
def force_decode(string, encoding): def force_decode(string, encoding):
"""Forcibly get a unicode string out of a bytestring.""" """Forcibly get a unicode string out of a bytestring."""
if isinstance(string, bytes): if isinstance(string, six.binary_type):
try: try:
if encoding: if encoding:
string = string.decode(encoding) string = string.decode(encoding)

View File

@ -9,17 +9,16 @@
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
import sys
# this imports the standard library inspect module without resorting to # this imports the standard library inspect module without resorting to
# relatively import this module # relatively import this module
inspect = __import__('inspect') inspect = __import__('inspect')
import six
from sphinx.util import force_decode 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 from functools import partial
def getargspec(func): def getargspec(func):
"""Like inspect.getargspec but supports functools.partial as well.""" """Like inspect.getargspec but supports functools.partial as well."""
@ -129,7 +128,7 @@ def safe_repr(object):
s = repr(object) s = repr(object)
except Exception: except Exception:
raise ValueError raise ValueError
if isinstance(s, bytes): if isinstance(s, six.binary_type):
return force_decode(s, None).replace('\n', ' ') return force_decode(s, None).replace('\n', ' ')
return s.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__] classes = [c for c in inspect.getmro(obj) if attr_name in c.__dict__]
cls = classes[0] if classes else object 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 False
return getattr(builtins, safe_getattr(cls, '__name__', '')) is cls return getattr(six.moves.builtins, safe_getattr(cls, '__name__', '')) is cls

View File

@ -20,6 +20,8 @@ import shutil
import gettext import gettext
from os import path from os import path
import six
# Errnos that we need. # Errnos that we need.
EEXIST = getattr(errno, 'EEXIST', 0) EEXIST = getattr(errno, 'EEXIST', 0)
ENOENT = getattr(errno, 'ENOENT', 0) ENOENT = getattr(errno, 'ENOENT', 0)
@ -147,7 +149,7 @@ no_fn_re = re.compile(r'[^a-zA-Z0-9_-]')
def make_filename(string): def make_filename(string):
return no_fn_re.sub('', string) or 'sphinx' return no_fn_re.sub('', string) or 'sphinx'
if sys.version_info < (3, 0): if six.PY2:
# strftime for unicode strings # strftime for unicode strings
def ustrftime(format, *args): def ustrftime(format, *args):
# if a locale is set, the time strings are encoded in the encoding # 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() fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
if sys.version_info < (3, 0): if six.PY2:
bytes = str bytes = str
else: else:
bytes = bytes bytes = bytes

View File

@ -12,20 +12,19 @@
import sys import sys
import codecs import codecs
import six
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Python 2/3 compatibility # Python 2/3 compatibility
if sys.version_info >= (3, 0): if six.PY3:
# Python 3 # Python 3
class_types = (type,)
# the ubiquitous "bytes" helper functions # the ubiquitous "bytes" helper functions
def b(s): def b(s):
return s.encode('utf-8') return s.encode('utf-8')
bytes = bytes
# prefix for Unicode strings # prefix for Unicode strings
u = '' u = ''
# StringIO/BytesIO classes from io import TextIOWrapper
from io import StringIO, BytesIO, TextIOWrapper
# safely encode a string for printing to the terminal # safely encode a string for printing to the terminal
def terminal_safe(s): def terminal_safe(s):
return s.encode('ascii', 'backslashreplace').decode('ascii') 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 # try to match ParseError details with SyntaxError details
raise SyntaxError(err.msg, (filepath, lineno, offset, err.value)) raise SyntaxError(err.msg, (filepath, lineno, offset, err.value))
return unicode(tree) return unicode(tree)
from itertools import zip_longest # Python 3 name from html import escape as htmlescape # >= Python 3.2
import builtins
else: else:
# Python 2 # Python 2
from types import ClassType
class_types = (type, ClassType)
b = str b = str
bytes = str
u = 'u' u = 'u'
from StringIO import StringIO
BytesIO = StringIO
# no need to refactor on 2.x versions # no need to refactor on 2.x versions
convert_with_2to3 = None convert_with_2to3 = None
def TextIOWrapper(stream, encoding): def TextIOWrapper(stream, encoding):
@ -68,11 +61,9 @@ else:
return s.encode('ascii', 'backslashreplace') return s.encode('ascii', 'backslashreplace')
# some kind of default system encoding; should be used with a lenient # some kind of default system encoding; should be used with a lenient
# error handler # error handler
import locale sys_encoding = __import__('locale').getpreferredencoding()
sys_encoding = locale.getpreferredencoding()
# use Python 3 name # use Python 3 name
from itertools import izip_longest as zip_longest from cgi import escape as htmlescape # 2.6, 2.7
import __builtin__ as builtins
def execfile_(filepath, _globals): def execfile_(filepath, _globals):
@ -101,10 +92,4 @@ def execfile_(filepath, _globals):
code = compile(source, filepath_enc, 'exec') code = compile(source, filepath_enc, 'exec')
else: else:
raise raise
exec code in _globals six.exec_(code, _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

View File

@ -13,7 +13,7 @@ from uuid import uuid4
from operator import itemgetter from operator import itemgetter
from itertools import product from itertools import product
from sphinx.util.pycompat import zip_longest import six
# anything below that ratio is considered equal/changed # anything below that ratio is considered equal/changed
@ -52,7 +52,7 @@ def merge_doctrees(old, new, condition):
ratios = {} ratios = {}
seen = set() seen = set()
# compare the nodes each doctree in order # 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: if old_node is None:
new_nodes.append(new_node) new_nodes.append(new_node)
continue continue

View File

@ -12,6 +12,8 @@ import sys
import shutil import shutil
from codecs import open from codecs import open
import six
FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding() FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding()
@ -20,7 +22,7 @@ class path(unicode):
""" """
Represents a path which behaves like a string. 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'): def __new__(cls, s, encoding=FILESYSTEMENCODING, errors='strict'):
if isinstance(s, str): if isinstance(s, str):
s = s.decode(encoding, errors) s = s.decode(encoding, errors)

View File

@ -1,6 +1,6 @@
.. autosummary:: .. autosummary::
:nosignatures: :nosignatures:
:toctree: :toctree:
dummy_module dummy_module

View File

@ -15,6 +15,9 @@ import sys
from os import path, chdir, listdir, environ from os import path, chdir, listdir, environ
import shutil import shutil
import six
testroot = path.dirname(__file__) or '.' testroot = path.dirname(__file__) or '.'
if 'BUILD_TEST_PATH' in environ: if 'BUILD_TEST_PATH' in environ:
# for tox testing # for tox testing
@ -26,7 +29,7 @@ else:
shutil.rmtree(newroot, ignore_errors=True) shutil.rmtree(newroot, ignore_errors=True)
if sys.version_info >= (3, 0): if six.PY3:
print('Copying and converting sources to build/lib/tests...') print('Copying and converting sources to build/lib/tests...')
from distutils.util import copydir_run_2to3 from distutils.util import copydir_run_2to3
copydir_run_2to3(testroot, newroot) copydir_run_2to3(testroot, newroot)

View File

@ -9,9 +9,9 @@
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from StringIO import StringIO import six
from docutils import nodes from docutils import nodes
from sphinx.application import ExtensionError from sphinx.application import ExtensionError
from sphinx.domains import Domain from sphinx.domains import Domain
@ -49,7 +49,7 @@ def test_emit_with_nonascii_name_node(app):
def test_output(): def test_output():
status, warnings = StringIO(), StringIO() status, warnings = six.StringIO(), six.StringIO()
app = TestApp(status=status, warning=warnings) app = TestApp(status=status, warning=warnings)
try: try:
status.truncate(0) # __init__ writes to status status.truncate(0) # __init__ writes to status
@ -70,7 +70,7 @@ def test_output():
def test_extensions(): def test_extensions():
status, warnings = StringIO(), StringIO() status, warnings = six.StringIO(), six.StringIO()
app = TestApp(status=status, warning=warnings) app = TestApp(status=status, warning=warnings)
try: try:
app.setup_extension('shutil') app.setup_extension('shutil')
@ -85,7 +85,7 @@ def test_domain_override():
name = 'foo' name = 'foo'
class C(Domain): class C(Domain):
name = 'foo' name = 'foo'
status, warnings = StringIO(), StringIO() status, warnings = six.StringIO(), six.StringIO()
app = TestApp(status=status, warning=warnings) app = TestApp(status=status, warning=warnings)
try: try:
# No domain know named foo. # No domain know named foo.

View File

@ -10,13 +10,11 @@
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
import sys
from StringIO import StringIO
# "raises" imported for usage by autodoc # "raises" imported for usage by autodoc
from util import TestApp, Struct, raises from util import TestApp, Struct, raises
from nose.tools import with_setup from nose.tools import with_setup
import six
from docutils.statemachine import ViewList from docutils.statemachine import ViewList
from sphinx.ext.autodoc import AutoDirective, add_documenter, \ from sphinx.ext.autodoc import AutoDirective, add_documenter, \
@ -811,7 +809,7 @@ class Class(Base):
u"""should be documented as well - süß""" u"""should be documented as well - süß"""
# initialized to any class imported from another module # initialized to any class imported from another module
mdocattr = StringIO() mdocattr = six.StringIO()
"""should be documented as well - süß""" """should be documented as well - süß"""
roger = _funky_classmethod("roger", 2, 3, 4) roger = _funky_classmethod("roger", 2, 3, 4)

View File

@ -11,9 +11,9 @@
import os import os
import re import re
import sys
import htmlentitydefs import htmlentitydefs
from StringIO import StringIO
import six
try: try:
import pygments import pygments
@ -29,7 +29,7 @@ def teardown_module():
(test_root / '_build').rmtree(True) (test_root / '_build').rmtree(True)
html_warnfile = StringIO() html_warnfile = six.StringIO()
ENV_WARNINGS = """\ ENV_WARNINGS = """\
%(root)s/autodoc_fodder.py:docstring of autodoc_fodder\\.MarkupError:2: \ %(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; ' %(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) ENV_WARNINGS = remove_unicode_literals(ENV_WARNINGS)
HTML_WARNINGS = remove_unicode_literals(HTML_WARNINGS) HTML_WARNINGS = remove_unicode_literals(HTML_WARNINGS)

View File

@ -12,10 +12,10 @@ from __future__ import print_function
import os import os
import re import re
import sys
from StringIO import StringIO
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
import six
from sphinx.writers.latex import LaTeXTranslator from sphinx.writers.latex import LaTeXTranslator
from util import test_root, SkipTest, remove_unicode_literals, with_app from util import test_root, SkipTest, remove_unicode_literals, with_app
@ -26,7 +26,7 @@ def teardown_module():
(test_root / '_build').rmtree(True) (test_root / '_build').rmtree(True)
latex_warnfile = StringIO() latex_warnfile = six.StringIO()
LATEX_WARNINGS = ENV_WARNINGS + """\ LATEX_WARNINGS = ENV_WARNINGS + """\
None:None: WARNING: citation not found: missing None:None: WARNING: citation not found: missing
@ -35,7 +35,7 @@ WARNING: invalid pair index entry u''
WARNING: invalid pair index entry u'keyword; ' WARNING: invalid pair index entry u'keyword; '
""" """
if sys.version_info >= (3, 0): if six.PY3:
LATEX_WARNINGS = remove_unicode_literals(LATEX_WARNINGS) LATEX_WARNINGS = remove_unicode_literals(LATEX_WARNINGS)

View File

@ -12,10 +12,10 @@ from __future__ import print_function
import os import os
import re import re
import sys
from StringIO import StringIO
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
import six
from sphinx.writers.texinfo import TexinfoTranslator from sphinx.writers.texinfo import TexinfoTranslator
from util import test_root, SkipTest, remove_unicode_literals, with_app from util import test_root, SkipTest, remove_unicode_literals, with_app
@ -26,7 +26,7 @@ def teardown_module():
(test_root / '_build').rmtree(True) (test_root / '_build').rmtree(True)
texinfo_warnfile = StringIO() texinfo_warnfile = six.StringIO()
TEXINFO_WARNINGS = ENV_WARNINGS + """\ TEXINFO_WARNINGS = ENV_WARNINGS + """\
None:None: WARNING: citation not found: missing 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.\\*' 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) TEXINFO_WARNINGS = remove_unicode_literals(TEXINFO_WARNINGS)

View File

@ -9,7 +9,7 @@
:copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
import sys import six
from util import TestApp, with_app, with_tempdir, raises, raises_msg 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 # test the warning for bytestrings with non-ascii content
# bytestrings with non-ascii content are a syntax error in python3 so we # bytestrings with non-ascii content are a syntax error in python3 so we
# skip the test there # skip the test there
if sys.version_info >= (3, 0): if six.PY3:
return return
(dir / 'conf.py').write_text( (dir / 'conf.py').write_text(
u'# -*- coding: latin-1\nproject = "fooä"\n', encoding='latin-1') u'# -*- coding: latin-1\nproject = "fooä"\n', encoding='latin-1')

View File

@ -11,12 +11,13 @@
from __future__ import print_function from __future__ import print_function
import sys import sys
import StringIO
import six
from util import with_app from util import with_app
status = StringIO.StringIO() status = six.StringIO()
cleanup_called = 0 cleanup_called = 0
@with_app(buildername='doctest', status=status) @with_app(buildername='doctest', status=status)

View File

@ -11,13 +11,14 @@
import os import os
import re import re
from StringIO import StringIO
from functools import wraps from functools import wraps
import six
from util import test_roots, TestApp from util import test_roots, TestApp
html_warnfile = StringIO() html_warnfile = six.StringIO()
root = test_roots / 'test-docutilsconf' root = test_roots / 'test-docutilsconf'

View File

@ -8,7 +8,7 @@
:copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
import sys import six
from util import TestApp, remove_unicode_literals, path from util import TestApp, remove_unicode_literals, path
@ -57,7 +57,7 @@ def test_images():
htmlbuilder.imgpath = 'dummy' htmlbuilder.imgpath = 'dummy'
htmlbuilder.post_process_images(tree) htmlbuilder.post_process_images(tree)
image_uri_message = "no matching candidate for image URI u'foo.*'" 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) image_uri_message = remove_unicode_literals(image_uri_message)
assert image_uri_message in app._warning.content[-1] assert image_uri_message in app._warning.content[-1]
assert set(htmlbuilder.images.keys()) == \ assert set(htmlbuilder.images.keys()) == \

View File

@ -11,11 +11,8 @@
import zlib import zlib
import posixpath import posixpath
try:
from io import BytesIO
except ImportError:
from cStringIO import StringIO as BytesIO
import six
from docutils import nodes from docutils import nodes
from sphinx import addnodes from sphinx import addnodes
@ -48,7 +45,7 @@ a term std:term -1 glossary.html#term-a-term -
def test_read_inventory_v1(): def test_read_inventory_v1():
f = BytesIO(inventory_v1) f = six.BytesIO(inventory_v1)
f.readline() f.readline()
invdata = read_inventory_v1(f, '/util', posixpath.join) invdata = read_inventory_v1(f, '/util', posixpath.join)
assert invdata['py:module']['module'] == \ assert invdata['py:module']['module'] == \
@ -58,12 +55,12 @@ def test_read_inventory_v1():
def test_read_inventory_v2(): def test_read_inventory_v2():
f = BytesIO(inventory_v2) f = six.BytesIO(inventory_v2)
f.readline() f.readline()
invdata1 = read_inventory_v2(f, '/util', posixpath.join) invdata1 = read_inventory_v2(f, '/util', posixpath.join)
# try again with a small buffer size to test the chunking algorithm # try again with a small buffer size to test the chunking algorithm
f = BytesIO(inventory_v2) f = six.BytesIO(inventory_v2)
f.readline() f.readline()
invdata2 = read_inventory_v2(f, '/util', posixpath.join, bufsize=5) invdata2 = read_inventory_v2(f, '/util', posixpath.join, bufsize=5)

View File

@ -13,14 +13,15 @@ from __future__ import print_function
import os import os
import re import re
from StringIO import StringIO
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
from xml.etree import ElementTree from xml.etree import ElementTree
import six
from util import test_roots, path, with_app, SkipTest from util import test_roots, path, with_app, SkipTest
warnfile = StringIO() warnfile = six.StringIO()
root = test_roots / 'test-intl' root = test_roots / 'test-intl'
doctreedir = root / '_build' / 'doctree' doctreedir = root / '_build' / 'doctree'

View File

@ -11,8 +11,8 @@
import sys import sys
import time import time
from StringIO import StringIO
import tempfile import six
from util import raises, with_tempdir, with_app, SkipTest 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_ from sphinx.util.pycompat import execfile_
warnfile = StringIO() warnfile = six.StringIO()
def setup_module(): def setup_module():
@ -35,7 +35,7 @@ def mock_raw_input(answers, needanswer=False):
raise AssertionError('answer for %r missing and no default ' raise AssertionError('answer for %r missing and no default '
'present' % prompt) 'present' % prompt)
called.add(prompt) called.add(prompt)
if sys.version_info < (3, 0): if six.PY2:
prompt = str(prompt) # Python2.x raw_input emulation prompt = str(prompt) # Python2.x raw_input emulation
# `raw_input` encode `prompt` by default encoding to print. # `raw_input` encode `prompt` by default encoding to print.
else: else:
@ -264,7 +264,7 @@ def test_quickstart_and_build(tempdir):
(tempdir / '_build' / 'html'), #outdir (tempdir / '_build' / 'html'), #outdir
(tempdir / '_build' / '.doctree'), #doctreedir (tempdir / '_build' / '.doctree'), #doctreedir
'html', #buildername 'html', #buildername
status=StringIO(), status=six.StringIO(),
warning=warnfile) warning=warnfile)
app.builder.build_all() app.builder.build_all()
warnings = warnfile.getvalue() warnings = warnfile.getvalue()

View File

@ -10,7 +10,8 @@
""" """
import os import os
from StringIO import StringIO
import six
from sphinx.websupport import WebSupport from sphinx.websupport import WebSupport
@ -31,8 +32,8 @@ def search_adapter_helper(adapter):
clear_builddir() clear_builddir()
settings = {'builddir': os.path.join(test_root, 'websupport'), settings = {'builddir': os.path.join(test_root, 'websupport'),
'status': StringIO(), 'status': six.StringIO(),
'warning': StringIO()} 'warning': six.StringIO()}
settings.update({'srcdir': test_root, settings.update({'srcdir': test_root,
'search': adapter}) 'search': adapter})
support = WebSupport(**settings) support = WebSupport(**settings)

View File

@ -10,9 +10,10 @@
""" """
import os import os
from StringIO import StringIO
from functools import wraps from functools import wraps
import six
from sphinx.websupport import WebSupport from sphinx.websupport import WebSupport
from sphinx.websupport.errors import DocumentNotFoundError, \ from sphinx.websupport.errors import DocumentNotFoundError, \
CommentNotAllowedError, UserNotAuthorizedError CommentNotAllowedError, UserNotAuthorizedError
@ -30,8 +31,8 @@ from util import test_root, raises, skip_if
default_settings = {'builddir': os.path.join(test_root, 'websupport'), default_settings = {'builddir': os.path.join(test_root, 'websupport'),
'status': StringIO(), 'status': six.StringIO(),
'warning': StringIO()} 'warning': six.StringIO()}
def teardown_module(): def teardown_module():
(test_root / 'generated').rmtree(True) (test_root / 'generated').rmtree(True)

View File

@ -8,12 +8,13 @@
""" """
import sys import sys
import StringIO
import tempfile import tempfile
import shutil import shutil
import re import re
from functools import wraps from functools import wraps
import six
from sphinx import application from sphinx import application
from sphinx.theming import Theme from sphinx.theming import Theme
from sphinx.ext.autodoc import AutoDirective from sphinx.ext.autodoc import AutoDirective
@ -162,7 +163,7 @@ class TestApp(application.Sphinx):
if confoverrides is None: if confoverrides is None:
confoverrides = {} confoverrides = {}
if status is None: if status is None:
status = StringIO.StringIO() status = six.StringIO()
if warning is None: if warning is None:
warning = ListOutput('stderr') warning = ListOutput('stderr')
if freshenv is None: if freshenv is None: