-
-
Notifications
You must be signed in to change notification settings - Fork 49
reader resolution algorithm seems inconsistent between stdlib and importlib_resources #295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
No activity? :-( @jaraco? |
Thanks for the ping. I've been overloaded (mainly with life events). I'll plan to take a look soon. |
First, thanks for sharing your detailed analysis and considerate question. I agree, it should be possible to accomplish what you seek with a simple and straightforward hook. In 3e24498, I explored simply giving the native reader precedence, but it triggers a few test failures on Python 3.10 and later, all in ResourceFromNamespaceZipTests:
I'll need to dig deeper to understand the meaning behind those failures and what else it might imply about the current approach. |
Aha! The reason the tests are failing is because the "native" NamespaceReader and MultiplexedPath on Python 3.10-3.12 doesn't yet have the fixes introduced in #290 (and presumably Python 3.13). The mission of this project is to provide forward-compatibility to features/fixes like that, so that, for example, these zip files with namespace packages can be made available to Python 3.8. The presence of a Still, it does seem irresponsible to be treating a I've explored that concept in 2331da9. I tried actually resolving the reader and checking its class, but that again falls afowl of the aforementioned errors because merely allowing the stdlib readers to construct themselves fails for the ResourceFromNamespaceZipTests. I really don't like keying on |
In #296, I've refactored the project to separate concerns and re-use repeated logic, which should make it easier to address this concern. |
Ensure that standard library readers are replaced while third-party readers are passed along. Closes #295.
In #297, I've drafted a change that I think will address the reported concern. @mmerickel Can you test this concept against the use-case you described and see if it works the same as
|
thanks so much for looking at this - I'll try to find time to get into it and try out the proposed changes |
Ensure that standard library readers are replaced while third-party readers are passed along. Closes #295.
Ensure that standard library readers are replaced while third-party readers are passed along. Closes #295.
On further consideration - I see now the changes in #297 are failing on Python 3.9 and earlier, so the technique as devised isn't adequate and I'm investigating further. |
Okay. The latest version now passes tests on all Pythons. It's a little messy, but at least encapsulated. Feel free to test with:
|
@jaraco sorry I took so long on this, real life has been overwhelming. I just tested 6.3.0 and my custom |
Fantastic! Thanks for following up and no problem on the delay. Glad I could help. |
Hello friends,
I'm looking at how to reimplement resource overrides in Pyramid. It's a unique feature that in the past involved patching a custom
package.__loader__
which could intercept and do its own file lookups for various requests. This worked with all pkg_resources apis, likepkg_resources.resource_filename
, etc to return a different path than the one physically on disk when a path is overridden.To implement this, I've been going through the PEPs and trying to understand the protocol that
importlib.resources
uses to support overriding how resources are loaded from a package. I've narrowed this down tospec.loader.get_resource_reader()
being able to be defined. My plan will be to define aProxyLoader
which defines its ownget_resource_reader
but proxies the rest of the loader functionality back to the original loader. So, I'm looking at how to define a customabc.TraversableResources
class that does what I need, and then hookpackage.__spec__.loader
to return it fromget_resource_reader()
.From what I can tell, the logic here is inconsistent between importlib_resources and the stdlib impl in CPython. I'm looking here:
https://github.com/python/cpython/blob/5ddb2740404ad62e74ecb0ea97ed98651821ed3f/Lib/importlib/resources/_adapters.py#L28-L29
compared to
importlib_resources/importlib_resources/_compat.py
Lines 75 to 90 in 7d8b020
In both cases, TraversableResourceLoader is attempting to determine which reader to return. In the stdlib, preference is given to the native
spec.loader.get_resource_reader()
if the reader returned has afiles()
method. However, importlib_resources inverts the lookup such that zip/namespace/file take priority over the "native" reader. So for example, ifself.path
exists, then whatever I set asspec.loader.get_resource_reader()
will never be invoked and hence I can't override the lookups.Currently, to get this to work with importlib_resources, it appears that I would need the
spec.path
to be a non-existent path, which would trigger the logic to fallback to the native reader that I patch, but this is by far not ideal.The TLDR is that I would propose importlib_resources moves the
_native_reader(self.spec)
invocation to the TOP of the list, which would be more in line with the stdlib.I would really appreciate any guidance here. Maybe I'm completely off base and missing something critical in the importlib machinery, and happy to talk more about this use-case in Pyramid that has been supported for many years via a PEP320 loader used by pkg_resources. Thank you!
The text was updated successfully, but these errors were encountered: