diff --git a/Lib/idlelib/idle_test/test_iomenu.py b/Lib/idlelib/idle_test/test_iomenu.py index 90a23620354f313..3ef9fcbc5bb569b 100644 --- a/Lib/idlelib/idle_test/test_iomenu.py +++ b/Lib/idlelib/idle_test/test_iomenu.py @@ -1,11 +1,13 @@ "Test , coverage 17%." from idlelib import iomenu +import os import unittest +from unittest import mock from test.support import requires -from tkinter import Tk +from tkinter import Tk, TclVersion from idlelib.editor import EditorWindow -from idlelib import util +from idlelib import macosx, util from idlelib.idle_test.mock_idle import Func # Fail if either tokenize.open and t.detect_encoding does not exist. @@ -38,6 +40,17 @@ def tearDownClass(cls): def test_init(self): self.assertIs(self.io.editwin, self.editwin) + def test_defaultfilename_tilde(self): + # gh-59568: escape a leading tilde for Tcl older than 9. + io = self.io + with mock.patch.object(io, 'filename', os.path.join('dir', '~file.py')): + dirname, base = io.defaultfilename() + self.assertEqual(dirname, 'dir') + if TclVersion < 9 and not macosx.isAquaTk(): + self.assertEqual(base, os.path.join(os.curdir, '~file.py')) + else: + self.assertEqual(base, '~file.py') + def test_fixnewlines_end(self): eq = self.assertEqual io = self.io diff --git a/Lib/idlelib/iomenu.py b/Lib/idlelib/iomenu.py index 9560aaa2da0c424..96bf6078f12c3ec 100644 --- a/Lib/idlelib/iomenu.py +++ b/Lib/idlelib/iomenu.py @@ -5,11 +5,13 @@ import tempfile import tokenize +from tkinter import TclVersion from tkinter import filedialog from tkinter import messagebox from tkinter.simpledialog import askstring # loadfile encoding. from idlelib.config import idleConf +from idlelib import macosx from idlelib.util import py_extensions py_extensions = ' '.join("*"+ext for ext in py_extensions) @@ -405,7 +407,12 @@ def askopenfile(self): def defaultfilename(self, mode="open"): if self.filename: - return os.path.split(self.filename) + dirname, base = os.path.split(self.filename) + if base[:1] == '~' and TclVersion < 9 and not macosx.isAquaTk(): + # Tcl before version 9 substitutes a leading tilde in + # a file name (gh-59568). The macOS dialog does not. + base = os.path.join(os.curdir, base) + return dirname, base elif self.dirname: return self.dirname, "" else: diff --git a/Misc/NEWS.d/next/IDLE/2026-09-16-18-00-00.gh-issue-59568.tilde1.rst b/Misc/NEWS.d/next/IDLE/2026-09-16-18-00-00.gh-issue-59568.tilde1.rst new file mode 100644 index 000000000000000..3eabd4e176ad8a6 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2026-09-16-18-00-00.gh-issue-59568.tilde1.rst @@ -0,0 +1,2 @@ +Fix "Save As" and "Open" dialogs in IDLE for a file whose name starts with +``~`` on Windows and X11 with Tcl/Tk older than 9.