This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Recommend importlib.abc.Traversable users to implement __fspath__
Type: Stage:
Components: Documentation Versions: Python 3.10
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: FFY00, brett.cannon, docs@python, jaraco
Priority: normal Keywords:

Created on 2021-05-21 00:09 by FFY00, last changed 2022-04-11 14:59 by admin.

Messages (6)
msg394083 - (view) Author: Filipe Laíns (FFY00) * (Python triager) Date: 2021-05-21 00:09
The files()/Traversable api is meant to replace ResourceReader api, but it falls short in one dimension, tying the abstraction to a file system path.

I propose to document that Traversable users *should* implement __fspath__ if the Traversable represents a file-system path.

This will essentially make os.fspath(importlib.resources.files(module) / resource) the equivalent of importlib.resources.path(module, resource), for which currently there is no replacement using files().
msg394084 - (view) Author: Filipe Laíns (FFY00) * (Python triager) Date: 2021-05-21 00:12
I am gonna wait until/if GH-26272 (#44196) gets merged because this would conflict with that.
msg394211 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2021-05-23 17:36
The problem with the `__fspath__` protocol is that it assumes a file system. The `importlib.resources` and `Traversable` protocols are trying to provide a lower-level interface that doesn't assume a file system. Fortunately, there already exists a helper function `as_file` (https://docs.python.org/3/library/importlib.html#importlib.resources.as_file) that's meant to provide the user experience that `path` once provided, but for Traversable files.

Does that satisfy the need you've identified?
msg394213 - (view) Author: Filipe Laíns (FFY00) * (Python triager) Date: 2021-05-23 17:49
That's why I said it should be optional. If the object can implement it, it should. `pathlib.Path` certainly can, `zipfile.Path` can't, and that's alright.
If the Traversable does not represent a path on the file-system, it does not make sense to implement `__fspath__`, so it shouldn't.

I think `as_file` should learn to behave like `path`, if `__fspath__` is available, it will use that path, otherwise it will do what it does currently, which is creating a temporary path and writing the resource contents there.
msg394219 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2021-05-23 19:29
> I think `as_file` should learn to behave like `path`, if `__fspath__` is available, it will use that path.

Oh, that's an interesting idea. And that's effectively what happens [here](https://github.com/python/importlib_resources/blob/1886e2b9d699c55afc1b75dc19e7026ad27e453a/importlib_resources/_common.py#L109), where `as_file` returns a native Path object if that's what it encounters. Maybe another dispatcher could accept `os.PathLike` and in that case, return `pathlib.Path(os.fspath(path))`.

Only thing is, that code would serve no purpose until there existed at least one other resource provider besides FileReader that has file-system-local resources. I'm not aware of any such provider.
msg394223 - (view) Author: Filipe Laíns (FFY00) * (Python triager) Date: 2021-05-23 20:12
CompatibilityFiles would use this. We could add a dispatch for that too, but that's 2 different cases now and `os.PathLike` would be able to handle both.
History
Date User Action Args
2022-04-11 14:59:45adminsetgithub: 88366
2021-05-23 20:12:51FFY00setmessages: + msg394223
2021-05-23 19:29:00jaracosetmessages: + msg394219
2021-05-23 17:49:58FFY00setmessages: + msg394213
2021-05-23 17:36:03jaracosetmessages: + msg394211
2021-05-21 00:20:29FFY00setassignee: docs@python

components: + Documentation
nosy: + docs@python
2021-05-21 00:12:45FFY00setmessages: + msg394084
2021-05-21 00:09:16FFY00create