**another deep, calming breath** On Wed, May 11, 2016 at 7:43 PM, Brett Cannon <br...@python.org> wrote: > Open Issues > =========== > > Should os.fspath() return bytes? > -------------------------------- >
In most cases, it of course should not. The section (or the title) do not represent my view on the topic, but bytes paths are not going away any time soon, so this requires considerations. Below is a copy paste of my comment in the discussion on my pull request ( https://github.com/brettcannon/path-pep/pull/2 ). It is about whether os.fspath should look like def fspath(path, *, type_constraint=str): ... This was already discussed before, receiving positive reactions. It would be an extension to what is in the draft Brett just posted. Note that the return type, however, does not depend on `type_constraint`. It fully depends on `path`. The constraint only determines when an exception is raised instead of returning a value. When using str-based paths normally, one would do os.fspath(path) Calling it with os.fspath(path, type_constraint=(str, bytes)) would turn off rejection of bytes paths (and be consistent with the rest of `os` and `os.path` where functions accept both types). But the default value for the keyword argument would be a good reminder that str-based paths should be used by default. This str-constraint is also present in the current drafted version, but it is not optional or visible in the signature. (See the diffs of my pull request for an example implementation of this.) So below is the copy-paste from the pull request discussion that I promised: """ Nobody wants to promote using `bytes` for paths without a proper reason. However, `os.fspath(path, type_contraint=str)` is already a compromise from the current `os.*` convention (of symmetrically supporting both `str` and `bytes`) towards enforcing `str`-based paths. As you know, the reason for using `os.fspath` is to switch to a lower-level representation of paths as strings. When you use it, you are already deciding that you are lower-level and want to examine or manipulate path strings manually. I think the `type_constraint=str` keyword-only argument (with the default) is a good way to remind the 'user' that `str` is the way to go unless you know what you are doing and, to `bytes` users, that `os.fspath` (by default) rejects bytes. Looking at the discussions on python-dev, one notices that the active people in the discussions were mostly in favor of exposing the bytes-supporting version in one way or the other. Some were even against bytes-rejecting versions. Most people (Python programmers), especially in the long term, should not be using `os.fspath` a lot. If they want to print a path, they should simply do so: `print(path_obj)`, or `print(f"The path is: {path_obj}")`. However, there will always be people that for whatever reason want to convert a pathlib object into a string, and without even consulting the docs, they may write `str(path_obj)`. And that's not the end of the world. It's not any worse than `str(integer)` for instance. After all, if the main point is to convert something into a generic string, the function should probably be called `str`, not `fspath`. But if the idea is to convert any path object into something that `os` and similar code internally understand, then `os.fspath` sounds fine to me. So I would not go as far as 'never use `str(path)`'. What we don't want is things like `open(str(path), 'w')`. I know you agree, because you wrote that yourself. But once this protocol is available, I see no reason why people would voluntarily wrap their path objects in `str(...)`, so I don't see that as a problem in the future (thanks to this PEP). So, especially in the long term, I don't expect `fspath` to be an everyday tool for people. Even in shorter term, people don't usually need it, because the stdlib will already support pathlib objects. Since it is not an everyday tool, I think it's ok to have that extra keyword-only argument. Even if it were an everyday tool, I can see the keyword-only argument in the signature as useful thing in a documentation sense. [As a side note, I could imagine someone convincing me that `fspath` should *always* accept both `str`- and `bytes`-based paths, because that would simplify it and align it with the rest of `os`. This would not be any worse than the status quo in terms of early failures. That would, however, still not detect accidental use of bytes paths (when forgotten to decode from the encoding it was received in).] """ -- Koos _______________________________________________ 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