I don't know, although having NPY_CHAR after NPY_NTYPES goes back to 1.0.3
NPY_NTYPES,
NPY_NOTYPE,
NPY_CHAR, /* special flag */
And I expect it was desired to keep it there on the expectation that there was a reason for it. The decision not to append was in 1.4.0
NPY_DATETIME, NPY_TIMEDELTA,
NPY_NTYPES,
NPY_NOTYPE,
NPY_CHAR, /* special flag */
And probably due to Robert Kern or Travis, IIRC who worked on getting it in.
I don't see a good way to get around the ABI break, I think the question going forward needs to be whether we leave it after NPY_NTYPES or make it part of the unchanging ABI, and I suspect we need to know what the 'special flag' comment means before we can make that decision. My suspicion is that it wasn't considered a real numeric type, but rather a flag marking a special string type, in which case it probably doesn't really belong among the types, which I think is also indicated by NPY_NOTYPE. Moving NPY_CHAR could have implications we would want to check, but I'd generally favor moving it all else being equal.
Chuck