Skip to content

Commit

Permalink
Add support for deprecating connections.
Browse files Browse the repository at this point in the history
  • Loading branch information
TallJimbo committed Jun 30, 2023
1 parent 806fb6d commit c2187a6
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 2 deletions.
1 change: 1 addition & 0 deletions doc/changes/DM-39227.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make it possible to deprecate `PipelineTask` connections.
2 changes: 1 addition & 1 deletion python/lsst/pipe/base/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def __new__(
configConnectionsNamespace: dict[str, pexConfig.Field] = {}
for fieldName, obj in connectionsClass.allConnections.items():
configConnectionsNamespace[fieldName] = pexConfig.Field[str](
doc=f"name for connection {fieldName}", default=obj.name
doc=f"name for connection {fieldName}", default=obj.name, deprecated=obj.deprecated
)
# If there are default templates also add them as fields to
# configure the template values
Expand Down
8 changes: 8 additions & 0 deletions python/lsst/pipe/base/connectionTypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ class BaseConnection:
doc: str = ""
multiple: bool = False

deprecated: str | None = dataclasses.field(default=None, kw_only=True)
"""A description of why this connectoin is deprecated, including the
version after which it may be removed.
If not `None`, the string is appended to the docstring for this connection
and the corresponding config Field.
"""

_connection_type_set: ClassVar[str]

def __get__(self, inst, klass):
Expand Down
10 changes: 9 additions & 1 deletion python/lsst/pipe/base/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,15 @@ def __call__(cls, *, config: PipelineTaskConfig | None = None) -> PipelineTaskCo
instance.allConnections = MappingProxyType(instance._allConnections)
for internal_name, connection in cls.allConnections.items():
dataset_type_name = getattr(config.connections, internal_name).format(**templateValues)
instance_connection = dataclasses.replace(connection, name=dataset_type_name)
instance_connection = dataclasses.replace(
connection,
name=dataset_type_name,
doc=(
connection.doc
if connection.deprecated is None
else f"{connection.doc}\n{connection.deprecated}"
),
)
instance._allConnections[internal_name] = instance_connection

# Finally call __init__. The base class implementation does nothing;
Expand Down
18 changes: 18 additions & 0 deletions tests/test_connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,24 @@ class TestConnectionsWithBrokenDimensionsIter(pipeBase.PipelineTask, dimensions=
with self.assertRaises(TypeError):
pipeBase.connectionTypes.Output(Doc="mock doc", dimensions=1, name="output", storageClass="mock")

def test_deprecation(self) -> None:
"""Test support for deprecating connections."""

class TestConnections(pipeBase.PipelineTaskConnections, dimensions=self.test_dims):
input1 = pipeBase.connectionTypes.Input(
doc="Docs for input1",
name="input1_dataset_type",
storageClass="StructuredDataDict",
deprecated="Deprecated in v50000, will be removed after v50001.",
)

class TestConfig(pipeBase.PipelineTaskConfig, pipelineConnections=TestConnections):
pass

config = TestConfig()
with self.assertWarns(FutureWarning):
config.connections.input1 = "some_other_dataset_type"


class MyMemoryTestCase(lsst.utils.tests.MemoryTestCase):
pass
Expand Down

0 comments on commit c2187a6

Please sign in to comment.