I’m encountered with a fairly strange circumstance where the names that are not exported from a package can also be imported into another project environment.

Detail: There is a package named MyPkg that is just in development. In this package, function f has been exported explicitly with export f, while function g hasn’t. I added this package in another project environment with command dev path/to/MyPkg for the purpose of package test. After using MyPkg in the new environment I found I can invoke not only function f but also g.

That is not expected. If g is not exported, then using MyPkg shouldn’t make the name available. You can still import MyPkg: g to request the internal name explicitly though.

I found that the issue lies in my use of Reexport. Once I use the @reexport using SomePkg command, the aforementioned issue occurs. Is this considered a bug?

module Y
export g
g(x) = x + 1
end
module X
export h
using Reexport
@reexport using JuMP
@reexport using ..Y
add_variable(model) = @variable(model)
f(x) = x + 2
h(x) = x + 3
end
using ..X
g(1) # Available
f(1) # Not available
h(1) # Available
add_variable # Available. Why?

module Y
export g
g(x) = x + 1
end
module X
export h
using Reexport
@reexport using JuMP
@reexport using ..Y
add_variable(model) = @variable(model)
function add_variable2(model)
return @variable(model)
end
f(x) = x + 2
h(x) = x + 3
end
using ..X
g(1) # Available
f(1) # Not available
h(1) # Available
add_variable # Available. Why?
add_variable2 # Not available. Why?

Maybe what I feel strange lies in I don’t understand the difference between the definitions of function add_variable and add_variable2.

But, sorry. There is still a phenomenon that I feel strange.

module X
export h
using Reexport
@reexport using JuMP
add_variable(x) = x + 1
f(x) = x + 2
h(x) = x + 3
end
using ..X
f(1) # Not available
h(1) # Available
add_variable # Available.
add_variable(1) # Available. Why?

Since add_variable is part of the JuMP API, it’s not surprising that it can be exported. However, I am now wondering why the new methods defined for add_variable in module X can also be exported, and it seems like it overwrite the original add_variable function in JuMP.

The reexport macro expands to, among other things,

export add_variable

I.e. module X exports the symbol add_variable, whatever it happens to be bound to in the module. In this case it is first imported from JuMP with using, then you shadow it with your own definition.

module Y
export f, g
f(x) = x + 1
g(x) = x + 2
end
module X
export h
using Reexport
@reexport using ..Y: f
h(x) = f(x) + 3
# Place-1: let `f` available here.
end
using ..X
# Place-2: let `g` available and `f` not available here.

If I want to let f available at Place-1 and let g available and f not available at Place-2, how should I code?

If I understand correctly, you want to use Y.f as f only from within X, and you want to use X.g as g outside of f. If so, then just don’t re-export. Reexport is a convenience for exporting everything. If that’s not want you want, then explicitly export what you do want.