julia
julia copied to clipboard
`__init__` side effects order is not defined, such that any global effects from `__init__` are a data race
julia> Threads.@spawn ((@eval using .Bad); @show Main.Bad.x); module Bad; x = 0; __init__() = (yield(); global x = 1;) end
Main.Bad.x = 0
Main.Bad
julia> Main.Bad.x
1
This is now relied upon by REPLExt in Pkg (and all JLL files), so this must be fixed before the next release
A problem is that we cannot easily define the state of __init__ for various using clauses:
module A
module B
using ..A # assumes A.__init__ shouldn't run yet
end
B.__init__()
@async (using .A) # assumes that the state of A.__init__ is UB???
end
A.__init__()
using .A # assumes A.__init__ should have run
That doesn't really bother me because it's much more general than just when init runs; you can run arbitrary code on any line of the module before the whole module has even been evaluated.