From cda0e32cf012ed948da0f6aa914670e51b4ee903 Mon Sep 17 00:00:00 2001 From: Asish Kumar Date: Mon, 25 May 2026 03:15:06 +0530 Subject: [PATCH] Improve power user mode error for dynamic resolvers --- hamilton/function_modifiers/delayed.py | 8 ++++---- tests/function_modifiers/test_delayed.py | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/hamilton/function_modifiers/delayed.py b/hamilton/function_modifiers/delayed.py index d1fa34b91..d88179dd3 100644 --- a/hamilton/function_modifiers/delayed.py +++ b/hamilton/function_modifiers/delayed.py @@ -148,13 +148,13 @@ def optional_config(self) -> dict[str, Any] | None: return self._optional_config def resolve(self, config: dict[str, Any], fn: Callable) -> NodeTransformLifecycle: - if not config[settings.ENABLE_POWER_USER_MODE]: + if not config.get(settings.ENABLE_POWER_USER_MODE, False): raise InvalidDecoratorException( - "Dynamic functions are only allowed in power user mode!" + "Dynamic functions are only allowed in power user mode. " "Why? This is occasionally needed to enable highly flexible " "dataflows, but it can compromise readability if you're not " - "careful! To enable power user mode, pass in the configuration " - f"parameter {settings.ENABLE_POWER_USER_MODE}=True to your driver." + "careful! To enable power user mode, build your driver with " + f".with_config({{{settings.ENABLE_POWER_USER_MODE!r}: True}})." ) missing_configs = [] for item in self.required_config(): diff --git a/tests/function_modifiers/test_delayed.py b/tests/function_modifiers/test_delayed.py index b48fc92b9..65da75540 100644 --- a/tests/function_modifiers/test_delayed.py +++ b/tests/function_modifiers/test_delayed.py @@ -167,11 +167,30 @@ def fn() -> pd.DataFrame: extract_columns(*cols_to_extract + some_cols_you_might_want_to_extract) ), ) - with pytest.raises(base.InvalidDecoratorException): + with pytest.raises(base.InvalidDecoratorException) as exc_info: decorator.resolve( {"cols_to_extract": ["a", "b"], **CONFIG_WITH_POWER_MODE_DISABLED}, fn=fn, ) + error_message = str(exc_info.value) + assert "power user mode" in error_message + assert ".with_config({'hamilton.enable_power_user_mode': True})" in error_message + + +def test_delayed_without_power_mode_config_fails_with_helpful_error(): + def fn() -> pd.DataFrame: + return pd.DataFrame() + + decorator = resolve( + when=ResolveAt.CONFIG_AVAILABLE, + decorate_with=lambda cols_to_extract: extract_columns(*cols_to_extract), + ) + + with pytest.raises(base.InvalidDecoratorException) as exc_info: + decorator.resolve({"cols_to_extract": ["a", "b"]}, fn=fn) + error_message = str(exc_info.value) + assert "power user mode" in error_message + assert ".with_config({'hamilton.enable_power_user_mode': True})" in error_message def test_dynamic_resolve_with_extract_fields():