Exahilosys / survey

A simple library for creating beautiful interactive prompts.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Typing multiple "keys" at once / very fast leads to an error

notniknot opened this issue · comments

When one types multiple keys at once, very fast or copies e.g. an URL into the field the following error is raised:

Traceback (most recent call last):
  File "/Users/XXXX/projects/charter/test.py", line 3, in <module>
    test_field = survey.routines.input("test_field: ")
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_theme.py", line 75, in wrapper
    return function(*args, **kwargs)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_routines.py", line 73, in _input
    result = _widgets.start(
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_widgets.py", line 398, in _start
    _system.console.start(sketch, invoke)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_console.py", line 91, in start
    self._start(sketch, invoke)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_console.py", line 71, in _start
    self._handle.start(callback)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_handle.py", line 57, in start
    self._start(invoke)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_helpers.py", line 35, in wrapper
    return function(self, *args, **kwargs)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_handle.py", line 41, in _start
    source.listen()
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_source.py", line 189, in listen
    self._listen()
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_source.py", line 181, in _listen
    self._advance()
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_helpers.py", line 35, in wrapper
    return function(self, *args, **kwargs)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_source.py", line 175, in _advance
    self._process(info)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_source.py", line 168, in _process
    self._callback(name, info)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_console.py", line 67, in callback
    print(True)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_console.py", line 60, in print
    self._screen.print(sketch, re)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_screen.py", line 70, in print
    self._print(sketch, re, clean = clean, learn = learn)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_helpers.py", line 35, in wrapper
    return function(self, *args, **kwargs)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_helpers.py", line 35, in wrapper
    return function(self, *args, **kwargs)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_screen.py", line 46, in _print
    self._render.draw(*info, **kwargs)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_render.py", line 249, in draw
    self._draw(learn, clean, lines, point)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_helpers.py", line 35, in wrapper
    return function(self, *args, **kwargs)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_helpers.py", line 35, in wrapper
    return function(self, *args, **kwargs)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_render.py", line 189, in _draw
    cur_y, cur_x = self._cursor.locate()
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_cursor.py", line 326, in locate
    point = self._locate()
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_helpers.py", line 35, in wrapper
    return function(self, *args, **kwargs)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_helpers.py", line 35, in wrapper
    return function(self, *args, **kwargs)
  File "/usr/local/Caskroom/mambaforge/base/envs/charter/lib/python3.9/site-packages/survey/_core/_cursor.py", line 313, in _locate
    point = tuple(map(int, code.args))
AttributeError: 'Text' object has no attribute 'args'

with the following code (tested it with form as well):

import survey

test_field = survey.routines.input("test_field: ")

My environment: macOS Ventura 13.4.1, Conda, Python 3.9.16, survey==4.5.2

Edit:

  • macOS VSCode with zsh or bash: does not work
  • macOS default Terminal with zsh: Error is harder to trigger (pasting multiple URLs at once triggers it)
  • Debian VSCode with bash: does not work
  • Windows VSCode with CMD or Powershell: seems to work
commented

I'm afraid this is is an inherent limitation in computing power and terminal used in conjunction with this library. As far as I can tell, the issue lies with runes being added to the buffer exactly after the cursor requests data from the terminal, and ends up getting these seemingly irrelevant runes as response. This should not happen if the terminal could always process the requests sent to it fast enough, but in some cases, it might. I cannot reproduce this on a higher end computer, but ran into it myself during development on a lower-spec laptop.

An obvious solution would be to search forward in the text buffer for an ansi sequence that complies with what the cursor is expected to receive as response to its request. However, this does not guarantee that the response will be to the request it just made, or one that was made before (or after) and got resolved at that moment.

I will continue researching this and make a mvp of the above solution.

commented

The solution is in e7d5e98, I am going to live this open for a few weeks just in case anyone still runs into this issue, as I am unable to test it with my current hardware.

Thanks for the quick response! Tested 4.5.3 and it is pretty much usable for me now.

Just noticed one minor side effect when using the form routine. When typing real fast in the edit mode it can happen that certain chars are appended to the description. When filtering in a form they are sometimes appended to one of the items. But this is not a deal breaker and only rarely the case.

Example
import survey

form = {
    "name": survey.widgets.Input(),
    "price": survey.widgets.Count(),
    "type": survey.widgets.Select(options=("food", "stationary", "tobacco", "literature")),
}
data = survey.routines.form("Item Data: ", form=form)
? Item Data: kjddkldl[back: submit]
>  name: sdfjsdfjlsdfkljklsdfsfjklsfjsfjksdjkf
  price: 0                                    
   type: > food                               
           stationary                         
           tobacco                            
           literature

(a few of the chars get appended to the description when I'm hammering on my keyboard)

commented

I see, this is probably because some keys get inserted when the cursor is back at origin and about to redraw, I believe using a lock to prevent any characters from being inserted between draws should do the trick.

Edit: This is already being done, so further inspection is needed to determine the cause.

commented

Closing as stale.