[Python-ideas] tweaking the file system path protocol

Steven D'Aprano steve at pearwood.info
Tue May 23 20:41:26 EDT 2017

On Wed, May 24, 2017 at 12:18:16AM +0300, Serhiy Storchaka wrote:
> 23.05.17 20:04, Brett Cannon пише:

> >What exactly is the performance issue you are having that is leading to 
> >this proposal?
> It seems to me that the purpose of this proposition is not performance, 
> but the possibility to use __fspath__ in str or bytes subclasses. 
> Currently defining __fspath__ in str or bytes subclasses doesn't have 
> any effect.

That's how I interpreted the proposal, with any performance issue being 
secondary. (I don't expect that converting path-like objects to strings 
would be the bottleneck in any application doing actual disk IO.)

> I don't know a reasonable use case for this feature. The __fspath__ 
> method of str or bytes subclasses returning something not equivalent to 
> self looks confusing to me.

I can imagine at least two:

- emulating something like DOS 8.3 versus long file names;
- case normalisation

but what would make this really useful is for debugging. For instance, I 
have used something like this to debug problems with int() being called 

py> class MyInt(int):
...     def __int__(self):
...             print("__int__ called")
...             return super().__int__()
py> x = MyInt(23)
py> int(x)
__int__ called

It would be annoying and inconsistent if int(x) avoided calling __int__ 
on int subclasses. But that's exactly what happens with fspath and str. 
I see that as a bug, not a feature: I find it hard to believe that we 
would design an interface for string-like objects (paths) and then 
intentionally prohibit it from applying to strings.

And if we did, surely its a misfeature. Why *shouldn't* subclasses of 
str get the same opportunity to customize the result of __fspath__ as 
they get to customize their __repr__ and __str__?

py> class MyStr(str):
...     def __repr__(self):
...             return 'repr'
...     def __str__(self):
...             return 'str'
py> s = MyStr('abcdef')
py> repr(s)
py> str(s)

I don't think that backwards compatibility is an issue here. Nobody will 
have had reason to write str subclasses with __fspath__ methods, so 
changing the behaviour to no longer ignore them shouldn't break any 
code. But of course, we should treat this as a new feature, and only 
change the behaviour in 3.7.


More information about the Python-ideas mailing list