no-private-imports: regex слеп к скобочным multi-line from ... import (...) #5
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Баг
Хук
no-private-imports(scripts/check_no_private_imports.py,IMPORT_RE)анализирует только строку, содержащую
from ... import. При скобочноймного-строчной форме импорта символы лежат на строках-продолжениях, которые
regex не видит → приватные импорты проходят молча.
Воспроизведение
Однострочный аналог
from x import _yловится корректно — проблема только вскобочной многострочной форме.
Где всплыло
baton, PR #922 (ревью): пропущенный приватный импорт прошёл зелёный CI
именно из-за этой слепой зоны. В baton-репо так же скрыто ≥4 pre-existing
нарушения (
_tail_text,_build_argv), невидимых хуку.Предлагаемое решение
Парсить импорты не построчным regex, а через
ast(модульast.ImportFrom—node.names[].name), либо сшивать логические строки дозакрывающей скобки перед матчингом.
ast-подход заодно убираетfalse-positive на строках-комментариях/докстрингах с похожим текстом.
Аналогичную слепую зону стоит проверить у
no-private-method-calls, еслион тоже построчный.
Acceptance
no-private-importsловит приватные символы в скобочной multi-lineформе
from ... import (...).no-private-method-calls.Связано: baton #687 (boy-scout-зачистка запретов; Группа A-хвост зависит от
ручной дочистки, пока хук слеп).
Закрываю: сделано в #13 (в
main, версия0.15.0).Разбор
no-private-importsпереведён с построчной регулярки наast, поэтому скобочный многострочный импорт ловится по построению — совпадение ищется не в строке сfrom … import, а в самих именах узла. На jamzap/backend это 30 нарушений из 51, которые до сих пор проходили молча. Заодно снят обратный дефект: алиас больше не считается импортируемым символом (from x import public as _local— чисто,from x import _private as public— FAIL).Фикстуры:
fixtures/private_imports/multiline.pyиmultiline_last.py(приватное имя последним — мутация «проверять только первое имя» иначе выживала),alias.py,private_as_public.py,relative.py,deferred.py,star.py,bom.py.Осталось за рамками этой задачи и ведётся в #19: приватный модуль в пути импорта (
from ._private import public) по-прежнему проходит — смотрится импортируемое имя, а не путь.