summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshimizukawa <shimizukawa@gmail.com>2014-01-18 16:34:47 +0900
committershimizukawa <shimizukawa@gmail.com>2014-01-18 16:34:47 +0900
commit39287f95535866e2d4d1544f8688ce22fd19a69a (patch)
treea9986764ecd8124fd1c93c6185ea3488e71e2b20
parentcaf7fccc80bc2fb485599113bb4e977de0729169 (diff)
parent80a0712b8190ca3d55531a9d1fe3205e364437d1 (diff)
downloadsphinx-39287f95535866e2d4d1544f8688ce22fd19a69a.tar.gz
merge heads
-rw-r--r--CHANGES5
-rw-r--r--doc/install.rst6
-rw-r--r--doc/intro.rst2
-rw-r--r--setup.py12
-rw-r--r--sphinx/__init__.py5
-rw-r--r--sphinx/builders/epub.py8
-rw-r--r--sphinx/builders/html.py12
-rw-r--r--sphinx/builders/linkcheck.py3
-rw-r--r--sphinx/ext/autodoc.py4
-rw-r--r--sphinx/highlighting.py18
-rw-r--r--sphinx/pycode/__init__.py2
-rw-r--r--sphinx/pycode/pgen2/parse.c89
-rw-r--r--sphinx/quickstart.py2
-rw-r--r--sphinx/transforms.py1
-rw-r--r--sphinx/util/inspect.py9
-rw-r--r--sphinx/util/jsonimpl.py20
-rw-r--r--sphinx/util/osutil.py9
-rw-r--r--sphinx/util/pycompat.py185
-rw-r--r--sphinx/versioning.py3
-rw-r--r--sphinx/writers/latex.py1
-rw-r--r--tests/test_autodoc.py11
-rw-r--r--tests/test_intl.py6
-rw-r--r--tests/test_versioning.py1
-rw-r--r--tests/test_websupport.py7
-rw-r--r--tests/util.py7
-rw-r--r--tox.ini10
26 files changed, 55 insertions, 383 deletions
diff --git a/CHANGES b/CHANGES
index 020058ee..33cc66fd 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,11 @@
Release 1.3 (in development)
============================
+Change support versions
+-----------------------
+
+* Drop Python-2.5, 3.1 (support code was completely removed)
+
Incompatible changes
--------------------
diff --git a/doc/install.rst b/doc/install.rst
index bf653872..71e37e9c 100644
--- a/doc/install.rst
+++ b/doc/install.rst
@@ -4,7 +4,7 @@ Installing Sphinx
=================
Since Sphinx is written in the Python language, you need to install Python
-(the required version is at least 2.5) and Sphinx.
+(the required version is at least 2.6) and Sphinx.
Sphinx packages are available on the `Python Package Index
<https://pypi.python.org/pypi/Sphinx>`_.
@@ -79,8 +79,8 @@ sidebar and under "Quick Links", click "Windows Installer" to download.
.. note::
- Currently, Python offers two major versions, 2.x and 3.x. Sphinx 1.2 can run
- under Python 2.5 to 2.7 and 3.1 to 3.3, with the recommended version being
+ Currently, Python offers two major versions, 2.x and 3.x. Sphinx 1.3 can run
+ under Python 2.6, 2.7, 3.2, 3.3, with the recommended version being
2.7. This chapter assumes you have installed Python 2.7.
Follow the Windows installer for Python.
diff --git a/doc/intro.rst b/doc/intro.rst
index 66d0c58d..dd541bf1 100644
--- a/doc/intro.rst
+++ b/doc/intro.rst
@@ -54,7 +54,7 @@ See the :ref:`pertinent section in the FAQ list <usingwith>`.
Prerequisites
-------------
-Sphinx needs at least **Python 2.5** or **Python 3.1** to run, as well as the
+Sphinx needs at least **Python 2.6** or **Python 3.2** to run, as well as the
docutils_ and Jinja2_ libraries. Sphinx should work with docutils version 0.7
or some (not broken) SVN trunk snapshot. If you like to have source code
highlighting support, you must also install the Pygments_ library.
diff --git a/setup.py b/setup.py
index 553cf12d..53a4c04b 100644
--- a/setup.py
+++ b/setup.py
@@ -44,20 +44,20 @@ A development egg can be found `here
<http://bitbucket.org/birkenfeld/sphinx/get/tip.gz#egg=Sphinx-dev>`_.
'''
+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.7']
if sys.version_info[:3] >= (3, 3, 0):
requires[1] = 'docutils>=0.10'
-if sys.version_info < (2, 6) or (3, 0) <= sys.version_info < (3, 3):
+if (3, 0) <= sys.version_info < (3, 3):
requires.append('Jinja2>=2.3,<2.7')
-else:
+else: # 2.6, 2.7, 3.3 or later
requires.append('Jinja2>=2.3')
-if sys.version_info < (2, 5):
- print('ERROR: Sphinx requires at least Python 2.5 to run.')
- sys.exit(1)
-
# tell distribute to use 2to3 with our own fixers
extra = {}
if sys.version_info >= (3, 0):
diff --git a/sphinx/__init__.py b/sphinx/__init__.py
index f93e57a1..2551526f 100644
--- a/sphinx/__init__.py
+++ b/sphinx/__init__.py
@@ -42,8 +42,9 @@ if '+' in __version__ or 'pre' in __version__:
def main(argv=sys.argv):
"""Sphinx build "main" command-line entry."""
- if sys.version_info[:3] < (2, 5, 0):
- sys.stderr.write('Error: Sphinx requires at least Python 2.5 to run.\n')
+ if (sys.version_info[:3] < (2, 6, 0) or
+ (3, 0, 0) <= sys.version_info[:3] < (3, 2, 0)):
+ sys.stderr.write('Error: Sphinx requires at least Python 2.6 to run.\n')
return 1
try:
from sphinx import cmdline
diff --git a/sphinx/builders/epub.py b/sphinx/builders/epub.py
index 1dfcc704..35061b79 100644
--- a/sphinx/builders/epub.py
+++ b/sphinx/builders/epub.py
@@ -12,7 +12,6 @@
import os
import re
-import sys
import time
import codecs
import zipfile
@@ -750,12 +749,5 @@ class EpubBuilder(StandaloneHTMLBuilder):
zipfile.ZIP_STORED)
for file in projectfiles:
fp = path.join(outdir, file)
- if sys.version_info < (2, 6):
- # When zipile.ZipFile.write call with unicode filename, ZipFile
- # encode filename to 'utf-8' (only after Python-2.6).
- if isinstance(file, unicode):
- # OEBPS Container Format (OCF) 2.0.1 specification require
- # "File Names MUST be UTF-8 encoded".
- file = file.encode('utf-8')
epub.write(fp, file, zipfile.ZIP_DEFLATED)
epub.close()
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index dd62e2ba..b6ebf926 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -16,11 +16,7 @@ import codecs
import posixpath
import cPickle as pickle
from os import path
-try:
- from hashlib import md5
-except ImportError:
- # 2.4 compatibility
- from md5 import md5
+from hashlib import md5
from docutils import nodes
from docutils.io import DocTreeInput, StringOutput
@@ -35,7 +31,7 @@ from sphinx.util.osutil import SEP, os_path, relative_uri, ensuredir, \
movefile, ustrftime, copyfile
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.matching import patmatch, compile_matchers
-from sphinx.util.pycompat import any, b
+from sphinx.util.pycompat import b
from sphinx.errors import SphinxError
from sphinx.locale import _
from sphinx.search import js_index
@@ -1098,8 +1094,4 @@ class JSONHTMLBuilder(SerializingHTMLBuilder):
searchindex_filename = 'searchindex.json'
def init(self):
- if jsonimpl.json is None:
- raise SphinxError(
- 'The module simplejson (or json in Python >= 2.6) '
- 'is not available. The JSONHTMLBuilder builder will not work.')
SerializingHTMLBuilder.init(self)
diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py
index 6cbe361b..171e68d5 100644
--- a/sphinx/builders/linkcheck.py
+++ b/sphinx/builders/linkcheck.py
@@ -10,7 +10,6 @@
"""
import re
-import sys
import Queue
import socket
import threading
@@ -110,7 +109,7 @@ class CheckExternalLinksBuilder(Builder):
def check_thread(self):
kwargs = {}
- if sys.version_info > (2, 5) and self.app.config.linkcheck_timeout:
+ if self.app.config.linkcheck_timeout:
kwargs['timeout'] = self.app.config.linkcheck_timeout
def check():
diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py
index c454641b..571f36cb 100644
--- a/sphinx/ext/autodoc.py
+++ b/sphinx/ext/autodoc.py
@@ -29,7 +29,7 @@ from sphinx.util.nodes import nested_parse_with_titles
from sphinx.util.compat import Directive
from sphinx.util.inspect import getargspec, isdescriptor, safe_getmembers, \
safe_getattr, safe_repr, is_builtin_class_method
-from sphinx.util.pycompat import base_exception, class_types
+from sphinx.util.pycompat import class_types
from sphinx.util.docstrings import prepare_docstring
@@ -1130,7 +1130,7 @@ class ExceptionDocumenter(ClassDocumenter):
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
return isinstance(member, class_types) and \
- issubclass(member, base_exception)
+ issubclass(member, BaseException)
class DataDocumenter(ModuleLevelDocumenter):
diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py
index 2c95dec0..c30c9ef3 100644
--- a/sphinx/highlighting.py
+++ b/sphinx/highlighting.py
@@ -63,12 +63,6 @@ _LATEX_STYLES = r'''
\newcommand\PYGZcb{\char`\}}
'''
-parsing_exceptions = (SyntaxError, UnicodeEncodeError)
-if sys.version_info < (2, 5):
- # Python <= 2.4 raises MemoryError when parsing an
- # invalid encoding cookie
- parsing_exceptions += MemoryError,
-
class PygmentsBridge(object):
# Set these attributes if you want to have different Pygments formatters
@@ -131,10 +125,6 @@ class PygmentsBridge(object):
# lines beginning with "..." are probably placeholders for suite
src = re.sub(r"(?m)^(\s*)" + mark + "(.)", r"\1"+ mark + r"# \2", src)
- # if we're using 2.5, use the with statement
- if sys.version_info >= (2, 5):
- src = 'from __future__ import with_statement\n' + src
-
if sys.version_info < (3, 0) and isinstance(src, unicode):
# Non-ASCII chars will only occur in string literals
# and comments. If we wanted to give them to the parser
@@ -143,18 +133,12 @@ class PygmentsBridge(object):
# just replace all non-ASCII characters.
src = src.encode('ascii', 'replace')
- if (3, 0) <= sys.version_info < (3, 2):
- # Python 3.1 can't process '\r' as linesep.
- # `parser.suite("print('hello')\r\n")` cause error.
- if '\r\n' in src:
- src = src.replace('\r\n', '\n')
-
if parser is None:
return True
try:
parser.suite(src)
- except parsing_exceptions:
+ except (SyntaxError, UnicodeEncodeError):
return False
else:
return True
diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py
index 2c0708f9..54e79da6 100644
--- a/sphinx/pycode/__init__.py
+++ b/sphinx/pycode/__init__.py
@@ -17,7 +17,7 @@ from sphinx.errors import PycodeError
from sphinx.pycode import nodes
from sphinx.pycode.pgen2 import driver, token, tokenize, parse, literals
from sphinx.util import get_module_source, detect_encoding
-from sphinx.util.pycompat import next, StringIO, BytesIO, TextIOWrapper
+from sphinx.util.pycompat import StringIO, BytesIO, TextIOWrapper
from sphinx.util.docstrings import prepare_docstring, prepare_commentdoc
diff --git a/sphinx/pycode/pgen2/parse.c b/sphinx/pycode/pgen2/parse.c
index e09f5058..96fa6c8b 100644
--- a/sphinx/pycode/pgen2/parse.c
+++ b/sphinx/pycode/pgen2/parse.c
@@ -353,95 +353,6 @@ static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name); /*proto*/
-#if PY_VERSION_HEX < 0x02050000
-#ifndef PyAnySet_CheckExact
-
-#define PyAnySet_CheckExact(ob) \
- ((ob)->ob_type == &PySet_Type || \
- (ob)->ob_type == &PyFrozenSet_Type)
-
-#define PySet_New(iterable) \
- PyObject_CallFunctionObjArgs((PyObject *)&PySet_Type, (iterable), NULL)
-
-#define Pyx_PyFrozenSet_New(iterable) \
- PyObject_CallFunctionObjArgs((PyObject *)&PyFrozenSet_Type, (iterable), NULL)
-
-#define PySet_Size(anyset) \
- PyObject_Size((anyset))
-
-#define PySet_Contains(anyset, key) \
- PySequence_Contains((anyset), (key))
-
-#define PySet_Pop(set) \
- PyObject_CallMethod(set, (char *)"pop", NULL)
-
-static INLINE int PySet_Clear(PyObject *set) {
- PyObject *ret = PyObject_CallMethod(set, (char *)"clear", NULL);
- if (!ret) return -1;
- Py_DECREF(ret); return 0;
-}
-
-static INLINE int PySet_Discard(PyObject *set, PyObject *key) {
- PyObject *ret = PyObject_CallMethod(set, (char *)"discard", (char *)"O", key);
- if (!ret) return -1;
- Py_DECREF(ret); return 0;
-}
-
-static INLINE int PySet_Add(PyObject *set, PyObject *key) {
- PyObject *ret = PyObject_CallMethod(set, (char *)"add", (char *)"O", key);
- if (!ret) return -1;
- Py_DECREF(ret); return 0;
-}
-
-#endif /* PyAnySet_CheckExact (<= Py2.4) */
-
-#if PY_VERSION_HEX < 0x02040000
-#ifndef Py_SETOBJECT_H
-#define Py_SETOBJECT_H
-
-static PyTypeObject *__Pyx_PySet_Type = NULL;
-static PyTypeObject *__Pyx_PyFrozenSet_Type = NULL;
-
-#define PySet_Type (*__Pyx_PySet_Type)
-#define PyFrozenSet_Type (*__Pyx_PyFrozenSet_Type)
-
-#define PyAnySet_Check(ob) \
- (PyAnySet_CheckExact(ob) || \
- PyType_IsSubtype((ob)->ob_type, &PySet_Type) || \
- PyType_IsSubtype((ob)->ob_type, &PyFrozenSet_Type))
-
-#define PyFrozenSet_CheckExact(ob) ((ob)->ob_type == &PyFrozenSet_Type)
-
-static int __Pyx_Py23SetsImport(void) {
- PyObject *sets=0, *Set=0, *ImmutableSet=0;
-
- sets = PyImport_ImportModule((char *)"sets");
- if (!sets) goto bad;
- Set = PyObject_GetAttrString(sets, (char *)"Set");
- if (!Set) goto bad;
- ImmutableSet = PyObject_GetAttrString(sets, (char *)"ImmutableSet");
- if (!ImmutableSet) goto bad;
- Py_DECREF(sets);
-
- __Pyx_PySet_Type = (PyTypeObject*) Set;
- __Pyx_PyFrozenSet_Type = (PyTypeObject*) ImmutableSet;
-
- return 0;
-
- bad:
- Py_XDECREF(sets);
- Py_XDECREF(Set);
- Py_XDECREF(ImmutableSet);
- return -1;
-}
-
-#else
-static int __Pyx_Py23SetsImport(void) { return 0; }
-#endif /* !Py_SETOBJECT_H */
-#endif /* < Py2.4 */
-#endif /* < Py2.5 */
-
-
static INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
PyObject *r;
if (!j) return NULL;
diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py
index ce18c0c1..3e32f35b 100644
--- a/sphinx/quickstart.py
+++ b/sphinx/quickstart.py
@@ -11,6 +11,7 @@
import sys, os, time, re
from os import path
+from io import open
TERM_ENCODING = getattr(sys.stdin, 'encoding', None)
@@ -21,7 +22,6 @@ from sphinx.util.osutil import make_filename
from sphinx.util.console import purple, bold, red, turquoise, \
nocolor, color_terminal
from sphinx.util import texescape
-from sphinx.util.pycompat import open
# function to get input from terminal -- overridden by the test suite
try:
diff --git a/sphinx/transforms.py b/sphinx/transforms.py
index 338d4739..35e9d297 100644
--- a/sphinx/transforms.py
+++ b/sphinx/transforms.py
@@ -23,7 +23,6 @@ from sphinx.util import split_index_msg
from sphinx.util.nodes import traverse_translatable_index, extract_messages
from sphinx.util.osutil import ustrftime, find_catalog
from sphinx.util.compat import docutils_version
-from sphinx.util.pycompat import all
from sphinx.domains.std import (
make_term_from_paragraph_node,
make_termnodes_from_paragraph_node,
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index 61061a9a..c7556d05 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -55,7 +55,7 @@ if sys.version_info >= (3, 0):
raise TypeError('%r is not a Python function' % func)
return inspect.getfullargspec(func)
-elif sys.version_info >= (2, 5):
+else: # 2.6, 2.7
from functools import partial
def getargspec(func):
"""Like inspect.getargspec but supports functools.partial as well."""
@@ -86,12 +86,7 @@ elif sys.version_info >= (2, 5):
del func_defaults[i]
except IndexError:
pass
- if sys.version_info >= (2, 6):
- return inspect.ArgSpec(args, varargs, varkw, func_defaults)
- else:
- return (args, varargs, varkw, func_defaults)
-else:
- getargspec = inspect.getargspec
+ return inspect.ArgSpec(args, varargs, varkw, func_defaults)
def isdescriptor(x):
diff --git a/sphinx/util/jsonimpl.py b/sphinx/util/jsonimpl.py
index aa0ea825..de846b24 100644
--- a/sphinx/util/jsonimpl.py
+++ b/sphinx/util/jsonimpl.py
@@ -10,27 +10,15 @@
"""
import UserString
+import json
-try:
- import json
- # json-py's json module has no JSONEncoder; this will raise AttributeError
- # if json-py is imported instead of the built-in json module
- JSONEncoder = json.JSONEncoder
-except (ImportError, AttributeError):
- try:
- import simplejson as json
- JSONEncoder = json.JSONEncoder
- except ImportError:
- json = None
- JSONEncoder = object
-
-
-class SphinxJSONEncoder(JSONEncoder):
+
+class SphinxJSONEncoder(json.JSONEncoder):
"""JSONEncoder subclass that forces translation proxies."""
def default(self, obj):
if isinstance(obj, UserString.UserString):
return unicode(obj)
- return JSONEncoder.default(self, obj)
+ return json.JSONEncoder.default(self, obj)
def dump(obj, fp, *args, **kwds):
diff --git a/sphinx/util/osutil.py b/sphinx/util/osutil.py
index 87717771..a5c461a6 100644
--- a/sphinx/util/osutil.py
+++ b/sphinx/util/osutil.py
@@ -69,6 +69,9 @@ def ensuredir(path):
raise
+# This function is same as os.walk of Python2.6, 2.7, 3.2, 3.3 except a
+# customization that check UnicodeError.
+# The customization obstacle to replace the function with the os.walk.
def walk(top, topdown=True, followlinks=False):
"""Backport of os.walk from 2.6, where the *followlinks* argument was
added.
@@ -155,9 +158,8 @@ else:
def safe_relpath(path, start=None):
- from sphinx.util.pycompat import relpath
try:
- return relpath(path, start)
+ return os.path.relpath(path, start)
except ValueError:
return path
@@ -171,14 +173,13 @@ def find_catalog(docname, compaction):
def find_catalog_files(docname, srcdir, locale_dirs, lang, compaction):
- from sphinx.util.pycompat import relpath
if not(lang and locale_dirs):
return []
domain = find_catalog(docname, compaction)
files = [gettext.find(domain, path.join(srcdir, dir_), [lang])
for dir_ in locale_dirs]
- files = [relpath(f, srcdir) for f in files if f]
+ files = [path.relpath(f, srcdir) for f in files if f]
return files
diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py
index 1e5ea314..9941dc0c 100644
--- a/sphinx/util/pycompat.py
+++ b/sphinx/util/pycompat.py
@@ -11,7 +11,6 @@
import sys
import codecs
-import encodings
# ------------------------------------------------------------------------------
# Python 2/3 compatibility
@@ -48,6 +47,7 @@ if sys.version_info >= (3, 0):
# try to match ParseError details with SyntaxError details
raise SyntaxError(err.msg, (filepath, lineno, offset, err.value))
return unicode(tree)
+ from itertools import zip_longest # Python 3 name
else:
# Python 2
@@ -69,6 +69,8 @@ else:
# error handler
import locale
sys_encoding = locale.getpreferredencoding()
+ # use Python 3 name
+ from itertools import izip_longest as zip_longest
def execfile_(filepath, _globals):
@@ -81,8 +83,8 @@ def execfile_(filepath, _globals):
finally:
f.close()
- # py25,py26,py31 accept only LF eol instead of CRLF
- if sys.version_info[:2] in ((2, 5), (2, 6), (3, 1)):
+ # py26 accept only LF eol instead of CRLF
+ if sys.version_info[:2] == (2, 6):
source = source.replace(b('\r\n'), b('\n'))
# compile to a code object, handle syntax errors
@@ -100,178 +102,7 @@ def execfile_(filepath, _globals):
exec code in _globals
-try:
- from html import escape as htmlescape
-except ImportError:
+if sys.version_info >= (3, 2):
+ from html import escape as htmlescape # >= Python 3.2
+else: # 2.6, 2.7, 3.1
from cgi import escape as htmlescape
-
-# ------------------------------------------------------------------------------
-# Missing builtins and itertools in Python < 2.6
-
-if sys.version_info >= (2, 6):
- # Python >= 2.6
- next = next
-
- from itertools import product
- try:
- from itertools import zip_longest # Python 3 name
- except ImportError:
- from itertools import izip_longest as zip_longest
-
- import os
- relpath = os.path.relpath
- del os
-
- import io
- open = io.open
-
-else:
- # Python < 2.6
- from itertools import izip, repeat, chain
-
- # this is on Python 2, where the method is called "next" (it is refactored
- # to __next__ by 2to3, but in that case never executed)
- def next(iterator):
- return iterator.next()
-
- # These replacement functions have been taken from the Python 2.6
- # itertools documentation.
- def product(*args, **kwargs):
- pools = map(tuple, args) * kwargs.get('repeat', 1)
- result = [[]]
- for pool in pools:
- result = [x + [y] for x in result for y in pool]
- for prod in result:
- yield tuple(prod)
-
- def zip_longest(*args, **kwds):
- # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
- fillvalue = kwds.get('fillvalue')
- def sentinel(counter = ([fillvalue]*(len(args)-1)).pop):
- yield counter() # yields the fillvalue, or raises IndexError
- fillers = repeat(fillvalue)
- iters = [chain(it, sentinel(), fillers) for it in args]
- try:
- for tup in izip(*iters):
- yield tup
- except IndexError:
- pass
-
- from os.path import curdir
- def relpath(path, start=curdir):
- """Return a relative version of a path"""
- from os.path import sep, abspath, commonprefix, join, pardir
-
- if not path:
- raise ValueError("no path specified")
-
- start_list = abspath(start).split(sep)
- path_list = abspath(path).split(sep)
-
- # Work out how much of the filepath is shared by start and path.
- i = len(commonprefix([start_list, path_list]))
-
- rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
- if not rel_list:
- return start
- return join(*rel_list)
- del curdir
-
- from types import MethodType
- def open(filename, mode='r', *args, **kw):
- newline = kw.pop('newline', None)
- mode = mode.replace('t', '')
- f = codecs.open(filename, mode, *args, **kw)
- if newline is not None:
- f._write = f.write
- def write(self, text):
- text = text.replace(u'\r\n', u'\n').replace(u'\n', newline)
- self._write(text)
- f.write = MethodType(write, f)
- return f
-
-
-# ------------------------------------------------------------------------------
-# Missing builtins and codecs in Python < 2.5
-
-if sys.version_info >= (2, 5):
- # Python >= 2.5
- base_exception = BaseException
- any = any
- all = all
-
-else:
- # Python 2.4
- base_exception = Exception
-
- def all(gen):
- for i in gen:
- if not i:
- return False
- return True
-
- def any(gen):
- for i in gen:
- if i:
- return True
- return False
-
- # Python 2.4 doesn't know the utf-8-sig encoding, so deliver it here
-
- def my_search_function(encoding):
- norm_encoding = encodings.normalize_encoding(encoding)
- if norm_encoding != 'utf_8_sig':
- return None
- return (encode, decode, StreamReader, StreamWriter)
-
- codecs.register(my_search_function)
-
- # begin code copied from utf_8_sig.py in Python 2.6
-
- def encode(input, errors='strict'):
- return (codecs.BOM_UTF8 +
- codecs.utf_8_encode(input, errors)[0], len(input))
-
- def decode(input, errors='strict'):
- prefix = 0
- if input[:3] == codecs.BOM_UTF8:
- input = input[3:]
- prefix = 3
- (output, consumed) = codecs.utf_8_decode(input, errors, True)
- return (output, consumed+prefix)
-
- class StreamWriter(codecs.StreamWriter):
- def reset(self):
- codecs.StreamWriter.reset(self)
- try:
- del self.encode
- except AttributeError:
- pass
-
- def encode(self, input, errors='strict'):
- self.encode = codecs.utf_8_encode
- return encode(input, errors)
-
- class StreamReader(codecs.StreamReader):
- def reset(self):
- codecs.StreamReader.reset(self)
- try:
- del self.decode
- except AttributeError:
- pass
-
- def decode(self, input, errors='strict'):
- if len(input) < 3:
- if codecs.BOM_UTF8.startswith(input):
- # not enough data to decide if this is a BOM
- # => try again on the next call
- return (u"", 0)
- elif input[:3] == codecs.BOM_UTF8:
- self.decode = codecs.utf_8_decode
- (output, consumed) = codecs.utf_8_decode(input[3:],errors)
- return (output, consumed+3)
- # (else) no BOM present
- self.decode = codecs.utf_8_decode
- return codecs.utf_8_decode(input, errors)
-
- # end code copied from utf_8_sig.py
diff --git a/sphinx/versioning.py b/sphinx/versioning.py
index a16751bb..ccab41d4 100644
--- a/sphinx/versioning.py
+++ b/sphinx/versioning.py
@@ -11,8 +11,9 @@
"""
from uuid import uuid4
from operator import itemgetter
+from itertools import product
-from sphinx.util.pycompat import product, zip_longest, all
+from sphinx.util.pycompat import zip_longest
# anything below that ratio is considered equal/changed
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index b55adda0..5429bcbb 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -25,7 +25,6 @@ from sphinx.errors import SphinxError
from sphinx.locale import admonitionlabels, _
from sphinx.util import split_into
from sphinx.util.osutil import ustrftime
-from sphinx.util.pycompat import any
from sphinx.util.texescape import tex_escape_map, tex_replace_map
from sphinx.util.smartypants import educate_quotes_latex
diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py
index 3735a7b6..82eb0f71 100644
--- a/tests/test_autodoc.py
+++ b/tests/test_autodoc.py
@@ -751,12 +751,8 @@ def _funky_classmethod(name, b, c, d, docstring=None):
some arguments."""
def template(cls, a, b, c, d=4, e=5, f=6):
return a, b, c, d, e, f
- if sys.version_info >= (2, 5):
- from functools import partial
- function = partial(template, b=b, c=c, d=d)
- else:
- def function(cls, a, e=5, f=6):
- return template(a, b, c, d, e, f)
+ from functools import partial
+ function = partial(template, b=b, c=c, d=d)
function.__name__ = name
function.__doc__ = docstring
return classmethod(function)
@@ -788,10 +784,9 @@ class Class(Base):
#: should be documented -- süß
attr = 'bar'
+ @property
def prop(self):
"""Property."""
- # stay 2.4 compatible (docstring!)
- prop = property(prop, doc="Property.")
docattr = 'baz'
"""should likewise be documented -- süß"""
diff --git a/tests/test_intl.py b/tests/test_intl.py
index c9822089..0119d677 100644
--- a/tests/test_intl.py
+++ b/tests/test_intl.py
@@ -16,8 +16,6 @@ from StringIO import StringIO
from subprocess import Popen, PIPE
from xml.etree import ElementTree
-from sphinx.util.pycompat import relpath
-
from util import test_roots, path, with_app, SkipTest
@@ -49,7 +47,7 @@ def setup_module():
for f in [f for f in files if f.endswith('.po')]:
po = dirpath / f
mo = root / 'xx' / 'LC_MESSAGES' / (
- relpath(po[:-3], root) + '.mo')
+ os.path.relpath(po[:-3], root) + '.mo')
if not mo.parent.exists():
mo.parent.makedirs()
try:
@@ -75,7 +73,7 @@ def teardown_module():
def elem_gettexts(elem):
def itertext(self):
# this function copied from Python-2.7 'ElementTree.itertext'.
- # for compatibility to Python-2.5, 2.6, 3.1
+ # for compatibility to Python-2.6
tag = self.tag
if not isinstance(tag, basestring) and tag is not None:
return
diff --git a/tests/test_versioning.py b/tests/test_versioning.py
index 6469a33c..5cff92ff 100644
--- a/tests/test_versioning.py
+++ b/tests/test_versioning.py
@@ -15,7 +15,6 @@ from docutils.parsers.rst.directives.html import MetaBody
from sphinx import addnodes
from sphinx.versioning import add_uids, merge_doctrees, get_ratio
-from sphinx.util.pycompat import all
from util import test_root, TestApp
diff --git a/tests/test_websupport.py b/tests/test_websupport.py
index 611a131a..d950a36c 100644
--- a/tests/test_websupport.py
+++ b/tests/test_websupport.py
@@ -11,12 +11,7 @@
import os
from StringIO import StringIO
-
-try:
- from functools import wraps
-except ImportError:
- # functools is new in 2.5
- wraps = lambda f: (lambda w: w)
+from functools import wraps
from sphinx.websupport import WebSupport
from sphinx.websupport.errors import DocumentNotFoundError, \
diff --git a/tests/util.py b/tests/util.py
index 4ba89030..a2f345bf 100644
--- a/tests/util.py
+++ b/tests/util.py
@@ -13,12 +13,7 @@ import tempfile
import shutil
import re
from codecs import open
-
-try:
- from functools import wraps
-except ImportError:
- # functools is new in 2.4
- wraps = lambda f: (lambda w: w)
+from functools import wraps
from sphinx import application
from sphinx.theming import Theme
diff --git a/tox.ini b/tox.ini
index f1675e90..006819ef 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist=py25,py26,py27,py31,py32,py33,pypy,du11,du10,du09,du08,du07
+envlist=py26,py27,py32,py33,pypy,du11,du10,du09,du08,du07
[testenv]
deps=
@@ -12,14 +12,6 @@ commands=
{envpython} tests/run.py {posargs}
sphinx-build -W -b html -d {envtmpdir}/doctrees doc {envtmpdir}/html
-[testenv:py25]
-deps=
- simplejson==2.5.0
- {[testenv]deps}
-setenv=
- PIP_INSECURE = 1
- {[testenv]setenv}
-
[testenv:py33]
deps=
docutils>=0.10.0