[Python-Dev] Pathlib enhancements - acceptable inputs and outputs for fspath and os.fspath() (original) (raw)
Koos Zevenhoven k7hoven at gmail.com
Mon Apr 18 17:58:59 EDT 2016
- Previous message (by thread): [Python-Dev] Pathlib enhancements - acceptable inputs and outputs for __fspath__ and os.fspath()
- Next message (by thread): [Python-Dev] Pathlib enhancements - acceptable inputs and outputs for __fspath__ and os.fspath()
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Mon, Apr 18, 2016 at 5:03 PM, Ethan Furman <ethan at stoneleaf.us> wrote:
On 04/18/2016 12:41 AM, Nick Coghlan wrote:
Given the variant you [Koos] suggested, what if we defined the API semantics like this:
# Offer the simplest possible API as the public vesion def fspath(pathlike) -> str: return os.rawfspath(pathlike) # Expose the complexity in the "private" variant def rawfspath(pathlike, *, outputtypes = (str,)) -> (str, bytes): # Short-circuit for instances of the output type if isinstance(pathlike, outputtypes): return pathlike # We'd have a tidier error message here for non-path objects result = pathlike.fspath() if not isinstance(result, outputtypes): raise TypeError("argument is not and does not provide an acceptable pathname") return result My initial reaction was that this was overly complex, but after thinking about it a couple days I /really/ like it. It has a reasonable default for the 99% real-world use-case, while still allowing for custom and exact tailoring (for the 99% stdlib use-case ;) .
While it does seem we finally might be nearly there :), this still seems to need some further discussion.
As described in that long post of mine, I suppose some third-party code may need the variations (A-C), while it seems that in the stdlib, most places need (str, bytes), i.e. (A), except in pathlib, which needs (str,), i.e. (B). I'm not sure what I think about making the variations private, even if "hiding" the bytes version is, as I said, an important role of the public function.
Except for that type hint, there is nothing in the function that might mislead the user to think bytes paths are something important in Python 3. It's a matter of documentation whether it "supports" bytes or not. In fact, that function (assuming the name os.fspath) could now even be documented to support this:
patharg = os.fspath(patharg, output_types = (str, pathlib.PurePath)) # :-)
So are we still going to end up with two functions or can we deal with one? What should the typehint be? Something new in typing.py? How about FSPath[...] as follows:
FSPath[bytes] # bytes-based pathlike, including bytes FSPath[str] # str-based pathlike, including str
pathstring = typing.TypeVar('pathstring', str, bytes) # could be extended with PurePath or some path ABC
So the above variation might become:
def fspathname(pathlike: FSPath[pathstring], *, output_types: tuple = (str,)) -> pathstring: # Short-circuit for instances of the output type if isinstance(pathlike, output_types): return pathlike # We'd have a tidier error message here for non-path objects result = pathlike.fspath() if not isinstance(result, output_types): raise TypeError("valid output type not provided via fspath") return result
And similar type hints would apply to os.path functions. For instance, os.path.dirname:
def dirname(p: FSPath[pathstring]) -> pathstring: ...
This would say pathstring all over and not give anyone any ideas about bytes, unless they know what they're doing.
Complicated? Yes, typing is. But I think we will need this kind of hints for os.path functions anyway.
-Koos
- Previous message (by thread): [Python-Dev] Pathlib enhancements - acceptable inputs and outputs for __fspath__ and os.fspath()
- Next message (by thread): [Python-Dev] Pathlib enhancements - acceptable inputs and outputs for __fspath__ and os.fspath()
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]