Skip to content

Generator .close does not release resources #118272

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

Closed
gsbrodal opened this issue Apr 25, 2024 · 2 comments · Fixed by #118277
Closed

Generator .close does not release resources #118272

gsbrodal opened this issue Apr 25, 2024 · 2 comments · Fixed by #118277
Labels
3.12 only security fixes 3.13 bugs and security fixes type-bug An unexpected behavior, bug, or error

Comments

@gsbrodal
Copy link

gsbrodal commented Apr 25, 2024

Bug report

Bug description:

Sending a generator .close() in Python 3.12 does not release resources used by local variables as it used to do in earlier versions of Python. Wrapping the generator content in a try: ... except GeneratorExit: pass releases the resources as expected.

The following shows the difference in space usage between wrapping the code with try-except and not.

def generator_using_a_lot_of_space():
    a_big_set = set(range(10_000_000))
    yield 42

g = generator_using_a_lot_of_space()
input('A <press enter>')  # 13.4 MB
print(next(g))
input('B <press enter>')  # 576.6 MB
g.close()
input('C <press enter>')  # 576.6 MB  <== space usage used to drop to 13-14 MB

def generator_using_a_lot_of_space():
    a_big_set = set(range(10_000_000))
    try: 
        yield 42
    except GeneratorExit:
        pass
    
g = generator_using_a_lot_of_space()
input('D <press enter>')  # 14.6 MB
print(next(g))
input('E <press enter>')  # 575.6 MB
g.close()
input('F <press enter>')  # 14.6 MB  <== drop in space usage as expected

The above space measurements were done with
Python 3.12.3 (tags/v3.12.3:f6650f9, Apr 9 2024, 14:05:25) [MSC v.1938 64 bit (AMD64)] on win32
and looking at the space usage reported by the Windows 11 Task Manager.

CPython versions tested on:

3.12

Operating systems tested on:

Windows

Linked PRs

@gsbrodal gsbrodal added the type-bug An unexpected behavior, bug, or error label Apr 25, 2024
@graingert
Copy link
Contributor

bisected to eb4774d using:

import gc
import weakref

class Foo:
    pass

f = Foo()
f_wr = weakref.ref(f)

def genfn():
    a = f
    yield


g = genfn()
next(g)
del f
g.close()
gc.collect()
print(f_wr)

outputs:

<weakref at 0x7fd58a1917b0; to 'Foo' at 0x7fd58ab12cf0>

should output:

<weakref at 0x7ad6faf19d50; dead>

passes on 3.11, fails on 3.12 and 3.13a6

@graingert graingert added 3.12 only security fixes 3.13 bugs and security fixes triaged The issue has been accepted as valid by a triager. labels Apr 25, 2024
iritkatriel added a commit to iritkatriel/cpython that referenced this issue Apr 25, 2024
@iritkatriel
Copy link
Member

Thank you, @gsbrodal for the report, and @graingert for the investigation.

@iritkatriel iritkatriel removed the triaged The issue has been accepted as valid by a triager. label Apr 29, 2024
iritkatriel added a commit to iritkatriel/cpython that referenced this issue Apr 30, 2024
iritkatriel added a commit to iritkatriel/cpython that referenced this issue May 1, 2024
iritkatriel added a commit that referenced this issue May 1, 2024
SonicField pushed a commit to SonicField/cpython that referenced this issue May 8, 2024
SonicField pushed a commit to SonicField/cpython that referenced this issue May 8, 2024
iritkatriel added a commit to iritkatriel/cpython that referenced this issue Jun 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.12 only security fixes 3.13 bugs and security fixes type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants