Python 3.14.7: фокус на чужом Tk-виджете возвращает None вместо KeyError. Практическая инструкция отделяет симптом от соседних причин: синтетический fixture, отрицательный control, таблица наблюдений, критерий остановки и минимальный пакет для поддержки без production-данных.
Факт, который можно опровергнуть
Начните с вопроса, который можно опровергнуть: «как проверить focus_get для Tk-виджета, созданного не tkinter, в Python 3.14.7». Changelog подтверждает узкую change boundary: focus_get(), focus_displayof(), focus_lastfor() и winfo_containing() теперь возвращают None для виджета, созданного не tkinter. Она связана с конкретной болью — Torn-off menu или виджет расширения существует в одном Tcl/Tk, но не зарегистрирован как Python widget, и запрос текущего focus ломал обработчик KeyError. — но не подтверждает частоту встречаемости. Поэтому ниже есть чистый fixture, противоположный control и стоп-линия; без них отсутствие crash или один удачный запуск остаются слабым наблюдением.
Карточка воспроизведения
Запишите карточку опыта T22-10: точная версия, режим запуска, короткий hash входа и действие «в локальном GUI-сеансе создать обычный tkinter root и один Tcl-created child с уникальным безопасным именем, затем направить фокус и вызвать четыре метода». Используйте только обратимые ресурсы. До выполнения определите, где появятся stdout, stderr и exit code, а также как будет выполнена очистка. Так диагностический пакет останется повторяемым и не потребует доступа к реальной инфраструктуре.
Control перед выводом
Отрицательный control обязателен: повторить четыре вызова для зарегистрированного Entry и для состояния без focus, пересоздавая root между ветками. Заполняйте «источник widget | focus target | метод | return type | widget path | exception class | root destroyed» до интерпретации вывода. Если результат зависит от порядка, поменяйте порядок и начните заново с чистого fixture. Не объединяйте несколько исправлений в одном опыте: иначе невозможно связать наблюдение с issue boundary.
Формальное условие приёмки
Формальное условие passed: зарегистрированный widget возвращается объектом, foreign widget и отсутствие focus дают None, а KeyError не покидает API boundary. Один позитивный запуск недостаточен — повтор должен сохранить тот же контракт. При расходящихся результатах снизьте вывод до inconclusive и проверьте происхождение бинарника, feature flags и чистоту input. Не повышайте уверенность количеством одинаковых перезапусков одного загрязнённого процесса.
Предел вмешательства
Предел вмешательства: не использовать рабочее окно приложения; завершить опыт при невозможности получить display, зависшем mainloop или неуничтоженном root. Нельзя расширять тест на production, чужие PID или реальные данные. После target удалите fixture, закройте локальные endpoints и повторите маленький baseline control. Только совпавший baseline доказывает, что эксперимент не оставил состояние.
Сокращённый support bundle
Сокращённый support bundle содержит: версии Python/Tk, четыре результата по трём веткам, обезличенные widget paths и подтверждение destroy. Свяжите его с T22-10, добавьте hash синтетического input и критерий «зарегистрированный widget возвращается объектом, foreign widget и отсутствие focus дают None, а KeyError не покидает API boundary». Абсолютные пути замените ролями, бинарные данные — hashes, сообщения с приватным контекстом — классами исключений.
Материал подготовлен редакцией VOne с помощью ИИ по открытым официальным и первичным источникам; факты, даты и ссылки перепроверены. Реальные пользовательские данные не использовались.
Источники и проверка
- Python 3.14.7 release проверено 2026-08-29
- Python 3.14.7 changelog проверено 2026-08-29
- CPython issue #88758 проверено 2026-08-29
Информация актуальна на дату публикации. Правила сервисов, приложений и сетей могут меняться.