<div dir="ltr"><div><div><div>Your pathstring seems to be the same as the predefined (in typing.py, and PEP 484) AnyStr.<br><br></div>You are indeed making sense, except that for various reasons the stdlib is not likely to adopt in-line signature annotations yet -- not even for new code.<br><br></div>However once there's agreement on os.fspath() it can be added to the stubs in <a href="http://github.com/python/typeshed">github.com/python/typeshed</a>.<br><br></div>Is there going to be a PEP for os.fspath()? (I muted most of the discussions so I'm not sure where it stands.)<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Apr 18, 2016 at 5:40 PM, Koos Zevenhoven <span dir="ltr"><<a href="mailto:k7hoven@gmail.com" target="_blank">k7hoven@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I actually proposed this already in one of the pathlib threads on<br>
python-dev, but I decided to repost here, because this is easily seen<br>
as a separate issue. I'll start with some introduction, then moving on<br>
to the actual type hinting part.<br>
<br>
In our seemingly never-ending discussions about pathlib support in the<br>
stdlib in various threads, first here on python-ideas, then even more<br>
extensively on python-dev, have perhaps almost converged. The required<br>
changes involve a protocol method, probably named __fspath__, which<br>
any path-like type could implement to return a more, let's say,<br>
"classical" path object such as a str. However, the protocol is<br>
polymorphic and may also return bytes, which has a lot do do with the<br>
fact that the stdlib itself is polymophic and currently accepts str as<br>
well as bytes paths almost everywhere, including the newly-introduced<br>
os.scandir + DirEntry combination. The upcoming improvements will<br>
further allow passing pathlib path objects as well as DirEntry objects<br>
to any stdlib function that take paths.<br>
<br>
It came up, for instance here [1], that the function associated with<br>
the protocol, potentially named os.fspath, will end up needing type<br>
hints. This function takes pathlike objects and turns them into str or<br>
bytes. There are various different scenarios [2] that can be<br>
considered for code dealing with paths, but let's consider the case of<br>
os.path.* and other traditional python path-related functions.<br>
<br>
Some examples:<br>
<br>
os.path.join<br>
<br>
Currently, it takes str or bytes paths and returns a joined path of<br>
the same type (mixing different types raises an exception).<br>
<br>
In the future, it will also accept pathlib objects (underlying type<br>
always str) and DirEntry (underlying type str or bytes) or third-party<br>
path objects (underlying type str or bytes). The function will then<br>
return a pathname of the underlying type.<br>
<br>
os.path.dirname<br>
<br>
Currently, it takes a str or bytes and returns the dirname of the same type.<br>
In the future, it will also accept Path and DirEntry and return the<br>
underlying type.<br>
<br>
Let's consider the type hint of os.path.dirname at present and in the future:<br>
<br>
Currently, one could write<br>
<br>
def dirname(p: Union[str, bytes]) -> Union[str, bytes]:<br>
    ...<br>
<br>
While this is valid, it could be more precise:<br>
<br>
pathstring = typing.TypeVar('pathstring', str, bytes)<br>
<br>
def dirname(p: pathstring) -> pathstring:<br>
    ...<br>
<br>
This now contains the information that the return type is the same as<br>
the argument type. The name 'pathstring' may be considered slightly<br>
misleading because "byte strings" are not actually strings in Python<br>
3, but at least it does not advertise the use of bytes as paths, which<br>
is very rarely desirable.<br>
<br>
But what about the future. There are two kinds of rich path objects,<br>
those with an underlying type of str and those with an underlying type<br>
of bytes. These should implement the __fspath__() protocol and return<br>
their underlying type. However, we do care about what (underlying)<br>
type is provided by the protocol, so we might want to introduce<br>
something like typing.FSPath[underlying_type]:<br>
<br>
FSPath[str]       # str-based pathlike, including str<br>
FSPath[bytes]  # bytes-based pathlike, including bytes<br>
<br>
And now, using the above defined TypeVar pathstring, the future<br>
version of dirname would be type annotated as follows:<br>
<br>
def dirname(p: FSPath[pathstring]) -> pathstring:<br>
    ...<br>
<br>
It's getting late. I hope this made sense :).<br>
<br>
-Koos<br>
<br>
[1] <a href="https://mail.python.org/pipermail/python-dev/2016-April/144246.html" rel="noreferrer" target="_blank">https://mail.python.org/pipermail/python-dev/2016-April/144246.html</a><br>
[2] <a href="https://mail.python.org/pipermail/python-dev/2016-April/144239.html" rel="noreferrer" target="_blank">https://mail.python.org/pipermail/python-dev/2016-April/144239.html</a><br>
_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">http://python.org/psf/codeofconduct/</a><br>
</blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</div>