def join(base, *additions):
'''
Extends os.path.join so work with s3:// and file:// urls
This inherits a quirk of os.path.join: if 'addition' is
an absolute path, path components of base are thrown away.
'addition' must be an absolute or relative path, not
a URL.
`base` and `addition` can use any path separator, but the
result will always be normalized to os.sep.
'''
from urlparse import urlparse, urljoin, ParseResult
addition = sep.join(additions)
(scheme, netloc, _, params, query, fragment) = urlparse(addition)
if any([scheme, netloc, params, query, fragment]):
raise ValueError('Addition must be an absolute or relative path, not a URL')
if islocal(base):
return os.path.join(parse(base).path, addition.replace(sep, os.sep))
k = parse(base)
# Call urljoin instead of os.path.join, since it uses '/' instead of
# os.sep, which is '\' on Windows.
#
# Given disparity between os.path.join and urljoin, we prefer the
# behavior of os.path.join:
#
# >>> os.path.join('foo/bar', 'baz')
# 'foo/bar/baz'
# >>> urlparse.urljoin('foo/bar', 'baz')
# 'foo/baz'
#
# So we add a trailing slash if there is none
if k.path.endswith(sep):
s3path = urljoin(k.path, addition)
else:
s3path = urljoin(k.path + sep, addition)
return ParseResult(k.scheme, k.netloc, s3path, k.params, k.query, k.fragment).geturl() # pylint: disable=too-many-function-args,unexpected-keyword-arg
评论列表
文章目录