From 45de088e3891c72c908daf2d985ec1191e1ed0bb Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 15 May 2026 03:24:37 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20get=5Fblock=5Fat?= =?UTF-8?q?tr=20by=20removing=20hasattr=20overhead?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactors `get_block_attr` to remove the use of `hasattr()`, replacing it with `isinstance(dict)` check first and using `getattr(block, attr, default)` to avoid double-evaluation overhead and prevent edge cases where dictionaries might return built-in methods instead of intended keys. Co-authored-by: shreyashjagtap157 <38904253+shreyashjagtap157@users.noreply.github.com> --- .jules/bolt.md | 4 ++++ core/anthropic/content.py | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 18ff3f4..dc60696 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -14,3 +14,7 @@ 1. Increased default HTTP_READ_TIMEOUT to 600s across all providers. 2. Modified GlobalRateLimiter to treat httpx.TimeoutException and openai.APITimeoutError as retryable events (Status 408). 3. Increased SDK max_retries to 2 in OpenAIChatTransport to handle transient connection resets. + +## 2024-05-25 - Avoid hasattr() Overheads in High-Frequency Python Loops +**Learning:** In high-frequency content block parsing logic for APIs, `hasattr()` is computationally expensive because it catches and hides internal `AttributeError` exceptions inside the CPython interpreter runtime. Also, if a dictionary has a key that matches a built-in dict method name (like `get` or `keys`), `hasattr()` evaluates to `True` leading to method object extraction instead of key retrieval. +**Action:** When working with mixed dict/object types in payload schemas, explicitly isolate dict behaviors using `isinstance(obj, dict)` initially, then fall back to direct `getattr(obj, attr, default)` calls to avoid double-lookups and exception silencing overheads. diff --git a/core/anthropic/content.py b/core/anthropic/content.py index e16aaaf..204235c 100644 --- a/core/anthropic/content.py +++ b/core/anthropic/content.py @@ -5,11 +5,9 @@ from typing import Any def get_block_attr(block: Any, attr: str, default: Any = None) -> Any: """Get an attribute from a Pydantic model, lightweight object, or dict.""" - if hasattr(block, attr): - return getattr(block, attr) if isinstance(block, dict): return block.get(attr, default) - return default + return getattr(block, attr, default) def get_block_type(block: Any) -> str | None: