Is there a way to deepcopy a module?

using DeepcopyModules
module M;  x = 1;  f() = (global x += 1);  end
M2 = deepcopy_module(M)

The package is on github. However, this code crashes. Is there any other way?

The error is:

main at /buildworker/worker/package_linux64/build/cli/loader_exe.c:42unknown function (ip: 0x7efc98030d8f)__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)Process julia aborted (core dumped) at Mon Jul 11 10:36:15 2022

X-post from here

I almost managed to deepcopy a module without going into the C internals. The only link that remains is that a change of a function definition in the initial module affects the copy. Any ideas how to get rid of that?

function getmodulename(x::Module)
    ## extracts name of passed module
    nn = quote
        $x
    end
    n_with_parent = nn.args[2] |> string
    ## Works for nested modules
    parent = parentmodule(x)
    m_maybe = match(Regex("(?<=$(parent)\\.).*"), n_with_parent)
    return Symbol(m_maybe.match)
end

function copy_module(m::Module, new::Module)
    mname = getmodulename(m)
    unused_names = [mname, Symbol("#eval"), Symbol("#include"), :eval, :include]
    mnames = names(m; all = true)
    filter!(x-> x ∉ unused_names && !startswith(string(x), '#'), mnames)
    properties = [getproperty(m, n) for n in mnames]
    ismodule = isa.(properties, Ref(Module)) 
    ## Modules get copied recursively
    modules = properties[ismodule]
    for _m in modules
        _mname = getmodulename(_m)
        _new = new.Core.eval(new, :(module $_mname end))
        copy_module(_m, _new)
    end
    ## Functions cannot be copied but are defined such that
    ## a change in `new` does not affect `m`
    ## without a change in `new` the function will refer to
    ## whatever is currently in `m` (incl. changes)
    isfunction = isa.(properties, Ref(Function))
    functions = properties[isfunction]
    for (_n, _f) in zip(mnames[isfunction], functions)
        new.Core.eval(new, :($(_n)(x) = (y->$(_f)(y))(x)))
    end
    ## Values are assigned with deepcopy
    assignments = [:($nn = deepcopy($pp)) for (nn,pp) in zip(mnames[.!(ismodule) .&& .!(isfunction)], properties[.!(ismodule).&& .!(isfunction)])]
    [new.Core.eval(new, i) for i in assignments]
    return new
end

module A 
x = 1
y = [1,3,4]
f(x) = println(x)
module C
z = [1,2,3]
end
end

module B end
copy_module(A, B)

A.f("HI")
B.f("HI")
A.f(x) = x^2 # modifies A.f AND B.f
A.f("HI")
B.f("HI")

B.f(x) = lowercase(x) # modifies ONLY B.f
A.f("HI")
B.f("HI")

A.x
B.x
A.Core.eval(A, :(x = 2)) # modifies ONLY A.x
A.x
B.x

B.Core.eval(B, :(x = "HI")) # modifies ONLY B.x
A.x
B.x

B.C.z .= [4,5,6] # modifies ONLY B.C.z
A.C.z
B.C.z

A.y !== B.y ## not same memory
A.C.z !== B.C.z ## not same memory