From 5901deac04e7c2f6a267f9ad49742c753de6fcd7 Mon Sep 17 00:00:00 2001 From: Christopher Doris Date: Wed, 8 Oct 2025 10:55:09 +0100 Subject: [PATCH 1/7] fix #676 and test GUI compat better along the way --- CondaPkg.toml | 11 ++++++++--- Project.toml | 2 +- src/Compat/gui.jl | 2 +- src/Core/stdlib.jl | 3 ++- test/Compat.jl | 15 ++++++++++++--- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/CondaPkg.toml b/CondaPkg.toml index 8ebe709d..08aaf949 100644 --- a/CondaPkg.toml +++ b/CondaPkg.toml @@ -1,12 +1,17 @@ -[deps.libstdcxx] + +[deps.openssl] version = "<=julia" -[deps.libstdcxx-ng] +[deps.libstdcxx] version = "<=julia" -[deps.openssl] +[deps.libstdcxx-ng] version = "<=julia" [deps.python] build = "**cpython**" version = ">=3.9,<4" + +[dev.deps] +matplotlib = "" +pyside6 = "" diff --git a/Project.toml b/Project.toml index 547d665c..5eb3baf0 100644 --- a/Project.toml +++ b/Project.toml @@ -17,7 +17,7 @@ UnsafePointers = "e17b2a0c-0bdf-430a-bd0c-3a23cae4ff39" [compat] Aqua = "0 - 999" CategoricalArrays = "0.10, 1" -CondaPkg = "0.2.30" +CondaPkg = "0.2.33" Dates = "1" Libdl = "1" MacroTools = "0.5" diff --git a/src/Compat/gui.jl b/src/Compat/gui.jl index ad7b1687..b0be9363 100644 --- a/src/Compat/gui.jl +++ b/src/Compat/gui.jl @@ -159,7 +159,7 @@ function init_gui() # add a hook to automatically call fix_qt_plugin_path() fixqthook = - Py(() -> (Core.CONFIG.auto_fix_qt_plugin_path && fix_qt_plugin_path(); nothing)) + Py(() -> (PythonCall.CONFIG.auto_fix_qt_plugin_path && fix_qt_plugin_path(); nothing)) pymodulehooks.add_hook("PyQt4", fixqthook) pymodulehooks.add_hook("PyQt5", fixqthook) pymodulehooks.add_hook("PySide", fixqthook) diff --git a/src/Core/stdlib.jl b/src/Core/stdlib.jl index 98ddcce1..61d132e1 100644 --- a/src/Core/stdlib.jl +++ b/src/Core/stdlib.jl @@ -40,7 +40,8 @@ function init_stdlib() class JuliaCompatHooks: def __init__(self): self.hooks = {} - def find_module(self, name, path=None): + def find_spec(self, name, path=None, target=None): + print("find_spec:", name) hs = self.hooks.get(name) if hs is not None: for h in hs: diff --git a/test/Compat.jl b/test/Compat.jl index 79037f29..62c52d29 100644 --- a/test/Compat.jl +++ b/test/Compat.jl @@ -5,13 +5,22 @@ @test PythonCall.fix_qt_plugin_path() === false end @testset "event_loop_on/off" begin - for g in [:pyqt4, :pyqt5, :pyside, :pyside2, :pyside6, :gtk, :gtk3, :wx] + @testset "$g" for g in [:pyqt4, :pyqt5, :pyside, :pyside2, :pyside6, :gtk, :gtk3, :wx] # TODO: actually test the various GUIs somehow? - @show g - @test_throws PyException PythonCall.event_loop_on(g) + if g == :pyside6 + # pyside6 is installed as a dev dependency + # AND it's a dependency of matplotlib, which is also a dev dependency + @test PythonCall.event_loop_on(g) isa Timer + else + @test_throws PyException PythonCall.event_loop_on(g) + end @test PythonCall.event_loop_off(g) === nothing end end + @testset "matplotlib issue 676" begin + plt = pyimport("matplotlib.pyplot") + @test plt.get_backend() isa Py + end end @testitem "ipython" begin From 3ffe3f54643938a7f3a0b1ce3fb425ab21c65e66 Mon Sep 17 00:00:00 2001 From: Christopher Doris Date: Wed, 8 Oct 2025 10:56:36 +0100 Subject: [PATCH 2/7] remove debug printing --- src/Core/stdlib.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Core/stdlib.jl b/src/Core/stdlib.jl index 61d132e1..96c526c7 100644 --- a/src/Core/stdlib.jl +++ b/src/Core/stdlib.jl @@ -41,7 +41,6 @@ function init_stdlib() def __init__(self): self.hooks = {} def find_spec(self, name, path=None, target=None): - print("find_spec:", name) hs = self.hooks.get(name) if hs is not None: for h in hs: From 3c47839edd34d58c021e793577624462b5145319 Mon Sep 17 00:00:00 2001 From: Christopher Doris Date: Wed, 8 Oct 2025 12:19:09 +0100 Subject: [PATCH 3/7] require newer juliapkg --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 892cc148..0a646f05 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ classifiers = [ "Operating System :: OS Independent", ] requires-python = ">=3.9, <4" -dependencies = ["juliapkg >=0.1.17, <0.2"] +dependencies = ["juliapkg >=0.1.21, <0.2"] [dependency-groups] dev = [ From 57469123571cfe1462111d50ad76c50e54ccd12a Mon Sep 17 00:00:00 2001 From: Christopher Doris Date: Wed, 8 Oct 2025 12:20:45 +0100 Subject: [PATCH 4/7] skip some tests in CI if using system python --- test/Compat.jl | 10 ++++++---- test/runtests.jl | 7 +++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/test/Compat.jl b/test/Compat.jl index 62c52d29..00c93ac6 100644 --- a/test/Compat.jl +++ b/test/Compat.jl @@ -1,4 +1,4 @@ -@testitem "gui" begin +@testitem "gui" setup=[Setup] begin @testset "fix_qt_plugin_path" begin @test PythonCall.fix_qt_plugin_path() isa Bool # second time is a no-op @@ -7,7 +7,7 @@ @testset "event_loop_on/off" begin @testset "$g" for g in [:pyqt4, :pyqt5, :pyside, :pyside2, :pyside6, :gtk, :gtk3, :wx] # TODO: actually test the various GUIs somehow? - if g == :pyside6 + if Setup.devdeps && g == :pyside6 # pyside6 is installed as a dev dependency # AND it's a dependency of matplotlib, which is also a dev dependency @test PythonCall.event_loop_on(g) isa Timer @@ -18,8 +18,10 @@ end end @testset "matplotlib issue 676" begin - plt = pyimport("matplotlib.pyplot") - @test plt.get_backend() isa Py + if Setup.devdeps + plt = pyimport("matplotlib.pyplot") + @test plt.get_backend() isa Py + end end end diff --git a/test/runtests.jl b/test/runtests.jl index b9e874db..f09e9ef6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,3 +1,10 @@ using TestItemRunner +@testmodule Setup begin + # test if we are in CI + ci = get(ENV, "CI", "") == "true" + # test if we have all dev conda deps (assume true if not in CI) + devdeps = ci ? ENV["JULIA_PYTHONCALL_EXE"] == "@CondaPkg" : true +end + @run_package_tests From c3d563e9b0967e764702b6609a33d5cb321abf3f Mon Sep 17 00:00:00 2001 From: Christopher Doris Date: Wed, 8 Oct 2025 12:36:45 +0100 Subject: [PATCH 5/7] fix ci attempt 2 --- test/runtests.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index f09e9ef6..115648be 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,10 +1,11 @@ using TestItemRunner @testmodule Setup begin + using PythonCall # test if we are in CI ci = get(ENV, "CI", "") == "true" - # test if we have all dev conda deps (assume true if not in CI) - devdeps = ci ? ENV["JULIA_PYTHONCALL_EXE"] == "@CondaPkg" : true + # test if we have all dev conda deps + devdeps = PythonCall.C.CTX.which == :CondaPkg end @run_package_tests From e8335660bedd5a72cf2a125c76d43d77c23f1159 Mon Sep 17 00:00:00 2001 From: Christopher Doris Date: Thu, 9 Oct 2025 20:19:58 +0100 Subject: [PATCH 6/7] fix world age issue on Julia 1.12 --- src/JlWrap/any.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/JlWrap/any.jl b/src/JlWrap/any.jl index 9685cc4b..96a6a3d2 100644 --- a/src/JlWrap/any.jl +++ b/src/JlWrap/any.jl @@ -28,9 +28,10 @@ function pyjlany_setattr(self, k_::Py, v_::Py) v = pyconvert(Any, v_) if self isa Module && !isdefined(self, k) # Fix for https://github.com/JuliaLang/julia/pull/54678 - Base.Core.eval(self, Expr(:global, k)) + @eval self (global $k = $v) + else + setproperty!(self, k, v) end - setproperty!(self, k, v) Py(nothing) end pyjl_handle_error_type(::typeof(pyjlany_setattr), self, exc) = pybuiltins.AttributeError From cc71b69380ca36af38fd1ca17dd8b145efa3cf01 Mon Sep 17 00:00:00 2001 From: Christopher Doris Date: Thu, 9 Oct 2025 20:28:03 +0100 Subject: [PATCH 7/7] install julia 1.11 in python test workflow --- .github/workflows/tests.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f0fd9e1f..2754633f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -84,6 +84,12 @@ jobs: uses: actions/setup-python@v6 with: python-version: ${{ matrix.pyversion }} + + - name: Check Python OpenSSL version (see setup_julia) + shell: python + run: | + import ssl + assert ssl.OPENSSL_VERSION_INFO < (3, 5) - name: Set up uv uses: astral-sh/setup-uv@v6 @@ -94,7 +100,9 @@ jobs: id: setup_julia uses: julia-actions/setup-julia@v2 with: - version: '1' + # Python in the GitHub runners ships with OpenSSL 3.0. Julia 1.12 requires + # OpenSSL 3.5. Therefore juliapkg requires Julia 1.11 or lower. + version: '1.11' - name: Set up test Julia project if: ${{ matrix.juliaexe == 'julia' }}