gh-89520: IDLE - Make extentions use user's keys, not all defaults#28713
Merged
gpshead merged 54 commits intopython:mainfrom Apr 12, 2026
Merged
gh-89520: IDLE - Make extentions use user's keys, not all defaults#28713gpshead merged 54 commits intopython:mainfrom
gpshead merged 54 commits intopython:mainfrom
Conversation
I was trying to write an extension for Idle, and was noticing extension keys defined in ~/.idlerc weren't being used, so I looked into it and found `GetExtensionKeys`, `__GetRawExtensionKeys`, and `GetKeyBinding` would never check for user keys, always assuming default keys have everything. This is not always true. In a system with multiple users, you would not want to modify the default config file for a custom extension, as that is used for everyone. This pull request is changing aforementioned functions to also check user config files, and overwrite values acquired from the default config file if the user config redefined one.
Config saving and loading also weren't working quite right for extensions.
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Contributor
Author
|
@terryjreedy Ping |
Contributor
Author
|
@gpshead Would you mind looking at this one as well? It's been nearly two years since I've last heard from terry about this. |
…ig.py ChainMap is designed for Mapping types, not lists. GetOptionList() returns a list of strings, so passing these to ChainMap only worked by accident via CPython's dict.fromkeys() in ChainMap.__iter__. Replace with set() union, matching the pattern already used in GetExtensionKeys. The actual user-over-default prioritization is handled by GetOption(), not by the iteration order.
…etExtensionKeys GetExtensionKeys is a method on IdleConf. Using the module-level singleton idleConf instead of self is inconsistent with every other method in the class.
…xtensions Fix two issues in load_extensions: 1. def_str (the "default" value) was sourced from user config when the option existed there. This meant opening the extensions dialog could silently revert user customizations, since the user's value would be treated as the default and then removed. Now prefers default config, falling back to user config only for user-only extensions. 2. The value lookup was skipping user config for default-only options. Restore the original behavior of always trying user config first (which returns def_obj as fallback when the option is absent).
…ontent Rename from bpo-45357 to gh-issue-89520 format. Fix content to remove incorrect mention of GetKeyBinding (not changed in this PR).
…e section read_dict is additive and doesn't remove sections. Setting enable to False still leaves the ZzDummy section in user config. Use remove_section to fully restore the original empty state.
…files Create ZZDummyMixin in test_zzdummy.py containing shared test methods (checklines, test_init, test_reload, test_z_in_event, test_z_out_event, test_roundtrip). Both ZZDummyTest classes now inherit from the mixin, eliminating ~90 lines of duplication from test_zzdummy_user.py.
Restore the original extensionName parameter name on GetExtensionKeys and GetExtensionBindings to avoid breaking callers using keyword arguments.
gpshead
approved these changes
Apr 12, 2026
Member
gpshead
left a comment
There was a problem hiding this comment.
manually tested in addition to the unittests, it appears to work. i refactored the change with claude a bit to polish it up and address any remaining issues.
Contributor
Author
|
Thank you so much! I've been waiting to get this merged for five years now, glad this is finally done. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I was trying to write an extension for Idle, and was noticing extension keys defined in ~/.idlerc weren't being used, so I looked into it and found that in idlelib.config.idleConf,
GetExtensionKeys,__GetRawExtensionKeys, andGetKeyBindingwould never check for user keys, always assuming default keys have everything. This is not always true. In a system with multiple users, you would not want to modify the default config file for a custom extension, as that is used for everyone. This pull request is changing aforementioned functions to also check user config files, and overwrite values acquired from the default config file if the user config redefined one.Edit:
The especially interesting part is that extensions are loaded anyways if they have an entry in the user's IDLE configuration file, but their keybinds are only loaded properly if they are defined in the root configuration file at the moment. This pull request is fixing this difference and allows extension keybinds to be loaded from the user's IDLE configuration file, making user extensions work just as well as root extensions.