# PR #29549 完整报告

- 仓库：`sgl-project/sglang`
- 标题：Replace hasattr with isinstance in SHM feature helpers
- 合并时间：2026-06-29 12:31
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/29549

---

# 执行摘要

- 一句话：用 isinstance 替换 hasattr 检查 SHM 特征辅助函数
- 推荐动作：建议合入。此 PR 是有意义的代码清理，提升了类型安全和可维护性，适合作为代码可读性改进的示例。

# 功能与动机

清除 `hasattr` 和 `getattr` 的动态属性检查，改用 `isinstance` 直接判断已知类型（`BaseBatchReq`、`TokenizedGenerateReqInput`、`TokenizedEmbeddingReqInput`），利用类型信息使代码意图更清晰、更安全。

# 实现拆解

1. **新增导入**：在 `mm_utils.py` 中导入 `BaseBatchReq`、`TokenizedGenerateReqInput`、`TokenizedEmbeddingReqInput`（来自 `sglang.srt.managers.io_struct`）。
2. **`wrap_shm_features`**：将 `hasattr(obj, "mm_inputs") and obj.mm_inputs` 替换为 `if obj.mm_inputs:`；将 `getattr(item, "hash", None)` 替换为 `item.hash`；将两个 `hasattr(item, ...)` 条件替换为直接字段访问 `item.feature is not None` 和 `item.precomputed_embeddings is not None`。
3. **`has_shm_features`**：将 `hasattr(req, "batch")` 替换为 `isinstance(req, BaseBatchReq)`；将 `hasattr(req, "mm_inputs")` 替换为 `isinstance(req, (TokenizedGenerateReqInput, TokenizedEmbeddingReqInput))`；将 `getattr(item, "precomputed_embeddings", None)` 替换为直接访问 `item.precomputed_embeddings`。
4. **`unwrap_shm_features`**：同样使用 `isinstance` 检查类型，并直接访问 `mm_inputs`、`feature`、`precomputed_embeddings` 字段。

关键文件：
- `python/sglang/srt/managers/mm_utils.py`（模块 多模态工具；类别 source；类型 dependency-wiring；符号 wrap_shm_features, unwrap_shm_features, has_shm_features）: 唯一修改的文件，重构了三个核心函数，替换 hasattr/isinstance 以及直接字段访问。

关键符号：wrap_shm_features, unwrap_shm_features, has_shm_features

## 关键源码片段

### `python/sglang/srt/managers/mm_utils.py`

唯一修改的文件，重构了三个核心函数，替换 hasattr/isinstance 以及直接字段访问。

```python
def has_shm_features(recv_reqs):
    """Return True if any request in the list contains ShmPointerMMData."""
    for req in recv_reqs:
        # 替换 hasattr(req, "batch") 为 isinstance(req, BaseBatchReq)
        if isinstance(req, BaseBatchReq):
            if has_shm_features(req.batch):
                return True
        # 替换 hasattr(req, "mm_inputs") 为 isinstance 检查具体类型
        elif (
            isinstance(req, (TokenizedGenerateReqInput, TokenizedEmbeddingReqInput))
            and req.mm_inputs
        ):
            for item in req.mm_inputs.mm_items:
                if _feature_has_shm(item.feature):
                    return True
                # 直接访问 item.precomputed_embeddings，无需 getattr 回退
                if _feature_has_shm(item.precomputed_embeddings):
                    return True
    return False

```

# 评论区精华

无实质性 review 讨论，作者自身评论 "approved, ready for merge"。

- 暂无高价值评论线程

# 风险与影响

- 风险：风险极低。变更仅为类型检查替换和直接字段访问，不涉及逻辑语义变化。但若未来新增请求类型未包含在 `isinstance` 检查中，可能导致遗漏；不过由于目前所有合法请求类型都已覆盖，实际风险可忽略。
- 影响：影响范围限于 `python/sglang/srt/managers/mm_utils.py` 一个文件。对用户无感知；对开发者而言，代码更易读、更类型安全。
- 风险标记：暂无

# 关联脉络

- 暂无明显关联 PR