Skip to content

fix(python): 更新 Python 版本匹配逻辑以支持更广泛的版本 - #651

Merged
wess09 merged 4 commits into
masterfrom
dev
Jul 28, 2026
Merged

fix(python): 更新 Python 版本匹配逻辑以支持更广泛的版本#651
wess09 merged 4 commits into
masterfrom
dev

Conversation

@wess09

@wess09 wess09 commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary by Sourcery

调整自动搜查战斗流程和 Python 环境管理,以提升减轻情绪值的准确性,并放宽对受管 Python 版本的限制。

Bug 修复:

  • 防止在自动搜查战斗和协同解体流程中,对沉船(D 级)战斗重复或错误地进行情绪值减轻。
  • 通过仅在专用沉船弹窗中进行确认,并将处理延后到状态处理阶段,避免将短暂出现的 D 级界面匹配误判为真实沉船。

增强:

  • 在自动搜查战斗过程中跟踪舰队索引和情绪减轻标记,将沉船处理统一集中到状态阶段执行。
  • 优化 SP 关卡通关判定逻辑,从“任意非 D 级评级”改为必须达到 S 级后才视为通关。
  • 放宽受管 Python 搜索规则,选择本机最新安装的 CPython,并接受任意能够成功初始化的 Python 3 版本,而不是只固定使用单一指定版本。

构建:

  • 更新基于 uv 的自包含 Python 启动流程,不再固定特定 Python 版本,并在可用时使用通用的 python3 可执行文件。
Original summary in English

Summary by Sourcery

Adjust auto-search combat flow and Python environment management to improve emotion reduction accuracy and loosen managed Python version constraints.

Bug Fixes:

  • Prevent duplicate or incorrect emotion reduction on shipwreck (D-rank) battles during auto-search combat and coalition scuttle flows.
  • Avoid misclassifying transient D-rank screen matches as true shipwrecks by only confirming via the dedicated shipwreck dialog and deferring handling to status processing.

Enhancements:

  • Track fleet index and emotion-reduction flags across auto-search combat to centralize shipwreck handling in the status phase.
  • Refine SP stage completion logic to require S-rank instead of any non-D rank before treating the run as passed.
  • Relax managed Python discovery to select the latest installed CPython and accept any Python 3 version that initializes correctly, rather than a single pinned version.

Build:

  • Update uv-based self-contained Python bootstrap to stop pinning a specific Python version and to use generic python3 executables when available.

Beatrice-betty and others added 4 commits July 28, 2026 00:22
1. 新增相关状态变量防止重复触发沉船心情扣减
2. 调整结算超时处理逻辑,避免误触扣心情和点击
3. 规范沉船判定和心情扣减的触发时机
## 由 Sourcery 提供的摘要

调整自动搜查战斗结算逻辑,以正确区分已确认的沉船损失与暂时匹配到的 D 评价战斗,并优化 SP 关卡通关判定条件。

错误修复:
- 防止在未出现沉船确认弹窗时,将自动搜查战斗误判为 D 评价撤退。
- 确保在结果识别过程中,S/A/B 评价结果可以覆盖暂时匹配到的 D 评价模板。
- 修复联合舰队 SP 关卡的通关逻辑,使只有已确认的 S 评价结算才计为通关,而 A/B/C/D 评价会继续出击。
- 通过记录士气已被扣减的状态,避免在沉船时重复扣减士气。

功能改进:
- 在联合自沉战斗中显式记录 S 评价结果,以支持精确的 SP 通关判定。
- 将 D 评价的沉船确认和士气扣减集中到自动搜查战斗状态阶段统一处理,使逻辑更加稳健。

<details>
<summary>Original summary in English</summary>

## Summary by Sourcery

Adjust automatic search combat settlement handling to correctly
distinguish confirmed shipwreck losses from transient D-rank matches and
refine SP stage clear conditions.

