On Fri, May 13, 2016 at 4:00 AM, Steven D'Aprano <st...@pearwood.info>
wrote:

> On Thu, May 12, 2016 at 08:53:12PM +0000, Brett Cannon wrote:
>
> > Second draft that takes Guido's comments into consideration. The biggest
> > change is os.fspath() now returns whatever path.__fspath__() returns
> > instead of restricting it to only str.
>
> Counter suggestion:
>
> - __fspath__() method may return either bytes or str (no change
>   from the PEP as it stands now);
>
> - but os.fspath() will only return str;
>
> - and os.fspathb() will only return bytes;
>
> - there is no os function that returns "str or bytes, I don't
>   care which". (If you really need that, call __fspath__ directly.)
>
> Note that this differs from the already rejected suggestion that there
> should be two dunder methods, __fspath__() and __fspathb__().
>
> Why?
>
> (1) Normally, the caller knows whether they want str or bytes. (That's
> been my experience, you may disagree.) If so, and they call os.fspath()
> expecting a str, they won't be surprised by it returning bytes. And visa
> versa for when you expect a bytes path.
>
> (2) This behaviour will match that of os.{environ[b],getcwd[b],getenv[b]}.
>
> Cons:
>
> (3) Polymorphic code that truly doesn't care whether it gets bytes or
> str will have a slightly less convenient way of getting it, namely by
> calling __fspath__() itself, instead of os.fspath().
>

More cons:

- It would be confusing that there'd be no direct corresponding between
os.fspath(x) and x.__fspath__(), unlike for most other dunders (next(x) ->
x.__next__(), iter(x) -> x.__iter__(), and so on).

- Your examples like os.getcwd() have no input to determine whether to
return bytes or str, so for those we use an alternate name to request
bytes. However for most os methods the same method handles both, e.g.
os.listdir(b'.') will return a list of bytes objects while os.listdir('.')
will return a list of strings. os.fspath() firmly falls in the latter camp:
it takes an input whose __fspath__() method will return either str or
bytes, so that's all the guidance it needs.

Really, if you want bytes, you should use os.fsencode(); if you want
strings, use os.fsencode(); if you want to be polymorphic, use os.fspath()
and check the type it returns. I find the case where you'd explicitly want
to exclude bytes unusual; Nick already proposed pathlib.Path(os.fspath(x))
for that.

-- 
--Guido van Rossum (python.org/~guido)
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to