JuliaPy / JuliaPy/PythonCall.jl

Segmentation fault when registering Julia-defined Python class with Matplotlib

未关闭
#289 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
Julia
星标
1.1k
派生
86
平均合并
1 天 22 小时
30 天内合并 PR
3

描述

I have implemented a custom axis transform [according to the documentation](https://matplotlib.org/stable/api/transformations.html):

```julia
SqrtTransform = pytype("SqrtTransform", (matplotlib.transforms.Transform,), [
"__module__" => "__main__",
pyfunc(name="__init__",
function (self)
self.input_dims = 1
self.output_dims = 1
self.is_separable = true
self.has_inverse = true
matplotlib.transforms.Transform.__init__(self)
end),
pyfunc(name="transform_non_affine",
function(self, a)
b = pyconvert(Array, a)
v = similar(b)
sel = b .>= 0
v[sel] .= .√(b[sel])
# v[.!sel] .= NaN
v
end),
pyfunc(name="inverted",
(self) -> SquareTransform())
])

SquareTransform = pytype("SquareTransform", (matplotlib.transforms.Transform,), [
"__module__" => "__main__",
pyfunc(name="__init__",
function (self)
self.input_dims = 1
self.output_dims = 1
self.is_separable = true
self.has_inverse = true
matplotlib.transforms.Transform.__init__(self)
end),
pyfunc(name="transform_non_affine",
function(self, a)
pyconvert(Array, a) .^ 2
end),
pyfunc(name="inverted",
(self) -> SqrtTransform())
])

SqrtScale = pytype("SqrtScale", (matplotlib.scale.ScaleBase,), [
"__module__" => "__main__",
"name" => "sqrt",
pyfunc(name="__init__",
function(self, axis, args...; kwargs...)
matplotlib.scale.ScaleBase.__init__(self, axis)
end),
pyfunc(name="get_transform",
(self) -> SqrtTransform()),
pyfunc(name="set_default_locators_and_formatters",
(self, axis) -> nothing),
pyfunc(name="limit_range_for_scale",
function(self, vmin, vmax, minpos)
max(vmin, 0), max(vmax, 0)
end)])
```

To register this with Matplotlib, one uses
```julia
matplotlib.scale.register_scale(SqrtScale)
```

This works well from a script, but not if I try to put it into a package. If I just put the line registering the transform with Matplotlib after the class definitions, nothing happens, i.e. Matplotlib does not in fact register the new transform. If I instead try to register it from `__init__()`, or from the REPL after having loaded the package, it crashes with the following trace:

```julia
signal (11): Segmentation fault: 11
in expression starting at REPL[4]:1
_PyFunction_Vectorcall at /Users/jagot/work/projects/move-to-pythoncall/.CondaPkg/env/lib/libpython3.11.dylib (unknown line)
PyObject_CallObject at /Users/jagot/.julia/packages/PythonCall/dsECZ/src/cpython/pointers.jl:299 [inlined]
pycallargs at /Users/jagot/.julia/packages/PythonCall/dsECZ/src/abstract/object.jl:210
unknown function (ip: 0x10ce5a8e6)
ijl_apply_generic at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
#pycall#59 at /Users/jagot/.julia/packages/PythonCall/dsECZ/src/abstract/object.jl:228
ijl_apply_generic at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
do_apply at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
pycall at /Users/jagot/.julia/packages/PythonCall/dsECZ/src/abstract/object.jl:218
ijl_apply_generic at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
do_apply at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
#_#11 at /Users/jagot/.julia/packages/PythonCall/dsECZ/src/Py.jl:352
ijl_apply_generic at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
do_apply at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
Py at /Users/jagot/.julia/packages/PythonCall/dsECZ/src/Py.jl:352
ijl_apply_generic at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
do_call at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
eval_body at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
jl_interpret_toplevel_thunk at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
jl_toplevel_eval_flex at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
jl_toplevel_eval_flex at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
jl_toplevel_eval_flex at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
ijl_toplevel_eval_in at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
eval at ./boot.jl:368 [inlined]
eval_user_input at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-5.0/build/default-macmini-x64-5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:151
repl_backend_loop at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-5.0/build/default-macmini-x64-5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:247
start_repl_backend at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-5.0/build/default-macmini-x64-5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:232
#run_repl#47 at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-5.0/build/default-macmini-x64-5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:369
run_repl at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-5.0/build/default-macmini-x64-5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:355
jfptr_run_repl_63566.clone_1 at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
#967 at ./client.jl:419
jfptr_YY.967_56999.clone_1 at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
jl_f__call_latest at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
#invokelatest#2 at ./essentials.jl:729 [inlined]
invokelatest at ./essentials.jl:726 [inlined]
run_main_repl at ./client.jl:404
exec_options at ./client.jl:318
_start at ./client.jl:522
jfptr__start_57423.clone_1 at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
true_main at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
jl_repl_entrypoint at /Users/jagot/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
Allocations: 19584391 (Pool: 19573667; Big: 10724); GC: 22
```

Environment:
```julia
Status `~/work/projects/move-to-pythoncall/Project.toml`
[84fb645a] Jagot v0.1.0 `~/.julia/dev/Jagot`
[6099a3de] PythonCall v0.9.12
[274fc56d] PythonPlot v1.0.2
[295af30f] Revise v3.5.2
```

贡献指南

这个仓库没有索引到贡献指南

调研方向

Reproduce the provided Matplotlib registration example first as a script, then from package initialization and the REPL. Start with PythonCall's pytype and pycall paths shown in the trace, and compare object lifetime and registration behavior across those contexts. Done means package-based registration works without a segmentation fault and the custom scale is registered.

由索引模型根据 Issue 内容生成。

评估

技术栈
julia, python
领域
backend, tooling
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。