27
27
from IPython .core import interactiveshell
28
28
from IPython .core .oinspect import OInfo
29
29
from IPython .testing .decorators import (
30
- skipif , skip_win32 , onlyif_unicode_paths , onlyif_cmds_exist ,
30
+ skipif ,
31
+ skip_win32 ,
32
+ onlyif_unicode_paths ,
33
+ onlyif_cmds_exist ,
34
+ skip_if_not_osx ,
31
35
)
32
36
from IPython .testing import tools as tt
33
37
from IPython .utils .process import find_cmd
@@ -124,16 +128,16 @@ def test_In_variable(self):
124
128
newlen = len (ip .user_ns ['In' ])
125
129
self .assertEqual (oldlen + 1 , newlen )
126
130
self .assertEqual (ip .user_ns ['In' ][- 1 ],'1;' )
127
-
131
+
128
132
def test_magic_names_in_string (self ):
129
133
ip .run_cell ('a = """\n %exit\n """' )
130
134
self .assertEqual (ip .user_ns ['a' ], '\n %exit\n ' )
131
-
135
+
132
136
def test_trailing_newline (self ):
133
137
"""test that running !(command) does not raise a SyntaxError"""
134
138
ip .run_cell ('!(true)\n ' , False )
135
139
ip .run_cell ('!(true)\n \n \n ' , False )
136
-
140
+
137
141
def test_gh_597 (self ):
138
142
"""Pretty-printing lists of objects with non-ascii reprs may cause
139
143
problems."""
@@ -142,8 +146,7 @@ def __repr__(self):
142
146
return "\xe9 " * 50
143
147
import IPython .core .formatters
144
148
f = IPython .core .formatters .PlainTextFormatter ()
145
- f ([Spam (),Spam ()])
146
-
149
+ f ([Spam (), Spam ()])
147
150
148
151
def test_future_flags (self ):
149
152
"""Check that future flags are used for parsing code (gh-777)"""
@@ -163,9 +166,9 @@ def test_can_pickle(self):
163
166
" def __init__(self,x=[]):\n "
164
167
" list.__init__(self,x)" ))
165
168
ip .run_cell ("w=Mylist([1,2,3])" )
166
-
169
+
167
170
from pickle import dumps
168
-
171
+
169
172
# We need to swap in our main module - this is only necessary
170
173
# inside the test framework, because IPython puts the interactive module
171
174
# in place (but the test framework undoes this).
@@ -176,7 +179,7 @@ def test_can_pickle(self):
176
179
finally :
177
180
sys .modules ['__main__' ] = _main
178
181
self .assertTrue (isinstance (res , bytes ))
179
-
182
+
180
183
def test_global_ns (self ):
181
184
"Code in functions must be able to access variables outside them."
182
185
ip = get_ipython ()
@@ -222,13 +225,13 @@ def test_var_expand(self):
222
225
self .assertEqual (ip .var_expand (u'echo {f}' ), u'echo Ca\xf1 o' )
223
226
self .assertEqual (ip .var_expand (u'echo {f[:-1]}' ), u'echo Ca\xf1 ' )
224
227
self .assertEqual (ip .var_expand (u'echo {1*2}' ), u'echo 2' )
225
-
228
+
226
229
self .assertEqual (ip .var_expand (u"grep x | awk '{print $1}'" ), u"grep x | awk '{print $1}'" )
227
230
228
231
ip .user_ns ['f' ] = b'Ca\xc3 \xb1 o'
229
232
# This should not raise any exception:
230
233
ip .var_expand (u'echo $f' )
231
-
234
+
232
235
def test_var_expand_local (self ):
233
236
"""Test local variable expansion in !system and %magic calls"""
234
237
# !system
@@ -253,7 +256,7 @@ def test_var_expand_local(self):
253
256
254
257
def test_var_expand_self (self ):
255
258
"""Test variable expansion with the name 'self', which was failing.
256
-
259
+
257
260
See htt
F438
ps://github.com/ipython/ipython/issues/1878#issuecomment-7698218
258
261
"""
259
262
ip .run_cell (
@@ -273,20 +276,20 @@ def test_bad_var_expand(self):
273
276
self .assertEqual (ip .var_expand (u"{asdf}" ), u"{asdf}" )
274
277
# ZeroDivisionError
275
278
self .assertEqual (ip .var_expand (u"{1/0}" ), u"{1/0}" )
276
-
279
+
277
280
def test_silent_postexec (self ):
278
281
"""run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks"""
279
282
pre_explicit = mock .Mock ()
280
283
pre_always = mock .Mock ()
281
284
post_explicit = mock .Mock ()
282
285
post_always = mock .Mock ()
283
286
all_mocks = [pre_explicit , pre_always , post_explicit , post_always ]
284
-
287
+
285
288
ip .events .register ('pre_run_cell' , pre_explicit )
286
289
ip .events .register ('pre_execute' , pre_always )
287
290
ip .events .register ('post_run_cell' , post_explicit )
288
291
ip .events .register ('post_execute' , post_always )
289
-
292
+
290
293
try :
291
294
ip .run_cell ("1" , silent = True )
292
295
assert pre_always .called
@@ -317,29 +320,29 @@ def test_silent_postexec(self):
317
320
ip .events .unregister ('pre_execute' , pre_always )
318
321
ip .events .unregister ('post_run_cell' , post_explicit )
319
322
ip .events .unregister ('post_execute' , post_always )
320
-
323
+
321
324
def test_silent_noadvance (self ):
322
325
"""run_cell(silent=True) doesn't advance execution_count"""
323
326
ec = ip .execution_count
324
327
# silent should force store_history=False
325
328
ip .run_cell ("1" , store_history = True , silent = True )
326
-
329
+
327
330
self .assertEqual (ec , ip .execution_count )
328
331
# double-check that non-silent exec did what we expected
329
332
# silent to avoid
330
333
ip .run_cell ("1" , store_history = True )
331
334
self .assertEqual (ec + 1 , ip .execution_count )
332
-
335
+
333
336
def test_silent_nodisplayhook (self ):
334
337
"""run_cell(silent=True) doesn't trigger displayhook"""
335
338
d = dict (called = False )
336
-
339
+
337
340
trap = ip .display_trap
338
341
save_hook = trap .hook
339
-
342
+
340
343
def failing_hook (* args , ** kwargs ):
341
344
d ['called' ] = True
342
-
345
+
343
346
try :
344
347
trap .hook = failing_hook
345
348
res = ip .run_cell ("1" , silent = True )
@@ -354,7 +357,7 @@ def failing_hook(*args, **kwargs):
354
357
355
358
def test_ofind_line_magic (self ):
356
359
from IPython .core .magic import register_line_magic
357
-
360
+
358
361
@register_line_magic
359
362
def lmagic (line ):
360
363
"A line magic"
@@ -370,10 +373,10 @@ def lmagic(line):
370
373
parent = None ,
371
374
)
372
375
self .assertEqual (lfind , info )
373
-
376
+
374
377
def test_ofind_cell_magic (self ):
375
378
from IPython .core .magic import register_cell_magic
376
-
379
+
377
380
@register_cell_magic
378
381
def cmagic (line , cell ):
379
382
"A cell magic"
@@ -490,7 +493,7 @@ def test_custom_exception(self):
490
493
def my_handler (shell , etype , value , tb , tb_offset = None ):
491
494
called .append (etype )
492
495
shell .showtraceback ((etype , value , tb ), tb_offset = tb_offset )
493
-
496
+
494
497
ip .set_custom_exc ((ValueError ,), my_handler )
495
498
try :
496
499
res = ip .run_cell ("raise ValueError('test')" )
@@ -501,7 +504,7 @@ def my_handler(shell, etype, value, tb, tb_offset=None):
501
504
finally :
502
505
# Reset the custom exception hook
503
506
ip .set_custom_exc ((), None )
504
-
507
+
505
508
@mock .patch ("builtins.print" )
506
509
def test_showtraceback_with_surrogates (self , mocked_print ):
507
510
values = []
@@ -618,15 +621,15 @@ def test_exit_code_ok(self):
618
621
def test_exit_code_error (self ):
619
622
self .system ('exit 1' )
620
623
self .assertEqual (ip .user_ns ['_exit_code' ], 1 )
621
-
624
+
622
625
@skipif (not hasattr (signal , 'SIGALRM' ))
623
626
def test_exit_code_signal (self ):
624
627
self .mktmp ("import signal, time\n "
625
628
"signal.setitimer(signal.ITIMER_REAL, 0.1)\n "
626
629
"time.sleep(1)\n " )
627
630
self .system ("%s %s" % (sys .executable , self .fname ))
628
631
self .assertEqual (ip .user_ns ['_exit_code' ], - signal .SIGALRM )
629
-
632
+
630
633
@onlyif_cmds_exist ("csh" )
631
634
def test_exit_code_signal_csh (self ): # pragma: no cover
632
635
SHELL = os .environ .get ("SHELL" , None )
@@ -730,7 +733,7 @@ class TestAstTransform(unittest.TestCase):
730
733
def setUp (self ):
731
734
self .negator = Negator ()
732
735
ip .ast_transformers .append (self .negator )
733
-
736
+
734
737
def tearDown (self ):
735
738
ip .ast_transformers .remove (self .negator )
736
739
@@ -752,7 +755,7 @@ def test_timeit(self):
752
755
def f (x ):
753
756
called .add (x )
754
757
ip .push ({'f' :f })
755
-
758
+
756
759
with tt .AssertPrints ("std. dev. of" ):
757
760
ip .run_lin
F438
e_magic ("timeit" , "-n1 f(1)" )
758
761
self .assertEqual (called , {- 1 })
@@ -761,29 +764,29 @@ def f(x):
761
764
with tt .AssertPrints ("std. dev. of" ):
762
765
ip .run_cell_magic ("timeit" , "-n1 f(2)" , "f(3)" )
763
766
self .assertEqual (called , {- 2 , - 3 })
764
-
767
+
765
768
def test_time (self ):
766
769
called = []
767
770
def f (x ):
768
771
called .append (x )
769
772
ip .push ({'f' :f })
770
-
773
+
771
774
# Test with an expression
772
775
with tt .AssertPrints ("Wall time: " ):
773
776
ip .run_line_magic ("time" , "f(5+9)" )
774
777
self .assertEqual (called , [- 14 ])
775
778
called [:] = []
776
-
779
+
777
780
# Test with a statement (different code path)
778
781
with tt .AssertPrints ("Wall time: " ):
779
782
ip .run_line_magic ("time" , "a = f(-3 + -2)" )
780
783
self .assertEqual (called , [5 ])
781
-
784
+
782
785
def test_macro (self ):
783
786
ip .push ({'a' :10 })
784
787
# The AST transformation makes this do a+=-1
785
788
ip .define_macro ("amacro" , "a+=1\n print(a)" )
786
-
789
+
787
790
with tt .AssertPrints ("9" ):
788
791
ip .run_cell ("amacro" )
789
792
with tt .AssertPrints ("8" ):
@@ -836,21 +839,21 @@ class TestAstTransform2(unittest.TestCase):
836
839
def setUp (self ):
837
840
self .intwrapper = IntegerWrapper ()
838
841
ip .ast_transformers .append (self .intwrapper )
839
-
842
+
840
843
self .calls = []
841
844
def Integer (* args ):
842
845
self .calls .append (args )
843
846
return args
844
847
ip .push ({"Integer" : Integer })
845
-
848
+
846
849
def tearDown (self ):
847
850
ip .ast_transformers .remove (self .intwrapper )
848
851
del ip .user_ns ['Integer' ]
849
-
852
+
850
853
def test_run_cell (self ):
851
854
ip .run_cell ("n = 2" )
852
855
self .assertEqual (self .calls , [(2 ,)])
853
-
856
+
854
857
# This shouldn't throw an error
855
858
ip .run_cell ("o = 2.0" )
856
859
self .assertEqual (ip .user_ns ['o' ], 2.0 )
@@ -887,10 +890,10 @@ class TestAstTransformError(unittest.TestCase):
887
890
def test_unregistering (self ):
888
891
err_transformer = ErrorTransformer ()
889
892
ip .ast_transformers .append (err_transformer )
890
-
893
+
891
894
with self .assertWarnsRegex (UserWarning , "It will be unregistered" ):
892
895
ip .run_cell ("1 + 2" )
893
-
896
+
894
897
# This should have been removed.
895
898
self .assertNotIn (err_transformer , ip .ast_transformers )
896
899
@@ -901,7 +904,7 @@ class StringRejector(ast.NodeTransformer):
901
904
Used to verify that NodeTransformers can signal that a piece of code should
902
905
not be executed by throwing an InputRejected.
903
906
"""
904
-
907
+
905
908
def visit_Constant (self , node ):
906
909
if isinstance (node .value , str ):
907
910
raise InputRejected ("test" )
@@ -941,18 +944,18 @@ def test__IPYTHON__():
941
944
class DummyRepr (object ):
942
945
def __repr__ (self ):
943
946
return "DummyRepr"
944
-
947
+
945
948
def _repr_html_ (self ):
946
949
return "<b>dummy</b>"
947
-
950
+
948
951
def _repr_javascript_ (self ):
949
952
return "console.log('hi');" , {'key' : 'value' }
950
-
953
+
951
954
952
955
def test_user_variables ():
953
956
# enable all formatters
954
957
ip .display_formatter .active_types = ip .display_formatter .format_types
955
-
958
+
956
959
ip .user_ns ['dummy' ] = d = DummyRepr ()
957
960
keys = {'dummy' , 'doesnotexist' }
958
961
r = ip .user_expressions ({ key :key for key in keys })
@@ -974,7 +977,7 @@ def test_user_variables():
974
977
975
978
# back to text only
976
979
ip .display_formatter .active_types = ['text/plain' ]
977
-
980
+
978
981
def test_user_expression ():
979
982
# enable all formatters
980
983
ip .display_formatter .active_types = ip .display_formatter .format_types
@@ -1199,3 +1202,20 @@ def test_set_show_tracebacks_noop(self):
1199
1202
assert result .result is None
1200
1203
assert isinstance (result .error_in_exec , AssertionError )
1201
1204
assert str (result .error_in_exec ) == "This should not raise an exception"
1205
+
1206
+
1207
+ @skip_if_not_osx
1208
+ def test_enable_gui_osx ():
1209
+ simple_prompt = ip .simple_prompt
1210
+ ip .simple_prompt = False
1211
+
1212
+ ip .enable_gui ("osx" )
1213
+ assert ip .active_eventloop == "osx"
1214
+ ip .enable_gui ()
1215
+
1216
+ # The following line fails for IPython <= 8.25.0
1217
+ ip .enable_gui ("macosx" )
1218
+ assert ip .active_eventloop == "osx"
1219
+ ip .enable_gui ()
1220
+
1221
+ ip .simple_prompt = simple_prompt
0 commit comments