Python 3.14.7: encoding начального curses-экрана живёт после окна. Практическая инструкция отделяет симптом от соседних причин: синтетический fixture, отрицательный control, таблица наблюдений, критерий остановки и минимальный пакет для поддержки без production-данных.
Факт, который можно опровергнуть
Начните с вопроса, который можно опровергнуть: «как проверить lifetime encoding для curses.unctrl и ungetch после освобождения window в Python 3.14.7». Changelog подтверждает узкую change boundary: Encoding initial screen теперь хранится как private copy, а не borrowed pointer на потенциально уничтоженное window. Она связана с конкретной болью — curses хранит encoding initial screen через заимствованный указатель на window, окно освобождается, а unctrl() или ungetch() позже кодирует non-ASCII и может обратиться к освобождённой памяти. — но не подтверждает частоту встречаемости. Поэтому ниже есть чистый fixture, противоположный control и стоп-линия; без них отсутствие crash или один удачный запуск остаются слабым наблюдением.
Карточка воспроизведения
Запишите карточку опыта T22-15: точная версия, режим запуска, короткий hash входа и действие «под pty и в child process инициализировать curses, запомнить encoding, создать и удалить дополнительное окно, затем вызвать unctrl/ungetch на одной безопасной non-ASCII метке». Используйте только обратимые ресурсы. До выполнения определите, где появятся stdout, stderr и exit code, а также как будет выполнена очистка. Так диагностический пакет останется повторяемым и не потребует доступа к реальной инфраструктуре.
Control перед выводом
Отрицательный control обязателен: повторить вызовы до удаления окна, выполнить ASCII-ветку и затем новую сессию без reuse глобального screen state. Заполняйте «locale | screen encoding | момент удаления | function | return type | exit code | terminal restored» до интерпретации вывода. Если результат зависит от порядка, поменяйте порядок и начните заново с чистого fixture. Не объединяйте несколько исправлений в одном опыте: иначе невозможно связать наблюдение с issue boundary.
Формальное условие приёмки
Формальное условие passed: вызовы до и после удаления не валят child, encoding остаётся согласованной, а terminal state восстанавливается в finally. Один позитивный запуск недостаточен — повтор должен сохранить тот же контракт. При расходящихся результатах снизьте вывод до inconclusive и проверьте происхождение бинарника, feature flags и чистоту input. Не повышайте уверенность количеством одинаковых перезапусков одного загрязнённого процесса.
Предел вмешательства
Предел вмешательства: не запускать вне pty и не оставлять терминал в curses mode; сигнал, timeout или невозможность endwin немедленно блокируют вывод. Нельзя расширять тест на production, чужие PID или реальные данные. После target удалите fixture, закройте локальные endpoints и повторите маленький baseline control. Только совпавший baseline доказывает, что эксперимент не оставил состояние.
Сокращённый support bundle
Сокращённый support bundle содержит: locale и encoding без environment dump, порядок newwin/del, результаты unctrl/ungetch, exit code и marker восстановления terminal. Свяжите его с T22-15, добавьте hash синтетического input и критерий «вызовы до и после удаления не валят child, encoding остаётся согласованной, а terminal state восстанавливается в finally». Абсолютные пути замените ролями, бинарные данные — hashes, сообщения с приватным контекстом — классами исключений.
Материал подготовлен редакцией VOne с помощью ИИ по открытым официальным и первичным источникам; факты, даты и ссылки перепроверены. Реальные пользовательские данные не использовались.
Источники и проверка
- Python 3.14.7 release проверено 2026-08-29
- Python 3.14.7 changelog проверено 2026-08-29
- CPython issue #151695 проверено 2026-08-29
Информация актуальна на дату публикации. Правила сервисов, приложений и сетей могут меняться.