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' }} 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/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 = [ 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..96c526c7 100644 --- a/src/Core/stdlib.jl +++ b/src/Core/stdlib.jl @@ -40,7 +40,7 @@ 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): hs = self.hooks.get(name) if hs is not None: for h in hs: 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 diff --git a/test/Compat.jl b/test/Compat.jl index 79037f29..00c93ac6 100644 --- a/test/Compat.jl +++ b/test/Compat.jl @@ -1,17 +1,28 @@ -@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 @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 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 + else + @test_throws PyException PythonCall.event_loop_on(g) + end @test PythonCall.event_loop_off(g) === nothing end end + @testset "matplotlib issue 676" begin + if Setup.devdeps + plt = pyimport("matplotlib.pyplot") + @test plt.get_backend() isa Py + end + end end @testitem "ipython" begin diff --git a/test/runtests.jl b/test/runtests.jl index b9e874db..115648be 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,3 +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 + devdeps = PythonCall.C.CTX.which == :CondaPkg +end + @run_package_tests