944
def _win32_canonical_relpath(base, path):
944
def cicp_canonical_relpath(base, path):
945
945
"""Return the canonical path relative to base.
947
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.
948
will return the relpath as stored on the file-system rather than in the
949
case specified in the input string, for all existing portions of the path.
951
NOTE: There is a risk that this will cause O(N) behaviour if called
952
for every path in a tree. However, it is expected this should only be
953
used on path specified by the users. A cache with lifetime controlled
954
by the caller would probably resolve this if it becomes a problem.
956
TODO: it should be possible to optimize this for Windows by using the
957
win32 API FindFiles function to look for the specified name - but using
958
os.listdir() still gives us the correct, platform agnostic semantics in
955
961
rel = relpath(base, path)
956
962
# '.' will have been turned into ''
962
968
_listdir = os.listdir
964
970
# use an explicit iterator so we can easily consume the rest on early exit.
965
bit_iter = iter(rel.replace('\\', '/').split('/'))
971
bit_iter = rel.split('/')
966
972
for bit in bit_iter:
967
973
lbit = bit.lower()
968
974
for look in _listdir(current):
978
984
return current[len(abs_base)+1:]
986
# XXX - TODO - we need better detection/integration of case-insensitive
987
# file-systems; Linux often sees FAT32 devices, for example, so could
988
# probably benefit from the same basic support there. For now though, only
989
# Windows gets that support, and it gets it for *all* file-systems!
980
990
if sys.platform == "win32":
981
canonical_relpath = _win32_canonical_relpath
991
canonical_relpath = cicp_canonical_relpath
983
993
canonical_relpath = relpath