gh-153506: Fix IDLE crash on non-iterable __all__#153527
gh-153506: Fix IDLE crash on non-iterable __all__#153527muhamedfazalps wants to merge 5 commits into
Conversation
When a module has __all__ set to a non-iterable value (like None), pressing Tab for module-name completion raised an uncaught TypeError. Now checks hasattr(__all__, '__iter__') before calling sorted(), falling back to the standard private-name filtering.
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Closing in favour of existing PR: #153507 |
Problem
Fixes gh-153506
When a module has
__all__set to a non-iterable value (likeNoneor an integer), pressing Tab for module-name completion in IDLE's shell raises an uncaughtTypeError.Root Cause
autocomplete.pycallssorted(eval("__all__", namespace))without checking if the value is iterable. If__all__ = None(an easy typo),sorted()raisesTypeError.Solution
Add a
hasattr(__all__, '__iter__')check before callingsorted(). If__all__is not iterable, fall back to the standard private-name filtering ([s for s in bigl if s[:1] != '_']).This is consistent with how Python's import system handles non-iterable
__all__— it raises an error, but IDLE should be resilient and fall back gracefully.Testing
Verified that:
__all__ = Noneno longer crashes — falls back to standard completion__all__ = ['valid', 'names']still works correctly__all__still works