Doc/library/idle.rst, help.py, help.html, config-main.def, CPython main 993a0c65a7b.
Tracked in the umbrella issue python/cpython#154760 — one of 69 idlelib findings from a two-pass review with code-review-toolkit.
Each numbered heading below is one finding and has its own anchor, so the umbrella table links straight to it. The numbers are row numbers in that table, not identifiers — when referring to one of these, cite #154760 and the row, not the bare number.
Do not start work on a finding until a maintainer has cleared it in #154760. Every row there starts at Under analysis, which means not yet cleared.
AI disclaimer: these reports were drafted with Claude Code. Every cited line was re-read in the tree, every "Verified" block was produced by running the code, and the prior-art search was run against the full python/cpython tracker before publishing.
How to read a finding. Where is the line as of the commit above and will drift. Guarded twin is a place in idlelib that already handles the same situation correctly — it is both the evidence that this is a defect by the project's own standard and the shape of the fix. Prior art records what the tracker already says.
FIX · confirmed by reading · shape same-fact-derived-from-two-sources
Where: Doc/library/idle.rst:731-732
What happens. The Library Reference says sys.argv[0] is set to '', '-c' or '-r' respectively; the code at pyshell.py:1583 is elif script: sys.argv = [script] + args — the script path, never '-r'. The '' and '-c' thirds are correct; only -r is wrong. Code written against the doc tests sys.argv[0] == '-r', gets 'foo.py', takes the wrong branch, and nothing raises. Wrong since 2015.
Guarded twin. usage_msg at pyshell.py:1509 — idle -h says 'passing "foo.py" in sys.argv[0]', which is correct. The tool's own help output and its reference documentation state the same fact and disagree.
Suggested fix. Correct the third bullet in idle.rst to name the script path.
Prior art — no matching report found. Searched the cached python/cpython tracker corpus (1626 topic-IDLE issues + 281 unlabelled idlelib issues + 573 PRs + 86 idle.rst items; 2503 unique) for this defect's terms and for its file/function names. No matching report.
FIX · confirmed by reading · shape documented-recipe-not-wired-up
Where: Doc/library/idle.rst:752
What happens. The 'Startup failure' section tells a user to run tcpconnect -irv 127.0.0.1 6543 to diagnose a failed subprocess connection, but PORT = 0 (pyshell.py:51) — IDLE binds an ephemeral port. 6543 occurs in exactly two places in the whole tree: idle.rst:754 and its generated copy help.html:619; zero occurrences in idlelib source. The recipe cannot distinguish the two cases it exists to distinguish — a user hitting the documented failure gets a refusal on a port nothing listens on, and concludes the wrong thing either way. Written into the docs in 2021 and never true.
Guarded twin. The same section's ** Invalid host: advice, which names a real, checkable string.
Suggested fix. Drop the port, or describe how to discover the ephemeral one.
Prior art — no matching report found. Searched the cached python/cpython tracker corpus (1626 topic-IDLE issues + 281 unlabelled idlelib issues + 573 PRs + 86 idle.rst items; 2503 unique) for this defect's terms and for its file/function names. No matching report.
CONSIDER · confirmed by reading · shape generated-doc-propagates-a-source-error
Where: help.py:251
What happens. Doc/library/idle.rst -> sphinx -> copy_strip() -> Lib/idlelib/help.html, shown in-app. All 35/35 rst section headings are present in help.html, both written by the same commit. The generator is working correctly — which is exactly what makes this a finding: 0037 and 0038 are reproduced verbatim into the shipped HTML, and regenerating cannot fix any of it.
Guarded twin. README.txt, which is hand-maintained and is correct where the generated chain is not.
Suggested fix. Fix errors at the rst source; regeneration is not a remedy.
Prior art — no matching report found. Searched the cached python/cpython tracker corpus (1626 topic-IDLE issues + 281 unlabelled idlelib issues + 573 PRs + 86 idle.rst items; 2503 unique) for this defect's terms and for its file/function names. No matching report.
CONSIDER · confirmed by reading · shape refactor-changed-behaviour-doc-did-not
Where: Doc/library/idle.rst, Lib/idlelib/help.html, mainmenu.py:115
What happens. 'the General tab' appears at 5 rst sites, but that tab was split into Windows and Shell/Ed in 3.11 (GH-26621) and help sources moved to Extensions. Separately, 'IDLE Help' was renamed to 'IDLE Doc' in 3.12 (mainmenu.py:115) and the rename propagated to NONE of six live user-facing sites, including two runtime error messages and idle -h. A user following the instructions looks for a tab and a menu item that are not there.
Guarded twin. README.txt:204-205, hand-maintained, already says 'Windows tab' / 'Shell/Ed tab'.
Suggested fix. Update the rst and the six 'IDLE Help' sites; the generated help.html follows.
Prior art — no matching report found. Searched the cached python/cpython tracker corpus (1626 topic-IDLE issues + 281 unlabelled idlelib issues + 573 PRs + 86 idle.rst items; 2503 unique) for this defect's terms and for its file/function names. No matching report.
CONSIDER · confirmed by reading · shape implemented-but-undocumented-option
Where: config-main.def:48, config-main.def:67
What happens. print-command-posix, print-command-win, delete-exitfunc and [History] cyclic are parsed, defaulted and consumed, but appear in neither idle.rst nor the Settings dialog. print-command-* is the sharpest: idle.rst:104 documents Print Window with no hint the command is configurable, the Linux default is lpr, and config-main.def:48 tells the user to change settings through the dialog — which for these four is impossible. Inverse direction: [EditorWindow] encoding (config-main.def:67) has no consumer anywhere.
Guarded twin. Every other option in config-main.def, each of which is reachable from the dialog.
Suggested fix. Document the four, or surface them in the dialog; delete the phantom.
Prior art — no matching report found. Searched the cached python/cpython tracker corpus (1626 topic-IDLE issues + 281 unlabelled idlelib issues + 573 PRs + 86 idle.rst items; 2503 unique) for this defect's terms and for its file/function names. No matching report.
CONSIDER · confirmed by reading · shape unreachable-name-in-a-closed-vocabulary
Where: mainmenu.py:80, undo.py:38, config-keys.def:261
What happens. <> is on the Run menu of the Find-in-Files window but bound only in PyShellEditorWindow (pyshell.py:131), so it silently does nothing there — and unlike every sibling skipped bind (editor.py:305,313; pyshell.py:957) it is NOT paired with update_menu_state(..., 'disabled'), so the item looks live. <> is bound at undo.py:38 under if self.debug and appears in no keyset, so it is reachable from nothing. <> is defined once (config-keys.def:261) and read by nothing.
Guarded twin. editor.py:305,313 and pyshell.py:957 — the siblings that skip a bind AND disable the menu entry.
Suggested fix. Pair the skipped bind with update_menu_state(..., 'disabled'); delete the two dead events.
Prior art — no matching report found. Searched the cached python/cpython tracker corpus (1626 topic-IDLE issues + 281 unlabelled idlelib issues + 573 PRs + 86 idle.rst items; 2503 unique) for this defect's terms and for its file/function names. No matching report.