-
-
Notifications
You must be signed in to change notification settings - Fork 31k
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
Strange reference cycle (?) introduced with shim frames #100964
Comments
cc @markshannon |
I believe that commit slightly changed how/when generators clear their frames upon raising or returning. I forget exactly how, though... I think it might be that the generator used to link, unlink, and clear its own frame in Seems like it could definitely be related. |
If you add gc.collect() before the print you get "None []" in the output, so there's a cycle but no leak. |
Yup, this issue is just about new cycles being created where there were none before. The context for the failing testcase is a regression test for python-trio/trio#1770 (which kinda explains why we care about this in the first place). |
You can add gc.collect() to the test. |
Sorry, I think you might be misunderstanding me. In order to minimize stalls, in trio we've put in some extra work to remove reference cycles (to make GC run less often). This new shim frames mechanism adds some reference cycles which probably shouldn't be added -- the news message says "The extra frame should be invisible to all Python and most C extensions." Adding |
Ok, so I'll label it performance instead of bug. |
Note to self: |
Is this our cycle?
|
Unfortunately that didn't seem to work:
(using WSL since atm (as for the previous comment about whether that's the cycle here, I don't know.) |
This was fixed in trio but it turns out that fix was because python-trio/trio@a3d9d25 (specifically due to this change: python-trio/trio@a3d9d25#diff-568b66d9830d9516b524413eb041a1d4c8ccf0b76af4e10d96098888ce323235R937) ... I'll dedicate some more time to hopefully pinning this down because even though this isn't very important it still bothers me! |
hi. i've found a minimal reproduction that only relies on the standard library. this feels so cursed. import weakref
import asyncio
async def preserve(a):
try:
raise Exception("aaa")
except BaseException as exc:
e = exc
try:
return e
finally:
del e
class Dummy:
def __repr__(self):
return "ahahahahahah its broken!!"
class PersonManager:
async def __aenter__(self):
self._person = Dummy()
return self._person
async def __aexit__(self, etype, exc, tb):
new_exc = await preserve(self._person)
return True
async def f():
async with PersonManager() as me:
pass
h = weakref.ref(me)
del me
await asyncio.sleep(0.01)
print(h())
asyncio.run(f()) sorry for taking so long. |
Thanks, this is super helpful. Smaller reproducer that prints import weakref
import asyncio
async def preserve():
try:
raise Exception()
except Exception as exc:
return exc
class PeopleManager:
pass
def __aexit__(self):
new_exc = asyncio.run(preserve())
def f():
manager = PeopleManager()
__aexit__(manager)
h = weakref.ref(manager)
del manager
print(h() is None)
f() |
New minimal reproducer, using a generator instead of import weakref
def g():
try:
raise Exception()
except Exception as e:
yield e
class C:
pass
def f(o):
r = next(g())
o = C()
f(o)
h = weakref.ref(o)
del o
print(h() is None) The cycle is On 3.11 and earlier, |
New minimal test: def g():
yield
generator = g()
frame = generator.gi_frame
# None on 3.11, None on 3.12:
print(f"Started: {frame.f_back = }")
next(generator)
# None on 3.11, None on 3.12:
print(f"Suspended: {frame.f_back = }")
next(generator, None)
# None on 3.11, non-None on 3.12:
print(f"Exhausted: {frame.f_back = }") So, something about transferring ownership of the |
Bug report
python-trio/trio#2514 (comment)
(I haven't figured out how to reproduce without the
import trio
)I bisected this to 1e197e6
Previously:
Now:
I'm not certain this should be a bug, but raising because I'm confused as to the cause.
Linked PRs
The text was updated successfully, but these errors were encountered: