It's only 'more robust' as long as you don't care about languages in which it isn't.
The example is bad, because reversing code points also corrupts the content, but in a different and a somewhat harder to detect way. A better method of reversing text is to split it by grapheme clusters and reverse that. (It may still fail to work when someone manages to sneak a bidi control character in the string, and I am quite confident there may be other issues here that I cannot anticipate right now.) Python 3 offers no advantage here over Python 2. Reversing code points only appears to work, until you feed it stress-marked Cyrillic or Korean with individually encoded jamo; which is quite similar to the charge levelled against Python 2 strings: 'it appears to work, until you feed it non-ASCII input'. The problem isn't solved; the failures are just swept over to language environments in which Western programmers often don't bother to test their programs.
Expecting len() to count characters in a string, as you seem to be doing, is also wrong.
>>> len('а́')
2
The correct way to count characters is, again, to count grapheme clusters. However, counting characters is not an operation that useful in practice either. If you want to check a string against a database limit, those are usually specified in bytes (or sometimes indeed in code points). If you wish to know how much a piece of text takes on screen, you should ask a font-rendering library to compute it for you; unless you're rendering to a tty, in which case fine, count grapheme clusters. Apart from which syntax gets you codepoint versus byte length, there's no difference here between Python 2 and Python 3 here.
Case conversion is also locale-dependent. In Turkish and Azeri, the uppercase form of i is not I, but İ. In Lithuanian, the lowercase form of Ì should be i̇̀, which has both a dot and a grave accent above. str.upper() and str.lower() fail to take that into account, and don't even warn about it in the documentation. Again, it almost works... until you're a Turk and it doesn't. Is it really all that better than Python 2?
Manipulating human-readable strings is hard. Operating on code points instead of bytes makes it easier, but doesn't solve it completely. Handwaving about 'tools to deal with those tricky situations' is not an answer; I am quite sure some of those tools exist for Python 2 as well.