# Names that are not exported from a package can also be imported into another project

**URL:** <https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424>\
**Category:** General Usage\
**Tags:** question, package\
**Created:** [April 2, 2024, 2:47pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424 "2024-04-02T14:47:28Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [April 2, 2024, 2:47pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/1 "2024-04-02T14:47:29Z")

</div>

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`.

Is this reasonable?

Thanks in advance!

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [April 2, 2024, 3:03pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/2 "2024-04-02T15:03:19Z")

</div>

That is as expected. Symbols from modules can be brought into scope whether exported or not.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 2, 2024, 3:05pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/3 "2024-04-02T15:05:14Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [April 2, 2024, 3:41pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/4 "2024-04-02T15:41:09Z")

</div>

That’s what I meant. Thanks for the clarification.

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [April 2, 2024, 4:49pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/5 "2024-04-02T16:49:29Z")

</div>

In that case, I need to check what went wrong. 🤔

Thanks!

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [April 3, 2024, 8:18am UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/6 "2024-04-03T08:18:59Z")

</div>

> [@WuSiren](#):
>
> 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`.
> 
> Is this reasonable?
> 
> Thanks in advance!

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?

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 3, 2024, 8:57am UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/7 "2024-04-03T08:57:08Z")

</div>

We use Reexport.jl too, and don’t see this issue.

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [April 3, 2024, 10:51am UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/8 "2024-04-03T10:51:22Z")

</div>

For instance,

```julia
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?

```

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [April 3, 2024, 11:20am UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/9 "2024-04-03T11:20:53Z")

</div>

What is strange in that example? `X` directly exports `h` and reexports `g` from `Y` and `add_variable` from `JuMP`. It doesn’t export `f`.

It all looks consistent with your observations at the end.

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [April 3, 2024, 12:45pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/10 "2024-04-03T12:45:31Z")

</div>

```julia
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`.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [April 3, 2024, 12:48pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/11 "2024-04-03T12:48:00Z")

</div>

The difference is that `JuMP` exports `add_variable` but not `add_variable2` and you do `@reexport using JuMP`.

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [April 3, 2024, 12:55pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/12 "2024-04-03T12:55:51Z")

</div>

> [@GunnarFarneback](#):
>
> add\_variable

Why does `JuMP` export `add_variable`? Isn’t it a function name like `add_variable2` that is defined in module `X`?

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [April 3, 2024, 12:59pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/13 "2024-04-03T12:59:46Z")

</div>

Because [`add_variable`](https://jump.dev/JuMP.jl/stable/api/JuMP/#add_variable) is part of the JuMP API? You probably shouldn’t be reexporting JuMP if you don’t know what it contains.

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [April 3, 2024, 1:07pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/14 "2024-04-03T13:07:04Z")

</div>

Ah, I see! It had been troubling me for a while. Thank you for your patient help and valuable advice! 🤝 🤝 🤝

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [April 3, 2024, 1:19pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/15 "2024-04-03T13:19:47Z")

</div>

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

```julia
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`. 🤔

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [April 3, 2024, 1:35pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/16 "2024-04-03T13:35:13Z")

</div>

The reexport macro expands to, among other things,

```julia
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.

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [April 3, 2024, 1:39pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/17 "2024-04-03T13:39:10Z")

</div>

Thank you, for me it finally makes sense, although I still feels a bit strange. 🤝

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [April 3, 2024, 2:05pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/18 "2024-04-03T14:05:40Z")

</div>

By the way,

```julia
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?

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [April 3, 2024, 3:11pm UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/19 "2024-04-03T15:11:07Z")

</div>

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.

From [GitHub - simonster/Reexport.jl: Julia macro for re-exporting one module from another](https://github.com/simonster/Reexport.jl) (with emphasis added):

> Maybe you have a module `X` that depends on module `Y` and you want `using X` to pull in **all** of the symbols from `Y` .

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [April 4, 2024, 5:47am UTC](https://discourse.julialang.org/t/names-that-are-not-exported-from-a-package-can-also-be-imported-into-another-project/112424/20 "2024-04-04T05:47:05Z")

</div>

Thanks!
