33Being experimental, it does not form part of the JuliaCall API. It may be changed or removed
44in any release.
55
6- Enable the extension by calling the magic '%load_ext juliacall.ipython '.
6+ Enable the extension by calling the magic '%load_ext juliacall'.
77
88Features:
99- Magic `%julia code` to evaluate a piece of Julia code in-line.
1717import __main__
1818
1919_set_var = Main .seval ("(k, v) -> @eval $(Symbol(k)) = $v" )
20- _get_var = Main .seval ("k -> @eval $(Symbol(k))" )
20+ _get_var = Main .seval ("k -> hasproperty(Main, Symbol(k)) ? PythonCall.pyjlraw(getproperty(Main, Symbol(k))) : nothing" )
21+ _egal = Main .seval ("===" )
2122
2223@magics_class
2324class JuliaMagics (Magics ):
2425
2526 @line_cell_magic
2627 def julia (self , line , cell = None ):
28+ # parse the line and cell into code and variables
2729 invars = []
2830 outvars = []
31+ syncvars = []
2932 if cell is None :
3033 code = line
3134 else :
@@ -36,15 +39,28 @@ def julia(self, line, cell=None):
3639 elif k .startswith ('>' ):
3740 outvars .append (k [1 :])
3841 else :
39- invars .append (k )
40- outvars .append (k )
41- for k in invars :
42+ syncvars .append (k )
43+ # copy variables to Julia
44+ # keep a cache of variables we may want to copy out again
45+ cachevars = {}
46+ for k in invars + syncvars :
4247 if k in __main__ .__dict__ :
4348 _set_var (k , __main__ .__dict__ [k ])
49+ if k in syncvars :
50+ cachevars [k ] = _get_var (k )
51+ # run the code
4452 ans = Main .seval ('begin\n ' + code + '\n end' )
53+ # flush stderr/stdout
4554 PythonCall ._flush_stdio ()
46- for k in outvars :
47- __main__ .__dict__ [k ] = _get_var (k )
55+ # copy variables back to Python
56+ # only copy those which are new or have changed value
57+ for k in outvars + syncvars :
58+ v0 = cachevars .get (k )
59+ v1 = _get_var (k )
60+ if v1 is not None and (v0 is None or not _egal (v0 , v1 )):
61+ print (k )
62+ __main__ .__dict__ [k ] = v1 ._jl_any ()
63+ # return the value unless suppressed with trailing ";"
4864 if not code .strip ().endswith (';' ):
4965 return ans
5066
@@ -84,6 +100,3 @@ def load_ipython_extension(ip):
84100 pushdisplay(IPythonDisplay())
85101 nothing
86102 end""" )
87-
88- def unload_ipython_extension (ip ):
89- pass
0 commit comments