Bug Fixes:
- Prevent misclassifying auto-search battles as D-rank retreats unless a
shipwreck confirmation popup appears.
- Ensure S/A/B rank results can override transiently matched D-rank
templates during result recognition.
- Fix coalition SP stage clear logic so only confirmed S-rank
settlements count as clears, with A/B/C/D ranks continuing sorties.
- Avoid duplicate morale reduction on shipwreck by tracking whether the
reduction has already been applied.

Enhancements:
- Record S-rank results explicitly in coalition scuttle battles to
support precise SP clear determination.
- Centralize D-rank shipwreck confirmation and morale reduction in the
auto-search combat status phase for more robust handling.

</details>

Bug 修复:
- 在自动索敌战斗中,只有在出现沉船确认弹窗后才将战斗视为沉船,避免误判为 D 评价撤退。
- 确保在战斗结果识别过程中,S/A/B 评价可以覆盖临时匹配到的 D 评价模板。
- 修复联合舰队 SP 关卡通关逻辑,只有确认的 S 评价结算才视为通关,而 A/B/C/D 评价会触发继续出击。

增强:
- 在联合拆解战中显式记录 S 评价结果,以支持更精确的 SP 通关判定。

<details>
<summary>Original summary in English</summary>

## 由 Sourcery 提供的摘要

调整自动搜查战斗结算逻辑,以正确区分已确认的沉船损失与暂时匹配到的 D 评价战斗,并优化 SP 关卡通关判定条件。

错误修复:
- 防止在未出现沉船确认弹窗时,将自动搜查战斗误判为 D 评价撤退。
- 确保在结果识别过程中,S/A/B 评价结果可以覆盖暂时匹配到的 D 评价模板。
- 修复联合舰队 SP 关卡的通关逻辑,使只有已确认的 S 评价结算才计为通关,而 A/B/C/D 评价会继续出击。
- 通过记录士气已被扣减的状态,避免在沉船时重复扣减士气。

功能改进:
- 在联合自沉战斗中显式记录 S 评价结果,以支持精确的 SP 通关判定。
- 将 D 评价的沉船确认和士气扣减集中到自动搜查战斗状态阶段统一处理,使逻辑更加稳健。

<details>
<summary>Original summary in English</summary>

## Summary by Sourcery

Adjust automatic search combat settlement handling to correctly
distinguish confirmed shipwreck losses from transient D-rank matches and
refine SP stage clear conditions.

Bug Fixes:
- Prevent misclassifying auto-search battles as D-rank retreats unless a
shipwreck confirmation popup appears.
- Ensure S/A/B rank results can override transiently matched D-rank
templates during result recognition.
- Fix coalition SP stage clear logic so only confirmed S-rank
settlements count as clears, with A/B/C/D ranks continuing sorties.
- Avoid duplicate morale reduction on shipwreck by tracking whether the
reduction has already been applied.

Enhancements:
- Record S-rank results explicitly in coalition scuttle battles to
support precise SP clear determination.
- Centralize D-rank shipwreck confirmation and morale reduction in the
auto-search combat status phase for more robust handling.

</details>

</details>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@wess09
wess09 merged commit e109aa0 into master Jul 28, 2026
8 checks passed
@sourcery-ai

sourcery-ai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Reviewer's Guide

优化自动搜索战斗中沉船心情值减少和SP清零判定逻辑,避免重复或误判导致的心情惩罚;同时将由 uv 管理的 Python 查找与校验逻辑泛化为支持任意已安装的 CPython 3.x,而不是固定绑定到 3.14.3 版本。

更新后的自动搜索战斗沉船心情减少时序图

