Skip to content

Commit e14969c

Browse files
authored
Fix false multiple decorator error when combining schema.output and tag (#1574)
Changes SchemaOutput inherits from tag and shares its lifecycle name, so multiplicity check tripped on the existing tag instance. Count only decorators of the same concrete class as self before raising, independent decorators sharing a lifecycle name now compose.
1 parent 5301a9d commit e14969c

2 files changed

Lines changed: 19 additions & 3 deletions

File tree

hamilton/function_modifiers/base.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,13 @@ def __call__(self, fn: Callable):
119119
"""
120120
self.validate(fn)
121121
lifecycle_name = self.__class__.get_lifecycle_name()
122-
if hasattr(fn, self.get_lifecycle_name()):
123-
if not self.allows_multiple():
122+
if hasattr(fn, lifecycle_name):
123+
curr_value = getattr(fn, lifecycle_name)
124+
same_class_present = any(d.__class__ is self.__class__ for d in curr_value)
125+
if same_class_present and not self.allows_multiple():
124126
raise ValueError(
125127
f"Got multiple decorators for decorator @{self.__class__}. Only one allowed."
126128
)
127-
curr_value = getattr(fn, lifecycle_name)
128129
setattr(fn, lifecycle_name, curr_value + [self])
129130
else:
130131
setattr(fn, lifecycle_name, [self])

tests/function_modifiers/test_metadata.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,21 @@ def foo() -> pd.DataFrame:
231231
)
232232

233233

234+
def test_schema_output_combined_with_tag_does_not_raise():
235+
@function_modifiers.schema.output(("ticker", "str"), ("fee", "float"))
236+
@function_modifiers.tag(table_type="reference")
237+
def ref_table_1() -> pd.DataFrame:
238+
return pd.DataFrame.from_records([{"ticker": "AAPL", "fee": 1.0}])
239+
240+
nodes = function_modifiers.base.resolve_nodes(ref_table_1, {})
241+
node_map = {n.name: n for n in nodes}
242+
node_ = node_map["ref_table_1"]
243+
assert (
244+
node_.tags[function_modifiers.schema.INTERNAL_SCHEMA_OUTPUT_KEY] == "ticker=str,fee=float"
245+
)
246+
assert node_.tags["table_type"] == "reference"
247+
248+
234249
def test_decorate_node_with_schema_output_invalid_type():
235250
# quick test to decorate node with schemas
236251
# this tests an internal implementation, so we will likely change

0 commit comments

Comments
 (0)