On modern Unicode-aware terminals and browsers, right-to-left characters not only displayed in the order different from how they are stored, but affect neutral characters, including punctuation, spaces and digits. For example:
>>> '12\u05be34'
'12־34'
You must see '1234X’ where X is a RTL character. It is shown as the 5th character, even if it is actually the 3rd character.
Worse, this can escape the string’s repr and affect representation of other items:
>>> list('12\u05be34')
['1', '2', '־', '3', '4']
You must see [’1’, ‘2’, ‘4’ ,’3’ ,’X’]. Not only it moves the item with the RTL character to the end of the list (it is the third item), but shows the following items in the reversed order.
This is bad. repr() of string supposed to show you accurate representation of the string content, this is why it escapes control characters (including the marks that explicitly control the text direction). The only solution – treat the strong right-to-left characters as non-printable and escape it in repr().
As a side effect, str.isprintable() will return False for such characters. This may be surprising, but this is it’s definition – it returns True for and only for characters which are not escaped in repr(). In particularly, it returns False for whitespaces except the space, and True for characters which can be not supported by your terminal.