classification
Title: timeit disables garbage collection if timed code raises an exception
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.2, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: Gareth.Rees, python-dev, rhettinger
Priority: normal Keywords: patch

Created on 2011-07-07 14:58 by Gareth.Rees, last changed 2011-07-29 07:09 by rhettinger. This issue is now closed.

Files
File name Uploaded Description Edit
issue12514.patch Gareth.Rees, 2011-07-07 15:58 review
Messages (6)
msg139978 - (view) Author: Gareth Rees (Gareth.Rees) * Date: 2011-07-07 14:58
If you call timeit.timeit and the timed code raises an exception, then garbage collection is disabled. I have verified this in Python 2.7 and 3.2. Here's an interaction with Python 3.2:

    Python 3.2 (r32:88445, Jul  7 2011, 15:52:49) 
    [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import timeit, gc
    >>> gc.isenabled()
    True
    >>> timeit.timeit('raise Exception')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/timeit.py", line 228, in timeit
        return Timer(stmt, setup, timer).timeit(number)
      File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/timeit.py", line 194, in timeit
        timing = self.inner(it, self.timer)
      File "<timeit-src>", line 6, in inner
    Exception
    >>> gc.isenabled()
    False

The problem is with the following code in Lib/timeit.py (lines 192–196):

    gcold = gc.isenabled()
    gc.disable()
    timing = self.inner(it, self.timer)
    if gcold:
        gc.enable()

This should be changed to something like this:

    gcold = gc.isenabled()
    gc.disable()
    try:
        timing = self.inner(it, self.timer)
    finally:
        if gcold:
            gc.enable()
msg139980 - (view) Author: Gareth Rees (Gareth.Rees) * Date: 2011-07-07 15:58
Patch attached.
msg139981 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2011-07-07 16:33
Thank you.  The patch looks correct.  I will apply it as soon as I get a chance.
msg141334 - (view) Author: Roundup Robot (python-dev) Date: 2011-07-29 06:56
New changeset 56e7b42089c8 by Raymond Hettinger in branch '2.7':
Issue 12514: Use try/finally to assure that timeit restores GC when done.
http://hg.python.org/cpython/rev/56e7b42089c8
msg141335 - (view) Author: Roundup Robot (python-dev) Date: 2011-07-29 07:08
New changeset 1cdb281a78ce by Raymond Hettinger in branch '3.2':
Issue 12514: Use try/finally to assure that timeit restores GC when done.
http://hg.python.org/cpython/rev/1cdb281a78ce

New changeset 7df53f5788a4 by Raymond Hettinger in branch 'default':
Issue 12514: Use try/finally to assure that timeit restores GC when done.
http://hg.python.org/cpython/rev/7df53f5788a4
msg141336 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2011-07-29 07:09
Thanks for the bug report and patch.
History
Date User Action Args
2011-07-29 07:09:15rhettingersetstatus: open -> closed
resolution: fixed
messages: + msg141336
2011-07-29 07:08:28python-devsetmessages: + msg141335
2011-07-29 06:56:48python-devsetnosy: + python-dev
messages: + msg141334
2011-07-07 16:33:44rhettingersetmessages: + msg139981
2011-07-07 16:32:19rhettingersetassignee: rhettinger

nosy: + rhettinger
2011-07-07 15:58:02Gareth.Reessetfiles: + issue12514.patch
keywords: + patch
messages: + msg139980
2011-07-07 14:58:52Gareth.Reescreate