First off, hi Harry! I am super glad that someone has taken an interest in this. Please let me know if I can be helpful in your effort to fix this. FilePath totally has the right sort of shape to handle all these problems very gracefully, but its current implementation is (as you have noticed!) a disaster, regardless of python 2/3 issues, it doesn't handle text/bytes correctly on python 2.
Also, sorry for being a bit late to the party, been on vacation for a week :-).
It doesn't really make sense to talk about "native strings" unless you're talking about Python code objects; __doc__ and func_name are "native strings"; the inputs to FilePath are bytes, pure and simple. This is mostly just because FilePath was designed way back when I only really knew about the way path names worked on Linux.
Among several of the design errors in Python 3's allegedly superior unicode support was to call the text type "str", when this was a confusing name in the first place, and is now ambiguous, confusing, and arguably wrong all at once; at the cost of one additional letter, it could have been "text", which is both a whole word and a more accurate description of what it does. I generally use "text" rather than "string" to describe the text type anyway, because it's a lot less ambiguous and requires less backtracking ("oh I was talking about python 2 there, let me rephrase").
This is not really true. This is how Linux and BSD handle file names; it is not how OS X handle file names. (Nor is it how Windows works, as you've mentioned above.)
On OS X, file names are normalized (I forget the normalization at the moment, but you can look it up) UTF-8. They _must_ be normalized UTF-8; it doesn't matter what $LANG is. If you try to deal with filenames that are invalid UTF-8 byte sequences, the OS will URL-encode portions of the filename for you and _force_ its name (as returned by listdir() at least) to be a valid UTF-8 sequence. If you give it something non-normalized, it will normalize it for you.
The design should not be as naive as "support bytes" or "support unicode", or even "support both". In order to deal with some of these nastier edge-cases, you need a method that can give you a name to display to a user that's "human readable", a weird-Python-broken-surrogates-trick unicode object, and some bytes. Then there's possibly some extra methods that could be added which are only sometimes available, like "driveLetter()" or somesuch. (Maybe we could do better and have some kind of general mount-point object, but I digress.)
In other words, we need to give the developer an expressive enough API to clearly indicate their intent, and then have clear enough API documentation for them to figure out what their intent is :).
At the implementation level, these potential methods are both platform-specific and subtly distinctive. For example, the "human readable name" implementation of a broken FilePath should include replacement characters rather than broken-surrogate hacks. Replacement characters have a defined method for displaying them; since broken surrogates are just invalid garbage, some software might elect not to display the string at all, or throw an error. It might also be sensible (as a future enhancement, this is not something we should try to do as a basic part of proper unicode support) to do some encoding-guessing and mojibake detection when trying to compute the human-readable name, since this name is just for display and it makes sense to work as hard as possible to display something sensible, since it does NOT need to be able to be fed back in to FilePath. But of course on OS X, the thing to do would just be to convert to the percent-escaped version, since that's what the platform presents. And on Windows, it might be sensible for the thing that gives you bytes to give you a faithful UTF-8 version of the filename rather than some platform-dependent ANSI junk, since as far as I can tell there's no need to ever get a byte sequence you could pass back to some other ANSI API. If it were, that could be an explicitly separate API.
Finally, the fact that FilePath exposes the internal representation of the path (as ".path") is sort of a design error, and we should eventually deprecate that attribute, since there are multiple use-cases you might want that string for and we should return the appropriate version depending on which one you want. I wouldn't worry about getting that attribute to do anything useful beyond a very rudimentary level of compatibility; in fact it would be great if the internal storage of the path were always unicode on Windows and always bytes on UNIX-ish platforms, and ".path" were just a proxy that always gave you bytes. (Although possibly the internal representation should just be unicode too on OS X, I keep finding myself on the fence about that.)
Hopefully the existing ticket is sufficient, but, open as many as you need :). There might be a bunch of methods that need modification here, and at least e.g. the ZipPath work could be done separately.