Skip to content

Commit

Permalink
Clean up the TaskMetadata.names() topLevelOnly deprecation
Browse files Browse the repository at this point in the history
We should have been able to remove the parameter by now but
this was made difficult by us still allowing code to use
it without warning.
  • Loading branch information
timj committed Aug 2, 2023
1 parent 496a576 commit 8fbcfa0
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 30 deletions.
54 changes: 26 additions & 28 deletions python/lsst/pipe/base/_task_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,9 @@
from typing import Any, Protocol

from lsst.daf.butler._compat import _BaseModelCompat
from lsst.utils.introspection import find_outside_stacklevel
from pydantic import Field, StrictBool, StrictFloat, StrictInt, StrictStr

_DEPRECATION_REASON = "Will be removed after v25."
_DEPRECATION_VERSION = "v24"

# The types allowed in a Task metadata field are restricted
# to allow predictable serialization.
_ALLOWED_PRIMITIVE_TYPES = (str, float, int, bool)
Expand Down Expand Up @@ -256,41 +254,41 @@ def getArray(self, key: str) -> list[Any]:
# Report the correct key.
raise KeyError(f"'{key}' not found") from None

def names(self, topLevelOnly: bool = True) -> set[str]:
def names(self, topLevelOnly: bool | None = None) -> set[str]:
"""Return the hierarchical keys from the metadata.
Parameters
----------
topLevelOnly : `bool`
If true, return top-level keys, otherwise full metadata item keys.
topLevelOnly : `bool` or `None`, optional
This parameter is deprecated and will be removed in the future.
If given it can only be `False`. All names in the hierarchy are
always returned.
Returns
-------
names : `collections.abc.Set`
A set of top-level keys or full metadata item keys, including
the top-level keys.
Notes
-----
Should never be called in new code with ``topLevelOnly`` set to `True`
-- this is equivalent to asking for the keys and is the default
when iterating through the task metadata. In this case a deprecation
message will be issued and the ability will raise an exception
in a future release.
When ``topLevelOnly`` is `False` all keys, including those from the
hierarchy and the top-level hierarchy, are returned.
A set of all keys, including those from the hierarchy and the
top-level hierarchy.
"""
if topLevelOnly:
warnings.warn("Use keys() instead. " + _DEPRECATION_REASON, FutureWarning)
return set(self.keys())
else:
names = set()
for k, v in self.items():
names.add(k) # Always include the current level
if isinstance(v, TaskMetadata):
names.update({k + "." + item for item in v.names(topLevelOnly=topLevelOnly)})
return names
raise RuntimeError(
"The topLevelOnly parameter is no longer supported and can not have a True value."
)

if topLevelOnly is False:
warnings.warn(
"The topLevelOnly parameter is deprecated and is always assumed to be False."
" It will be removed completely after v26.",
category=FutureWarning,
stacklevel=find_outside_stacklevel("lsst.pipe.base"),
)

names = set()
for k, v in self.items():
names.add(k) # Always include the current level
if isinstance(v, TaskMetadata):
names.update({k + "." + item for item in v.names()})
return names

def paramNames(self, topLevelOnly: bool) -> set[str]:
"""Return hierarchical names.
Expand Down
2 changes: 1 addition & 1 deletion tests/test_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ def testGetFullMetadata(self):
self.assertIsInstance(fullMetadata["addMult:mult"], _TASK_METADATA_TYPE)
self.assertEqual(set(fullMetadata), {"addMult", "addMult:add", "addMult:mult"})

all_names = fullMetadata.names(topLevelOnly=False)
all_names = fullMetadata.names()
self.assertIn("addMult", all_names)
self.assertIn("addMult.runStartUtc", all_names)

Expand Down
2 changes: 1 addition & 1 deletion tests/test_taskmetadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def testTaskMetadata(self):

self.assertEqual(meta.paramNames(topLevelOnly=False), {"test", "new.int", "new.str"})
self.assertEqual(meta.paramNames(topLevelOnly=True), {"test"})
self.assertEqual(meta.names(topLevelOnly=False), {"test", "new", "new.int", "new.str"})
self.assertEqual(meta.names(), {"test", "new", "new.int", "new.str"})
self.assertEqual(meta.keys(), ("test", "new"))
self.assertEqual(len(meta), 2)
self.assertEqual(len(meta["new"]), 2)
Expand Down

0 comments on commit 8fbcfa0

Please sign in to comment.