Skip to content

Commit 4a47e4c

Browse files
dougborgclaude
andcommitted
fix(client): guard _convert_nested_value to_dict fallback with callable()
Third Copilot review on #729: ``hasattr(value, "to_dict")`` would accept a non-callable ``to_dict`` attribute and then raise ``TypeError`` at the call. Use ``getattr(...) + callable(...)`` so the fallback can't introduce a new failure mode on exotic attrs-like objects that expose ``to_dict`` as a property or similar. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent fc7de8b commit 4a47e4c

1 file changed

Lines changed: 7 additions & 3 deletions

File tree

  • katana_public_api_client/models_pydantic

katana_public_api_client/models_pydantic/_base.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,13 @@ def _convert_nested_value(value: Any, registry: Any) -> Any:
292292
# inline properties), so the pydantic generator emits
293293
# ``dict[str, Any]`` while the attrs generator still synthesizes
294294
# a concrete class. The pydantic model expects a dict, so fall
295-
# back to ``to_dict()`` when the attrs side exposes it.
296-
if hasattr(value, "to_dict"):
297-
return value.to_dict()
295+
# back to ``to_dict()`` when the attrs side exposes it as a
296+
# callable (``callable`` rather than ``hasattr`` guards against
297+
# an exotic non-callable ``to_dict`` attribute, which would
298+
# otherwise raise ``TypeError`` at call time).
299+
to_dict_fn = getattr(value, "to_dict", None)
300+
if callable(to_dict_fn):
301+
return to_dict_fn()
298302
# Last resort: warn and pass through. Pydantic validation will
299303
# surface the type mismatch loudly enough.
300304
logger = logging.getLogger(__name__)

0 commit comments

Comments
 (0)