https://github.com/python/cpython/commit/3f5491a09223f7371b4b4c92225e8dfdf1c989b7
commit: 3f5491a09223f7371b4b4c92225e8dfdf1c989b7
branch: main
author: Serhiy Storchaka <[email protected]>
committer: terryjreedy <[email protected]>
date: 2026-07-01T12:35:57-04:00
summary:
gh-134300: Remove idlelib from the path of the IDLE user process (#152739)
The idlelib directory ends up on sys.path when idle.py is run as a script,
and it was passed to the user process, where it let user code import
idlelib submodules as top-level modules, such as "import help".
files:
A Misc/NEWS.d/next/IDLE/2026-07-01-15-00-00.gh-issue-134300.iDlPaT.rst
M Lib/idlelib/idle_test/test_pyshell.py
M Lib/idlelib/pyshell.py
diff --git a/Lib/idlelib/idle_test/test_pyshell.py
b/Lib/idlelib/idle_test/test_pyshell.py
index 51f7691eefe9d5..dec81bdbbccd67 100644
--- a/Lib/idlelib/idle_test/test_pyshell.py
+++ b/Lib/idlelib/idle_test/test_pyshell.py
@@ -2,6 +2,7 @@
# Plus coverage of test_warning. Was 20% with test_openshell.
from idlelib import pyshell
+import os
import unittest
from test.support import requires
from tkinter import Tk
@@ -28,6 +29,14 @@ def test_restart_line_narrow(self):
self.assertEqual(pyshell.restart_line(width, ''), expect)
self.assertEqual(pyshell.restart_line(taglen+2, ''), expect+' =')
+ def test_fix_user_path(self):
+ # gh-134300: the idlelib directory is removed, other entries kept.
+ eq = self.assertEqual
+ idlelib_dir = os.path.dirname(os.path.abspath(pyshell.__file__))
+ eq(pyshell.fix_user_path(['', '/a', idlelib_dir, '/b']), ['', '/a',
'/b'])
+ eq(pyshell.fix_user_path(['/a', '/b']), ['/a', '/b'])
+ eq(pyshell.fix_user_path([idlelib_dir]), [])
+
class PyShellFileListTest(unittest.TestCase):
diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py
index f117f0bfb52f2a..ef3d014d936ce8 100755
--- a/Lib/idlelib/pyshell.py
+++ b/Lib/idlelib/pyshell.py
@@ -408,6 +408,17 @@ def restart_line(width, filename): # See bpo-38141.
return tag[:-2] # Remove ' ='.
+def fix_user_path(path):
+ """Return path without the idlelib directory (gh-134300).
+
+ That directory is on sys.path when idle.py is run as a script.
+ Otherwise user code could import idlelib submodules as top-level
+ modules, such as "import help".
+ """
+ idlelib_dir = os.path.dirname(os.path.abspath(__file__))
+ return [p for p in path if p != idlelib_dir]
+
+
class ModifiedInterpreter(InteractiveInterpreter):
def __init__(self, tkconsole):
@@ -568,6 +579,7 @@ def transfer_path(self, with_cwd=False):
path.extend(sys.path)
else:
path = sys.path
+ path = fix_user_path(path) # gh-134300
self.runcommand("""if 1:
import sys as _sys
diff --git
a/Misc/NEWS.d/next/IDLE/2026-07-01-15-00-00.gh-issue-134300.iDlPaT.rst
b/Misc/NEWS.d/next/IDLE/2026-07-01-15-00-00.gh-issue-134300.iDlPaT.rst
new file mode 100644
index 00000000000000..791acbbed62aaf
--- /dev/null
+++ b/Misc/NEWS.d/next/IDLE/2026-07-01-15-00-00.gh-issue-134300.iDlPaT.rst
@@ -0,0 +1,3 @@
+Do not add the ``idlelib`` directory to the path of the IDLE user process.
+User code run in IDLE can no longer import ``idlelib`` submodules as
+top-level modules, such as ``import help``.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]