text boxes never stop listening
Nobody has claimed this yet.
- #1 by @CJstate — closed without merging
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 88/100
Research direction
Start with _text_area.py and _input.py at the cited _on_mount methods, then read Footer's unmount cleanup in _footer.py as a reference. Use the provided reproducer to check that removed Input and TextArea widgets are no longer retained without publishing the signal; done means the leak is fixed for both widgets.
Written by the indexing model from the issue text.
Description
The bug
TextArea._on_mount (_text_area.py:1904-1911) and Input._on_mount (_input.py:715-722) subscribe to self.screen.text_selection_started_signal with a callback that closes over self, and neither unsubscribes on unmount.
Signal keeps subscribers in a WeakKeyDictionary (signal.py:44), but the stored value is a wrapper holding that callback (signal.py:82-95), which holds self, so the weak key never dies. Dead subscribers are pruned only in publish() (signal.py:125-128), and nothing in Textual 8.2.8 publishes this signal. So every removed TextArea or Input stays alive, with its subtree, for the screen's lifetime.
Footer (_footer.py:333) and KeyPanel (_key_panel.py:182) already unsubscribe their own signal on unmount.
Example
import asyncio, gc
from textual.app import App
from textual.widgets import Input
async def main():
app = App()
async with app.run_test() as pilot:
for _ in range(20):
widget = Input()
await app.mount(widget)
await pilot.pause()
await widget.remove()
await pilot.pause()
del widget
gc.collect()
print(sum(type(o) is Input for o in gc.get_objects())) # 20, expected 0
asyncio.run(main())
One manual app.screen.text_selection_started_signal.publish(app.screen) drops it to 2. With TextArea in place of Input it stays at 20 until both a publish and an app theme change (the theme watcher is #6666).
Textual 8.2.8, Python 3.11.14, macOS.
Suggested fix
In TextArea and Input, unsubscribe on unmount, as Footer does:
self.screen.text_selection_started_signal.unsubscribe(self)
- Dominant language
- Python
- Stars
- 37.6k
- Forks
- 1.4k
- PR merge metrics
- No merged PRs in 30d
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Textualize/textual
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Textualize/textual#6753 · 1 comment ·
-
8.2.8: _parse_extended_key crashes the input thread on Kitty colon sub-parameters (key:shifted:base, mods:event) — ValueError in int(), app panicsPossibly taken @NavpreetSSidhu claimed this 9 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
Textualize/textual#6746 · 3 comments ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Textualize/textual#6738 · 4 comments ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Textualize/textual#6735 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Textualize/textual#6734 · 2 comments ·
All issues in Textualize/textual
Similar issues
-
Remove the `pull_request_target` workflow before GitHub blocks itPossibly taken @jat255 claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
IBM/mcp-context-forge#7483 ·
Maintainers usually reply within 2 days
-
bug good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
[Bug Report]: OpenAI 辅助 API 连通性测试因输出上限仅 1 token 误报“未知错误”Possibly taken @fjfanjian claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Project-N-E-K-O/N.E.K.O#3640 ·
Maintainers usually reply within 1 day
-
author-page correction
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
acl-org/acl-anthology#10808 · 1 comment ·
Maintainers usually reply within 1 day