From 3ae24bb0e4ab3c56dae494bc0ca58c88526305d2 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 13 Sep 2026 07:20:58 +0300 Subject: [PATCH] gh-90304: Fix IDLE startup failure with a broken font (GH-152419) On some systems a font reports a zero width for the '0' character (seen with a broken font on openSUSE). EditorWindow.set_width() divides the Text widget's pixel width by that value, so the ZeroDivisionError prevented IDLE from starting at all. set_width() now falls back to the configured width when the measured width is zero. self.width is consumed by the === RESTART === separator in the shell and by the squeezer's line wrapping. (cherry picked from commit 8a2db991dabe7ee5afd8385ef569f6e1f0120d6f) Co-authored-by: Serhiy Storchaka Co-authored-by: Claude Opus 4.8 --- Lib/idlelib/editor.py | 4 +++- Lib/idlelib/idle_test/test_editor.py | 13 +++++++++++++ .../2026-06-27-17-27-21.gh-issue-90304.464d22.rst | 4 ++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/IDLE/2026-06-27-17-27-21.gh-issue-90304.464d22.rst diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 2b4b95e053ba10b..5e9f6aa86e81925 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -325,7 +325,9 @@ def set_width(self): # http://www.tcl.tk/man/tcl8.6/TkCmd/text.htm#M21 zero_char_width = \ Font(text, font=text.cget('font')).measure('0') - self.width = pixel_width // zero_char_width + # Some fonts report a zero width for '0' (gh-90304). + self.width = (pixel_width // zero_char_width if zero_char_width + else text.tk.getint(text.cget('width'))) def new_callback(self, event): dirname, basename = self.io.defaultfilename() diff --git a/Lib/idlelib/idle_test/test_editor.py b/Lib/idlelib/idle_test/test_editor.py index 873637f67defa37..e32981091b72a6e 100644 --- a/Lib/idlelib/idle_test/test_editor.py +++ b/Lib/idlelib/idle_test/test_editor.py @@ -3,6 +3,7 @@ from idlelib import editor import unittest from collections import namedtuple +from unittest import mock from test.support import requires from tkinter import Tk, Text @@ -30,6 +31,18 @@ def test_init(self): self.assertEqual(e.root, self.root) e._close() + def test_set_width_zero_char_width(self): + # A zero-width '0' must not raise ZeroDivisionError (gh-90304). + e = Editor(root=self.root) + try: + with mock.patch.object(editor, 'Font') as MockFont: + MockFont.return_value.measure.return_value = 0 + e.set_width() + self.assertEqual(e.width, + e.text.tk.getint(e.text.cget('width'))) + finally: + e._close() + class GetLineIndentTest(unittest.TestCase): def test_empty_lines(self): diff --git a/Misc/NEWS.d/next/IDLE/2026-06-27-17-27-21.gh-issue-90304.464d22.rst b/Misc/NEWS.d/next/IDLE/2026-06-27-17-27-21.gh-issue-90304.464d22.rst new file mode 100644 index 000000000000000..c92c1f75b9d7a7d --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2026-06-27-17-27-21.gh-issue-90304.464d22.rst @@ -0,0 +1,4 @@ +Prevent IDLE from failing to start when a font reports a zero width for +the ``'0'`` character. Such a broken font caused a +:exc:`ZeroDivisionError`; the editor now falls back to the configured +width.