Bugs item #1545463, was opened at 2006-08-23 14:24 Message generated for change (Comment added) made by jimjjewett You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1545463&group_id=5470
Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: Python Interpreter Core Group: Python 2.4 Status: Open Resolution: None Priority: 5 Submitted By: Alexander Belopolsky (belopolsky) Assigned to: Nobody/Anonymous (nobody) Summary: New-style classes fail to cleanup attributes Initial Comment: > cat x.py class X(object): def __init__(self, x): self.x = x print 'creating X(%r)' % x def __del__(self): print 'deleting X(%r)' % self.x class A(object): x = X('new') class B: x = X('old') > python x.py creating X('new') creating X('old') deleting X('old') Python 2.4.2 (#2, Jan 13 2006, 12:00:38) Python 2.6a0 (trunk:51513M, Aug 23 2006, 14:17:11) ---------------------------------------------------------------------- Comment By: Jim Jewett (jimjjewett) Date: 2006-08-30 09:22 Message: Logged In: YES user_id=764593 The funny interaction with modules is probably that the module retains a reference to the class (and vice versa), so the class can't go away until the module does -- and a module in sys.modules can't go away. The __del__ methods are not called if the interpreter can't decide which to call first. For example, if A.attr=B B.attr=A then A and B form a cycle (like the class and its defining module). If only one has a __del__ method, it gets called, but if both do, then python doesn't know which to call first, so it never calls either. You may have a cycle like module <==> class <==>instanceA \ <==>instanceB So that it can't decide whether to take care of instanceA or instanceB first. Or it might be that the __del__ methods actually are being called, but not until module teardown has begun, so they don't work right. ---------------------------------------------------------------------- Comment By: Alexander Belopolsky (belopolsky) Date: 2006-08-23 20:08 Message: Logged In: YES user_id=835142 I used __del__ just to illustrate the problem. In real life application, X was a type defined in a C module and I've noticed that it's tp_dealloc is not called on instances assigned to class variables. BTW, what are the circumstances when __del__() methods are not called for objects that still exist when the interpreter exits? ---------------------------------------------------------------------- Comment By: Georg Brandl (gbrandl) Date: 2006-08-23 19:18 Message: Logged In: YES user_id=849994 There's also this sentence in the __del__ docs: """ It is not guaranteed that __del__() methods are called for objects that still exist when the interpreter exits. """ ---------------------------------------------------------------------- Comment By: Alexander Belopolsky (belopolsky) Date: 2006-08-23 18:54 Message: Logged In: YES user_id=835142 Yes, I've found that (using gc.get_referrers!), but this does not explain why A is not cleaned up when the program exits. Note that if I put class A definition inside a function, it does get cleaned up. Must be some funny interation between module and new-style class objects. ---------------------------------------------------------------------- Comment By: Georg Brandl (gbrandl) Date: 2006-08-23 18:45 Message: Logged In: YES user_id=849994 Note that new-style classes are always part of a reference cycle (you can find this out via gc.get_referrers). Therefore, they will not be deleted instantly, but only after gc collects them (you can trigger that via gc.collect). ---------------------------------------------------------------------- Comment By: Alexander Belopolsky (belopolsky) Date: 2006-08-23 18:01 Message: Logged In: YES user_id=835142 It looks like the class object is not deleted alltogether: class X(object): def __init__(self, x): self.x = x print 'creating X(%r)' % x def __del__(self): print 'deleting X(%r)' % self.x class A(object): x = X('new') del A Output: creating X('new') deleting X('new') ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1545463&group_id=5470 _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com