JuliaPy / PythonCall.jl

Python and Julia in harmony.
https://juliapy.github.io/PythonCall.jl/stable/
MIT License
817 stars 66 forks source link

Error for code with PythonCall that works with PyCall #576

Open karlwessel opened 2 days ago

karlwessel commented 2 days ago

Affects: PythonCall

Describe the bug The following code throws an error:

using PythonCall
np = pyimport("numpy")
d3 = pyimport("dedalus.public")
coords = d3.CartesianCoordinates("x")
dist = d3.Distributor(coords, dtype=np.float64)
xbasis = d3.RealFourier(coords["x"], size=16, bounds=(0,1))
B = dist.VectorField(coords, name="B", bases=(xbasis))
problem = d3.IVP([B])

problem.add_equation(pytuple((d3.dt(B) - d3.Laplacian(B), 0)))

ERROR: Python: Julia: TypeError: non-boolean (Py) used in boolean context
Stacktrace:
  [1] in
    @ ./operators.jl:1309 [inlined]
  [2] pyjlany_contains(self::Vector{Py}, v::Py)
    @ PythonCall.JlWrap ~/.julia/packages/PythonCall/Nr75f/src/JlWrap/any.jl:117
  [3] _pyjl_callmethod(f::Any, self_::Ptr{PythonCall.C.PyObject}, args_::Ptr{PythonCall.C.PyObject}, nargs::Int64)
    @ PythonCall.JlWrap ~/.julia/packages/PythonCall/Nr75f/src/JlWrap/base.jl:67
  [4] _pyjl_callmethod(o::Ptr{PythonCall.C.PyObject}, args::Ptr{PythonCall.C.PyObject})
    @ PythonCall.JlWrap.Cjl ~/.julia/packages/PythonCall/Nr75f/src/JlWrap/C.jl:63
  [5] PyObject_CallObject
    @ ~/.julia/packages/PythonCall/Nr75f/src/C/pointers.jl:303 [inlined]
  [6] macro expansion
    @ ~/.julia/packages/PythonCall/Nr75f/src/Core/Py.jl:132 [inlined]
  [7] pycallargs(f::Py, args::Py)
    @ PythonCall.Core ~/.julia/packages/PythonCall/Nr75f/src/Core/builtins.jl:220
  [8] pycall(::Py, ::Py, ::Vararg{Py}; kwargs::@Kwargs{})
    @ PythonCall.Core ~/.julia/packages/PythonCall/Nr75f/src/Core/builtins.jl:243
  [9] pycall(::Py, ::Py, ::Vararg{Py})
    @ PythonCall.Core ~/.julia/packages/PythonCall/Nr75f/src/Core/builtins.jl:233
 [10] (::Py)(::Py, ::Vararg{Py}; kwargs::@Kwargs{})
    @ PythonCall.Core ~/.julia/packages/PythonCall/Nr75f/src/Core/Py.jl:357
 [11] top-level scope
    @ REPL[13]:1
 [12] eval
    @ ./boot.jl:430 [inlined]
 [13] eval_user_input(ast::Any, backend::REPL.REPLBackend, mod::Module)
    @ REPL ~/.julia/juliaup/julia-1.11.1+0.x64.linux.gnu/share/julia/stdlib/v1.11/REPL/src/REPL.jl:245
 [14] repl_backend_loop(backend::REPL.REPLBackend, get_module::Function)
    @ REPL ~/.julia/juliaup/julia-1.11.1+0.x64.linux.gnu/share/julia/stdlib/v1.11/REPL/src/REPL.jl:342
 [15] start_repl_backend(backend::REPL.REPLBackend, consumer::Any; get_module::Function)
    @ REPL ~/.julia/juliaup/julia-1.11.1+0.x64.linux.gnu/share/julia/stdlib/v1.11/REPL/src/REPL.jl:327
 [16] run_repl(repl::REPL.AbstractREPL, consumer::Any; backend_on_current_task::Bool, backend::Any)
    @ REPL ~/.julia/juliaup/julia-1.11.1+0.x64.linux.gnu/share/julia/stdlib/v1.11/REPL/src/REPL.jl:483
 [17] run_repl(repl::REPL.AbstractREPL, consumer::Any)
    @ REPL ~/.julia/juliaup/julia-1.11.1+0.x64.linux.gnu/share/julia/stdlib/v1.11/REPL/src/REPL.jl:469
 [18] (::Base.var"#1139#1141"{Bool, Symbol, Bool})(REPL::Module)
    @ Base ./client.jl:446
 [19] #invokelatest#2
    @ ./essentials.jl:1055 [inlined]
 [20] invokelatest
    @ ./essentials.jl:1052 [inlined]
 [21] run_main_repl(interactive::Bool, quiet::Bool, banner::Symbol, history_file::Bool, color_set::Bool)
    @ Base ./client.jl:430
 [22] repl_main
    @ ./client.jl:567 [inlined]
 [23] _start()
    @ Base ./client.jl:541
