Представляем cstvis: независимые изменения Python-кода.
Находит все возможные изменения Python-кода и применяет их по одному, сохраняя форматирование и комментарии.
На этой странице 3 раздела
Мутационное тестирование проверяет качество тестов: оно вносит в программу небольшие изменения и смотрит, заметят ли их тесты. Для этого инструмент должен найти все возможные места правки, а затем применять и проверять их по одному. Обычные средства преобразования синтаксического дерева меняют все подходящие части кода за один проход и сами по себе не дают такого разделения.
LibCST представляет Python-код в виде дерева, сохраняя форматирование и комментарии. Библиотека умеет менять это дерево, но не нумерует возможные правки так, чтобы вызывающий код мог выбрать ровно одну. Полноценные системы вроде mutmut также запускают тесты и управляют сессиями. Небольшая отдельная библиотека полезна, когда эти задачи уже решает другая часть системы.
cstvis — Python-библиотека поверх LibCST именно для такого сценария. Она находит и запоминает каждое место, где возможна заданная правка, а затем применяет любую одну правку к исходному файлу. Релиз доступен на GitHub.
Обнаружение независимых преобразований
cstvis не заменяет парсер или API преобразований LibCST. Он координирует возможные правки, чтобы вызывающий код мог сначала перечислить их, а затем применить одну выбранную.
Функция с @changer.converter обрабатывает тип узла LibCST, указанный в аннотации первого параметра. Фильтры удаляют неподходящие вхождения. iterate_coordinates() возвращает оставшиеся диапазоны, а apply_coordinate() применяет один диапазон к нетронутому модулю.
from libcst import Add, Subtract
from cstvis import Changer
changer = Changer("total = left + right")
@changer.converter
def replace_add(node: Add, context):
return Subtract(
whitespace_before=node.whitespace_before,
whitespace_after=node.whitespace_after,
)
coordinate = next(changer.iterate_coordinates())
print(changer.apply_coordinate(coordinate))
#> total = left - right
Поэтому два сложения дают двух кандидатов, и каждый применяется отдельно к исходному тексту.
Контекст содержит координату, комментарий на первой строке узла и разобранные metacode-директивы, поэтому конвертеру не нужно самостоятельно искать комментарии.
Сравнение с другими инструментами преобразования
Обычные сценарии преобразования LibCST остаются лучшим выбором для сложного многошагового рефакторинга.
Bowler и RedBaron предлагают более высокоуровневые сценарии рефакторинга с сохранением исходного оформления. Стандартный ast.NodeTransformer проще, если форматирование и комментарии сохранять не нужно.
cstvis решает более узкую задачу: регистрирует преобразования LibCST по типам, даёт им доступ к комментариям и независимо применяет каждую правку через интерфейс, не привязанный к конкретной системе запуска.
Для чего предназначен cstvis
cstvis не обходит директории, не хранит сессии, не запускает тесты и не распределяет задачи. Он допускает одно преобразование для каждого точного типа элемента синтаксического дерева и всегда применяет выбранную правку к исходному тексту. Другая система может использовать каждую такую правку как отдельную задачу.