IndentationError: unexpected indent в Python — как исправить

Python Автор: Среда и версия: CPython 3.14.5

IndentationError: unexpected indent означает, что строка началась правее, хотя новый блок кода в этом месте не открывался. В Python ведущие пробелы задают структуру программы, а не только внешний вид.

Сначала откройте строку из сообщения и две-три строки над ней. Затем определите, к какому if, циклу или функции относится команда. Все ошибки ниже воспроизведены на CPython 3.14.5.

Четыре сообщения об отступах

Похожие на вид ошибки требуют разных исправлений:

  • unexpected indent — появился лишний уровень отступа;
  • expected an indented block — после заголовка блока нет тела с отступом;
  • unindent does not match any outer indentation level — строка вернулась на уровень, которого раньше не было;
  • TabError: inconsistent use of tabs and spaces — табы и пробелы задают неоднозначные уровни.

IndentationError наследуется от SyntaxError, а TabError — от IndentationError. Все они возникают до выполнения программы.

Unexpected indent: лишний отступ

У второй строки четыре пробела, хотя первая не открывает блок:

total = 10
    print(total)
  File "main.py", line 2
    print(total)
IndentationError: unexpected indent

Обе команды должны находиться на верхнем уровне:

total = 10
print(total)

Если отступ был нужен, выше должен быть заголовок блока с двоеточием:

if total > 0:
    print(total)

Не удаляйте пробелы вслепую. Сначала решите, должна ли строка выполняться всегда или только внутри условия, цикла либо функции. От этого зависит правильный уровень.

Expected an indented block: нет тела блока

Если тело блока начинается со следующей строки, Python ждёт хотя бы одну команду правее заголовка:

if total > 0:
print(total)
  File "main.py", line 2
    print(total)
    ^^^^^
IndentationError: expected an indented block after 'if' statement on line 1

Сдвиньте тело условия на один уровень:

if total > 0:
    print(total)

То же правило действует после for, while, def, class, with, try, except, finally, match и case. Комментарий не считается телом блока. Если реализацию нужно оставить на потом, используйте pass:

def send_report():
    # реализация появится позже
    pass

Unindent does not match: возврат на несуществующий уровень

В этом примере вложенные блоки начинаются с четырёх и восьми пробелов, а последняя строка — с двух:

if authorized:
    if active:
        print('ok')
  print('done')
  File "main.py", line 4
    print('done')
                 ^
IndentationError: unindent does not match any outer indentation level

Отступ должен вернуться на один из уже существующих уровней. Если print('done') относится к внешнему условию, оставьте четыре пробела:

if authorized:
    if active:
        print('ok')
    print('done')

Если команда должна выполняться после обоих условий, уберите отступ полностью. Два варианта синтаксически корректны, но выполняются в разные моменты, поэтому автоформатирование не может выбрать смысл за автора.

TabError: смешаны табы и пробелы

Табуляция и восемь пробелов могут выглядеть в редакторе одинаково, но храниться разными символами. Здесь обозначает один таб, а · — один пробел:

if True:
→print('tab')
········print('spaces')

Такой файл даёт:

  File "main.py", line 3
    print('spaces')
TabError: inconsistent use of tabs and spaces in indentation

Выделите файл целиком и выполните в редакторе команду наподобие «Convert indentation to spaces». После преобразования обе строки одного блока должны начинаться одинаково:

if True:
    print('tab replaced with spaces')
    print('spaces')

Python расширяет таб до следующей позиции, кратной восьми. TabError появляется не при любом табе, а когда смесь табов и пробелов делает структуру блока зависимой от способа их отображения. Практическое правило проще: используйте только пробелы.

Сколько пробелов ставить

Python принимает разные размеры отступа, если уровни однозначны и согласованы. Такой код синтаксически корректен, хотя читать его трудно:

if authorized:
  if active:
       print('ok')

В обычном проекте используйте четыре пробела на уровень. Это соглашение PEP 8, его понимают редакторы, форматтеры и другие разработчики. Внутри одного блока соседние команды должны начинаться в одной колонке.

Отступ внутри круглых, квадратных и фигурных скобок не открывает новый блок. Переносы здесь допустимы:

total = sum(
  [10, 20, 30]
)

Код с двумя пробелами внутри вызова компилируется. Четыре пробела всё равно удобнее как единое правило для проекта.

Почему else указывает не туда

else, elif, except и finally должны стоять на одном уровне со своим парным заголовком. В этом коде else ошибочно вложен внутрь if:

if total > 0:
    print('positive')
    else:
        print('zero or negative')

Исправленный вариант:

if total > 0:
    print('positive')
else:
    print('zero or negative')

Сообщение может указывать на else, хотя причина — уровень его ведущих пробелов. Сравнивайте колонку else с колонкой соответствующего if, а не с командой над ним.

Как проверить отступы без запуска

Сначала включите в редакторе отображение пробелов и табов. Затем преобразуйте табы в пробелы и выровняйте блок целиком — исправление одной строки часто оставляет соседнюю на старом уровне.

После правки проверьте файл стандартным компилятором:

На Linux и macOS:

python3 -m py_compile main.py

На Windows:

py -m py_compile main.py

Отсутствие вывода означает, что синтаксис и отступы корректны. Логику программы эта команда не проверяет.

Если последняя строка сообщения начинается с обычного SyntaxError, проблема может быть в двоеточии, скобке, кавычке или команде pip внутри интерпретатора. Эти случаи разобраны в статье «SyntaxError: invalid syntax».

Источники