`IndexError` was always a `Defect` \- it merely changed name so as to highlight that it's not catchable (and never has been).
The choice between `Defect` and `Error` is, like you're noticing, quite arbitrary - there's no line that one can draw between them, rather it depends on the mood of the developer at the time of writing and sometimes the surrounding code. It is also quite subjective what you consider "exceptional" and not, so that's not that much of a useful distinction, except (haha) in extreme cases.