Skip to main content

bslfmt

Детерминированный форматтер структурных отступов BSL. Проект работает как Python-библиотека и CLI; интеграция с MCP 1C будет отдельным потребителем пакета.

Границы

Форматтер приводит отступы и форматирование поддерживаемых операторов, а регистр ключевых слов — к каноническому. Он сохраняет значимые токены (без учёта регистра) и порядок кода, строк, комментариев и директив. Он не проверяет синтаксис BSL и не компилирует модули. Если структурное форматирование небезопасно, команда завершает работу с диагностикой, не перезаписывая источник.

Стиль форматирования

Стиль один, настроек нет. Он следует стандартам 1С «Тексты модулей» (std456) и «Перенос выражений» (std444) и практике типовых конфигураций.

  • Отступы — табуляцией, по вложенности блоков: процедуры и функции, Если/ИначеЕсли/Иначе, циклы, Попытка/Исключение. Английские и смешанные ключевые слова распознаются.
  • С колонки 0 — Процедура/Функция и их концы, аннотации (&НаСервере…), директивы препроцессора (#Область, #Если…, в том числе внутри процедур), переменные и код модуля вне процедур.
  • Строки продолжения многострочной инструкции — +1 отступ к её первой строке. Строка с ведущим И/Или/+/. (а также [, ,, ) или литералом) — продолжение инструкции; Экспорт на своей строке — часть объявления. ) стоит на уровне строки с открывающей скобкой. Текст запроса сразу после = и после одиночного Возврат — как раньше.
  • Многострочные строки: строки | сдвигаются вместе со строкой, где начался литерал; пробелы перед | не входят в значение строки.
  • Комментарии // встают на отступ следующей строки кода; перед строкой, которая закрывает блок (КонецЕсли, Иначе…) или начинается с ), — на уровень глубже. Комментарий в колонке 0 (маркеры доработок //!, //++, закомментированный код) остаётся в колонке 0. Текст комментариев не меняется.
  • Перенос строк: каждая инструкция — на своей строке (А = 1; Б = 2; → две строки); после Тогда, Цикл, Попытка, Иначе, Исключение тело начинается со следующей строки, а КонецЕсли, КонецЦикла, КонецПопытки, Иначе, ИначеЕсли, Исключение стоят отдельной строкой. Пустая инструкция (Цикл;, Иначе;) остаётся при своём слове, комментарий в конце строки — у последней части.
  • Раскладка по ширине 120: инструкция (в том числе заголовок и объявление), которая с отступом (таб — 4 знака) помещается в 120 знаков, — одна строка; переносы автора внутри неё убираются. Иначе она режется по порядку: Или → И → + (каждая часть на своей строке, оператор в начале) → последняя пара скобок (параметры одной строкой, иначе по одному на строку, ) отдельной строкой; пропущенные параметры — на строке предыдущего); части длиннее 120 режутся так же, рекурсивно. Если резать некуда, инструкция остаётся как была. Комментарий в конце строки в ширину не входит. Не трогаются инструкции с комментарием внутри, многострочным литералом или подряд идущими литералами, директивой, областью правки; литералы не режутся никогда. Внутри строки автора пробелы сохраняются как написаны (Не(А) остаётся Не(А)); на месте бывших переносов действует общее правило (Ф / (А) → Ф(А)). Инструкции с идентификаторами вне кириллицы и латиницы (например, казахские буквы) не раскладываются и остаются как есть.
  • Пробелы: вокруг бинарных операторов (=, <>, +, %…), после запятой; без пробелов перед , ; ) и после (. Лишние пробелы внутри строки схлопываются, хвостовые удаляются; выравнивание табами внутри строки заменяется одним пробелом.
  • Пустые строки: не больше одной подряд. Строки из одних пробелов и табов (так их заполняет конфигуратор) не очищаются.
  • Регистр ключевых слов — как в синтакс-помощнике 1С: или → Или, конецЕсЛи → КонецЕсли, НЕ → Не, NULL → Null. Так же директивы препроцессора и их символы (#если сервер тогда → #Если Сервер Тогда, #область → #Область) и аннотации (&наклиенте → &НаКлиенте). Английские слова остаются английскими (endif → EndIf). Не меняются имена переменных, методов и свойств (Запрос.выполнить()), имена меток и областей, неизвестные аннотации и символы препроцессора.
  • Методы расширений с &ИзменениеИКонтроль форматируются как обычный код: платформа не сверяет пробелы и табы в контролируемых строках.
  • Не трогаются: строки и даты, текст комментариев, области #Вставка/#Удаление, регистр букв вне ключевых слов, порядок кода.

Установка

Нужен Python 3.10+ или uv — он сам скачает Python. Пакет без зависимостей, одинаков для Windows, macOS и Linux.

uv tool install bslfmt        # команда bslfmt в терминале (рекомендуется)
pipx install bslfmt           # то же через pipx
uvx bslfmt Модуль.bsl         # разовый запуск без установки

Установить uv: Windows — winget install astral-sh.uv (или powershell -c "irm https://astral.sh/uv/install.ps1 | iex"); macOS — brew install uv; macOS и Linux — curl -LsSf https://astral.sh/uv/install.sh | sh. Обновление: uv tool upgrade bslfmt (или pipx upgrade bslfmt).

Для агентов и хуков

Форматировать файл на месте — одна команда, модуль через контекст агента не передаётся:

uvx bslfmt -i Модуль.bsl            # отформатировать файл (uv сам поставит пакет)
uvx bslfmt --check Модуль.bsl       # код выхода 1 — файл нужно отформатировать
uvx bslfmt -i -sbc Модуль.bsl       # и удалить комментарии внутри методов

Если пакет установлен (uv tool install bslfmt), то же без uvx. Вывод — UTF-8; сводка на файл: ФАЙЛ: изменён (строк: N) или ФАЙЛ: без изменений.

Установка для разработки

python -m venv .venv
. .venv/bin/activate
python -m pip install -e .
python -m unittest discover -s tests -v

Команда bslfmt появляется в активном окружении.

CI (GitHub Actions) прогоняет тесты на Windows, macOS и Linux и проверяет установленную команду: python tests/cli_smoke.py после pip install ..

CLI

bslfmt Модуль.bsl                        # результат на экран, файл не меняется
bslfmt -i Модуль.bsl Форма.bsl           # отформатировать файлы на месте
bslfmt --check Модуль.bsl Форма.bsl      # только проверить (для CI и хуков)
bslfmt --check --diff Модуль.bsl         # проверить и показать различия
bslfmt Модуль.bsl --output Новый.bsl     # записать результат в новый файл
bslfmt - < Модуль.bsl                    # стандартный ввод
bslfmt -i -sbc Модуль.bsl                # и удалить комментарии внутри методов
bslfmt --help                            # справка по всем режимам

-i переписывает только файлы, которым нужна правка: запись атомарная (временный файл рядом и замена), при отказе форматирования файл не меняется. Сводка на каждый файл: ФАЙЛ: изменён (строк: N) или ФАЙЛ: без изменений. Файл только для чтения не переписывается (ошибка, код 2). -- завершает флаги: bslfmt --check -- -файл.bsl. -sbc, --strip-body-comments (с любым режимом) удаляет строки-комментарии внутри процедур и функций — закомментированный код, маркеры доработок, пояснения. Это же касается строк-комментариев между строками многострочного литерала (//| Поле, в тексте запроса): в значение строки они не входят. Комментарии в конце строки кода, над методами, внутри самого текста строки (|// … — часть запроса: маркеры для СтрЗаменить, разделитель пакета) и в областях #Вставка/#Удаление остаются. Значения строк не меняются — это проверяется при каждом запуске. Без ключа комментарии не удаляются. --check ничего не записывает и перечисляет файлы, которые нужно отформатировать. Несколько файлов — только с -i, --check или --diff; каждый обрабатывается отдельно. --output создаёт новый файл и отказывается перезаписывать существующий.

Ввод и вывод (текст, различия, сводка, ошибки) — UTF-8 на любой ОС; переводы строк и BOM сохраняются как в исходнике.

Коды выхода (худший по всем файлам): 0 — успех (при --check — всё отформатировано); 1 — --check нашёл файлы для форматирования; 2 — ошибка аргументов, чтения или записи, неверная кодировка или отказ форматирования (сообщение в stderr с именем файла и номером строки, если он известен); 3 — внутренняя ошибка форматтера.

Python API

from bslfmt import format_code

formatted = format_code(source)

Для недоверенного ввода есть лимиты: max_chars — длина исходника (по умолчанию 20 000 000 символов), max_depth — вложенность блоков (по умолчанию 100). При превышении — FormatError; None отключает лимит.

formatted = format_code(source, max_chars=1_000_000, max_depth=50)
cleaned = format_code(source, strip_body_comments=True)

Сервису, который принимает код извне, стоит также запускать форматирование в отдельном процессе с ограничением памяти и времени.

Поддерживаемые функции и ограничения уточняются по синтетическим тестам в tests/; локальные корпуса и конфигурации в репозиторий не входят.

Лицензия

Apache License 2.0 — см. LICENSE и NOTICE. Проект не аффилирован с ООО «1С».

Metadata

Release files for bslfmt 0.25.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bslfmt 0.25.0
File Size Uploaded
bslfmt-0.25.0.tar.gz 82.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bslfmt 0.25.0
File Interpreter ABI Platform
bslfmt-0.25.0-py3-none-any.whl Python 3 none any Details

Total release size: 135.2 kB

Release files / bslfmt-0.25.0.tar.gz

Download URL bslfmt-0.25.0.tar.gz
Size 82.0 kB
Tags Source
SHA-256 checksum
How to use checksums
999b2c3b12ccbe73f8d75f48fcc745ce2bb3058dab0a7a8baaa996382aeec4bb
BLAKE2b-256 checksum
How to use checksums
94035f8ddb1630b65d612d9ba95d18bdb346c1cd197603d48ed78b99c9bef04e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / bslfmt-0.25.0-py3-none-any.whl

Download URL bslfmt-0.25.0-py3-none-any.whl
Size 53.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
40d996cedaec9960290c1b2e179f7565a7222d09f77a7f3e7d759d7d42eb4e2e
BLAKE2b-256 checksum
How to use checksums
2b21cac6275a6999f04629da27a58f02ae4dbba29ce7cc6c4f6e7d1df8f82902
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.25.0 This release

2 release files

0.23.0

2 release files

0.21.0

2 release files

0.20.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page