<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, 6 Apr 2016 at 12:32 Paul Moore <<a href="mailto:p.f.moore@gmail.com">p.f.moore@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 6 April 2016 at 19:32, Brett Cannon <<a href="mailto:brett@python.org" target="_blank">brett@python.org</a>> wrote:<br>
>> > Now we need clear details. :) Some open questions are:<br>
>> ><br>
>> >  1. Name: __path__, __fspath__, or something else?<br>
>><br>
>> __fspath__<br>
><br>
> +1 for __path__, +0 for __fspath__ (I don't know how widespread the notion<br>
> that "fs" means "file system" is).<br>
<br>
Agreed. But if we have a builtin, it should follow the name of the<br>
special attribute/method. And I'm not that keen on having a builtin<br>
with a generic name like 'path'.<br>
<br>
>> >  2. Method or attribute? (changes what kind of one-liner you might use<br>
>> >     in libraries, but I think historically all protocols have been<br>
>> >     methods and the serialized string representation might be costly to<br>
>> >     build)<br>
>><br>
>> I would prefer an attribute, but yeah I think dunders are typically<br>
>> methods, and I don't see this being special enough to not follow that<br>
>> trend.<br>
><br>
> Depends on what we want to tell 3rd-party libraries to do to support pathlib<br>
> if they are on 3.3 or if they are worried about people using Python 3.4.2 or<br>
> 3.5.1. An attribute still works with `getattr(path, '__path__', path)`. But<br>
> with a method you probably want either `path.__path__() if hasattr(path,<br>
> '__path__') else path` or `getattr(path, '__path__', lambda: path)()`.<br>
<br>
I'm a little confused by this. To support the older pathlib, they have<br>
to do patharg = str(patharg), because *none* of the proposed<br>
attributes (path or __path__) will exist.<br>
<br>
The getattr trick is needed to support the *new* pathlib, when you<br>
need a real string. Currently you need a string if you call stdlib<br>
functions or builtins. If we fix the stdlib/builtins, the need goes<br>
away for those cases, but remains if you need to call libraries that<br>
*don't* support pathlib (os.path will likely be one of those) or do<br>
direct string manipulation.<br>
<br>
In practice, I see the getattr trick as an "easy fix" for libraries<br>
that want to add support but in a minimally-intrusive way. On that<br>
basis, making the trick easy to use is important, which argues for an<br>
attribute.<br></blockquote><div><br></div><div>So then where's the confusion? :) You seem to get the points. I personally find `path.__path__() if hasattr(path, '__path__') else path` also readable (if obviously a bit longer).</div><div><br></div><div>-Brett</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
>> >  3. Built-in? (name is dependent on #1 if we add one)<br>
>><br>
>> fspath() -- and it would be handy to have a function that return either<br>
>> the __fspath__ results, or the string (if it was one), or raise an<br>
>> exception if neither of the above work out.<br>
<br>
fspath regardless of the name chosen in #1 - a new builtin called path<br>
just has too much likelihood of clashing with user code.<br>
<br>
But I'm not sure we need a builtin. I'm not at all clear how<br>
frequently we expect user code to need to use this protocol. Users<br>
can't use the builtin if they want to be backward compatible, But code<br>
that doesn't need backward compatibility can probably just work with<br>
pathlib (and the stdlib support for it) directly. For display, the<br>
implicit conversion to str is fine. For "get me a string representing<br>
the path", is the "path" attribute being abandoned in favour of this<br>
special method?</blockquote><div><br></div><div>Yes.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> I'm inclined to think that if you are writing "pure<br>
pathlib" code, pathobj.path looks more readable than fspath(pathobj) -<br>
certainly no *less* readable.<br></blockquote><div><br></div><div>I don't' know what you mean by "pure pathlib". You mean code that only works with pathlib objects? Or do you mean code that accepts pathlib objects but uses strings internally?</div><div><br></div><div>-Brett</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
But I'm not one of the people who disliked using .path, so I'm<br>
probably not best placed to judge. It would be good if someone who<br>
*does* feel strongly could explain why fspath(pathobj) is better than<br>
pathobj.path.<br></blockquote><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
> So:<br>
><br>
>   # Attribute<br>
>   def fspath(path):<br>
>       hasattr(path, '__path__'):<br>
>           return path.__path__<br>
>       if isinstance(path, str):<br>
>           return path<br>
>       raise NotImplementedError  # Or TypeError?<br>
><br>
>   # Method<br>
>   def fspath(path):<br>
>       try:<br>
>           return path.__path__()<br>
>       except AttributeError:<br>
>           if isinstance(path, str):<br>
>               return path<br>
>       raise TypeError  # Or NotImplementedError?<br>
<br>
You could of course use try/except for the attribute case. Or hasattr<br>
for the method case (where it would avoid masking AttributeError<br>
exceptions raised within the dunder method call (a possibility if user<br>
classes implement their own version of the protocol).<br>
<br>
Paul<br>
</blockquote></div></div>