Skip to content

Commit

Permalink
Add isComposite method to DatasetRef, DatasetType and StorageClass
Browse files Browse the repository at this point in the history
This provides an explicit interface for askign the question
of whether the thing is a composite type or not. Simplifies
doDisassembly significantly.
  • Loading branch information
timj committed Aug 28, 2018
1 parent 474dd7e commit dcd44b6
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 23 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 @@ -285,7 +285,7 @@ def getDirect(self, ref, parameters=None):
# if the ref exists in the store we return it directly
if self.datastore.exists(ref):
return self.datastore.get(ref, parameters=parameters)
elif ref.components:
elif ref.isComposite():
# Reconstruct the composite
components = {}
for compName, compRef in ref.components.items():
Expand Down
2 changes: 1 addition & 1 deletion python/lsst/daf/butler/core/assembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def getValidComponents(self, composite):
`CompositeAssembler.storageClass`.
"""
components = {}
if self.storageClass is not None and self.storageClass.components:
if self.storageClass is not None and self.storageClass.isComposite():
for c in self.storageClass.components:
if isinstance(composite, collections.Mapping):
comp = composite[c]
Expand Down
32 changes: 12 additions & 20 deletions python/lsst/daf/butler/core/composites.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
import logging

from .config import ConfigSubset
from .datasets import DatasetType, DatasetRef
from .storageClass import StorageClass

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -79,31 +77,25 @@ def doDisassembly(self, entity):
-------
disassemble : `bool`
Returns `True` if disassembly should occur; `False` otherwise.
Raises
------
ValueError
The supplied argument is not understood.
"""
components = None
datasetTypeName = None
storageClassName = None
if isinstance(entity, DatasetRef):
entity = entity.datasetType
if isinstance(entity, DatasetType):
datasetTypeName = entity.name
storageClassName = entity.storageClass.name
components = entity.storageClass.components
elif isinstance(entity, StorageClass):
storageClassName = entity.name
components = entity.components
else:
raise ValueError(f"Unexpected argument: {entity:!r}")

# We know for a fact this is not a composite
if not components:

if not hasattr(entity, "isComposite"):
raise ValueError(f"Supplied entity ({entity}) is not understood.")

# If this is not a composite there is nothing to disassemble.
if not entity.isComposite():
log.debug("%s will not be disassembled (not a composite)", entity)
return False

matchName = "{} (via default)".format(entity)
disassemble = self.config["default"]

for name in (datasetTypeName, storageClassName):
for name in (entity.lookupNames()):
if name is not None and name in self.config["names"]:
disassemble = self.config[f"names.{name}"]
matchName = name
Expand Down
22 changes: 22 additions & 0 deletions python/lsst/daf/butler/core/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,17 @@ def componentTypeName(self, component):
return self.nameWithComponent(self.name, component)
raise KeyError("Requested component ({}) not understood by this DatasetType".format(component))

def isComposite(self):
"""Boolean indicating whether this `DatasetType` is a composite type.
Returns
-------
isComposite : `bool`
`True` if this `DatasetType` is a composite type, `False`
otherwise.
"""
return self.storageClass.isComposite()

def lookupNames(self):
"""Names to use when looking up this datasetType in a configuration.
Expand Down Expand Up @@ -282,6 +293,17 @@ def detach(self):
ref._id = None
return ref

def isComposite(self):
"""Boolean indicating whether this `DatasetRef` is a composite type.
Returns
-------
isComposite : `bool`
`True` if this `DatasetRef` is a composite type, `False`
otherwise.
"""
return self.datasetType.isComposite()

def lookupNames(self):
"""Names to use when looking up this DatasetRef in a configuration.
Expand Down
14 changes: 14 additions & 0 deletions python/lsst/daf/butler/core/storageClass.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,20 @@ def assembler(self):
raise TypeError(f"No assembler class is associated with StorageClass {self.name}")
return cls(storageClass=self)

def isComposite(self):
"""Boolean indicating whether this `StorageClass` is a composite
or not.
Returns
-------
isComposite : `bool`
`True` if this `StorageClass` is a composite, `False`
otherwise.
"""
if self.components:
return True
return False

def lookupNames(self):
"""Names to use when looking up this DatasetRef in a configuration.
Expand Down
2 changes: 1 addition & 1 deletion python/lsst/daf/butler/formatters/yamlFormatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def _coerceType(self, inMemoryDataset, storageClass, pytype=None):
Object of expected type `pytype`.
"""
if not hasattr(builtins, pytype.__name__):
if storageClass.components:
if storageClass.isComposite():
inMemoryDataset = storageClass.assembler().assemble(inMemoryDataset, pytype=pytype)
else:
# Hope that we can pass the arguments in directly
Expand Down
4 changes: 4 additions & 0 deletions tests/test_composites.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,17 @@ def testMap(self):
# These will fail (not a composite)
sc = StorageClass("StructuredDataJson")
d = DatasetType("dummyTrue", ("a", "b"), sc)
self.assertFalse(sc.isComposite())
self.assertFalse(d.isComposite())
self.assertFalse(c.doDisassembly(d), f"Test with DatasetType: {d}")
self.assertFalse(c.doDisassembly(sc), f"Test with StorageClass: {sc}")

# Repeat but this time use a composite storage class
sccomp = StorageClass("Dummy")
sc = StorageClass("StructuredDataJson", components={"dummy": sccomp})
d = DatasetType("dummyTrue", ("a", "b"), sc)
self.assertTrue(sc.isComposite())
self.assertTrue(d.isComposite())
self.assertTrue(c.doDisassembly(d), f"Test with DatasetType: {d}")
self.assertFalse(c.doDisassembly(sc), f"Test with StorageClass: {sc}")

Expand Down

0 comments on commit dcd44b6

Please sign in to comment.