mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
merge heads
This commit is contained in:
commit
dd41adf0a0
5
CHANGES
5
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
|
||||
--------------------
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
12
setup.py
12
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):
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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():
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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):
|
||||
|
@ -10,27 +10,15 @@
|
||||
"""
|
||||
|
||||
import UserString
|
||||
|
||||
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
|
||||
import json
|
||||
|
||||
|
||||
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):
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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üß"""
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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, \
|
||||
|
@ -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
|
||||
|
10
tox.ini
10
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
|
||||
|
Loading…
Reference in New Issue
Block a user