# Temporarily inject development dependencies into package

**URL:** https://discourse.julialang.org/t/temporarily-inject-development-dependencies-into-package/103838
**Category:** General Usage
**Created:** [September 14, 2023, 8:17am UTC](https://discourse.julialang.org/t/temporarily-inject-development-dependencies-into-package/103838 "2023-09-14T08:17:02Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![frankier](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frankier/32/35101_2.png) [@frankier](https://discourse.julialang.org/u/frankier)
#### Post date: [September 14, 2023, 8:17am UTC](https://discourse.julialang.org/t/temporarily-inject-development-dependencies-into-package/103838/1 "2023-09-14T08:17:03Z")

</div>

Typically for development packages, including the defaults such as `InteractiveUtils`, we install them into the global environment, and are able to access them from the REPL, no matter what project we are in. Sometimes rather than executing code in the REPL, it’s easier to modify some file within a project temporarily, just to get some information. In this case, I would like to modify part of my package to have `using InteractiveUtils: @code_warntype` and then use `@code_warntype`. Currently, to do so, I have to add InteractiveUtils as a package dependency, but I would quite like to be able to specify that I want certain packages to have access to the global environment in the environment stack, e.g. like setting `JULIA_DEBUG='mypackage'` but instead `JULIA_REPLENV='mypackage'` or similar.

Is there currently a better/existing way to achieve this? Would it be possible to have some startup code or a small utility package like `TestEnv` to do this?

---

<div class="post-metadata">

### Author: ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)
#### Post date: [September 14, 2023, 8:22am UTC](https://discourse.julialang.org/t/temporarily-inject-development-dependencies-into-package/103838/2 "2023-09-14T08:22:43Z")

</div>

Interested in the answer too, since it’s quite relevant for Infiltrator.jl as well

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [September 14, 2023, 11:43am UTC](https://discourse.julialang.org/t/temporarily-inject-development-dependencies-into-package/103838/3 "2023-09-14T11:43:43Z")

</div>

The `Infiltrator` documentation has a [tip](https://juliadebug.github.io/Infiltrator.jl/stable/#@infiltrate) about this, that I find incredibly useful: the following snippet allows package code to access `Infiltrator` when it’s loaded in an interactive session (even though it’s not declared as a dependency of the package itself)

```julia
if isdefined(Main, :Infiltrator)
  Main.infiltrate(@ __MODULE__ , Base.@locals, @ __FILE__ , @ __LINE__ )
end

```

  

I think the technique could be extended to many similar situations. For example, it should be possible to access `@code_warntype` from `InteractiveUtils` using something like this:

```julia
if isdefined(Main, :InteractiveUtils)
    interactiveutils = getproperty(Main, :InteractiveUtils)
    @eval $(interactiveutils).@code_warntype foo(x, y)
end

```

---

<div class="post-metadata">

### Author: ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)
#### Post date: [September 14, 2023, 12:35pm UTC](https://discourse.julialang.org/t/temporarily-inject-development-dependencies-into-package/103838/4 "2023-09-14T12:35:49Z")

</div>

Yeah I know the tip but I get tired of copypasting this after a while 🤣

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [September 14, 2023, 12:39pm UTC](https://discourse.julialang.org/t/temporarily-inject-development-dependencies-into-package/103838/5 "2023-09-14T12:39:21Z")

</div>

Can we make a macro for it?  
And then put that macro in startup.jl?

---

<div class="post-metadata">

### Author: ![frankier](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frankier/32/35101_2.png) [@frankier](https://discourse.julialang.org/u/frankier)
#### Post date: [September 15, 2023, 8:18am UTC](https://discourse.julialang.org/t/temporarily-inject-development-dependencies-into-package/103838/6 "2023-09-15T08:18:18Z")

</div>

> I think the technique could be extended to many similar situations. For example, it should be possible to access `@code_warntype` from `InteractiveUtils` using something like this:
> 
> ```julia
> if isdefined(Main, :InteractiveUtils)
> interactiveutils = getproperty(Main, :InteractiveUtils)
> @eval $(interactiveutils).@code_warntype foo(x, y)
> end
> 
> ```

If I try this, I get an error like the following at import time

```julia
ERROR: LoadError: ArgumentError: Package FooPackageDependency not found in current path.
- Run `import Pkg; Pkg.add("FooPackageDependency")` to install the FooPackageDependency package.
Stacktrace:
 [1] macro expansion
   @ ./loading.jl:1630 [inlined]
 [2] macro expansion
   @ ./lock.jl:267 [inlined]
 [3] require(into::Module, mod::Symbol)
   @ Base ./loading.jl:1611
 [4] include(fname::String)
   @ Base.MainInclude ./client.jl:478
 [5] top-level scope
   @ none:1

```

Where I’m importing `Package` which is where I’m pasting the snippet, which has `FooPackageDependency` in its dependencies, but I’m in an environment with `Package` in the dependencies and not `FooPackageDependency`.

I guess this is probably because I’m trying to use a macro which makes stuff a bit more difficult.

---

<div class="post-metadata">

### Author: ![frankier](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frankier/32/35101_2.png) [@frankier](https://discourse.julialang.org/u/frankier)
#### Post date: [September 15, 2023, 8:26am UTC](https://discourse.julialang.org/t/temporarily-inject-development-dependencies-into-package/103838/7 "2023-09-15T08:26:36Z")

</div>

> Can we make a macro for it?  
> And then put that macro in startup.jl?

I think maybe we could, at least for the calling a function from a module imported into Main case, but then I think we may have the same problem, the macro is defined in `Main` and we want to have it in `MyPackage`.

Perhaps if there was some way to hack at the `MyPackage`’s stack before `MyPackage is loaded? – But I don’t know whether this is even possible/makes sense/where to start. Also I guess this might trigger a bunch of recompilation.

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [September 15, 2023, 10:01am UTC](https://discourse.julialang.org/t/temporarily-inject-development-dependencies-into-package/103838/8 "2023-09-15T10:01:15Z")

</div>

We could put it into `Base` via `@eval` in the startup.jl  
see:

Since Base is accessibly everywhere we can then use it from what ever package we like

```julia
julia> module Bar
       bar()=Base.foo(100)
       end
Main.Bar

julia> @eval Base foo(x)=x
foo (generic function with 1 method)

julia> Bar.bar()
100

```

It won’t cause any recompilation as it doesn’t invalidate anything, since it isn’t used anywhere.

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [September 15, 2023, 11:17am UTC](https://discourse.julialang.org/t/temporarily-inject-development-dependencies-into-package/103838/9 "2023-09-15T11:17:05Z")

</div>

I just write `Main.@code_warntype foo(x, y)` or whatever in the package code and it works fine.

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [September 15, 2023, 11:25am UTC](https://discourse.julialang.org/t/temporarily-inject-development-dependencies-into-package/103838/10 "2023-09-15T11:25:16Z")

</div>

> [@Mason](#):
>
> I just write `Main.@code_warntype foo(x, y)` or whatever in the package code and it works fine.

Does it always work, or only in interactive contexts (where `InteractiveUtils` is automatically loaded)?

  

> [@oxinabox](#):
>
> We could put it into `Base` via `@eval` in the startup.jl
> 
> Since Base is accessibly everywhere we can then use it from what ever package we like

I’m not sure it’s necessary to put anything in `Base`, because `Main` seems to be accessible everywhere as well. For example, something like this seems to work (from my very limited testing):

```julia
# startup.jl
macro infiltrate_from_main()
    file = String( __source__.file); @show file
    line = __source__.line; @show line
    quote
        if isdefined(Main, :Infiltrator)
            Main.infiltrate($ __module__ , Base.@locals, $file, $line)
        end
    end
end

```

```julia
# package code
module Foo
function foo()
   Main.@infiltrate_from_main
end
end #module

```

  

> [@frankier](#):
>
> If I try this, I get an error like the following at import time

Could it be because precompilation is not happy with such constructs?

It seems (again, from very limited testing) that when debugging, it’s a bit more reliable to first load the package to be debugged, unaltered. And only afterwards modify its sources to incorporate calls to `Infiltrator`/`InteractiveUtils`/whatever, relying on `Revise` to make things work.

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [September 15, 2023, 11:27am UTC](https://discourse.julialang.org/t/temporarily-inject-development-dependencies-into-package/103838/11 "2023-09-15T11:27:39Z")

</div>

> [@ffevotte](#):
>
> Does it always work, or only in interactive contexts (where `InteractiveUtils` is automatically loaded)?

Only if `InteractiveUtils` is loaded.
