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

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