Skip to content

Commit 3a0cb78

Browse files
committed
Load CondaPkg lazily
This shaves ~0.5s off the load time if `JULIA_PYTHONCALL_EXE` is set.
1 parent 4adeb0a commit 3a0cb78

File tree

3 files changed

+28
-18
lines changed

3 files changed

+28
-18
lines changed

src/C/C.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ module C
77

88
using Base: @kwdef
99
using UnsafePointers: UnsafePtr
10-
using CondaPkg: CondaPkg
11-
using Pkg: Pkg
1210
using Libdl:
1311
dlpath, dlopen, dlopen_e, dlclose, dlsym, dlsym_e, RTLD_LAZY, RTLD_DEEPBIND, RTLD_GLOBAL
1412

src/C/context.jl

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ Execute `f()` on the main thread.
102102
"""
103103
on_main_thread
104104

105+
# CondaPkg is a rather heavy dependency so we go to some effort to load it lazily
106+
const CondaPkg_pkgid = Base.PkgId(Base.UUID("992eb4ea-22a4-4c89-a5bb-47a3300528ab"), "CondaPkg")
107+
108+
function load_CondaPkg(f::Function)
109+
if !haskey(Base.loaded_modules, CondaPkg_pkgid)
110+
Base.require(@__MODULE__, :CondaPkg)
111+
end
112+
113+
@invokelatest f(Base.loaded_modules[CondaPkg_pkgid])
114+
end
105115

106116
function init_context()
107117

@@ -125,22 +135,24 @@ function init_context()
125135
# Find Python executable
126136
exe_path = get(ENV, "JULIA_PYTHONCALL_EXE", "")
127137
if exe_path == "" || exe_path == "@CondaPkg"
128-
if CondaPkg.backend() == :Null
129-
exe_path = Sys.which("python")
130-
if exe_path === nothing
131-
error("CondaPkg is using the Null backend but Python is not installed")
138+
load_CondaPkg() do CondaPkg
139+
if CondaPkg.backend() == :Null
140+
exe_path = Sys.which("python")
141+
if exe_path === nothing
142+
error("CondaPkg is using the Null backend but Python is not installed")
143+
end
144+
exe_path::String
145+
else
146+
# By default, we use Python installed by CondaPkg.
147+
exe_path =
148+
Sys.iswindows() ? joinpath(CondaPkg.envdir(), "python.exe") :
149+
joinpath(CondaPkg.envdir(), "bin", "python")
150+
# It's not sufficient to only activate the env while Python is initialising,
151+
# it must also be active when loading extension modules (e.g. numpy). So we
152+
# activate the environment globally.
153+
# TODO: is this really necessary?
154+
CondaPkg.activate!(ENV)
132155
end
133-
exe_path::String
134-
else
135-
# By default, we use Python installed by CondaPkg.
136-
exe_path =
137-
Sys.iswindows() ? joinpath(CondaPkg.envdir(), "python.exe") :
138-
joinpath(CondaPkg.envdir(), "bin", "python")
139-
# It's not sufficient to only activate the env while Python is initialising,
140-
# it must also be active when loading extension modules (e.g. numpy). So we
141-
# activate the environment globally.
142-
# TODO: is this really necessary?
143-
CondaPkg.activate!(ENV)
144156
end
145157
CTX.which = :CondaPkg
146158
elseif exe_path == "@PyCall"

test/Aqua.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
@testitem "Aqua" begin
22
import Aqua
3-
Aqua.test_all(PythonCall)
3+
Aqua.test_all(PythonCall; stale_deps=(; ignore=[:CondaPkg]))
44
end

0 commit comments

Comments
 (0)