sequenceDiagram
    participant AutoSearchCombat
    participant Emotion

    AutoSearchCombat->>AutoSearchCombat: auto_search_combat(emotion_reduce, fleet_index)
    AutoSearchCombat->>AutoSearchCombat: set _auto_search_emotion_reduce
    AutoSearchCombat->>AutoSearchCombat: set _auto_search_fleet_index
    AutoSearchCombat->>AutoSearchCombat: set _shipwreck_emotion_reduced = False
    AutoSearchCombat->>AutoSearchCombat: auto_search_combat_execute(emotion_reduce, fleet_index)

    alt appear(OPTS_INFO_D) in auto_search_combat_execute
        alt emotion_reduce and not _shipwreck_emotion_reduced
            AutoSearchCombat->>Emotion: reduce(fleet_index, shipwreck=True)
            AutoSearchCombat->>AutoSearchCombat: _shipwreck_emotion_reduced = True
        end
        AutoSearchCombat->>AutoSearchCombat: _withdraw = True
    else appear(BATTLE_STATUS_D or EXP_INFO_D)
        AutoSearchCombat->>AutoSearchCombat: break loop (no emotion change)
    else confirm_timer.reached()
        AutoSearchCombat->>AutoSearchCombat: _withdraw = True (no emotion change)
    end

    AutoSearchCombat->>AutoSearchCombat: auto_search_combat_status()
    AutoSearchCombat->>AutoSearchCombat: handle_battle_status()
    AutoSearchCombat->>AutoSearchCombat: handle_exp_info()

    alt appear(OPTS_INFO_D) in auto_search_combat_status
        alt _auto_search_emotion_reduce and not _shipwreck_emotion_reduced
            AutoSearchCombat->>Emotion: reduce(_auto_search_fleet_index, shipwreck=True)
            AutoSearchCombat->>AutoSearchCombat: _shipwreck_emotion_reduced = True
        end
        AutoSearchCombat->>AutoSearchCombat: _withdraw = True
    end
Loading

泛化的 uv 管理 Python 查找与环境设置流程图

flowchart TD
    A[Start _ensure_self_contained_python] --> B{_venv_python_works and _managed_python_executable}
    B -->|yes| C[Return]
    B -->|no| D[_uv_python_env]
    D --> E{_managed_python_executable}
    E -->|no| F[Run uv python install --managed-python]
    F --> G[_managed_python_executable]
    E -->|yes| G
    G --> H[Run uv python find --managed-python]

    subgraph ManagedPythonSelection
        I[venv_python_install_dir]
        I --> J[glob cpython-*-* sorted reverse]
        J --> K{python.exe or bin/python3 or bin/python}
    end

    H --> L[End]
Loading

文件级变更

Change Details Files
使自动搜索战斗中的沉船心情减少具备幂等性,并改为由状态处理阶段确认检测到 OPTS_INFO_D 后再驱动,而不是依赖战斗状态的瞬时匹配。
  • 新增实例字段,用于记录沉船心情是否已被减少、当前自动搜索是否启用了心情减少,以及当前激活的舰队索引
  • 将沉船心情减少逻辑受新标志位控制,并在执行后设置“已减少”标志,以防止重复扣减
  • 调整 D 评价 / EXP D 界面处理逻辑,避免仅凭可能误识别的模板就设置撤退标志,并避免在超时时盲目点击 OPTS_INFO_D
  • 将战斗结果处理移动到 auto_search_combat_status 中,先通过 handle_battle_status/handle_exp_info 进行处理,只有在看到 OPTS_INFO_D 确认对话框时才减少心情
module/combat/auto_search_combat.py
优化联合舰队解体(coalition scuttle)SP 战斗结果处理逻辑,使其仅将已确认的 S 评价视为成功,并将其与瞬时的 D 评价模板匹配解耦。
  • 新增 _is_s_rank 标志位,用于记录已确认的 S 评价结果,在检测到 S 评价或持续自动搜索时设置
  • 在没有先前 OPTS_INFO_D 确认的情况下,避免将 D 评价或 EXP D 界面标记为触发撤退,而是依赖后续的评估条件
  • 在每场战斗前重置沉船与 S 评价标志位,并修改 SP 模式完成条件,使其在安排服务器更新延迟前要求 _is_s_rank 为真且没有沉船
