2025, Dec 03 15:01
Как подавить ложный E303 в JupyterLab (pylsp, flake8)
Разбираем ложный E303 PEP8 в JupyterLab: почему он появляется после Markdown и как его подавить через Settings > Code Diagnostics, минуя flake8/pylsp.
Когда вы настраиваете PEP8-линтер в JupyterLab на Windows 10 через pylsp и начинаете получать предупреждение «E303 too many blank lines» на первой строке каждой ячейки с кодом, которая следует за ячейкой Markdown, кажется, будто инструменты издеваются над вами. С кодом все в порядке, но редактор утверждает обратное. В этом материале объясняется, почему это происходит и как подавить ложные срабатывания, не ломая ваш процесс линтинга.
Как воспроизвести проблему
Сбой проявляется вне зависимости от того, какой код запускается в ячейке после Markdown. Даже крошечный, соответствующий PEP8 фрагмент вызовет предупреждение:
def sum_pair(x_val, y_val):
return x_val + y_val
res_total = sum_pair(1, 2)
print(res_total)
Поместите эту ячейку сразу после Markdown-ячейки — и линтер отметит самую первую строку кодовой ячейки как E303, хотя она вовсе не начинается с пустых строк.
Что на самом деле происходит
Такое поведение отслеживается в репозитории jupyterlab-lsp и, по-видимому, связано с более общей проблемой JupyterLab, касающейся добавления пробелов вокруг ячеек Markdown. Обсуждения здесь: задача jupyterlab-lsp и задача JupyterLab. Важно понимать: дело не во flake8. Интерфейс видит лишние пробелы на границах Markdown, и диагностика поднимается так, будто ваша кодовая ячейка начинается с дополнительных пустых строк.
Практическое решение прямо сейчас
Пока исходные задачи остаются открытыми, прагматичный обходной путь — игнорировать E303 на уровне интерфейса в JupyterLab. Для начала удалите любые записи E303, которые вы могли добавить в pylsp.plugins.flake8.ignore. Поскольку корень проблемы не во flake8, подавление кода там может не сработать, особенно если в вашей среде flake8 фактически не используется или отключен.
Затем откройте JupyterLab и перейдите в Settings > Code Diagnostics > Diagnostics code to ignore. Добавьте туда E303. Это подавит ложноположительные срабатывания в интерфейсе, независимо от того, какой конкретный плагин линтера отдает диагностику.
Почему игнорирование в интерфейсе работает, а flake8.ignore — нет
Здесь важна разница между уровнями, на которых фильтруются диагностические сообщения. Параметр pylsp.plugins.flake8.ignore просит flake8 через Language Server отфильтровать определенные коды до того, как они попадут в редактор. Это влияет только на диагностику, исходящую от flake8. Настройка Code Diagnostics «Diagnostics code to ignore» указывает интерфейсу JupyterLab отбрасывать такие коды уже после получения их от LSP, то есть охватывает диагностику единообразно — независимо от того, пришла она из flake8, pycodestyle, pyflakes, ruff или любого другого инструмента, проходящего через language server.
Нужно ли менять ваш код?
Нет, изменять исходники не требуется — проблема не в них. Пример ниже полностью корректен и пройдет проверки, как только вы добавите игнорирование E303 на уровне интерфейса:
def sum_pair(x_val, y_val):
return x_val + y_val
res_total = sum_pair(1, 2)
print(res_total)
Почему это важно
Ложные срабатывания подрывают доверие к статическому анализу и отвлекают от настоящих проблем. До тех пор, пока связанные задачи в JupyterLab и jupyterlab-lsp не будут закрыты, обработка E303 на уровне UI сохраняет рабочий ритм в ноутбуке сосредоточенным и предсказуемым — без полного отключения линтеров.
Итоги
Если E303 помечается на первой строке ячеек кода после Markdown, это известное следствие взаимодействия JupyterLab с цепочкой линтеров. Не спорьте с кодом. Удалите E303 из pylsp.plugins.flake8.ignore и добавьте E303 в Settings > Code Diagnostics > Diagnostics code to ignore. Этот обходной путь подтвержденно убирает шум, пока исходные задачи остаются открытыми.