From 33ec43d78d1c7122f5c06767feb0c6715d2cd050 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 18 Oct 2026 13:18:49 +0400 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=B2=D0=B8=D0=B4=20=D0=B0=D0=B1=D1=81?= =?UTF-8?q?=D0=BE=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D0=B8=D0=BE=D0=B4=D0=B0=20=D0=B1=D0=B5=D1=80=D1=91=D1=82?= =?UTF-8?q?=D1=81=D1=8F=20=D0=B8=D0=B7=20=D1=81=D0=BB=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D1=80=D1=8F;=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=B9=20repeats?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W --- arm_statements/loader.py | 9 ++++++++- arm_statements/tests/test_loader.py | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/arm_statements/loader.py b/arm_statements/loader.py index 7cfbe34..2ffc8f2 100644 --- a/arm_statements/loader.py +++ b/arm_statements/loader.py @@ -322,7 +322,7 @@ def _load_periods(directory: Path) -> PeriodRules: pattern = _rx(file, f"{key}.pattern", _get(file, entry, "pattern")) if not set(pattern.groupindex) <= _PERIOD_GROUPS: raise _fail(file, f"{key}.pattern", f"допустимые имена групп: {sorted(_PERIOD_GROUPS)}") - absolute.append(PeriodPattern(kind, pattern)) + absolute.append(PeriodPattern(abs_kind, pattern)) months: list[tuple[str, int]] = [] for stem, number in _map(file, "months", _get(file, data, "months")).items(): month = _int(file, f"months.{stem}", number) @@ -424,6 +424,13 @@ def _load_orders(directory: Path) -> CodeOrders: raise _fail(file, "version", "поддерживается только версия 1") repeats = _map(file, "repeats", _get(file, data, "repeats")) editions_raw = _map(file, "editions", _get(file, data, "editions")) + for ed_name, forms_node in repeats.items(): + if ed_name not in editions_raw: + raise _fail(file, f"repeats.{ed_name}", "редакции нет в editions") + known_forms = _map(file, f"editions.{ed_name}", editions_raw[ed_name]) + for form_name in _map(file, f"repeats.{ed_name}", forms_node): + if form_name not in known_forms: + raise _fail(file, f"repeats.{ed_name}.{form_name}", "формы нет в editions этой редакции") editions: list[Edition] = [] sequences: dict[tuple[Edition, DocumentType, FormVariant], tuple[str, ...]] = {} for ed_name, forms_node in editions_raw.items(): diff --git a/arm_statements/tests/test_loader.py b/arm_statements/tests/test_loader.py index 84a9e5e..f5df35c 100644 --- a/arm_statements/tests/test_loader.py +++ b/arm_statements/tests/test_loader.py @@ -139,3 +139,29 @@ def test_label_keys_are_checked(tmp_path: Path) -> None: target.write_text(target.read_text(encoding="utf-8").replace(" okpo:", " okpo_x:", 1), encoding="utf-8") with pytest.raises(RulesError, match="statement_headers"): load_rules(tmp_path) + + +def test_absolute_period_kinds_come_from_dictionary(rules: Rules) -> None: + expected = [ + "range_end", + "day_month_year", + "quarter", + "half", + "months", + "month_range", + "year", + ] + data = yaml.safe_load((RULES_DIR / "statement_periods.yaml").read_text(encoding="utf-8")) + assert [p["kind"] for p in data["absolute"]] == expected + assert [p.kind for p in rules.periods.absolute] == expected + + +def test_repeats_for_unknown_form_rejected(tmp_path: Path) -> None: + for path in RULES_DIR.glob("*.yaml"): + (tmp_path / path.name).write_bytes(path.read_bytes()) + orders = tmp_path / "statement_code_orders.yaml" + orders.write_text( + orders.read_text(encoding="utf-8").replace(" INCOME: []", " DISCLOSURE: []", 1), encoding="utf-8" + ) + with pytest.raises(RulesError, match="repeats"): + load_rules(tmp_path)