summaryrefslogtreecommitdiff
path: root/sphinx/util/pycompat.py
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2010-07-30 16:59:47 +0200
committerGeorg Brandl <georg@python.org>2010-07-30 16:59:47 +0200
commit3c786e434a1506b361ec22288e1223050d665c02 (patch)
treea9ac1d60f6c1e5cec60d943bd9f822e49a463aec /sphinx/util/pycompat.py
parent415e6711dfa2f65bd797891d5e92f332150601d3 (diff)
downloadsphinx-3c786e434a1506b361ec22288e1223050d665c02.tar.gz
Run 2to3 on config files which contain Python 2.x unicode literals.
Diffstat (limited to 'sphinx/util/pycompat.py')
-rw-r--r--sphinx/util/pycompat.py67
1 files changed, 62 insertions, 5 deletions
diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py
index 229b54b4..2ec71e72 100644
--- a/sphinx/util/pycompat.py
+++ b/sphinx/util/pycompat.py
@@ -12,6 +12,7 @@
import sys
import codecs
import encodings
+import re
try:
from types import ClassType
@@ -20,11 +21,6 @@ except ImportError:
# Python 3
class_types = (type,)
-try:
- base_exception = BaseException
-except NameError:
- base_exception = Exception
-
# the ubiquitous "bytes" helper function
if sys.version_info >= (3, 0):
@@ -34,6 +30,66 @@ else:
b = str
+encoding_re = re.compile(b(r'coding[=:]\s*([-\w.]+)'))
+unicode_literal_re = re.compile(ur"""
+(?:
+ "(?:[^"\]]*(?:\\.[^"\\]*)*)"|
+ '(?:[^'\]]*(?:\\.[^'\\]*)*)'
+)
+""", re.VERBOSE)
+
+
+try:
+ from lib2to3.refactor import RefactoringTool, get_fixers_from_package
+except ImportError:
+ _run_2to3 = None
+ def should_run_2to3(filepath):
+ return False
+else:
+ def should_run_2to3(filepath):
+ # th default source code encoding for python 2.x
+ encoding = 'ascii'
+ # only the first match of the encoding cookie counts
+ encoding_set = False
+ f = open(filepath, 'rb')
+ try:
+ for i, line in enumerate(f):
+ if line.startswith(b('#')):
+ if i == 0 and b('python3') in line:
+ return False
+ if not encoding_set:
+ encoding_match = encoding_re.match(line)
+ if encoding_match:
+ encoding = encoding_match.group(1)
+ encodin_set = True
+ elif line.strip():
+ try:
+ line = line.decode(encoding)
+ except UnicodeDecodeError:
+ # I'm not sure this will work but let's try it anyway
+ return True
+ if unicode_literal_re.search(line) is not None:
+ return True
+ finally:
+ f.close()
+ return False
+
+ def run_2to3(filepath):
+ sys.path.append('..')
+ fixers = get_fixers_from_package('lib2to3.fixes')
+ fixers.extend(get_fixers_from_package('custom_fixers'))
+ refactoring_tool = RefactoringTool(fixers)
+ source = refactoring_tool._read_python_source(filepath)[0]
+ ast = refactoring_tool.refactor_string(source, 'conf.py')
+ return unicode(ast)
+
+
+try:
+ base_exception = BaseException
+except NameError:
+ base_exception = Exception
+
+
try:
next = next
except NameError:
@@ -41,6 +97,7 @@ except NameError:
def next(iterator):
return iterator.next()
+
try:
bytes = bytes
except NameError: