I want to get feedback on an API for ergonomically passing Python variables to Julia code via juliacall. Here are a couple of ideas:
from juliacall import Main as jl
# proposal
jl.teval("const MY_CONST = $(x)", x=my_python_const)
a “template” eval, or
# proposal
with jl.let(x=my_python_const):
jl.seval("const MY_CONST = x")
which is a juliacall “let.”
This is designed to address the following issue. Currently, passing Python objects to Julia via seval
requires creating closure functions:
# already works
jl.seval("x -> @eval const MY_CONST = $x")(my_python_const)
While Python’s PEP 750 proposes Template Strings which could offer one solution:
# proposal
jl.seval(t"const MY_CONST = {my_python_const}")
We could implement something similar with a new teval
method:
# proposal
jl.teval("const MY_CONST = {my_python_const}")
However, this has two key issues:
- The
{}
syntax conflicts with Julia type signatures (e.g.,Vector{Float64}
), which could cause subtle bugs. Even if t-strings are eventually merged to Python, we would still face this issue! teval
wouldn’t have access to local variables to referencemy_python_const
Now, here are the two proposed approaches. The first is similar to Python’s .format
method, but with {} -> $()
to avoid conflicts.
# proposal
jl.teval("const MY_CONST = $(x)", x=my_python_const)
The second approach uses a context manager for temporary variable binding:
# proposal
with jl.let(x=my_python_const):
jl.seval("const MY_CONST = x")
Basically the seval
would have access to a stack of Python objects pushed via juliacall.let
, and put them into the Julia context via a Julia-evaluated let
statement.
Thoughts?
(I wanted to get broader feedback so am cross-posting this PythonCall.jl/juliacall issue here)