diff --git a/CHANGELOG.md b/CHANGELOG.md index bbcf59f3..21981d9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,9 @@ - Replaced hardcoded HTTP statuses with `HTTPStatus` from the `http` stdlib module. - Added `include_cookies` option to the `ExplorerApollo`. - Fixed typing on `extract_data_from_request` method. -- Fixed tests websockets after starlette update +- Fixed tests websockets after starlette update. - Added `share_enabled` param to `ExplorerPlayground` to enable share playground feature. +- Added support for nested attribute resolution in alias resolvers. ## 0.23 (2024-03-18) diff --git a/ariadne/resolvers.py b/ariadne/resolvers.py index 21a3014a..7a433414 100644 --- a/ariadne/resolvers.py +++ b/ariadne/resolvers.py @@ -79,9 +79,16 @@ def add_resolver_to_field( def resolve_parent_field(parent: Any, field_name: str) -> Any: - if isinstance(parent, Mapping): - return parent.get(field_name) - return getattr(parent, field_name, None) + value = parent + for name in field_name.split("."): + if isinstance(value, Mapping): + value = value.get(name) + else: + value = getattr(value, name, None) + + if value is None: + break + return value def resolve_to(attr_name: str) -> Resolver: diff --git a/tests/test_default_resolvers.py b/tests/test_default_resolvers.py index 6efa5d21..58b24d93 100644 --- a/tests/test_default_resolvers.py +++ b/tests/test_default_resolvers.py @@ -14,6 +14,15 @@ def callable_resolver(*_): assert alias_resolver(obj, None) +def test_alias_resolver_supports_nested_name(): + parent_mapping = {"nested": {"hello": "world"}} + parent_object = Mock(nested=Mock(hello="world")) + + alias_resolver = resolve_to("nested.hello") + assert alias_resolver(parent_mapping, None) == "world" + assert alias_resolver(parent_object, None) == "world" + + def test_alias_resolver_passess_field_args_to_callable_return_value(): def callable_resolver(*_, test): return test