perf(gen): grow не падает на ответах листа без null-полей

form4_ids вычисляет vsp_ids и project_ids из строк FORM_4 через .get
с пропуском отсутствующих ключей, grow_form4_sheet использует её.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-28 21:58:39 +04:00
parent 7efb640425
commit 501be971e7
2 changed files with 31 additions and 3 deletions

View File

@ -60,11 +60,27 @@ async def grow_vsp_sheet(api: Api, form_id: int, sheet: str, need: int, org_inde
return need
def form4_ids(rows: list[dict]) -> tuple[list[int], list[int]]:
"""(vsp_ids, project_ids) из строк листа FORM_4; отсутствующие ключи (data/header/vsp_id/project_id) пропускаются."""
vsp_ids: set[int] = set()
project_ids: set[int] = set()
for r in rows:
header = (r.get("data") or {}).get("header") or {}
if r.get("row_type") == "INPUT":
vid = header.get("vsp_id")
if vid is not None:
vsp_ids.add(vid)
elif r.get("row_type") == "ITEM":
pid = header.get("project_id")
if pid is not None:
project_ids.add(pid)
return sorted(vsp_ids), sorted(project_ids)
async def grow_form4_sheet(api: Api, form_id: int, sheet: str, need: int) -> int:
path = f"/form/{form_id}/sheet/{sheet}"
rows = (await api.get(path))["result"]
vsp_ids = sorted({r["data"]["header"]["vsp_id"] for r in rows if r.get("row_type") == "INPUT" and r["data"]["header"].get("vsp_id")})
project_ids = sorted({r["data"]["header"]["project_id"] for r in rows if r.get("row_type") == "ITEM"})
vsp_ids, project_ids = form4_ids(rows)
if not project_ids:
raise RuntimeError(f"{sheet}: нет проектов")
leaves = await leaf_items(api, "FORM_4", sheet)

View File

@ -1,6 +1,6 @@
import pytest
from perfkit.gen.grow import rows_to_add, TARGETS
from perfkit.gen.grow import form4_ids, rows_to_add, TARGETS
@pytest.mark.parametrize("cur,target,exp", [(31, 500, 469), (110, 300, 190), (500, 500, 0), (700, 500, 0), (0, 5, 5)])
@ -12,3 +12,15 @@ def test_targets_do_not_touch_small_pair_sheets():
# AHR_RENT и FORM_4/AHR остаются малыми (пара для @big)
assert ("FORM_2", "AHR_RENT") not in [(f, s) for f, s, _ in TARGETS]
assert ("FORM_4", "AHR") not in [(f, s) for f, s, _ in TARGETS]
def test_form4_ids_tolerates_absent_keys():
rows = [
{"row_type": "INPUT", "data": {"header": {"vsp_id": 3}}},
{"row_type": "INPUT", "data": {"header": {}}},
{"row_type": "INPUT", "data": {}},
{"row_type": "ITEM", "data": {"header": {"project_id": 11}}},
{"row_type": "ITEM", "data": {"header": {}}},
{"row_type": "ITEM", "data": {}},
]
assert form4_ids(rows) == ([3], [11])