Index: docutils-0.8.1/docutils/frontend.py =================================================================== --- docutils-0.8.1.orig/docutils/frontend.py +++ docutils-0.8.1/docutils/frontend.py @@ -33,6 +33,7 @@ import sys import warnings import ConfigParser as CP import codecs +import locale import optparse from optparse import SUPPRESS_HELP import docutils @@ -193,7 +194,36 @@ def make_paths_absolute(pathdict, keys, value = make_one_path_absolute(base_path, value) pathdict[key] = value +def _bytes_path_to_unicode(path): + '''Change a byte str path segment into unicode + + Note that this is arguably wrong for Unix systems. Unix filesystem paths + are bytes that programs interpret as characters. Filesystem paths are in + no way guaranteed to be decodable into unicode. So this could traceback + if the locale_encoding can't deal with any byte string and it could give + wrong values if the locale_encoding does not match the encoding of + a single one of the path component's values. + + However, the rest of docutils is turning command line args containing + filenames into unicode so switching to unicode is more inline with the + strategy taken by the rest of docutils. + ''' + # converting to Unicode (Python 3 does this automatically): + if sys.version_info < (3,0): + # TODO: make this failsafe and reversible + # locale.getpreferredencoding is not to be preferred to getlocale or + # getdefaultlocale but it is preferred to hardcoding a value. We end + # with latin-1 because it's one of the encodings that is valid for + # every byte. + encoding = locale_encoding or locale.getpreferredencoding() or 'latin-1' + path = unicode(path, encoding) + return path + def make_one_path_absolute(base_path, path): + if isinstance(base_path, unicode) and not isinstance(path, unicode): + path = _bytes_path_to_unicode(path) + elif isinstance(path, unicode) and not isinstance(base_path, unicode): + base_path = _bytes_path_to_unicode(base_path) return os.path.abspath(os.path.join(base_path, path)) def filter_settings_spec(settings_spec, *exclude, **replace):