prompt-toolkit / prompt-toolkit/python-prompt-toolkit
Memory usage over time (many prompts via inquirerpy)
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 10.6k
- Forks
- 815
- PR merge metrics
- No merged PRs in 30d
Description
Hi,
thanks a lot for this useful package.
Originally raised on inquirerpy (a prompt-toolkit wrapper); author advised to submit here instead:
I'm building an interactive app (with inquirerpy, not using asyncio) involving large lists and jumping back and forth instantiating new prompts on the way; it is intended to run for a while.
I noticed memory usage keeps growing and very little being released over time.
Am I right in assuming on event.app.exit() the prompt should exit and tear down entirely? Is there anything else I can/should do to reset/clean up?
Python 3.10.2 on windows (tags/v3.10.2:a58ebcc, Jan 17 2022, 13:59:55) [MSC v.1929 32 bit (Intel)]
inquirerpy==0.3.3
prompt-toolkit==3.0.28
Here's a simple demo to highlight the issue:
import time, random
from InquirerPy import inquirer
from pynput.keyboard import Key, Controller
from mem_top import mem_top
def makeChoices():
for i in range(1000):
words = "The value that should be presented to the user prior/after selection of the choice. This value is optional, if not provided, it will fallback to the string representation of value.".split()
random.shuffle(words) # not needed to reproduce
yield " ".join(words)
def getChoices():
choices = []
for choice in makeChoices(): choices.append(choice)
return choices
def _prompt(i):
inquirer.select(message="Testmem prompt" if i > 0 else "Press enter to start test", choices=getChoices(),
default=None, show_cursor=False).execute()
if (i < 100): # this runs in the next iteration
for i in range(1000):
keyboard.press(Key.down)
keyboard.release(Key.down)
keyboard.press(Key.enter)
keyboard.release(Key.enter)
keyboard = Controller()
i = -1
while i < 100:
i += 1
time.sleep(0.5)
_prompt(i)
print(mem_top())
"""
refs:
9093 <class 'prompt_toolkit.filters.base._AndCache'> {(~Condition(<function is_done at 0x03BE0FA0>), Condition(<function BaseComplexPrompt.__init__.<loca...
4001 <class 'prompt_toolkit.formatted_text.base.FormattedText'> FormattedText([('class:pointer', '❯'), ('class:marker', ' '), ('[SetCursorPosition]', ''), ('class:p...
types:
202428 <class 'dict'>
169534 <class 'prompt_toolkit.key_binding.key_bindings.Binding'>
155551 <class 'tuple'>
118098 <class 'list'>
59785 <class 'function'>
35636 <class 'frozenset'>
34023 <class 'prompt_toolkit.styles.base.Attrs'>
27188 <class 'cell'>
8699 <class 'collections.deque'>
8389 <class 'prompt_toolkit.cache.SimpleCache'>
"""
By the way, a feasible workaround is using multiprocessing for the prompts, however I'd prefer keeping things elegant and snappy.
Contributor guide
No contributing guide indexed for this repository
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.
Research direction
Start by running the supplied Python 3.10 demo with inquirerpy and prompt-toolkit 3.0.28, then inspect the lifecycle around inquirer.select(...).execute() and event.app.exit(). Use the listed retained types and references as leads for determining what survives each prompt; done means identifying the retention cause and confirming memory is released or documenting the required cleanup.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100