Menu

#11 Timeout causes library to throw error

v3
closed
None
5
2021-06-23
2019-02-20
Rolf
No

"timeout" conditions are not handled well by this library. When a timeout occurs, an exception is thown (I would have expected the "code" that is returned to be "timeout").

dialog.DialogError('the dialog-like program exited with status 3 (which was passed to it as the DIALOG_ERROR environment variable). Sometimes, the reason is simply that dialog was given a height or width parameter that is too big for the terminal in use. Its output, with leading and trailing whitespace stripped, was:\n\ntimeout')

Discussion

  • Florent Rougon

    Florent Rougon - 2021-06-17

    Hello,

    Sorry for replying “a bit” late: my ISP Free.fr and SourceForge can't get along, so notification or SourceForge mailing-list emails get lost. Regarding what you wrote:

    1) This is most probably related to layers below pythondialog.

    2) Without a minimal example to reproduce, this report is unlikely to be of any use, I'm afraid.

     
  • Florent Rougon

    Florent Rougon - 2021-06-17
    • labels: --> moreinfo
     
  • Rolf

    Rolf - 2021-06-17

    I can no longer reproduce this in a modern setup. Instead, timeouts result in an "esc" code, which also seems wrong.

    Example:
    import dialog
    if name == 'main':
    a = dialog.Dialog().checklist(
    'Stuff',
    choices=
    ['T1', 'One', 0
    ,
    ['T2', 'Two', 0],
    ],
    timeout=5)
    print(a)

    Run that and then just wait 5 seconds. I would expect it to say it encountered a timeout, instead I see "('esc', [])"

     
  • Florent Rougon

    Florent Rougon - 2021-06-17

    Thanks for the minimal example. The Dialog.checklist() method returns Dialog.ESC because the underlying dialog program returns DIALOG_ESC. Support for DIALOG_TIMEOUT in dialog was probably added after I implemented the exit status handling. With this patch applied:

    diff --git a/dialog.py b/dialog.py
    index e6031e5..35ca74c 100644
    --- a/dialog.py
    +++ b/dialog.py
    @@ -818,12 +818,14 @@ class Dialog:
         _DIALOG_EXTRA     = 4
         _DIALOG_HELP      = 5
         _DIALOG_ITEM_HELP = 6
    +    _DIALOG_TIMEOUT   = 7
         # cf. also _lowlevel_exit_codes and _dialog_exit_code_ll_to_hl which are
         # created by __init__(). It is not practical to define everything here,
         # because there is no equivalent of 'self' for the class outside method
         # definitions.
    -    _lowlevel_exit_code_varnames = frozenset(("OK", "CANCEL", "ESC", "ERROR",
    -                                              "EXTRA", "HELP", "ITEM_HELP"))
    +    _lowlevel_exit_code_varnames = frozenset(
    +        ("OK", "CANCEL", "ESC", "ERROR", "EXTRA", "HELP", "ITEM_HELP",
    +         "TIMEOUT"))
    
         # High-level exit codes, AKA "Dialog exit codes". These are the codes that
         # pythondialog-based applications should use.
    @@ -843,6 +845,9 @@ class Dialog:
         #: :term:`Dialog exit code` corresponding to the ``DIALOG_HELP`` and
         #: ``DIALOG_ITEM_HELP`` :term:`dialog exit statuses <dialog exit status>`
         HELP   = "help"
    +    #: :term:`Dialog exit code` corresponding to the ``DIALOG_TIMEOUT``
    +    #: :term:`dialog exit status`
    +    TIMEOUT = "timeout"
    
         # Define properties to maintain backward-compatibility while warning about
         # the obsolete attributes (which used to refer to the low-level exit codes
    

    the following example (essentially yours) distinguishes between “Esc pressed” and a timeout:

    import dialog
    
    d = dialog.Dialog()
    res = d.checklist(
        'Stuff',
        choices=[
            ('T1', 'One', 0),
            ('T2', 'Two', 0),
        ],
        timeout=2)
    
    print(res)
    print(res[0] == d.TIMEOUT)
    
     
  • Florent Rougon

    Florent Rougon - 2021-06-17
    • labels: moreinfo -->
    • assigned_to: Florent Rougon
     
  • Florent Rougon

    Florent Rougon - 2021-06-17

    This is fixed in 8ffc85fc1 (the commit message uses a wrong URL for the issue, sorry).

     
  • Florent Rougon

    Florent Rougon - 2021-06-17
    • status: open --> closed
     
  • Florent Rougon

    Florent Rougon - 2021-06-19

    Commit df4f82a63c should improve support for this timeout option. I hope no widget that normally produces output is broken by the empty output in case of a timeout.

     
  • Rolf

    Rolf - 2021-06-19

    Great. Can you push it out as a pip update?

     
  • Florent Rougon

    Florent Rougon - 2021-06-19

    I will, but unfortunately, I don't think dialog supports --timeout for all widgets. So far, I've seen it work with checklist (here), msgbox (in the latest version of demo.py) and menu (quick hack on demo.py). AFAICS, it doesn't work with inputbox nor with mixedform. I haven't tested with other widgets. All this with dialog version 1.3-20201126 from Debian unstable (which suffers from this little problem...).

     
  • Florent Rougon

    Florent Rougon - 2021-06-19

    pythondialog 3.5.2 is out with the changes (on PyPI.org, among others).

     
  • Rolf

    Rolf - 2021-06-19

    Strange. I can still reproduce the problem with your updated library.

    $ dialog --version
    Version: 1.3-20190808

    $ pip3 freeze | grep pythondialog
    pythondialog==3.5.2

     
  • Florent Rougon

    Florent Rougon - 2021-06-19

    Strange indeed. The following works fine for me:

    import dialog
    
    d = dialog.Dialog()
    res = d.checklist(
        'Stuff',
        choices=[
            ('T1', 'One', 0),
            ('T2', 'Two', 0),
        ],
        timeout=2)
    
    print(dialog.__version__)
    print(res)
    print(res[0] == d.TIMEOUT)
    

    Are you sure you ran your test with the correct pythondialog? The above script should print the version that is being used.

     
  • Florent Rougon

    Florent Rougon - 2021-06-19

    One possible explanation is that your dialog program is too old. Indeed, I tested the above with dialog 1.3-20201126, and in case I let the timeout expire, the output is:

    3.5.2
    ('timeout', [])
    True
    

    but with dialog 1.3-20190211 (on Debian buster) and pythondialog 3.5.2 too, the same test prints this:

    3.5.2
    ('esc', [])
    False
    

    So, maybe you need to upgrade dialog to make this work.

     
  • Rolf

    Rolf - 2021-06-19

    Alright. Thanks for your work. I'm not going to bother trying to upgrade my dialog installation, I'll just wait for my distro to get it.

     
  • Florent Rougon

    Florent Rougon - 2021-06-19

    All right, good night. :)

     
  • Florent Rougon

    Florent Rougon - 2021-06-23

    Hi,

    FYI, building dialog from source is not difficult (you may need to install a few -dev packages for its build dependencies). I just did it for the latest version, namely 1.3-20210621, with the following commands:

    tar -xzf dialog.tar.gz
    cd dialog-1.3-20210621
    ./configure --prefix=/opt/dialog-1.3-20210621 --enable-nls --with-ncursesw
    make
    

    (actually, I added -j7 to the make command). I specified the --prefix just in case I would later do a make install, but I usually don't perform this step: for my testing, dialog doesn't need to be installed. Then I applied the following temporary change to tell pythondialog's demo.py to use the newly-built executable:

    diff --git a/examples/demo.py b/examples/demo.py
    index 400c6f4..992bbd7 100755
    --- a/examples/demo.py
    +++ b/examples/demo.py
    @@ -335,7 +335,7 @@ class MyApp:
             # If you want to use Xdialog (pathnames are also OK for the 'dialog'
             # argument), you can use:
             #   dialog.Dialog(dialog="Xdialog", compat="Xdialog")
    -        self.Dialog_instance = dialog.Dialog(dialog="dialog")
    +        self.Dialog_instance = dialog.Dialog(dialog="/path/to/dialog-1.3-20210621/dialog")
             # See the module docstring at the top of the file to understand the
             # purpose of MyDialog.
             d = MyDialog(self.Dialog_instance)
    

    and ran ./examples/demo.py --test-suite. from the root of the pythondialog repository. This allowed me to confirm that dialog 1.3-20210621 is good for pythondialog.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.