No practical purpose, just curious. For PythonCall in Julia code, it’s easy to imagine that a Julia wrapper increments an underlying CPython object’s reference count to protect it from CPython’s GC (I don’t know if this is actually true, so please correct me). But I can’t imagine how juliacall in Python code can protect underlying Julia objects from Julia’s GC when there isn’t an explicit Julia program to start tracing from. Is there a hidden juliacall cache of Julia objects somewhere, and if so can I get a link to its implementation?
Here it is: PythonCall.jl/src/JlWrap/C.jl at 71666ca0a30eafee2456a191fa2490cdd0b0ed22 · JuliaPy/PythonCall.jl · GitHub
Pretty simple really, we keep a global vector containing all of the wrapped Julia values and the Python wrapper just holds the index into this vector.
And when the Python wrapper is deleted, the corresponding entry in the vector is set to nothing so the wrapped value can be GC’d.
Am I assuming correctly this vector is mutated by __del__ finalization? source link for juliacall.AnyValue on the docs site doesn’t take me to a .py file, weirdly a directory in the base Julia Github.
The type is implemented in Julia not Python, and the __del__ implementation is just a few lines down, here: PythonCall.jl/src/JlWrap/C.jl at 71666ca0a30eafee2456a191fa2490cdd0b0ed22 · JuliaPy/PythonCall.jl · GitHub
As for the link in the docs - we have some hacky shenanigans to document Python things using Documenter.jl so I’m not surprised that’s broken.