Python stacktrace:
 [1] __contains__
   @ ~/.julia/packages/PythonCall/Nr75f/src/JlWrap/any.jl:274
 [2] prep_nccs
   @ dedalus.core.field ~/recalcfinke/.CondaPkg/env/lib/python3.11/site-packages/dedalus/core/field.py:374
 [3] _build_matrix_expressions
   @ dedalus.core.problems ~/recalcfinke/.CondaPkg/env/lib/python3.11/site-packages/dedalus/core/problems.py:331
 [4] add_equation
   @ dedalus.core.problems ~/recalcfinke/.CondaPkg/env/lib/python3.11/site-packages/dedalus/core/problems.py:92
Stacktrace:
 [1] pythrow()
   @ PythonCall.Core ~/.julia/packages/PythonCall/Nr75f/src/Core/err.jl:92
 [2] errcheck
   @ ~/.julia/packages/PythonCall/Nr75f/src/Core/err.jl:10 [inlined]
 [3] pycallargs(f::Py, args::Py)
   @ PythonCall.Core ~/.julia/packages/PythonCall/Nr75f/src/Core/builtins.jl:220
 [4] pycall(::Py, ::Py, ::Vararg{Py}; kwargs::@Kwargs{})
   @ PythonCall.Core ~/.julia/packages/PythonCall/Nr75f/src/Core/builtins.jl:243
 [5] pycall(::Py, ::Py, ::Vararg{Py})
   @ PythonCall.Core ~/.julia/packages/PythonCall/Nr75f/src/Core/builtins.jl:233
 [6] (::Py)(::Py, ::Vararg{Py}; kwargs::@Kwargs{})
   @ PythonCall.Core ~/.julia/packages/PythonCall/Nr75f/src/Core/Py.jl:357
 [7] top-level scope
   @ REPL[13]:1

The same works when using PyCall:

using PyCall
np = pyimport("numpy")
d3 = pyimport("dedalus.public")
coords = d3.CartesianCoordinates("x")
dist = d3.Distributor(coords, dtype=np.float64)
xbasis = d3.RealFourier(get(coords, "x"), size=16, bounds=(0,1))
B = dist.VectorField(coords, name="B", bases=(xbasis))
problem = d3.IVP([B])

problem.add_equation((d3.dt(B) - d3.Laplacian(B), 0))

Your system

Pkg.status() Status /tmp/jl_zARGID/Project.toml [992eb4ea] CondaPkg v0.2.24 [6099a3de] PythonCall v0.9.23

CondaPkg.status() CondaPkg Status /tmp/jl_zARGID/CondaPkg.toml Environment /tmp/jl_zARGID/.CondaPkg/env Packages dedalus v3.0.3



**Additional context**
The MWE assumes that the python library `dedalus` is installed (using `CondaPkg` or `Conda` respectively).
Sorry for the rather large MWE, but I think that is the minimal sensible working setup of the project.
cjdoris commented 1 day ago

My guess is you want

problem = d3.IVP(pylist([B]))
karlwessel commented 19 hours ago

Yes, you are right, thank you! How did you spot this? Is this documented somewhere so I can read it up and spot it myself the next time?