Skip to content

gh-89520: IDLE - Make extentions use user's keys, not all defaults#28713

Merged
gpshead merged 54 commits intopython:mainfrom
CoolCat467:patch-1
Apr 12, 2026
Merged

gh-89520: IDLE - Make extentions use user's keys, not all defaults#28713
gpshead merged 54 commits intopython:mainfrom
CoolCat467:patch-1

Conversation

@CoolCat467
Copy link
Copy Markdown
Contributor

@CoolCat467 CoolCat467 commented Oct 3, 2021

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, 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.

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.

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.
blurb-it bot and others added 3 commits October 3, 2021 21:55
CoolCat467 and others added 3 commits February 1, 2022 14:57
@terryjreedy terryjreedy changed the title bpo-45357: Make extentions use user's keys, not all defaults bpo-45357: IDLE - Make extentions use user's keys, not all defaults Nov 2, 2022
@terryjreedy terryjreedy self-assigned this Nov 2, 2022
@terryjreedy terryjreedy changed the title bpo-45357: IDLE - Make extentions use user's keys, not all defaults gh-89520: IDLE - Make extentions use user's keys, not all defaults Nov 2, 2022
@python python deleted a comment from the-knights-who-say-ni Nov 2, 2022
@python-cla-bot
Copy link
Copy Markdown

python-cla-bot bot commented Apr 18, 2025

All commit authors signed the Contributor License Agreement.

CLA signed

@CoolCat467
Copy link
Copy Markdown
Contributor Author

@terryjreedy Ping

@CoolCat467
Copy link
Copy Markdown
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.

gpshead and others added 8 commits April 11, 2026 20:08
…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.
Copy link
Copy Markdown
Member

@gpshead gpshead left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@gpshead gpshead self-assigned this Apr 12, 2026
@gpshead gpshead enabled auto-merge (squash) April 12, 2026 04:19
@gpshead gpshead merged commit 208195d into python:main Apr 12, 2026
55 checks passed
@CoolCat467 CoolCat467 deleted the patch-1 branch April 12, 2026 04:44
@CoolCat467
Copy link
Copy Markdown
Contributor Author

Thank you so much! I've been waiting to get this merged for five years now, glad this is finally done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants