"""Докстрока `_page_contains_table` не обещает защиты, которой нет (#2464). Прежняя редакция утверждала: «Требуем явный caption «Таблица N» — hint-только режим (оглавление, перекрёстные ссылки) даёт false positive и подавляется.» Кода подавления в функции никогда не было — это `bool(cap.search(text))`, то есть обычный поиск подстроки. Строка оглавления «Таблица 11 Баланс территории ..... 34» от настоящей подписи не отличается: падеж тот же, именительный. Замер 20.08.2026 уточнил и сам пункт эпика: приведённый в нём пример перекрёстной ссылки «показатели приведены в таблице 12» регекс НЕ ловит — он требует именительное «Таблица N». Опасно ровно оглавление, а не любое упоминание. Это зафиксировано характеризующим тестом, чтобы следующая попытка подавления целилась в признаки оглавления, а не в падежи. Обещание защиты, которой нет, опаснее её отсутствия: читающий не станет её добавлять. Тот же класс, что «объявлено ≠ исполняется». Почему подавление не реализовано, а докстрока приведена к коду: таблица `ekb_ppt_tep` на проде пуста (0 строк) — URL в `_SEED_DOCS` заглушка, живых PDF нет, эвристику отсева оглавления не на чем откалибровать. Правило, придуманное без образцов, ловит ровно те случаи, которые придумали вместе с ним. """ from __future__ import annotations import inspect from app.services.scrapers import ekb_ppt_tep_parser as mod def test_docstring_does_not_promise_suppression_that_is_absent() -> None: """Головной: докстрока не должна обещать подавление false positive. На origin/main она содержит «даёт false positive и подавляется», а в теле функции — один `cap.search(text)`. Красное значение конкретно: обещание есть, реализации нет. """ doc = inspect.getdoc(mod._page_contains_table) or "" src = inspect.getsource(mod._page_contains_table) тело = src.split('"""')[-1] # Ищем именно ОБЕЩАНИЕ («подавляется»), а не разговор о подавлении: новая # редакция объясняет, почему подавление НЕ реализовано, и не должна краснеть. обещает = "подавляется" in doc реализует = any(kw in тело for kw in ("оглавлен", "leader", "count(", "finditer", "rsplit")) assert not (обещает and not реализует), ( "докстрока обещает подавление false positive, а в теле только поиск " f"подстроки:\n{тело.strip()}" ) def test_docstring_names_the_actual_behaviour() -> None: """Докстрока обязана честно называть false positive, а не умалчивать о нём. Просто убрать обещание было бы недостаточно: молчание читается как «всё хорошо». Ловит «починку» через вычёркивание неудобной фразы. """ doc = (inspect.getdoc(mod._page_contains_table) or "").lower() assert "false positive" in doc or "оглавлен" in doc, ( "докстрока не предупреждает о ложных срабатываниях на оглавлении" ) def test_toc_line_really_is_a_false_positive() -> None: """Характеризующий: строка оглавления действительно проходит как подпись. Зелёный с обеих сторон — он фиксирует ФАКТИЧЕСКОЕ поведение, о котором теперь говорит докстрока. Если кто-то реализует подавление, тест покраснеет и заставит обновить и докстроку, и его. """ оглавление = "СОДЕРЖАНИЕ\nТаблица 11 Баланс территории .......... 34\nТаблица 12 ТЭП .... 36" assert mod._page_contains_table(оглавление, 11) is True, "оглавление обязано срабатывать" # А вот перекрёстные ссылки в косвенных падежах регекс НЕ ловит: он требует # именительное «Таблица N». Пункт эпика приводил «приведены в таблице 12» как # пример false positive — замер это опроверг, и докстрока теперь говорит точнее. for мимо in ( "Основные показатели приведены в таблице 12 настоящей записки.", "см. Таблицу 12 ниже", "Данные в табл. 12", ): assert mod._page_contains_table(мимо, 12) is False, f"неожиданно сработало: {мимо!r}" assert mod._page_contains_table("Никаких таблиц тут нет", 11) is False def test_seed_comment_does_not_send_to_a_dead_host() -> None: """Комментарий сида не должен отправлять искать документ на несуществующем хосте. `gisogd.ekburg.ru` не резолвится ни с рабочей машины, ни с прод-хоста (проверено 20.08.2026), а прежний комментарий называл его местом, где «лежит реальный URL». Живой портал — gisogd66.midural.ru. """ from pathlib import Path src = Path(inspect.getsourcefile(mod)).resolve().parents[3] текст = (src / "app" / "workers" / "tasks" / "ekb_ppt_tep_sync.py").read_text(encoding="utf-8") assert "НЕ СУЩЕСТВУЕТ" in текст or "не резолв" in текст.lower(), ( "комментарий сида не предупреждает, что gisogd.ekburg.ru мёртв" ) assert "gisogd66.midural.ru" in текст, "не назван живой портал ГИСОГД-СО"