This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: Object lifetime and inner recursive function
Type: Stage:
Components: Interpreter Core Versions: Python 3.0, Python 3.1, Python 2.7, Python 2.6
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Eric.Wieser, eric.snow, ocean-city, pitrou
Priority: normal Keywords:

Created on 2009-01-12 11:19 by ocean-city, last changed 2022-04-11 14:56 by admin. This issue is now closed.

File name Uploaded Description Edit ocean-city, 2009-01-12 15:08
Messages (7)
msg79664 - (view) Author: Hirokazu Yamamoto (ocean-city) * (Python committer) Date: 2009-01-12 11:19
Hello. Sorry if this is noise. I expected

out of function
out of function
out of function

on following code, but actually I got

out of function
out of function
out of function

Is this expected behavoir? (I believed `a' would be
freed after returned from f(), so I was suprised)

If I remove the comment of gc.collect(), the code works as expected.


import gc

class A:
    def __del__(self):

def f():
    a = A()
    def g():

def main():
    for _ in range(3):
#       gc.collect()
        print("out of function")

if __name__ == '__main__':
msg79670 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-01-12 12:21
Since g calls "itself" in its own scope, it is stored as one of its own
cell vars, which creates a reference cycle. a is also part of its
reference cycle for the same reason, so it must wait for garbage
collection to be reclaimed.

If g didn't keep a reference to its cell vars, closures wouldn't be
possible, because the cell vars wouldn't survive the end of f's scope.

(g doesn't have to be recursive, it's enough that it makes a reference
to itself in its own scope:

def f():
    a = A()
    def g():

or even:

def f():
    a = A()
    def g():
    h = g

msg79672 - (view) Author: Hirokazu Yamamoto (ocean-city) * (Python committer) Date: 2009-01-12 12:58
Thank you for explanation. The combination of inner function + method 
variable was very handy for me, but maybe I should refrain from using 
it lightly. :-(
msg79680 - (view) Author: Hirokazu Yamamoto (ocean-city) * (Python committer) Date: 2009-01-12 15:08
A little followup. Attached script (some puzzle program) ate up 
my RAM (80MB) and never ran GC while solving. Current python GC looks 
at the number of GC objects, but GC object like set object can contain 
many non GC object, so... I feel it would be nice if there is better GC 
msg79706 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-01-12 22:51
Well, tracking memory consumption of each container would be better than
simpling couting them, but it's much more complicated as well (not to
mention that memory consumption can vary, so you must recalculate it
msg312343 - (view) Author: Eric Wieser (Eric.Wieser) * Date: 2018-02-19 08:33
Would it be possible for function self-reference cell vars to be weak references?

This wouldn't solve the issue for co-recursive inner functions, but would at least prevent reference cycles for the more common case of simple recursive functions.
msg324987 - (view) Author: Eric Wieser (Eric.Wieser) * Date: 2018-09-11 05:09
For anyone doing archaeology - this came up on python-dev about a year after this issue was filed:
Date User Action Args
2022-04-11 14:56:44adminsetgithub: 49171
2018-09-11 14:43:05eric.snowsetnosy: + eric.snow
2018-09-11 05:09:24Eric.Wiesersetmessages: + msg324987
2018-02-19 08:33:42Eric.Wiesersetnosy: + Eric.Wieser
messages: + msg312343
2009-01-12 22:51:35pitrousetmessages: + msg79706
2009-01-12 15:08:24ocean-citysetfiles: +
messages: + msg79680
2009-01-12 12:58:16ocean-citysetstatus: open -> closed
resolution: not a bug
messages: + msg79672
2009-01-12 12:21:41pitrousetnosy: + pitrou
messages: + msg79670
2009-01-12 11:19:17ocean-citycreate