module/coalition/coalition_scuttle.py
泛化由 uv 管理的 Python 环境设置逻辑,使其支持任意可用的 CPython 版本,而非固定绑定到 3.14.3。
  • 移除硬编码的 PYTHON_VERSION 常量,通过通用的 cpython-- glob 搜索托管的 Python 安装,并优先选择最新条目
  • 更新候选 Python 可执行路径,使用 python3 或 python,而不是特定版本的 python3.14
  • 放宽对 venv 的检查,仅要求 Python 调用可用,而不强制匹配精确的 3.14 版本
  • 确保在托管 Python 查找之前准备好环境变量,并停止向 uv venv 和 uv python find 传入显式版本,让 uv 自行选择合适版本
deploy/uv.py

Tips and commands

Interacting with Sourcery

  • 触发新的代码审查: 在 Pull Request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成 GitHub Issue: 在审查评论下回复,要求 Sourcery 基于该评论创建一个 issue。你也可以回复 @sourcery-ai issue,从该评论生成 issue。
  • 生成 Pull Request 标题: 在 Pull Request 标题的任意位置写上 @sourcery-ai 即可随时生成标题。你也可以在 Pull Request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 Pull Request 摘要: 在 Pull Request 正文的任意位置写上 @sourcery-ai summary,即可在该位置生成 PR 摘要。你也可以评论 @sourcery-ai summary 来随时(重新)生成摘要。
  • 生成审查者指南: 在 Pull Request 中评论 @sourcery-ai guide,即可随时(重新)生成审查者指南。
  • 解决所有 Sourcery 评论: 在 Pull Request 中评论 @sourcery-ai resolve,即可标记所有 Sourcery 评论为已解决。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 撤销所有 Sourcery 审查: 在 Pull Request 中评论 @sourcery-ai dismiss,即可撤销所有现有的 Sourcery 审查。特别适用于你想从头开始新的审查——别忘了再评论 @sourcery-ai review 来触发新的审查!

Customizing Your Experience

访问你的 dashboard 以:

  • 启用或禁用审查功能,例如 Sourcery 生成的 Pull Request 摘要、审查者指南等。
  • 更改审查语言。
  • 添加、删除或编辑自定义审查指令。
  • 调整其他审查设置。

Getting Help

Original review guide in English

Reviewer's Guide

Refines auto-search combat emotion reduction and SP-clear evaluation logic to avoid duplicate or false-positive mood penalties, while generalizing the uv-managed Python discovery and validation to work with any installed CPython 3.x rather than a fixed 3.14.3 version.

Sequence diagram for updated auto-search combat shipwreck emotion reduction

sequenceDiagram
    participant AutoSearchCombat
    participant Emotion

    AutoSearchCombat->>AutoSearchCombat: auto_search_combat(emotion_reduce, fleet_index)
    AutoSearchCombat->>AutoSearchCombat: set _auto_search_emotion_reduce
    AutoSearchCombat->>AutoSearchCombat: set _auto_search_fleet_index
    AutoSearchCombat->>AutoSearchCombat: set _shipwreck_emotion_reduced = False
    AutoSearchCombat->>AutoSearchCombat: auto_search_combat_execute(emotion_reduce, fleet_index)

    alt appear(OPTS_INFO_D) in auto_search_combat_execute
        alt emotion_reduce and not _shipwreck_emotion_reduced
            AutoSearchCombat->>Emotion: reduce(fleet_index, shipwreck=True)
            AutoSearchCombat->>AutoSearchCombat: _shipwreck_emotion_reduced = True
        end
        AutoSearchCombat->>AutoSearchCombat: _withdraw = True
    else appear(BATTLE_STATUS_D or EXP_INFO_D)
        AutoSearchCombat->>AutoSearchCombat: break loop (no emotion change)
    else confirm_timer.reached()
        AutoSearchCombat->>AutoSearchCombat: _withdraw = True (no emotion change)
    end

    AutoSearchCombat->>AutoSearchCombat: auto_search_combat_status()
    AutoSearchCombat->>AutoSearchCombat: handle_battle_status()
    AutoSearchCombat->>AutoSearchCombat: handle_exp_info()

    alt appear(OPTS_INFO_D) in auto_search_combat_status
        alt _auto_search_emotion_reduce and not _shipwreck_emotion_reduced
            AutoSearchCombat->>Emotion: reduce(_auto_search_fleet_index, shipwreck=True)
            AutoSearchCombat->>AutoSearchCombat: _shipwreck_emotion_reduced = True
        end
        AutoSearchCombat->>AutoSearchCombat: _withdraw = True
    end
Loading

Flow diagram for generalized uv-managed Python discovery and setup

flowchart TD
    A[Start _ensure_self_contained_python] --> B{_venv_python_works and _managed_python_executable}
    B -->|yes| C[Return]
    B -->|no| D[_uv_python_env]
    D --> E{_managed_python_executable}
    E -->|no| F[Run uv python install --managed-python]
    F --> G[_managed_python_executable]
    E -->|yes| G
    G --> H[Run uv python find --managed-python]

    subgraph ManagedPythonSelection
        I[venv_python_install_dir]
        I --> J[glob cpython-*-* sorted reverse]
        J --> K{python.exe or bin/python3 or bin/python}
    end

    H --> L[End]
Loading

File-Level Changes

Change Details Files
Make shipwreck emotion reduction in auto-search combat idempotent and driven by confirmed OPTS_INFO_D detection during status handling rather than transient battle-status matches.
  • Introduce instance fields to track whether shipwreck emotion has been reduced, whether emotion reduction is enabled for the current auto-search run, and which fleet index is active
  • Gate shipwreck emotion reduction on the new flags and set the reduced flag when applied to prevent double-deduction
  • Adjust D-rank / EXP D screen handling to avoid setting withdraw based solely on potentially mis-detected templates and to avoid blindly clicking OPTS_INFO_D on timeout
  • Move battle result handling into auto_search_combat_status, using handle_battle_status/handle_exp_info first and only reducing mood when an OPTS_INFO_D confirmation dialog is seen
module/combat/auto_search_combat.py
Refine coalition scuttle SP battle result handling so only confirmed S-rank clears are treated as successful, and decouple that from transient D-rank template matches.
  • Add an _is_s_rank flag to track confirmed S-rank results, set when S-rank or ongoing auto-search is detected
  • Avoid marking D-rank or EXP D screens as withdraw-triggering without prior OPTS_INFO_D confirmation, relying instead on subsequent evaluation conditions
  • Reset shipwreck and S-rank flags before each battle and change SP mode completion to require _is_s_rank and no shipwreck before scheduling server-update delay
module/coalition/coalition_scuttle.py
Generalize uv-managed Python environment setup to support any available CPython version instead of pinning to 3.14.3.
  • Remove the hard-coded PYTHON_VERSION constant and search for managed Python installations using a generic cpython-- glob, preferring the latest entry
  • Update candidate Python executable paths to use python3 or python rather than a version-specific python3.14
  • Relax the venv check to only require a working Python invocation instead of enforcing an exact 3.14 version match
  • Ensure environment variables are prepared before managed Python discovery and stop passing an explicit version to uv venv and uv python find so uv can choose an appropriate version
deploy/uv.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并给出了一些高层次的反馈:

  • CoalitionScuttleCombat 中,当 is_auto_search_running() 为 true 时就会设置 _is_s_rank,但这并不能真正保证是 S 评价结果;建议仅在检测到确认的 S/EXP_INFO_S 时才设置 _is_s_rank,以免 SP 完成逻辑把非 S 的战斗误判为通过。
  • AutoSearchCombat 上新增的 _auto_search_emotion_reduce_auto_search_fleet_index_shipwreck_emotion_reduced 标志是类属性,会在实例之间共享;如果自动周回流程可能并发运行或被复用,建议把这些改为实例属性,以避免不同运行之间的状态泄漏。
