944
def _win32_canonical_relpath(base, path):
945
"""Return the canonical path relative to base.
947
Like relpath, but on case-insensitive-case-preserving file-systems, this
948
will return the relpath as stored on the file-system rather than in the case
949
specified in the input string, for all existing portions of the path.
951
TODO: it should be possible to optimize this by using the win32 API
952
FindFiles function to look for the specified name - but using os.listdir()
953
still gives us the correct semantics in the short term.
955
rel = relpath(base, path)
956
# '.' will have been turned into ''
960
abs_base = abspath(base)
962
_listdir = os.listdir
964
# use an explicit iterator so we can easily consume the rest on early exit.
965
bit_iter = iter(rel.replace('\\', '/').split('/'))
968
for look in _listdir(current):
969
if lbit == look.lower():
970
current = pathjoin(current, look)
973
# got to the end, nothing matched, so we just return the
974
# non-existing bits as they were specified (the filename may be
975
# the target of a move, for example).
976
current = pathjoin(current, bit, *list(bit_iter))
978
return current[len(abs_base)+1:]
980
if sys.platform == "win32":
981
canonical_relpath = _win32_canonical_relpath
983
canonical_relpath = relpath
944
986
def safe_unicode(unicode_or_utf8_string):
945
987
"""Coerce unicode_or_utf8_string into unicode.