Question about transaction usage
Greg Ward
greg at gerg.ca
Sun Oct 4 14:20:37 UTC 2009
On Sat, Oct 3, 2009 at 5:36 PM, Matt Mackall <mpm at selenic.com> wrote:
> Unfortunately, destructors in Python are basically useless. If an
> exception is thrown, the traceback object will hold references to every
> stack frame in the call chain, preventing the destructors from getting
> invoked in a timely fashion (and sometimes at all!).
>
> So we make a point of manually destroying locks and transactions.
Got it. Thanks.
For the benefit of the archive, and anyone else who was confused by
this, I wrote a little script that illustrates the problem:
"""
class C(object):
def __del__(self):
print "C destructor called"
def func():
raise RuntimeError("ow!")
def main():
c = C()
try:
func()
finally:
#del c
pass
try:
main()
except Exception:
print "something bad happened"
else:
print "no exceptions"
"""
If you run it like as-is (no "del c"), the output is
something bad happened
C destructor called
which is bad: it means the object doesn't get destroyed until the
script is about to exit. In a command-line hg, that could probably be
tolerated; it just means the transaction aborts a little later than we
want it to abort. But it has an arbitrary feel to it, and the
non-locality of the action is unpleasant.
However, uncomment the "del c" line, and the output becomes
C destructor called
something bad happened
which is good: it means the object is destroyed from the scope where
it was created.
I think the most useful thing I learned from Java is that you must
never rely on destructors being called: if your object holds
resources, give it an explicit close() method. (C)Python destructors
are more deterministic than Java destructors, but the rule holds.
Greg
More information about the Mercurial-devel
mailing list