Skip to content

Commit

Permalink
Make split return ButlerURI as head.
Browse files Browse the repository at this point in the history
  • Loading branch information
DinoBektesevic committed May 4, 2020
1 parent bcedc70 commit 078d938
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 21 deletions.
2 changes: 1 addition & 1 deletion python/lsst/daf/butler/_butler.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ def makeRepo(root: str, config: Union[Config, str, None] = None, standalone: boo
raise ValueError(f"Bucket {uri.netloc} does not exist!")
s3 = boto3.client("s3")
# don't create S3 key when root is at the top-level of an Bucket
if not uri.path != "/":
if not uri.path == "/":
s3.put_object(Bucket=uri.netloc, Key=uri.relativeToPathRoot)
else:
raise ValueError(f"Unrecognized scheme: {uri.scheme}")
Expand Down
34 changes: 23 additions & 11 deletions python/lsst/daf/butler/core/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,39 +197,51 @@ def geturl(self):
return self._uri.geturl()

def split(self):
"""Splits URI into head and tail. Either head or tail can be empty.
Equivalent to os.path.split where head preserves the scheme and netloc.
"""Splits URI into head and tail. Equivalent to os.path.split where
head preserves the URI components.
Returns
-------
head: `str`
Everything leading up to tail. Trailing slashes are stripped from
the head. If `self.path` contains no slashes will be empty.
head: `ButlerURI`
Everything leading up to tail, expanded and normalized as per
ButlerURI rules.
tail : `str`
Last `self.path` component. Tail will be empty if path ends on a
separator. Tail will never contain separators.
"""
if self.scheme:
head, tail = posixpath.split(self.path)
return f"{self.scheme}://{self.netloc}{head}", tail
else:
return os.path.split(self.path)
head, tail = os.path.split(self.path)
headuri = self._uri._replace(path=head)
return self.__class__(headuri, forceDirectory=True), tail

def basename(self):
"""Returns the base name, last element of path, of the URI. If URI ends
on a slash returns an empty string. This is the second element returned
by split().
Equivalent of os.path.basename().
Returns
-------
tail : `str`
Last part of the path attribute. Trail will be empty if path ends
on a separator.
"""
return self.split()[1]

def dirname(self):
"""Returns the directory name of URI, everything up to the last element
of path.
"""Returns a ButlerURI containing all the directories of the path
attribute.
Equivalent of os.path.dirname except trailing slashes are preserved for
URIs with known schemes.
Equivalent of os.path.dirname()
Returns
-------
head : `ButlerURI`
Everything except the tail of path attribute, expanded and
normalized as per ButlerURI rules.
"""
return self.split()[0]

Expand Down
25 changes: 16 additions & 9 deletions tests/test_location.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,30 +177,37 @@ def testSplit(self):
"relative/file.ext", "relative/")

osRelExpected = os.path.join(testRoot, "relative")
expected = (("file:///absolute", "file.ext"), ("file:///absolute", ""),
("file:///absolute", "file.ext"), ("file:///absolute", ""),
("s3://bucket/root", "file.ext"), ("s3://bucket/root", ""),
(osRelExpected, "file.ext"), (osRelExpected, ""))
expected = (("file:///absolute/", "file.ext"), ("file:///absolute/", ""),
("file:///absolute/", "file.ext"), ("file:///absolute/", ""),
("s3://bucket/root/", "file.ext"), ("s3://bucket/root/", ""),
(f"file://{osRelExpected}/", "file.ext"), (f"file://{osRelExpected}/", ""))

for p, e in zip(testPaths, expected):
with self.subTest(path=p):
uri = ButlerURI(p, testRoot)
self.assertEqual(uri.split(), e)
head, tail = uri.split()
self.assertEqual((head.geturl(), tail), e)

# explicit file scheme should force posixpath, check os.path is ignored
posixRelFilePath = posixpath.join(testRoot, "relative")
uri = ButlerURI("file:relative/file.ext", testRoot)
self.assertEqual(uri.split(), (f"file://{posixRelFilePath}", "file.ext"))
head, tail = uri.split()
self.assertEqual((head.geturl(), tail), (f"file://{posixRelFilePath}/", "file.ext"))

# check head can be empty
curDir = os.path.abspath(os.path.curdir) + os.sep
uri = ButlerURI("file.ext", forceAbsolute=False)
self.assertEqual(uri.split(), ("", "file.ext"))
head, tail = uri.split()
self.assertEqual((head.geturl(), tail), (curDir, "file.ext"))

# ensure empty path is not a problem and conforms to os.path.split
uri = ButlerURI("", forceAbsolute=False)
self.assertEqual(uri.split(), (".", ""))
head, tail = uri.split()
self.assertEqual((head.geturl(), tail), (curDir, ""))

uri = ButlerURI(".", forceAbsolute=False)
self.assertEqual(uri.split(), ("", "."))
head, tail = uri.split()
self.assertEqual((head.geturl(), tail), (curDir, "."))


if __name__ == "__main__":
Expand Down

0 comments on commit 078d938

Please sign in to comment.