给 AI 代理的提示
请处理这次代码评审中的所有评论:

## 整体评论
-`CoalitionScuttleCombat` 中,当 `is_auto_search_running()` 为 true 时就会设置 `_is_s_rank`,但这并不能真正保证是 S 评价结果;建议仅在检测到确认的 S/EXP_INFO_S 时才设置 `_is_s_rank`,以免 SP 完成逻辑把非 S 的战斗误判为通过。
- `AutoSearchCombat` 上新增的 `_auto_search_emotion_reduce``_auto_search_fleet_index``_shipwreck_emotion_reduced` 标志是类属性,会在实例之间共享;如果自动周回流程可能并发运行或被复用,建议把这些改为实例属性,以避免不同运行之间的状态泄漏。

## 单条评论

### 评论 1
<location path="deploy/uv.py" line_range="185-188" />
<code_context>
 def _managed_python_executable(root: Path) -> Optional[Path]:
     install_dir = venv_python_install_dir(root)
-    for python_home in sorted(install_dir.glob(f"cpython-{PYTHON_VERSION}-*")):
+    for python_home in sorted(install_dir.glob("cpython-*-*"), reverse=True):
         candidates = [
             python_home / "python.exe",
-            python_home / "bin" / "python3.14",
+            python_home / "bin" / "python3",
             python_home / "bin" / "python",
         ]
</code_context>
<issue_to_address>
**suggestion (bug_risk):** 基于路径的反向排序方式可能无法稳定地选出版本最高的 cpython 目录

这个循环依赖对诸如 `cpython-3.10.5-*``cpython-3.9.18-*` 的名称进行字典序反向排序。根据具体命名(例如 `cpython-3.9.18-*``cpython-3.11.0-*`)或未来格式变更,字符串排序可能无法反映真实的版本顺序。如果目标是选择最新的解释器,建议从目录名中提取版本,并按 `(major, minor, patch)` 元组排序,而不是按原始字符串排序,以避免在存在多个安装时选到较旧的版本。

建议实现方式:

```python
DEPENDENCY_SYNC_TIMEOUT = 30 * 60


def _cpython_dir_version(path: Path) -> tuple[int, int, int]:
    """Extract a (major, minor, patch) tuple from a cpython install dir name.

    Expected formats include:
    - cpython-3.10.5-*
    - cpython-3.11-*
    Falls back to (0, 0, 0) if parsing fails so those entries are sorted last.
    """
    name = path.name
    # Expected name pattern: cpython-<version>-<suffix>
    parts = name.split("-")
    if len(parts) < 3 or parts[0] != "cpython":
        return (0, 0, 0)

    version_str = parts[1]
    version_components = version_str.split(".")
    # Normalize to (major, minor, patch) length
    try:
        major = int(version_components[0]) if len(version_components) > 0 else 0
        minor = int(version_components[1]) if len(version_components) > 1 else 0
        patch = int(version_components[2]) if len(version_components) > 2 else 0
    except ValueError:
        # Non-numeric version segment; treat as lowest priority
        return (0, 0, 0)

    return (major, minor, patch)


def _managed_python_executable(root: Path) -> Optional[Path]:

```

