-
-
Notifications
You must be signed in to change notification settings - Fork 507
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
Support Python 3.13 #2003
Support Python 3.13 #2003
Conversation
Thanks a lot for looking into this! Please ping me once you are finished. I'm also happy to help with issues. It feels like you are almost done, though. |
Heh, the "obvious" things are fixed. I don't immediately have great ideas for the pathlib thing though. I also haven't looked at why the An idea I have around the pickles issue, but which I don't like, is that we could adjust the binary content of the pickle itself, to rename the path. That can be made to work (and I believe it could be done in a way that's reliable), but it doesn't feel right. It feels like a better solution would be to hook the pickling logic somehow, but I don't know if there are hook points which would enable that? |
86f185e addresses the pathlib move, turns out there is a hook in pickle which solves exactly this issue and was easy to get working :) |
I don't think I would find a better solution to load those pickled objects. However, I think theres also a question of why these pickled objects need to be loaded across Python versions. |
Interesting. I thought I saw a function ( I'm currently looking into why Python 3.13 is seeing flaky tests; I can intermittently reproduce it locally, so it's not just CI. |
On the flakes: I've got as far as it seeming to be that an inference state id for a state which the sub-process doesn't know about (or seems not to know about) is being requested to be deleted. From what I can tell the inference state in question has been used with its subprocess (and that use doesn't appear to have errored). |
You are right about that. Does that help? I feel like the Unpickler would work, but I think it's probably bad that we transfer complex Python objects anyway that we don't control, because we're working across Python versions. I'm happy to also start debugging here if you don't feel like working on this anymore.
That sounds pretty bad. This is probably some fallout from my hack of reusing the I haven't seen any signs about inference states in sub-processes. Is that a result of your debugging? If so, how did you debug this? Asking for a friend, because I'm pretty sure this is also going to haunt me :D |
On the pathlib stuff: I haven't looked in detail at which functions are called, though through debugging the other issue I feel I have a better understanding of what's going on with the subprocesses (in general) now. Having a very brief look at the functions there which could be causing the issue, On the subprocess stuff, I have observed that In terms of how I've been debugging this, it's a lot of print statements I'm afraid. I've added a small hook to get logs back from the child process, but it's not pretty (and relies on collaboration from the subprocess, so it's not full logging; it also avoids using the stderr stream as I couldn't work out how to read that in a non-blocking manner). I've attached a diff to this message in case it's useful though. I've then been running a subset of the tests in a loop until they fail:
edit: added mention of I'm going to add some more tracking of the inference state ids to get a sense of where they get created, which will help clarify the GC interaction I hope. I'm not sure how much more time I'll have to spend on this this weekend and probably won't get back to the pathlib stuff soon. Hopefully I'll make some more progress on the ids today though. |
Looking in the docs for
So maybe there was always scope for an issue here? Either way, I think the use of Edit: for clarity: that's still looking at |
Aaah, aha, correcting myself then. I don't think this needs a Python bug. I believe there's a race of the form:
Edit: have confirmed this from logging. At this point the order of operations between the two I suspect that this could have happened under any Python version. My guess is that something in the GC behaviour on 3.13 is different and has highlighted the issue. I think the solution is to create our own ids for the |
I'm probably fine with either solution, as long as it feels good to you. I generally am really happy that you were able to pin this down. About the Path stuff: I can also try and install Python3.13 and see if I can reproduce it. I feel like once I can reproduce it, the fix will probably be quick. Whereas the whole InferenceState stuff is way way more complicated. |
For the Path stuff we actually hit the issue in both directions:
Either way around, I actually think it's fine that we're passing a Do you feel we need to invest in a solution other than the unpickler? |
I've implemented this in PeterJCLaw#3. Not sure how we want to arrange the branches -- it's not really related to the Python 3.13 upgrade, so I'm tempted to pull it out onto its own branch and then base this one (the upgrade) on that one. |
Not necessarily. I also don't think it's bad that we are passing Path. I just thought that it's weird but
Thanks a lot! It looks good.
I'm personally indifferent. :) Just do it however you feel like it works best for you. |
This should make it easier to add new entries as well as clarifying the intent of this filter.
In Python 3.13 the `locals` function now returns a fresh mapping each time it's called (when called in a function). We thus need to store a reference to the mapping being used, rather than re-fetching it each time. Since we don't actually need to modify the locals within the scope of the test function itself, it suffices to use our own mapping here rather than the result of calling `locals`, which fully isolates this test from the nature of that function. Fixes davidhalter#2002
This moves to using the 3.13 grammar as well as testing 3.13 in CI.
Jedi passes pickles to subprocesses which are running the target version of Python and thus may not be the same as the version under which Jedi itself is running. In Python 3.13, pathlib is being refactored to allow for easier extension and has thus moved most of its internal implementation to a submodule. Unfortunately this changes the paths of the symbols, causing pickles of those types to fail to load in earlier versions of Python. This commit introduces a custom unpickler which accounts for this move, allowing bi-directional passing of pickles to work.
a70bc50
to
a67deeb
Compare
The latest set of failures here look related to CI now using beta 3 (up from beta 2) of Python 3.13. Based on the failures we're seeing, one of python/cpython#121025 or python/cpython#121027 seems possibly related. Don't have time this evening to dig further, but should do later in the week. Have confirmed by running CI pinned to beta 2 (PeterJCLaw@2cbe074) that the issue doesn't reproduce there, so this is definitely related to changes in beta 3. |
I've pinned down the test failures around The specific issue which Jedi faces is that I haven't dug too deeply into why a What I'm not sure about is what the right fix is here. We could detect that the thing we're looking at is a |
I finally managed to get Python3.13 onto my computer and it seems like I got an older beta and therefore cannot reproduce it. Regardless I would say that the name in that signature is of a low priority anyway. It doesn't provide a lot of value. So I would even be fine with changing the assert and just check that a string is returned. My assumptions from reading the code is that there is that
Sorry I don't seem to be able to get a Python 3.13 shell quickly and I'm a bit lazy to set up all the docker stuff. I hope you don't mind. |
No worries, I had to build beta-3 myself. >>> from functools import partial
>>> cls = partial(str, 1).__class__
>>> cls
<class 'functools.partial'>
>>> type == cls
False
>>> isinstance(cls, type) For completeness, Something which did occur to me is whether we should react to In my mind there's a couple of cases to solve here -- the immediate one, where the descriptor actually returns itself, and also the future case where it'll return something else. In the latter I'm not actually sure what it'll return -- whether that's going to be another partial (but with a Another thing I'm slightly puzzled by is that testing the signature of partials manually with I appreciate the suggestion to make the test check for any string, though I'd really hope we can do that in the long term. I might do that as a short-term workaround though (for 3.13 specifically) and then defer this to being a known bug. |
Another thing I've just realised is that this is actually only an issue for the interpreter. When running as Aaanyway, given how limited the impact from this seems likely to be in light of this being interpreter only I've broken it out to #2012 and I'll update the test here to ignore 3.13+ for the name assertion. |
Thanks for all your work here. I generally agree. It would of course be nicer if this didn't regress. But it doesn't really matter. There are probably things we can improve around this, but This is why I don't really care about this bug. It wasn't really correct earlier. One could even argue that a signature like Feel free to merge. |
Did you see |
Apparently not. I thought I searched for it, but seemingly missed that 🤷 |
Are there already any plans for a new release which contains the fixes for Python 3.13? I tried backporting these so I can fix the package in openSUSE Tumbleweed, but there is still one test failing for me after the backport:
|
Is master also failing for you? |
I'm going to release Jedi once Python 3.13 is finally out. Feel free to use master. The master branch will probably release as 0.19.2 in October. |
This is about RPM package that is part of the distribution. I am currently fixing all packages that fail with Python 3.13 so that the Python system in openSUSE is ready for the Python 3.13 release. So, using a git snapshot is not really the feasible way here. |
@glaubitz you'll need to include the fix from #2008 as well I expect. @davidhalter perhaps it would make sense for us to publish a pre-release which downstream maintainers could pull in? |
@PeterJCLaw I'm currently not willing to do the extra work, since the git master will be pushed as a release anyway and maintainers can just use that instead. |
If all upstream projects handled it that way, Linux distributions would have a very hard time. |
Why? Maybe I don't understand? What's the difference between me now making a pre-release and me telling you to use a specific git commit that is fine? Also the distros that I have used and come in contact professionally don't even try to have every package ready before the Python release. Debian obviously is notorious for lagging behind a lot. Ubuntu is typically behind just a bit (24.04 is Python 3.11). Even Arch Linux/Gentoo users have only started complaining when we were actually late (AFAIK). It feels like it's typically Fedora (indirectly RHEL? with the commercial backing of Red Hat?)/Suse users that have these issues. Why is it that you guys want to have a package like Jedi ready before the release of Python 3.13? |
Various fixes to get the tests passing on Python 3.13, all within the tests themselves.
Also some small tidyups in one of the tests.
Moves to the 3.13 grammar from parso 0.8.4 and add testing on 3.13.
Reviewing by commit may be useful.
Fixes #2002.
Discovered issues:
pathlib
has been refactored, there's nowpathlib._local
andpathlib._abc
, which breaks passing pickled objects to subprocesses with different Python versionsfunctools.partial
is now a descriptor, which breaksDirectObjectAccess.py__name__
's assumptions (broken out into Python 3.13.0b3+functools.partial
being a descriptor messes with signatures #2012)