[Python-Dev] proposed os.fspath() change

Ethan Furman ethan at stoneleaf.us
Wed Jun 15 12:12:07 EDT 2016


I would like to make a change to os.fspath().

Specifically, os.fspath() currently raises an exception if something
besides str, bytes, or os.PathLike is passed in, but makes no checks
if an os.PathLike object returns something besides a str or bytes.

I would like to change that to the opposite: if a non-os.PathLike is
passed in, return it unchanged (so no change for str and bytes); if
an os.PathLike object returns something that is not a str nor bytes,
raise.

An example of the difference in the lzma file:

Current code (has not been upgraded to use os.fspath() yet)
-----------------------------------------------------------

     if isinstance(filename, (str, bytes)):
         if "b" not in mode:
             mode += "b"
         self._fp = builtins.open(filename, mode)
         self._closefp = True
         self._mode = mode_code
     elif hasattr(filename, "read") or hasattr(filename, "write"):
         self._fp = filename
         self._mode = mode_code
     else:
         raise TypeError(
              "filename must be a str or bytes object, or a file"
               )

Code change if using upgraded os.fspath() (placed before above stanza):

     filename = os.fspath(filename)

Code change with current os.fspath() (ditto):

     if isinstance(filename, os.PathLike):
         filename = os.fspath(filename)

My intention with the os.fspath() function was to minimize boiler-plate
code and make PathLike objects easy and painless to support; having to
discover if any given parameter is PathLike before calling os.fspath()
on it is, IMHO, just the opposite.

There is also precedent for having a __dunder__ check the return type:

     --> class Huh:
     ...   def __int__(self):
     ...     return 'string'
     ...   def __index__(self):
     ...     return b'bytestring'
     ...   def __bool__(self):
     ...     return 'true-ish'
     ...
     --> h = Huh()

     --> int(h)
     Traceback (most recent call last):
       File "<stdin>", line 1, in <module>
     TypeError: __int__ returned non-int (type str)

     --> ''[h]
     Traceback (most recent call last):
       File "<stdin>", line 1, in <module>
     TypeError: __index__ returned non-int (type bytes)

     --> bool(h)
     Traceback (most recent call last):
       File "<stdin>", line 1, in <module>
     TypeError: __bool__ should return bool, returned str

Arguments in favor or against?

--
~Ethan~


More information about the Python-Dev mailing list