diff --git a/src/pyeval.jl b/src/pyeval.jl index 4eca19d5..4264433e 100644 --- a/src/pyeval.jl +++ b/src/pyeval.jl @@ -77,10 +77,6 @@ function pyeval(s::AbstractString, returntype::TypeTuple=PyAny, return convert(returntype, pyeval_(s, pynamespace(Main), locals, input_type)) end -# get filename from @__FILE__ macro, which returns nothing in the REPL -make_fname(fname::AbstractString) = String(fname) -make_fname(fname::Any) = "REPL" - # a little finite-state-machine dictionary to keep track of where # we are in Python code, since $ is ignored in string literals and comments. # 'p' = Python code, '#' = comment, '$' = Julia interpolation @@ -202,14 +198,19 @@ pasted into the Python code. This allows you to evaluate code where the code itself is generated by a Julia expression. """ macro py_str(code, options...) + m = :(pynamespace($__module__)) + fname = String(__source__.file) + esc(:(PyCall.@_py_str($m, $m, $fname, $code, $(options...)))) +end + +macro _py_str(pyglobals, pylocals, fname, code, options...) T = length(options) == 1 && 'o' in options[1] ? PyObject : PyAny code, locals = interpolate_pycode(code) input_type = '\n' in code ? Py_file_input : Py_eval_input - fname = make_fname(@__FILE__) assignlocals = Expr(:block, [(isa(v,String) ? - :(m[$v] = PyObject($(esc(ex)))) : + :(pylocals[$v] = PyObject($(esc(ex)))) : nothing) for (v,ex) in locals]...) - code_expr = Expr(:call, esc(:(Base.string))) + code_expr = Expr(:call, Base.string) i0 = firstindex(code) for i in sort!(collect(filter(k -> isa(k,Integer), keys(locals)))) push!(code_expr.args, code[i0:prevind(code,i)], esc(locals[i])) @@ -217,7 +218,7 @@ macro py_str(code, options...) end push!(code_expr.args, code[i0:lastindex(code)]) if input_type == Py_eval_input - removelocals = Expr(:block, [:(delete!(m, $v)) for v in keys(locals)]...) + removelocals = Expr(:block, [:(delete!(pylocals, $v)) for v in keys(locals)]...) else # if we are evaluating multi-line input, then it is not # safe to remove the local variables, because they might be referred @@ -225,9 +226,9 @@ macro py_str(code, options...) removelocals = nothing end quote - m = pynamespace($__module__) + pyglobals, pylocals = $pyglobals, $pylocals $assignlocals - ret = $T(pyeval_($code_expr, m, m, $input_type, $fname)) + ret = $T(pyeval_($code_expr, pyglobals, pylocals, $input_type, $fname)) $removelocals ret end