diff --git a/CHANGELOG.md b/CHANGELOG.md index 66e02304..1506de11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Add `exe=@ENV` preference to read `JULIA_PYTHONCALL_EXE` without loading CondaPkg. * Improved TTFX in JuliaCall. * Minimum supported Python version is now 3.11. +* JuliaCall option `compiled_modules` now accepts `existing` and `strict` (Julia 1.11+). ## 0.9.37 (2026-10-12) * Compatibility fix with Python 3.15 from conda-forge, which no longer bundles libpython. diff --git a/docs/src/juliacall.md b/docs/src/juliacall.md index 84bdae00..11cb9333 100644 --- a/docs/src/juliacall.md +++ b/docs/src/juliacall.md @@ -127,7 +127,7 @@ be configured in two ways: | `-X juliacall-home=` | `PYTHON_JULIACALL_BINDIR=` | The directory containing the julia executable. | | `-X juliacall-check-bounds=` | `PYTHON_JULIACALL_CHECK_BOUNDS=` | Enable or disable bounds checking. | | `-X juliacall-compile=` | `PYTHON_JULIACALL_COMPILE=` | Enable or disable JIT compilation. | -| `-X juliacall-compiled-modules=` | `PYTHON_JULIACALL_COMPILED_MODULES=` | Enable or disable incrementally compiling modules. | +| `-X juliacall-compiled-modules=` | `PYTHON_JULIACALL_COMPILED_MODULES=` | Enable or disable incrementally compiling modules (`existing`, `strict`: Julia 1.11+). | | `-X juliacall-depwarn=` | `PYTHON_JULIACALL_DEPWARN=` | Enable or disable deprecation warnings. | | `-X juliacall-handle-signals=` | `PYTHON_JULIACALL_HANDLE_SIGNALS=` | Enable or disable Julia signal handling. | | `-X juliacall-inline=` | `PYTHON_JULIACALL_INLINE=` | Enable or disable inlining. | diff --git a/pysrc/juliacall/__init__.py b/pysrc/juliacall/__init__.py index 9370b60d..4b27810e 100644 --- a/pysrc/juliacall/__init__.py +++ b/pysrc/juliacall/__init__.py @@ -195,7 +195,7 @@ def args_from_config(config): CONFIG['opt_compile'] = choice('compile', ['yes', 'no', 'all', 'min'])[0] CONFIG["opt_trace_compile"] = option('trace_compile')[0] CONFIG["opt_trace_compile_timing"] = flag('trace_compile_timing')[0] - CONFIG['opt_compiled_modules'] = choice('compiled_modules', ['yes', 'no'])[0] + CONFIG['opt_compiled_modules'] = choice('compiled_modules', ['yes', 'no', 'existing', 'strict'])[0] CONFIG['opt_depwarn'] = choice('depwarn', ['yes', 'no', 'error'])[0] CONFIG['opt_inline'] = choice('inline', ['yes', 'no'])[0] CONFIG['opt_min_optlevel'] = choice('min_optlevel', ['0', '1', '2', '3'])[0] diff --git a/pytest/test_all.py b/pytest/test_all.py index 151a7361..8ceaf9df 100644 --- a/pytest/test_all.py +++ b/pytest/test_all.py @@ -199,3 +199,33 @@ def test_call_nogil(yld, raw): t2 = time() - t0 # executing the tasks should take about 1 second because they happen in parallel assert 0.9 < t2 < 1.5 + + +@pytest.mark.parametrize("mode,value", [("existing", 2), ("strict", 3)]) +def test_compiled_modules_option(mode, value): + import os + import subprocess + import sys + + from juliacall import Main as jl + + if jl.seval("VERSION < v\"1.11\""): + pytest.skip("--compiled-modules=existing/strict requires Julia 1.11") + # the parent process has loaded PythonCall, so its cache files exist for the + # same flags (the child inherits PYTHON_JULIACALL_*) and it can load them without compiling + env = os.environ.copy() + env["PYTHON_JULIACALL_COMPILED_MODULES"] = mode + result = subprocess.run( + [ + sys.executable, + "-c", + "from juliacall import Main as jl;" + " print(jl.seval('Base.JLOptions().use_compiled_modules'), end='')", + ], + env=env, + capture_output=True, + text=True, + timeout=180, + ) + assert result.returncode == 0, result.stderr + assert result.stdout == str(value)