]> granicus.if.org Git - python/commitdiff
Issue #5633: Fixed timeit when the statement is a string and the setup is not.
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 30 May 2015 16:44:55 +0000 (19:44 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Sat, 30 May 2015 16:44:55 +0000 (19:44 +0300)
Refactored timeit.__init__ for unified handling of stmt and setup parameters.

1  2 
Lib/test/test_timeit.py
Lib/timeit.py
Misc/NEWS

Simple merge
diff --cc Lib/timeit.py
index de7d5505e46242e757cec88a0cc7a85fc4e540fb,0b1c601c97420c539a5e65a6ffab8b057ae9a747..d9f9563c2e646eb59acbc6f0c71946c12f5fb4a7
@@@ -81,17 -78,17 +81,6 @@@ def reindent(src, indent)
      """Helper to reindent a multi-line statement."""
      return src.replace("\n", "\n" + " "*indent)
  
--def _template_func(setup, func):
--    """Create a timer function. Used if the "statement" is a callable."""
--    def inner(_it, _timer, _func=func):
--        setup()
--        _t0 = _timer()
--        for _i in _it:
--            _func()
--        _t1 = _timer()
--        return _t1 - _t0
--    return inner
--
  class Timer:
      """Class for timing execution speed of small code snippets.
  
      multi-line string literals.
      """
  
 -    def __init__(self, stmt="pass", setup="pass", timer=default_timer):
 +    def __init__(self, stmt="pass", setup="pass", timer=default_timer,
 +                 globals=None):
          """Constructor.  See class doc string."""
          self.timer = timer
 -        ns = {}
 +        local_ns = {}
 +        global_ns = _globals() if globals is None else globals
++        init = ''
++        if isinstance(setup, str):
++            # Check that the code can be compiled outside a function
++            compile(setup, dummy_src_name, "exec")
++            setup = reindent(setup, 4)
++        elif callable(setup):
++            local_ns['_setup'] = setup
++            init += ', _setup=_setup'
++            setup = '_setup()'
++        else:
++            raise ValueError("setup is neither a string nor callable")
          if isinstance(stmt, str):
              # Check that the code can be compiled outside a function
              if isinstance(setup, str):
--                compile(setup, dummy_src_name, "exec")
                  compile(setup + '\n' + stmt, dummy_src_name, "exec")
              else:
                  compile(stmt, dummy_src_name, "exec")
              stmt = reindent(stmt, 8)
--            if isinstance(setup, str):
--                setup = reindent(setup, 4)
-                 src = template.format(stmt=stmt, setup=setup)
 -                src = template.format(stmt=stmt, setup=setup, init='')
--            elif callable(setup):
-                 src = template.format(stmt=stmt, setup='_setup()')
-                 local_ns['_setup'] = setup
 -                src = template.format(stmt=stmt, setup='_setup()',
 -                                      init=', _setup=_setup')
 -                ns['_setup'] = setup
--            else:
--                raise ValueError("setup is neither a string nor callable")
-             self.src = src  # Save for traceback display
 -            self.src = src # Save for traceback display
--            code = compile(src, dummy_src_name, "exec")
-             exec(code, global_ns, local_ns)
-             self.inner = local_ns["inner"]
 -            exec(code, globals(), ns)
 -            self.inner = ns["inner"]
          elif callable(stmt):
--            self.src = None
--            if isinstance(setup, str):
--                _setup = setup
--                def setup():
-                     exec(_setup, global_ns, local_ns)
 -                    exec(_setup, globals(), ns)
--            elif not callable(setup):
--                raise ValueError("setup is neither a string nor callable")
--            self.inner = _template_func(setup, stmt)
++            local_ns['_stmt'] = stmt
++            init += ', _stmt=_stmt'
++            stmt = '_stmt()'
          else:
              raise ValueError("stmt is neither a string nor callable")
++        src = template.format(stmt=stmt, setup=setup, init=init)
++        self.src = src  # Save for traceback display
++        code = compile(src, dummy_src_name, "exec")
++        exec(code, global_ns, local_ns)
++        self.inner = local_ns["inner"]
  
      def print_exc(self, file=None):
          """Helper to print a traceback from the timed code.
diff --cc Misc/NEWS
index d6ff9e44fd6e5f3ac20863816d7ca8ffc0696d76,dada469adfbd5cd40a9bd3f8028e751eff8bd3df..2d418129490df86d7341376c637b9dd59d3dbb9f
+++ b/Misc/NEWS
@@@ -14,38 -14,6 +14,40 @@@ Core and Builtin
    PyObject_IsInstance(), PyObject_RichCompareBool() and _PyDict_Contains()
    to check for and handle errors correctly.
  
 +- Issue #24328: Fix importing one character extension modules.
 +
 +- Issue #11205: In dictionary displays, evaluate the key before the value.
 +
 +- Issue #24285: Fixed regression that prevented importing extension modules
 +  from inside packages. Patch by Petr Viktorin.
 +
 +Library
 +-------
 +
++- Issue #5633: Fixed timeit when the statement is a string and the setup is not.
++
 +- Issue #24326: Fixed audioop.ratecv() with non-default weightB argument.
 +  Original patch by David Moore.
 +
 +- Issue #16991: Add a C implementation of OrderedDict.
 +
 +
 +What's New in Python 3.5.0 beta 1?
 +==================================
 +
 +Release date: 2015-05-24
 +
 +Core and Builtins
 +-----------------
 +
 +- Issue #24276: Fixed optimization of property descriptor getter.
 +
 +- Issue #24268: PEP 489: Multi-phase extension module initialization.
 +  Patch by Petr Viktorin.
 +
 +- Issue #23955: Add pyvenv.cfg option to suppress registry/environment
 +  lookup for generating sys.path on Windows.
 +
  - Issue #24257: Fixed system error in the comparison of faked
    types.SimpleNamespace.