##// END OF EJS Templates
Added mean + stdv to the %timeit magic - New tests pending - Corrected old ones
Pablo Galindo -
Show More
@@ -15,6 +15,7 b' import os'
15 15 import sys
16 16 import time
17 17 import timeit
18 import math
18 19 from pdb import Restart
19 20
20 21 # cProfile was added in Python2.5
@@ -71,23 +72,27 b' class TimeitResult(object):'
71 72
72 73 """
73 74
74 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
75 def __init__(self, loops, repeat, average, stdev, all_runs, compile_time, precision):
75 76 self.loops = loops
76 77 self.repeat = repeat
77 self.best = best
78 self.worst = worst
78 self.average = average
79 self.stdev = stdev
79 80 self.all_runs = all_runs
80 81 self.compile_time = compile_time
81 82 self._precision = precision
82 83
83 84 def _repr_pretty_(self, p , cycle):
84 if self.loops == 1: # No s at "loops" if only one loop
85 unic = u"%d loop, best of %d: %s per loop" % (self.loops, self.repeat,
86 _format_time(self.best, self._precision))
87 else:
88 unic = u"%d loops, best of %d: %s per loop" % (self.loops, self.repeat,
89 _format_time(self.best, self._precision))
90 p.text(u'<TimeitResult : '+unic+u'>')
85 if self.loops == 1: # No s at "loops" if only one loop
86 unic = (u"%s loop, average of %d: %s +- %s per loop (using standard deviation)"
87 % (self.loops, self.repeat,
88 _format_time(self.average, self._precision),
89 _format_time(self.stdev, self._precision)))
90 else:
91 unic = (u"%s loops, average of %d: %s +- %s per loop (using standard deviation)"
92 % (self.loops, self.repeat,
93 _format_time(self.average, self._precision),
94 _format_time(self.stdev, self._precision)))
95 p.text(u'<TimeitResult : '+unic+u'>')
91 96
92 97
93 98 class TimeitTemplateFiller(ast.NodeTransformer):
@@ -117,7 +122,7 b' class TimeitTemplateFiller(ast.NodeTransformer):'
117 122
118 123 class Timer(timeit.Timer):
119 124 """Timer class that explicitly uses self.inner
120
125
121 126 which is an undocumented implementation detail of CPython,
122 127 not shared by PyPy.
123 128 """
@@ -457,7 +462,7 b' python-profiler package from non-free.""")'
457 462 """Run the named file inside IPython as a program.
458 463
459 464 Usage::
460
465
461 466 %run [-n -i -e -G]
462 467 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
463 468 ( -m mod | file ) [args]
@@ -652,7 +657,7 b' python-profiler package from non-free.""")'
652 657 __name__save = self.shell.user_ns['__name__']
653 658 prog_ns['__name__'] = '__main__'
654 659 main_mod = self.shell.user_module
655
660
656 661 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
657 662 # set the __file__ global in the script's namespace
658 663 # TK: Is this necessary in interactive mode?
@@ -852,7 +857,7 b' python-profiler package from non-free.""")'
852 857 continue
853 858 else:
854 859 break
855
860
856 861
857 862 except:
858 863 etype, value, tb = sys.exc_info()
@@ -950,20 +955,20 b' python-profiler package from non-free.""")'
950 955 ::
951 956
952 957 In [1]: %timeit pass
953 10000000 loops, best of 3: 53.3 ns per loop
958 100000000 loops, average of 7: 5.48 ns +- 0.354 ns per loop (using standard deviation)
954 959
955 960 In [2]: u = None
956 961
957 962 In [3]: %timeit u is None
958 10000000 loops, best of 3: 184 ns per loop
963 10000000 loops, average of 7: 22.7 ns +- 2.33 ns per loop (using standard deviation)
959 964
960 965 In [4]: %timeit -r 4 u == None
961 1000000 loops, best of 4: 242 ns per loop
966 10000000 loops, average of 4: 27.5 ns +- 2.91 ns per loop (using standard deviation)
962 967
963 968 In [5]: import time
964 969
965 970 In [6]: %timeit -n1 time.sleep(2)
966 1 loop, best of 3: 2 s per loop
971 1 loop, average of 7: 2 s +- 4.71 Β΅s per loop (using standard deviation)
967 972
968 973
969 974 The times reported by %timeit will be slightly higher than those
@@ -978,10 +983,11 b' python-profiler package from non-free.""")'
978 983 posix=False, strict=False)
979 984 if stmt == "" and cell is None:
980 985 return
981
986
982 987 timefunc = timeit.default_timer
983 988 number = int(getattr(opts, "n", 0))
984 repeat = int(getattr(opts, "r", timeit.default_repeat))
989 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
990 repeat = int(getattr(opts, "r", default_repeat))
985 991 precision = int(getattr(opts, "p", 3))
986 992 quiet = 'q' in opts
987 993 return_result = 'o' in opts
@@ -1036,22 +1042,26 b' python-profiler package from non-free.""")'
1036 1042 # This is used to check if there is a huge difference between the
1037 1043 # best and worst timings.
1038 1044 # Issue: https://github.com/ipython/ipython/issues/6471
1039 worst_tuning = 0
1040 1045 if number == 0:
1041 1046 # determine number so that 0.2 <= total time < 2.0
1042 number = 1
1043 for _ in range(1, 10):
1047 for index in range(0, 10):
1048 number = 10 ** index
1044 1049 time_number = timer.timeit(number)
1045 worst_tuning = max(worst_tuning, time_number / number)
1046 1050 if time_number >= 0.2:
1047 1051 break
1048 number *= 10
1052
1049 1053 all_runs = timer.repeat(repeat, number)
1050 best = min(all_runs) / number
1054 timings = [ dt / number for dt in all_runs]
1055
1056 def _avg(numbers):
1057 return math.fsum(numbers) / len(numbers)
1058
1059 def _stdev(numbers):
1060 mean = _avg(numbers)
1061 return (math.fsum([(x - mean) ** 2 for x in numbers]) / len(numbers)) ** 0.5
1051 1062
1052 worst = max(all_runs) / number
1053 if worst_tuning:
1054 worst = max(worst, worst_tuning)
1063 average = _avg(timings)
1064 stdev = _stdev(timings)
1055 1065
1056 1066 if not quiet :
1057 1067 # Check best timing is greater than zero to avoid a
@@ -1059,20 +1069,20 b' python-profiler package from non-free.""")'
1059 1069 # In cases where the slowest timing is lesser than a micosecond
1060 1070 # we assume that it does not really matter if the fastest
1061 1071 # timing is 4 times faster than the slowest timing or not.
1062 if worst > 4 * best and best > 0 and worst > 1e-6:
1063 print("The slowest run took %0.2f times longer than the "
1064 "fastest. This could mean that an intermediate result "
1065 "is being cached." % (worst / best))
1066 1072 if number == 1: # No s at "loops" if only one loop
1067 print(u"%d loop, best of %d: %s per loop" % (number, repeat,
1068 _format_time(best, precision)))
1073 print(u"%s loop, average of %d: %s +- %s per loop (using standard deviation)"
1074 % (number, repeat,
1075 _format_time(average, precision),
1076 _format_time(stdev, precision)))
1069 1077 else:
1070 print(u"%d loops, best of %d: %s per loop" % (number, repeat,
1071 _format_time(best, precision)))
1078 print(u"%s loops, average of %d: %s +- %s per loop (using standard deviation)"
1079 % (number, repeat,
1080 _format_time(average, precision),
1081 _format_time(stdev, precision)))
1072 1082 if tc > tc_min:
1073 1083 print("Compiler time: %.2f s" % tc)
1074 1084 if return_result:
1075 return TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1085 return TimeitResult(number, repeat, average, stdev, all_runs, tc, precision)
1076 1086
1077 1087 @skip_doctest
1078 1088 @needs_local_scope
@@ -1083,16 +1093,16 b' python-profiler package from non-free.""")'
1083 1093 The CPU and wall clock times are printed, and the value of the
1084 1094 expression (if any) is returned. Note that under Win32, system time
1085 1095 is always reported as 0, since it can not be measured.
1086
1096
1087 1097 This function can be used both as a line and cell magic:
1088 1098
1089 1099 - In line mode you can time a single-line statement (though multiple
1090 1100 ones can be chained with using semicolons).
1091 1101
1092 - In cell mode, you can time the cell body (a directly
1102 - In cell mode, you can time the cell body (a directly
1093 1103 following statement raises an error).
1094 1104
1095 This function provides very basic timing functionality. Use the timeit
1105 This function provides very basic timing functionality. Use the timeit
1096 1106 magic for more control over the measurement.
1097 1107
1098 1108 Examples
@@ -1133,10 +1143,10 b' python-profiler package from non-free.""")'
1133 1143 """
1134 1144
1135 1145 # fail immediately if the given expression can't be compiled
1136
1146
1137 1147 if line and cell:
1138 1148 raise UsageError("Can't use statement directly after '%%time'!")
1139
1149
1140 1150 if cell:
1141 1151 expr = self.shell.input_transformer_manager.transform_cell(cell)
1142 1152 else:
@@ -1186,7 +1196,7 b' python-profiler package from non-free.""")'
1186 1196 cpu_user = end[0]-st[0]
1187 1197 cpu_sys = end[1]-st[1]
1188 1198 cpu_tot = cpu_user+cpu_sys
1189 # On windows cpu_sys is always zero, so no new information to the next print
1199 # On windows cpu_sys is always zero, so no new information to the next print
1190 1200 if sys.platform != 'win32':
1191 1201 print("CPU times: user %s, sys: %s, total: %s" % \
1192 1202 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
@@ -1212,9 +1222,9 b' python-profiler package from non-free.""")'
1212 1222 so that magics are loaded in their transformed version to valid
1213 1223 Python. If this option is given, the raw input as typed at the
1214 1224 command line is used instead.
1215
1216 -q: quiet macro definition. By default, a tag line is printed
1217 to indicate the macro has been created, and then the contents of
1225
1226 -q: quiet macro definition. By default, a tag line is printed
1227 to indicate the macro has been created, and then the contents of
1218 1228 the macro are printed. If this option is given, then no printout
1219 1229 is produced once the macro is created.
1220 1230
@@ -1277,7 +1287,7 b' python-profiler package from non-free.""")'
1277 1287 return
1278 1288 macro = Macro(lines)
1279 1289 self.shell.define_macro(name, macro)
1280 if not ( 'q' in opts) :
1290 if not ( 'q' in opts) :
1281 1291 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1282 1292 print('=== Macro contents: ===')
1283 1293 print(macro, end=' ')
@@ -1323,11 +1333,11 b' def parse_breakpoint(text, current_file):'
1323 1333 return current_file, int(text)
1324 1334 else:
1325 1335 return text[:colon], int(text[colon+1:])
1326
1336
1327 1337 def _format_time(timespan, precision=3):
1328 1338 """Formats the timespan in a human readable form"""
1329 1339 import math
1330
1340
1331 1341 if timespan >= 60.0:
1332 1342 # we have more than a minute, format that in a human readable form
1333 1343 # Idea from http://snipplr.com/view/5713/
@@ -1343,13 +1353,13 b' def _format_time(timespan, precision=3):'
1343 1353 break
1344 1354 return " ".join(time)
1345 1355
1346
1356
1347 1357 # Unfortunately the unicode 'micro' symbol can cause problems in
1348 # certain terminals.
1358 # certain terminals.
1349 1359 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1350 1360 # Try to prevent crashes by being more secure than it needs to
1351 1361 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1352 units = [u"s", u"ms",u'us',"ns"] # the save value
1362 units = [u"s", u"ms",u'us',"ns"] # the save value
1353 1363 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1354 1364 try:
1355 1365 u'\xb5'.encode(sys.stdout.encoding)
@@ -1357,7 +1367,7 b' def _format_time(timespan, precision=3):'
1357 1367 except:
1358 1368 pass
1359 1369 scaling = [1, 1e3, 1e6, 1e9]
1360
1370
1361 1371 if timespan > 0.0:
1362 1372 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1363 1373 else:
@@ -120,16 +120,16 b' class InteractiveShellTestCase(unittest.TestCase):'
120 120 newlen = len(ip.user_ns['In'])
121 121 self.assertEqual(oldlen+1, newlen)
122 122 self.assertEqual(ip.user_ns['In'][-1],'1;')
123
123
124 124 def test_magic_names_in_string(self):
125 125 ip.run_cell('a = """\n%exit\n"""')
126 126 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
127
127
128 128 def test_trailing_newline(self):
129 129 """test that running !(command) does not raise a SyntaxError"""
130 130 ip.run_cell('!(true)\n', False)
131 131 ip.run_cell('!(true)\n\n\n', False)
132
132
133 133 def test_gh_597(self):
134 134 """Pretty-printing lists of objects with non-ascii reprs may cause
135 135 problems."""
@@ -139,7 +139,7 b' class InteractiveShellTestCase(unittest.TestCase):'
139 139 import IPython.core.formatters
140 140 f = IPython.core.formatters.PlainTextFormatter()
141 141 f([Spam(),Spam()])
142
142
143 143
144 144 def test_future_flags(self):
145 145 """Check that future flags are used for parsing code (gh-777)"""
@@ -162,7 +162,7 b' class InteractiveShellTestCase(unittest.TestCase):'
162 162 finally:
163 163 # Reset compiler flags so we don't mess up other tests.
164 164 ip.compile.reset_compiler_flags()
165
165
166 166 def test_can_pickle(self):
167 167 "Can we pickle objects defined interactively (GH-29)"
168 168 ip = get_ipython()
@@ -171,9 +171,9 b' class InteractiveShellTestCase(unittest.TestCase):'
171 171 " def __init__(self,x=[]):\n"
172 172 " list.__init__(self,x)"))
173 173 ip.run_cell("w=Mylist([1,2,3])")
174
174
175 175 from pickle import dumps
176
176
177 177 # We need to swap in our main module - this is only necessary
178 178 # inside the test framework, because IPython puts the interactive module
179 179 # in place (but the test framework undoes this).
@@ -184,7 +184,7 b' class InteractiveShellTestCase(unittest.TestCase):'
184 184 finally:
185 185 sys.modules['__main__'] = _main
186 186 self.assertTrue(isinstance(res, bytes))
187
187
188 188 def test_global_ns(self):
189 189 "Code in functions must be able to access variables outside them."
190 190 ip = get_ipython()
@@ -234,7 +234,7 b' class InteractiveShellTestCase(unittest.TestCase):'
234 234 ip.user_ns['f'] = b'Ca\xc3\xb1o'
235 235 # This should not raise any exception:
236 236 ip.var_expand(u'echo $f')
237
237
238 238 def test_var_expand_local(self):
239 239 """Test local variable expansion in !system and %magic calls"""
240 240 # !system
@@ -244,7 +244,7 b' class InteractiveShellTestCase(unittest.TestCase):'
244 244 ' return ret[0]\n')
245 245 res = ip.user_ns['test']()
246 246 nt.assert_in('ttt', res)
247
247
248 248 # %magic
249 249 ip.run_cell('def makemacro():\n'
250 250 ' macroname = "macro_var_expand_locals"\n'
@@ -252,10 +252,10 b' class InteractiveShellTestCase(unittest.TestCase):'
252 252 ip.user_ns['codestr'] = "str(12)"
253 253 ip.run_cell('makemacro()')
254 254 nt.assert_in('macro_var_expand_locals', ip.user_ns)
255
255
256 256 def test_var_expand_self(self):
257 257 """Test variable expansion with the name 'self', which was failing.
258
258
259 259 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
260 260 """
261 261 ip.run_cell('class cTest:\n'
@@ -264,7 +264,7 b' class InteractiveShellTestCase(unittest.TestCase):'
264 264 ' res = !echo Variable: {self.classvar}\n'
265 265 ' return res[0]\n')
266 266 nt.assert_in('see me', ip.user_ns['cTest']().test())
267
267
268 268 def test_bad_var_expand(self):
269 269 """var_expand on invalid formats shouldn't raise"""
270 270 # SyntaxError
@@ -273,19 +273,19 b' class InteractiveShellTestCase(unittest.TestCase):'
273 273 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
274 274 # ZeroDivisionError
275 275 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
276
276
277 277 def test_silent_postexec(self):
278 278 """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks"""
279 279 pre_explicit = mock.Mock()
280 280 pre_always = mock.Mock()
281 281 post_explicit = mock.Mock()
282 282 post_always = mock.Mock()
283
283
284 284 ip.events.register('pre_run_cell', pre_explicit)
285 285 ip.events.register('pre_execute', pre_always)
286 286 ip.events.register('post_run_cell', post_explicit)
287 287 ip.events.register('post_execute', post_always)
288
288
289 289 try:
290 290 ip.run_cell("1", silent=True)
291 291 assert pre_always.called
@@ -303,29 +303,29 b' class InteractiveShellTestCase(unittest.TestCase):'
303 303 ip.events.unregister('pre_execute', pre_always)
304 304 ip.events.unregister('post_run_cell', post_explicit)
305 305 ip.events.unregister('post_execute', post_always)
306
306
307 307 def test_silent_noadvance(self):
308 308 """run_cell(silent=True) doesn't advance execution_count"""
309 309 ec = ip.execution_count
310 310 # silent should force store_history=False
311 311 ip.run_cell("1", store_history=True, silent=True)
312
312
313 313 self.assertEqual(ec, ip.execution_count)
314 314 # double-check that non-silent exec did what we expected
315 315 # silent to avoid
316 316 ip.run_cell("1", store_history=True)
317 317 self.assertEqual(ec+1, ip.execution_count)
318
318
319 319 def test_silent_nodisplayhook(self):
320 320 """run_cell(silent=True) doesn't trigger displayhook"""
321 321 d = dict(called=False)
322
322
323 323 trap = ip.display_trap
324 324 save_hook = trap.hook
325
325
326 326 def failing_hook(*args, **kwargs):
327 327 d['called'] = True
328
328
329 329 try:
330 330 trap.hook = failing_hook
331 331 res = ip.run_cell("1", silent=True)
@@ -350,10 +350,10 b' class InteractiveShellTestCase(unittest.TestCase):'
350 350 In [2]: print 1,; print 2
351 351 1 2
352 352 """
353
353
354 354 def test_ofind_line_magic(self):
355 355 from IPython.core.magic import register_line_magic
356
356
357 357 @register_line_magic
358 358 def lmagic(line):
359 359 "A line magic"
@@ -364,10 +364,10 b' class InteractiveShellTestCase(unittest.TestCase):'
364 364 namespace = 'IPython internal', obj= lmagic.__wrapped__,
365 365 parent = None)
366 366 nt.assert_equal(lfind, info)
367
367
368 368 def test_ofind_cell_magic(self):
369 369 from IPython.core.magic import register_cell_magic
370
370
371 371 @register_cell_magic
372 372 def cmagic(line, cell):
373 373 "A cell magic"
@@ -454,7 +454,7 b' class InteractiveShellTestCase(unittest.TestCase):'
454 454 def my_handler(shell, etype, value, tb, tb_offset=None):
455 455 called.append(etype)
456 456 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
457
457
458 458 ip.set_custom_exc((ValueError,), my_handler)
459 459 try:
460 460 res = ip.run_cell("raise ValueError('test')")
@@ -465,7 +465,7 b' class InteractiveShellTestCase(unittest.TestCase):'
465 465 finally:
466 466 # Reset the custom exception hook
467 467 ip.set_custom_exc((), None)
468
468
469 469 @skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
470 470 def test_future_environment(self):
471 471 "Can we run code with & without the shell's __future__ imports?"
@@ -474,7 +474,7 b' class InteractiveShellTestCase(unittest.TestCase):'
474 474 self.assertEqual(ip.user_ns['a'], 0.5)
475 475 ip.run_cell("b = 1/2", shell_futures=False)
476 476 self.assertEqual(ip.user_ns['b'], 0)
477
477
478 478 ip.compile.reset_compiler_flags()
479 479 # This shouldn't leak to the shell's compiler
480 480 ip.run_cell("from __future__ import division \nc=1/2", shell_futures=False)
@@ -551,7 +551,7 b' class ExitCodeChecks(tt.TempFileMixin):'
551 551 def test_exit_code_error(self):
552 552 self.system('exit 1')
553 553 self.assertEqual(ip.user_ns['_exit_code'], 1)
554
554
555 555 @skipif(not hasattr(signal, 'SIGALRM'))
556 556 def test_exit_code_signal(self):
557 557 self.mktmp("import signal, time\n"
@@ -559,7 +559,7 b' class ExitCodeChecks(tt.TempFileMixin):'
559 559 "time.sleep(1)\n")
560 560 self.system("%s %s" % (sys.executable, self.fname))
561 561 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
562
562
563 563 @onlyif_cmds_exist("csh")
564 564 def test_exit_code_signal_csh(self):
565 565 SHELL = os.environ.get('SHELL', None)
@@ -630,56 +630,56 b' class TestAstTransform(unittest.TestCase):'
630 630 def setUp(self):
631 631 self.negator = Negator()
632 632 ip.ast_transformers.append(self.negator)
633
633
634 634 def tearDown(self):
635 635 ip.ast_transformers.remove(self.negator)
636
636
637 637 def test_run_cell(self):
638 638 with tt.AssertPrints('-34'):
639 639 ip.run_cell('print (12 + 22)')
640
640
641 641 # A named reference to a number shouldn't be transformed.
642 642 ip.user_ns['n'] = 55
643 643 with tt.AssertNotPrints('-55'):
644 644 ip.run_cell('print (n)')
645
645
646 646 def test_timeit(self):
647 647 called = set()
648 648 def f(x):
649 649 called.add(x)
650 650 ip.push({'f':f})
651
652 with tt.AssertPrints("best of "):
651
652 with tt.AssertPrints("average of "):
653 653 ip.run_line_magic("timeit", "-n1 f(1)")
654 654 self.assertEqual(called, {-1})
655 655 called.clear()
656
657 with tt.AssertPrints("best of "):
656
657 with tt.AssertPrints("average of "):
658 658 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
659 659 self.assertEqual(called, {-2, -3})
660
660
661 661 def test_time(self):
662 662 called = []
663 663 def f(x):
664 664 called.append(x)
665 665 ip.push({'f':f})
666
666
667 667 # Test with an expression
668 668 with tt.AssertPrints("Wall time: "):
669 669 ip.run_line_magic("time", "f(5+9)")
670 670 self.assertEqual(called, [-14])
671 671 called[:] = []
672
672
673 673 # Test with a statement (different code path)
674 674 with tt.AssertPrints("Wall time: "):
675 675 ip.run_line_magic("time", "a = f(-3 + -2)")
676 676 self.assertEqual(called, [5])
677
677
678 678 def test_macro(self):
679 679 ip.push({'a':10})
680 680 # The AST transformation makes this do a+=-1
681 681 ip.define_macro("amacro", "a+=1\nprint(a)")
682
682
683 683 with tt.AssertPrints("9"):
684 684 ip.run_cell("amacro")
685 685 with tt.AssertPrints("8"):
@@ -697,37 +697,37 b' class TestAstTransform2(unittest.TestCase):'
697 697 def setUp(self):
698 698 self.intwrapper = IntegerWrapper()
699 699 ip.ast_transformers.append(self.intwrapper)
700
700
701 701 self.calls = []
702 702 def Integer(*args):
703 703 self.calls.append(args)
704 704 return args
705 705 ip.push({"Integer": Integer})
706
706
707 707 def tearDown(self):
708 708 ip.ast_transformers.remove(self.intwrapper)
709 709 del ip.user_ns['Integer']
710
710
711 711 def test_run_cell(self):
712 712 ip.run_cell("n = 2")
713 713 self.assertEqual(self.calls, [(2,)])
714
714
715 715 # This shouldn't throw an error
716 716 ip.run_cell("o = 2.0")
717 717 self.assertEqual(ip.user_ns['o'], 2.0)
718
718
719 719 def test_timeit(self):
720 720 called = set()
721 721 def f(x):
722 722 called.add(x)
723 723 ip.push({'f':f})
724
725 with tt.AssertPrints("best of "):
724
725 with tt.AssertPrints("average of "):
726 726 ip.run_line_magic("timeit", "-n1 f(1)")
727 727 self.assertEqual(called, {(1,)})
728 728 called.clear()
729
730 with tt.AssertPrints("best of "):
729
730 with tt.AssertPrints("average of "):
731 731 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
732 732 self.assertEqual(called, {(2,), (3,)})
733 733
@@ -740,10 +740,10 b' class TestAstTransformError(unittest.TestCase):'
740 740 def test_unregistering(self):
741 741 err_transformer = ErrorTransformer()
742 742 ip.ast_transformers.append(err_transformer)
743
743
744 744 with tt.AssertPrints("unregister", channel='stderr'):
745 745 ip.run_cell("1 + 2")
746
746
747 747 # This should have been removed.
748 748 nt.assert_not_in(err_transformer, ip.ast_transformers)
749 749
@@ -792,18 +792,18 b' def test__IPYTHON__():'
792 792 class DummyRepr(object):
793 793 def __repr__(self):
794 794 return "DummyRepr"
795
795
796 796 def _repr_html_(self):
797 797 return "<b>dummy</b>"
798
798
799 799 def _repr_javascript_(self):
800 800 return "console.log('hi');", {'key': 'value'}
801
801
802 802
803 803 def test_user_variables():
804 804 # enable all formatters
805 805 ip.display_formatter.active_types = ip.display_formatter.format_types
806
806
807 807 ip.user_ns['dummy'] = d = DummyRepr()
808 808 keys = {'dummy', 'doesnotexist'}
809 809 r = ip.user_expressions({ key:key for key in keys})
@@ -818,14 +818,14 b' def test_user_variables():'
818 818 js, jsmd = d._repr_javascript_()
819 819 nt.assert_equal(data.get('application/javascript'), js)
820 820 nt.assert_equal(metadata.get('application/javascript'), jsmd)
821
821
822 822 dne = r['doesnotexist']
823 823 nt.assert_equal(dne['status'], 'error')
824 824 nt.assert_equal(dne['ename'], 'NameError')
825
825
826 826 # back to text only
827 827 ip.display_formatter.active_types = ['text/plain']
828
828
829 829 def test_user_expression():
830 830 # enable all formatters
831 831 ip.display_formatter.active_types = ip.display_formatter.format_types
@@ -843,14 +843,14 b' def test_user_expression():'
843 843 data = a['data']
844 844 metadata = a['metadata']
845 845 nt.assert_equal(data.get('text/plain'), '3')
846
846
847 847 b = r['b']
848 848 nt.assert_equal(b['status'], 'error')
849 849 nt.assert_equal(b['ename'], 'ZeroDivisionError')
850
850
851 851 # back to text only
852 852 ip.display_formatter.active_types = ['text/plain']
853
853
854 854
855 855
856 856
General Comments 0
You need to be logged in to leave comments. Login now