```python
    install_dir = venv_python_install_dir(root)
    python_homes = sorted(
        install_dir.glob("cpython-*-*"),
        key=_cpython_dir_version,
        reverse=True,
    )
    for python_home in python_homes:

```
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得我们的评审有帮助,请考虑分享 ✨
让我变得更有用!请在每条评论上点击 👍 或 👎,我会根据这些反馈持续改进评审质量。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • In CoalitionScuttleCombat, _is_s_rank is set when is_auto_search_running() is true, which doesn’t actually guarantee an S-rank result; consider limiting _is_s_rank to confirmed S/EXP_INFO_S detections so SP completion logic doesn’t misclassify non‑S runs as passed.
  • The new _auto_search_emotion_reduce, _auto_search_fleet_index, and _shipwreck_emotion_reduced flags on AutoSearchCombat are class attributes shared across instances; if multiple auto-search workflows can run concurrently or be reused, consider making these instance attributes to avoid cross-run state leakage.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `CoalitionScuttleCombat`, `_is_s_rank` is set when `is_auto_search_running()` is true, which doesn’t actually guarantee an S-rank result; consider limiting `_is_s_rank` to confirmed S/EXP_INFO_S detections so SP completion logic doesn’t misclassify non‑S runs as passed.
- The new `_auto_search_emotion_reduce`, `_auto_search_fleet_index`, and `_shipwreck_emotion_reduced` flags on `AutoSearchCombat` are class attributes shared across instances; if multiple auto-search workflows can run concurrently or be reused, consider making these instance attributes to avoid cross-run state leakage.

## Individual Comments

### Comment 1
<location path="deploy/uv.py" line_range="185-188" />
<code_context>
 def _managed_python_executable(root: Path) -> Optional[Path]:
     install_dir = venv_python_install_dir(root)
-    for python_home in sorted(install_dir.glob(f"cpython-{PYTHON_VERSION}-*")):
+    for python_home in sorted(install_dir.glob("cpython-*-*"), reverse=True):
         candidates = [
             python_home / "python.exe",
-            python_home / "bin" / "python3.14",
+            python_home / "bin" / "python3",
             python_home / "bin" / "python",
         ]
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Path-based reverse sorting of cpython dirs may not pick the highest version consistently

This loop relies on reverse lexicographic ordering of names like `cpython-3.10.5-*` and `cpython-3.9.18-*`. Depending on the exact naming (e.g. `cpython-3.9.18-*` vs `cpython-3.11.0-*`) or future format changes, string ordering may not reflect actual version ordering. If the goal is to pick the newest interpreter, consider extracting the version from the directory name and sorting by a `(major, minor, patch)` tuple rather than the raw string to avoid selecting an older version when multiple installs exist.

Suggested implementation:

```python
DEPENDENCY_SYNC_TIMEOUT = 30 * 60


def _cpython_dir_version(path: Path) -> tuple[int, int, int]:
    """Extract a (major, minor, patch) tuple from a cpython install dir name.

    Expected formats include:
    - cpython-3.10.5-*
    - cpython-3.11-*
    Falls back to (0, 0, 0) if parsing fails so those entries are sorted last.
    """
    name = path.name
    # Expected name pattern: cpython-<version>-<suffix>
    parts = name.split("-")
    if len(parts) < 3 or parts[0] != "cpython":
        return (0, 0, 0)

    version_str = parts[1]
    version_components = version_str.split(".")
    # Normalize to (major, minor, patch) length
    try:
        major = int(version_components[0]) if len(version_components) > 0 else 0
        minor = int(version_components[1]) if len(version_components) > 1 else 0
        patch = int(version_components[2]) if len(version_components) > 2 else 0
    except ValueError:
        # Non-numeric version segment; treat as lowest priority
        return (0, 0, 0)

    return (major, minor, patch)


def _managed_python_executable(root: Path) -> Optional[Path]:

```

```python
    install_dir = venv_python_install_dir(root)
    python_homes = sorted(
        install_dir.glob("cpython-*-*"),
        key=_cpython_dir_version,
        reverse=True,
    )
    for python_home in python_homes:

```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread deploy/uv.py
Comment on lines +185 to +188
for python_home in sorted(install_dir.glob("cpython-*-*"), reverse=True):
candidates = [
python_home / "python.exe",
python_home / "bin" / "python3.14",
python_home / "bin" / "python3",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): 基于路径的反向排序方式可能无法稳定地选出版本最高的 cpython 目录

