This is not a problem specific to python, this could happen with any programming language. If your code doesn't yield, then it will never be able to switch modes. We always program our robot in a loop that looks like this:
Code:
while self.IsEnabled() and self.IsOperatorControl():
.. do stuff here
In particular, if you're using wpilib.Wait() for anything other than a delay at the end of the main loop so you're not using 100% CPU, or if you're in a loop waiting for some switch or condition to change without doing anything else... you're probably doing it wrong. Once again, this goes for any programming language, not just python. There are many other ways to wait for things to happen, and by blocking on a wait statement you cannot do anything else on that thread while waiting, which is generally bad.
You might try looking at the Commands/Events stuff that WPILib introduced this year, there's support for it in Python despite a lack of documentation (in all languages, really).
I will admit, there are a variety of examples that come with RobotPy, and I don't really like many of them. This might be part of the problem. Hopefully I (or someone) will find some time to clean them up at some point.