# How does JuliaCall (PythonCall) protect Julia objects in Python code from Julia's GC?

**URL:** <https://discourse.julialang.org/t/how-does-juliacall-pythoncall-protect-julia-objects-in-python-code-from-julias-gc/132836>\
**Category:** General Usage\
**Tags:** interoperability, garbage-collection\
**Created:** [October 2, 2025, 10:12pm UTC](https://discourse.julialang.org/t/how-does-juliacall-pythoncall-protect-julia-objects-in-python-code-from-julias-gc/132836 "2025-10-02T22:12:50Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [October 2, 2025, 10:12pm UTC](https://discourse.julialang.org/t/how-does-juliacall-pythoncall-protect-julia-objects-in-python-code-from-julias-gc/132836/1 "2025-10-02T22:12:51Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [October 3, 2025, 7:22am UTC](https://discourse.julialang.org/t/how-does-juliacall-pythoncall-protect-julia-objects-in-python-code-from-julias-gc/132836/2 "2025-10-03T07:22:56Z")

</div>

Here it is: [PythonCall.jl/src/JlWrap/C.jl at 71666ca0a30eafee2456a191fa2490cdd0b0ed22 · JuliaPy/PythonCall.jl · GitHub](https://github.com/JuliaPy/PythonCall.jl/blob/71666ca0a30eafee2456a191fa2490cdd0b0ed22/src/JlWrap/C.jl#L17)

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.

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [October 3, 2025, 7:24am UTC](https://discourse.julialang.org/t/how-does-juliacall-pythoncall-protect-julia-objects-in-python-code-from-julias-gc/132836/3 "2025-10-03T07:24:36Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [October 3, 2025, 8:29pm UTC](https://discourse.julialang.org/t/how-does-juliacall-pythoncall-protect-julia-objects-in-python-code-from-julias-gc/132836/4 "2025-10-03T20:29:58Z")

</div>

> [@cjdoris](#):
>
> when the Python wrapper is deleted, the corresponding entry in the vector is set to `nothing`

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.

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [October 4, 2025, 11:16am UTC](https://discourse.julialang.org/t/how-does-juliacall-pythoncall-protect-julia-objects-in-python-code-from-julias-gc/132836/5 "2025-10-04T11:16:43Z")

</div>

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](https://github.com/JuliaPy/PythonCall.jl/blob/71666ca0a30eafee2456a191fa2490cdd0b0ed22/src/JlWrap/C.jl#L31)

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.