这个循环依赖对诸如 cpython-3.10.5-*cpython-3.9.18-* 的名称进行字典序反向排序。根据具体命名(例如 cpython-3.9.18-*cpython-3.11.0-*)或未来格式变更,字符串排序可能无法反映真实的版本顺序。如果目标是选择最新的解释器,建议从目录名中提取版本,并按 (major, minor, patch) 元组排序,而不是按原始字符串排序,以避免在存在多个安装时选到较旧的版本。

建议实现方式:

DEPENDENCY_SYNC_TIMEOUT = 30 * 60


def _cpython_dir_version(path: Path) -> tuple[int, int, int]:
    """Extract a (major, minor, patch) tuple from a cpython install dir name.

    Expected formats include:
    - cpython-3.10.5-*
    - cpython-3.11-*
    Falls back to (0, 0, 0) if parsing fails so those entries are sorted last.
    """
    name = path.name
    # Expected name pattern: cpython-<version>-<suffix>
    parts = name.split("-")
    if len(parts) < 3 or parts[0] != "cpython":
        return (0, 0, 0)

    version_str = parts[1]
    version_components = version_str.split(".")
    # Normalize to (major, minor, patch) length
    try:
        major = int(version_components[0]) if len(version_components) > 0 else 0
        minor = int(version_components[1]) if len(version_components) > 1 else 0
        patch = int(version_components[2]) if len(version_components) > 2 else 0
    except ValueError:
        # Non-numeric version segment; treat as lowest priority
        return (0, 0, 0)

    return (major, minor, patch)


def _managed_python_executable(root: Path) -> Optional[Path]:
    install_dir = venv_python_install_dir(root)
    python_homes = sorted(
        install_dir.glob("cpython-*-*"),
        key=_cpython_dir_version,
        reverse=True,
    )
    for python_home in python_homes:
Original comment in English

suggestion (bug_risk): Path-based reverse sorting of cpython dirs may not pick the highest version consistently

This loop relies on reverse lexicographic ordering of names like cpython-3.10.5-* and cpython-3.9.18-*. Depending on the exact naming (e.g. cpython-3.9.18-* vs cpython-3.11.0-*) or future format changes, string ordering may not reflect actual version ordering. If the goal is to pick the newest interpreter, consider extracting the version from the directory name and sorting by a (major, minor, patch) tuple rather than the raw string to avoid selecting an older version when multiple installs exist.

Suggested implementation:

DEPENDENCY_SYNC_TIMEOUT = 30 * 60


def _cpython_dir_version(path: Path) -> tuple[int, int, int]:
    """Extract a (major, minor, patch) tuple from a cpython install dir name.

    Expected formats include:
    - cpython-3.10.5-*
    - cpython-3.11-*
    Falls back to (0, 0, 0) if parsing fails so those entries are sorted last.
    """
    name = path.name
    # Expected name pattern: cpython-<version>-<suffix>
    parts = name.split("-")
    if len(parts) < 3 or parts[0] != "cpython":
        return (0, 0, 0)

    version_str = parts[1]
    version_components = version_str.split(".")
    # Normalize to (major, minor, patch) length
    try:
        major = int(version_components[0]) if len(version_components) > 0 else 0
        minor = int(version_components[1]) if len(version_components) > 1 else 0
        patch = int(version_components[2]) if len(version_components) > 2 else 0
    except ValueError:
        # Non-numeric version segment; treat as lowest priority
        return (0, 0, 0)

    return (major, minor, patch)


def _managed_python_executable(root: Path) -> Optional[Path]:
    install_dir = venv_python_install_dir(root)
    python_homes = sorted(
        install_dir.glob("cpython-*-*"),
        key=_cpython_dir_version,
        reverse=True,
    )
    for python_home in python_homes:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants