If you’re using a kivy ListAdapter or DictAdapter you might run into an annoying bug that I spent too long dealing with yesterday: This &^$#@ error:

Exception IndexError: 'list index out of range' in 'kivy.properties.observable_list_dispatch' ignored

The setup is this: you have a ListView, a ListAdapter, and some subordinate views like a ListItemButton or a subclassed ListItemLabel which are selectable. You’ve told your ListAdapter not to allow_empty_selection and selection_mode is ‘single’. You’re using the selection. Things mostly work but you keep seeing: Exception IndexError: 'list index out of range' in 'kivy.properties.observable_list_dispatch' ignored. Somewhere in kivy the error is getting caught and ignored, so you can’t try/except it.

I’ve come to believe the problem is the existence of a brief period in which no item is selected. When the user clicks on a selectable list item, the previously selected item is deselected and the newly clicked item is selected, between those two events there is no selected item. I got around the problem by making my code ignore events with a selection list length not equal to one.

I gained some insight into this issue with the native python debugger, “pdb”. I love debuggers, but I’ve used python’s on suprisingly few occasions. This is possibly because I haven’t encountered many problems in Python that aren’t laid bare by a backtrace.

To use pdb on this occasion, I imported it at the top of my program (e.g. import pdb) then in the code for my selectable list item’s on_touch_down handler, I added pdb.set_trace(), this call acts like a breakpoint. After re-running the program from the terminal (e.g. kivy someapp.py) and clicking on a selectable list item in the GUI, I got dumped into the pdb shell:

-> self.dispatch('on_press')
(Pdb) 

This is a special command shell for debugging which is similar to gdb.

-> self.dispatch('on_press')
(Pdb) help
    
Documented commands (type help <topic>):
========================================
EOF    bt         cont      enable  jump  pp       run      unt   
a      c          continue  exit    l     q        s        until 
alias  cl         d         h       list  quit     step     up    
args   clear      debug     help    n     r        tbreak   w     
b      commands   disable   ignore  next  restart  u        whatis
break  condition  down      j       p     return   unalias  where 
    
Miscellaneous help topics:
==========================
exec  pdb
    
Undocumented commands:
======================
retval  rv
    
(Pdb) help s
s(tep)
Execute the current line, stop at the first possible occasion
(either in a function that is called or in the current function).
(Pdb) 

All I needed to do to see the solution was use pdb to step through the program after my breakpoint. I won’t include the transcript here because there is a lot of kivy infrastructure along the way.

I would have liked to set a breakpoint on IndexError.__init__(), but I never managed to get that working. Still, pdb solved my kivy problem quickly and easily.