[Python-Dev] Pathlib enhancements - acceptable inputs and outputs for __fspath__ and os.fspath()
Brett Cannon
brett at python.org
Mon Apr 11 15:00:41 EDT 2016
On Mon, 11 Apr 2016 at 11:28 Ethan Furman <ethan at stoneleaf.us> wrote:
> On 04/11/2016 10:36 AM, Brett Cannon wrote:
> > On Mon, 11 Apr 2016 at 10:13 Ethan Furman wrote:
>
> >> I'm not saying that bytes paths are common -- and if this was a
> >> brand-new feature I wouldn't be pushing for it so hard; however, bytes
> >> paths are already supported and it seems to me to be much less of a
> >> headache to continue the support in this new protocol instead of drawing
> >> an artificial line in the sand.
> >
> > Headache for you? The stdlib? Library authors? Users of libraries? There
> > are a lot of users of this who have varying levels of pain for this.
>
> Yes, yes, maybe, maybe. :)
>
> >> Asked another way, what are we gaining by disallowing bytes in this new
> >> way of getting paths versus the pain caused when bytes are needed and/or
> >> accepted?
> >
> > Type consistency. E.g. if I pass in a DirEntry object into os.fspath()
> > and I don't know what the heck I'm getting back then that can lead to
> > subtle bugs [...]
>
> > How about we take something from the "explicit is better than implicit"
> > playbook and add a keyword argument to os.fspath() to allow bytes to
> > pass through?
> >
> > def fspath(path, *, allow_bytes=False):
> > if isinstance(path, str):
> > return path
> > # Allow bytearray?
> > elif allow_bytes and isinstance(path, bytes):
> > return path
> > try:
> > protocol = path.__fspath__()
> > except AttributeError:
> > pass
> > else:
> > # Explicit type check worth it, or better to rely on duck
> typing?
> > if isinstance(protocol_path, str):
> > return protocol_path
> > raise TypeError("expected a path-like object, str, or bytes (if
> > allowed), not {type(path)}")
>
> I think that might work. We currently have four path related things:
> bytes, str, Path, DirEntry -- two are str-only, one is bytes-only, and
> one can be either.
>
> I would write the above as:
>
> def fspath(path, *, allow_bytes=False):
> try:
> path = path.__fspath__()
> except AttributeError:
> pass
> if isinstance(path, str):
> return path
> elif allow_bytes and isinstance(path, bytes):
> return path
> else:
> raise SomeError()
>
> > For DirEntry users who use bytes, they will simply have to pass around
> > DirEntry.path which is not as nice as simply passing around DirEntry,
>
> If we go with the above we allow DirEntry.__fspath__ to return bytes and
> still get type-consistency of str unless the user explicitly declares
> they're okay with getting either (and even then the field is narrowed
> from four possible source types (or more as time goes on) to two.
>
You get type consistency from so.fspath(), not the protocol, though.
>
> To recap, this would allow both str & bytes in __fspath__, but the
> fspath() function defaults to only allowing str through.
>
> I can live with that.
>
I'm -0 on allowing __fspath__ to return bytes, but we can see what others
think.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20160411/69d01ce6/attachment.html>
More information about the Python-Dev
mailing list