[Python-Dev] Pathlib enhancements - acceptable inputs and outputs for __fspath__ and os.fspath()

Antoine Pitrou antoine at python.org
Mon Apr 11 10:56:25 EDT 2016

Ethan Furman <ethan <at> stoneleaf.us> writes:
>  > I also think the more explicit name helps answer some of the type
>  > signature questions that have arisen:
>  >
>  > 1. Does os.fspathname return rich Path objects? No, it returns names
>  > as str objects
>  > 2. Will file descriptors pass through os.fspathname? No, as they're
>  > not names, they're numeric descriptors.
>  > 3. Will bytes-like objects pass through os.fspathname? No, as they're
>  > not names, they're encodings of names
> If we add os.fspath(), but don't allow bytes to be returned from it, our 
> above example looks more like:
>    if isinstance(a_path_thingy, bytes):
>        # because os can accept bytes
>        pass
>    else:
>        a_path_thingy = os.fspath(a_path_thingy)
>    # do something with the path
> Yes, it's better -- but it still requires a pre-check before calling 
> os.fspath().
> It is my contention that this is better:
>    a_path_thingy = os.fspath(a_path_thingy)

It's not better, because a_path_thingy then may be a bytes object,
and the os.fspath() caller has to deal with it.  Conversely, if
os.fspath() is guaranteed to return a unicode string, then the caller
only has to worry about bytes paths if it really wants to; most callers
probably don't care.

I know what some people say: support for bytes paths is necessary
for "low-level functions" (definition required ;-)).  But in a
PEP 383 world, it's not necessary at all.

> 2) pathlib.Path accepts bytes --

Does it? Or are you proposing such a change?

>>> pathlib.Path(b".")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/antoine/35/lib/python3.5/pathlib.py", line 956, in __new__
    self = cls._from_parts(args, init=False)
  File "/home/antoine/35/lib/python3.5/pathlib.py", line 638, in _from_parts
    drv, root, parts = self._parse_args(args)
  File "/home/antoine/35/lib/python3.5/pathlib.py", line 630, in _parse_args
    % type(a))
TypeError: argument should be a path or str object, not <class 'bytes'>



More information about the Python-Dev mailing list