Prhub

#25437 Drop dead hasattr guards (hisparse_coordinator, metrics_collector)

原始 PR 作者 fzyzcjy 合并时间 2026-05-16 09:19 文件变更 2 提交数 1 评论 1 代码增减 +1 / -4

执行摘要

删除两个冗余的 hasattr 守卫语句

PR body 明确指出这两个 hasattr 守卫是死代码——ModelRunner.__init__ 已在构造函数中无条件设置 self.hisparse_coordinator = NoneScheduler.__init__enable_metrics 分支内创建 self.metrics_collector。守卫掩盖了真实的不变式,移除后若未来重构遗漏属性赋值,会立即在调用点抛出 AttributeError 而非静默失败。

可以直接合并的低风险机械重构。适合作为机械重构链中的一环,展示了如何安全地淘汰防御性编程遗迹。值得精读 PR body 的分析方法——通过追溯属性赋值点来证明守卫无效。

讨论亮点

PR 没有 review 评论或线程;机器人注释提示达到每日配额限制。PR body 已完整说明每个守卫为何是死亡代码,且有同类 PR 的信任度作为背景(作者 fzyzcjy 正在批量做机械重构)。

实现拆解

  1. 删除 model_runner.py 中的死守卫:移除 __init__ 末尾的 if not hasattr(self, "hisparse_coordinator"): self.hisparse_coordinator = None 块。该代码位于构造函数后续逻辑之后,而构造函数早前已无条件执行 self.hisparse_coordinator = None(见 __init__# For weight updates 之前的部分),因此守卫始终为假。
  2. 简化 scheduler.py 中的条件:将 if self.enable_metrics and hasattr(self, "metrics_collector"): 改为 if self.enable_metrics:Scheduler.__init__if self.enable_metrics: 分支内创建 self.metrics_collector,后续执行路径一致,hasattr 检查冗余。
  3. 无测试、配置或部署配套改动:这是一个纯机械重构,删除死代码,不影响外部行为。
文件 模块 状态 重要度
python/sglang/srt/model_executor/model_runner.py 模型加载器 modified 5.37
python/sglang/srt/managers/scheduler.py 调度器 modified 5.1

关键源码片段

python/sglang/srt/model_executor/model_runner.py data-contract

删除了 `if not hasattr(self, "hisparse_coordinator"): self.hisparse_coordinator = None` 死守卫,移除 3 行。

# python/sglang/srt/model_executor/model_runner.py
# 在 __init__ 末尾,原来有以下死守卫:
# if not hasattr(self, "hisparse_coordinator"):
# self.hisparse_coordinator = None
# 但构造函数中早有无条件赋值:
# self.hisparse_coordinator = None (大约在第 520 行前后)
# 因此这个守卫永远不会触发,现已删除。
python/sglang/srt/managers/scheduler.py core-logic

简化了 `if self.enable_metrics and hasattr(self, "metrics_collector"):` 为 `if self.enable_metrics:`,因为 `metrics_collector` 在 `enable_metrics` 分支内保证已创建。

# python/sglang/srt/managers/scheduler.py
# 在 init_model_worker 方法中,原来第 784 行:
# if self.enable_metrics and hasattr(self, "metrics_collector"):
# 改为:
if self.enable_metrics:
    self.metrics_collector.emit_constants(
        max_total_num_tokens=self.max_total_num_tokens,
        max_running_requests_under_SLO=getattr(
            self, "max_running_requests_under_SLO", None
        ),
        engine_startup_time=0.0,
        engine_load_weights_time=0.0,
        page_size=self.page_size,
        num_pages=self.max_total_num_tokens // self.page_size,
        context_len=self.model_config.context_len,
        startup_available_gpu_memory_gb=avail_mem,
    )
# 因为 Scheduler.__init__ 在 self.enable_metrics 为真时一定创建了
# self.metrics_collector,所以 hasattr 是多余的。

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

风险极低:两处守卫均被证明为死代码,移除后仅在极端情况下(若未来有人误删了构造函数中的属性赋值)才会导致 AttributeError,而这正是期望的快速失败行为。不影响运行时逻辑、性能或兼容性。

仅影响两个源文件,总共删除了 4 行、增加了 1 行(调整缩进)。对用户无感知;对开发者而言,未来若遗漏 hisparse_coordinatormetrics_collector 的初始化,将在调用点立即得到清晰的崩溃,而非静默跳过。

无显著风险

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论