Cimbali / pympress

Pympress is a simple yet powerful PDF reader designed for dual-screen presentations
https://cimbali.github.io/pympress/
GNU General Public License v2.0
1.19k stars 89 forks source link

Crash on comparison int vs string #219

Closed ojura closed 3 years ago

ojura commented 3 years ago

Describe the bug Occasional crash.

To Reproduce Unfortunately, I have no reliable steps to reproduce. It is sporadic.

Expected behavior A clear and concise description of what you expected to happen.

Screenshots Not crash :)

Environment (please complete the following information): Ubuntu/Windows

Debug information (see below for file locations) Here's a traceback, it might be apparent how this could happen:

(pympress:830): Gtk-CRITICAL **: 22:40:42.121: gtk_entry_set_text: assertion 'text != NULL' failed
Traceback (most recent call last):
  File "/home/juraj/.local/lib/python3.8/site-packages/pympress/ui.py", line 934, in open_file
    self.swap_document(target.get_string())
  File "/home/juraj/.local/lib/python3.8/site-packages/pympress/ui.py", line 720, in swap_document
    self.timing.set_document_metadata(self.doc.get_structure().copy(), self.doc.page_labels[:])
  File "/home/juraj/.local/lib/python3.8/site-packages/pympress/document.py", line 816, in get_structure
    page = min(number for number, label in enumerate(self.page_labels)
  File "/home/juraj/.local/lib/python3.8/site-packages/pympress/document.py", line 817, in <genexpr>
    if label == self.page_labels[page] and number > lower_bound)
TypeError: '>' not supported between instances of 'int' and 'str'

Here's the (very much incomplete) presentation. It's missing media though. frontier_detection.pdf

Additional context If you need anything else, feel free to ask. I'm currently trying to get that presentation done :)

Cimbali commented 3 years ago

Thanks for reporting! I’ll have a look. Does it happen when you do something in particular? It seems to be called from open_file, does it always happen when you open a file? Or maybe when the slide is reloaded (i.e. if it’s modified on disk)?

ojura commented 3 years ago

Added a debug print. lower_bound was a string with the content title. I can trigger it by just going left and right on slides (mashing left and right on the keyboard).

ojura commented 3 years ago

Here are some debug prints:

            # there should not be synonymous sections, correct the page here to a better guess
            if page in index:
                lower_bound = max(index)
                print ("debug 1 index='{}', lower_bound='{}'".format(index, lower_bound))
                find = index[lower_bound]
                print ("debug 2 find='{}'".format(find))
                while 'children' in find:
                    lower_bound = max(find)
                    print ("debug 3 lower_bound='{}'".format(lower_bound))
                    find = find[lower_bound]
                    print ("debug 4 find='{}'".format(find))

                try:
                    page = min(number for number, label in enumerate(self.page_labels)
                               if label == self.page_labels[page] and number > lower_bound)
                except ValueError:  # empty iterator
                    page = lower_bound + 1
                except TypeError:
                    print("crash: lower_bound is {}!!".format(lower_bound))
                    raise

And the trace:

debug 1 index='{5: {'title': 'Laser perception - SLAM'}}', lower_bound='5'
debug 2 find='{'title': 'Laser perception - SLAM'}'
debug 1 index='{5: {'title': 'Laser perception - SLAM'}, 6: {'title': 'Graph SLAM'}}', lower_bound='6'
debug 2 find='{'title': 'Graph SLAM'}'
debug 1 index='{5: {'title': 'Introduction', 'children': {5: {'title': 'Laser perception - SLAM'}, 6: {'title': 'Graph SLAM'}, 7: {'title': 'Spatio-temporal map segmentation - submaps'}}}}', lower_bound='5'
debug 2 find='{'title': 'Introduction', 'children': {5: {'title': 'Laser perception - SLAM'}, 6: {'title': 'Graph SLAM'}, 7: {'title': 'Spatio-temporal map segmentation - submaps'}}}'
debug 3 lower_bound='title'
debug 4 find='Introduction'
crash: lower_bound is title!!
ojura commented 3 years ago

Reading this without really trying to understand it much, I think you meant

lower_bound = max(find['children'])

instead of

lower_bound = max(find)

?

Anyway, it looks like a simple typo but can't currently decipher the intent. I'm sure you'll know how to fix it immediately :)

Cimbali commented 3 years ago

You’ve solved it :) the correct code is indeed:

                while 'children' in find:
                    lower_bound = max(find['children'].keys())
                    find = find['children'][lower_bound]