-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
AttributeError: module 'importlib.resources' has no attribute 'path'
on Python 3.13
#12401
Comments
Thanks @domdfcoding. Using However, the bug report seems valid still - https://docs.python.org/3/library/importlib.resources.html#importlib.resources.path indeed says that it was deprecated in Python 3.11, and if it was removed in meson/mesonbuild/dependencies/python.py Line 116 in bf9314e
The fix is to use |
Sadly, that introduces conditional code which looks really ugly and doing so makes me feel sad. :( I actually do not understand either the API evolution of importlib.resources -- the as_file approach looks terrible and non-idiomatic and feels like users of the stdlib are being punished for mysterious reasons -- or the removal of the straightforward wrappers that were intuitive and always did the right thing and caused zero harm but a lot of good, in addition to being broadly portable across python versions and even transparently gaining new features as time went by. @jaraco would it be possible to back out this removal and declare the previously deprecated functions to be long-term stable, idiomatic, intended uses -- precisely as they were in 3.12, as high level usability glue atop the internal plumbing of as_file? |
I wonder if it would clutter functional code less if the compat code was done at the beginning of the module assuming it needs workaround in meson. |
A perhaps preferable way to avoid the conditional code is to unconditionally depend on
I'm happy to shed some light on the motivations. In python/importlib_resources#58, it was discovered that the original assumption that "all resources are files in Python packages" was too constraining and ran against the reasonable expectations of packages to supply subdirectories of data. It was not possible to break this assumption while retaining the existing APIs; that is, the Case in point, 3bbfd4d was authored this year, well after the deprecation and many years after the preferred interface was published. The recommended replacement has been present in CPython since 3.9 and available in the We wish to give users "preferably one" way to access resources and not leave inadequate interfaces to proliferate. The harm comes from leaving the deprecated interfaces in place, encouraging users to adopt these inadequate interfaces without understanding the limitations and requiring all readers to understand the tradeoffs of one interface over the other (or naïvely selecting one without the understanding). You might also observe that by the time Python 3.13 is released, Python 3.8 will be EOL, so even with the removal, there will be no time when the actively supported set of Python versions doesn't have a single supported API for resources in the stdlib. I do see how that's little comfort for projects that support EOL Pythons or wish to test against prereleases.
It would be possible, but doing so would reintroduce the harm described above and erase the difficult work it's taken to get here. At this stage, I'd say there would need to be a very compelling case, much more than a concern of (temporary) ugliness. I appreciate you giving me the opportunity to shed some light on the issue and I hope this message helped alleviate some of the frustration that this change has brought. Please let me know if there may be another way I can help. |
Sure, but reimplementing the older API on top of the newer API should still make everything work fine. importlib.resources.path() internally "grew more capable". If you wrote code which was valid on python 3.8, it was still valid on python 3.12. If you wrote code which was valid on python 3.12, it would not be guaranteed to work on python 3.8. It's pretty common and straightforward to add new features to software, so importlib.resources has not innovated in the theory of software innovation in that respect.
In general, deprecating an old interface is not something I object to. Removing it is a bit more iffy. Encouraging cargo-cult adoption is a problem solved by deprecation warnings, not removal. I'm not certain I understand your reference to a maintenance burden. Given the old interface was a wrapper on top of the new interface, there's effectively no code to maintain. In fact, the old interface is a wrapper whose function body is identical to the documentation of importlib.resources:
This very much feels like the polar opposite of a maintenance burden.
I agree that commit 3bbfd4d was authored well after the deprecation, using the deprecated version. I did this for premeditated reasons: because I required an API that existed on python 3.7 and this project does not use non-stdlib code (backports are not in the stdlib). |
As far as I can tell, the only harm is a perceived harm of messaging, that it is harmful to people to be able to use deprecated functions because deprecated functions are deprecated and supposed to not be used. Given that, and in combination with this:
I believe that it is an undue burden on projects that wish to test against prereleases while supporting all non-EOL versions of python. It's also a problem when those projects don't just want to test against prereleases, but want to be used by other projects that need to test against prereleases because it is often quite complex to get them working in time. The PyData ecosystem is not a trivial one. And meson running on python 3.12 could build numpy/scipy for python 3.13 -- but we don't yet have a meson-internal wheel creator which could build the dist-info and package up a wheel for python 3.13 while internally running on top of python 3.12. We'd like one, it simply exists in the nebulous future. Side note: meson supports all non-EOL versions of python, which in this case means python 3.8 (~11 more months of support). Additionally, we do not bump the tl;dr It's not the EOL python that is affecting us here, it's the prerelease python. |
I'd like to return back to a previous comment I made:
I, personally, find the "new and improved" importlib.resources API to be awkward to use. More or less for one single reason: having to chain together files() with pathlib-style overloaded division and then pass the result to an as_file function. It feels very, very awkward to me as compared to the possibility of automatically having the support of a context manager when you need one. The What I'd really like to see is that in python 3.13 I could do this: import importlib.resources
with importlib.resources.files('mypackage') / 'datafile.txt' as f:
do_something_with_filesystem_file(f) It's the same thing I'm already doing with the legacy API, except that you port to the new API like this: -with importlib.resources.path('mypackage', 'datafile.txt') as f:
+with importlib.resources.files('mypackage') / 'datafile.txt' as f: |
I've never loved the fact that one needs to
The main reason it wasn't implemented this way was because for the common case where packages are installed into the file system, it was nice for I suppose what you're proposing could be possible, but I'm not sure the ergonomics benefits would outweigh the complication that would ensue from wrapping pathlib.Path and replacing It would require updating this protocol and then probably wrap the return value from files in an adapter that provides the context manager. The real challenge is going to be writing an adapter that's resilient across traversal. And now that I think about it, it won't work to change Traversable. Traversable is what the providers are meant to supply. We'll have to change the Would you be willing to draft an implementation and tell me if after experimenting with the above approach or perhaps an alternative if you think the approach would be worth the trouble? If so, I think the next best step would be to file a bug with importlib_resources. |
I just ran into this for one of our experimental builds. |
Not to be too much of an alarmist but Python 3.13 "no new features" deadline is in May. If a solution is not done in scope of CPython before that point, then there will be no other option than to workaround inside this package (or grow a new dependency to importlib-resources). |
This is a bit annoying in 3.13 build+tests CI |
still no working solution for 3.13? |
From the linked PR:
|
The CPython PR is merged now. The missing API is restored to CPython alpha releases. |
Describe the bug
On Python 3.13.0a1, while building numpy (directly from GitHub) meson fails first with
AttributeError: module 'importlib.resources' has no attribute 'path'
and then../../meson.build:40:22: ERROR: Unhandled python exception
.importlib.resources.path
was removed in Python 3.13To Reproduce
python3.13 -m pip wheel git+https://github.com/numpy/numpy
Expected behavior
Meson correctly compiles numpy
system parameters
The text was updated successfully, but these errors were encountered: