Index: Lib/hotshot/__init__.py =================================================================== --- Lib/hotshot/__init__.py (revision 60900) +++ Lib/hotshot/__init__.py (working copy) @@ -62,6 +62,7 @@ The string is compiled before profiling begins. """ code = compile(cmd, "", "exec") + globals.setdefault('__builtins__', __builtins__) self._prof.runcode(code, globals, locals) return self Index: Lib/test/test_hotshot.py =================================================================== --- Lib/test/test_hotshot.py (revision 60900) +++ Lib/test/test_hotshot.py (working copy) @@ -123,6 +123,26 @@ sys.path = orig_path if os.path.exists(test_support.TESTFN): os.remove(test_support.TESTFN) + + def test_builtins_present_in_globals(self): + """__builtins__ is present in the runctx() context even if it is not + present in the globals arg. + """ + profiler = self.new_profiler() + try: + profiler.runctx('len', {}, {}) + except NameError: + self.fail('runctx() globals should include builtins') + + def test_builtins_can_be_overriden(self): + """If __builtins__ is supplied in the runctx() globals arg, it + replaces the default __builtins__. + """ + profiler = self.new_profiler() + # The chances of hotshot ever containing a 'len' is rather small + myglobals = {'__builtins__': hotshot} + self.assertRaises(NameError, profiler.runctx, 'len', myglobals, {}) + def test_main(): test_support.run_unittest(HotShotTestCase)