# Work with deps with more restrictive julia compat

**URL:** https://discourse.julialang.org/t/work-with-deps-with-more-restrictive-julia-compat/112510
**Category:** General Usage
**Tags:** dependencies
**Created:** [April 4, 2024, 9:33am UTC](https://discourse.julialang.org/t/work-with-deps-with-more-restrictive-julia-compat/112510 "2024-04-04T09:33:38Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![lgoettgens](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lgoettgens/32/203968_2.png) [@lgoettgens](https://discourse.julialang.org/u/lgoettgens)
#### Post date: [April 4, 2024, 9:33am UTC](https://discourse.julialang.org/t/work-with-deps-with-more-restrictive-julia-compat/112510/1 "2024-04-04T09:33:38Z")

</div>

I am trying to make a minimal example from my real-world problem. Let’s say I have two packages `PkgA` and `PkgB`. Currently, `PkgA` has a julia compat of `1.0`, while `PkgB` has a julia compat of `1.7`.  
I now want to use some function of `PkgB` inside of `PkgA`, but only if `VERSION >= v"1.7"` (i.e. `PkgB` is compatible). In all other julia versions, I can replace this function with some trivial line of code. If instead of `PkgB` I use something from julia Base (with no new syntax), this just works with a `@static if`, but `PkgB` makes it necessary to declare this dependency.

How can I input the above into the `Project.toml` file of `PkgA`? I know that this could be achieved using weakdeps, but I would prefer a way where a user would not need to add an dependency on `PkgB` on their own.

---

<div class="post-metadata">

### Author: ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)
#### Post date: [April 4, 2024, 3:47pm UTC](https://discourse.julialang.org/t/work-with-deps-with-more-restrictive-julia-compat/112510/2 "2024-04-04T15:47:55Z")

</div>

Would it work if you make a weakdep but then have a `@static if VERSION>... using PkgB end`?

That way the weakdep solves the issue of having to include a dependency and the `@static if VERSION>=1.7 using PkgB end` solves the issue of the user of PkgA having to explicitly install PkgB.

---

<div class="post-metadata">

### Author: ![lgoettgens](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lgoettgens/32/203968_2.png) [@lgoettgens](https://discourse.julialang.org/u/lgoettgens)
#### Post date: [April 4, 2024, 3:58pm UTC](https://discourse.julialang.org/t/work-with-deps-with-more-restrictive-julia-compat/112510/3 "2024-04-04T15:58:28Z")

</div>

`using` a weakdep seems to lead to an error:

```julia
julia> using PkgA
Precompiling PkgA
        Info Given PkgA was explicitly requested, output will be shown live 
ERROR: LoadError: ArgumentError: Package PkgA does not have PkgB in its dependencies:
- You may have a partially installed environment. Try `Pkg.instantiate()`
  to ensure all packages in the environment are installed.
- Or, if you have PkgA checked out for development and have
  added PkgB as a dependency but haven't updated your primary
  environment's manifest file, try `Pkg.resolve()`.
- Otherwise you may need to report an issue with PkgA
Stacktrace: ....

```

---

<div class="post-metadata">

### Author: ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)
#### Post date: [April 4, 2024, 4:34pm UTC](https://discourse.julialang.org/t/work-with-deps-with-more-restrictive-julia-compat/112510/4 "2024-04-04T16:34:12Z")

</div>

This might be rather ugly, but it works on my end:

`PkgB` is `ExplicitImports` because I did not want to worry about getting something wrong when setting up dependencies between unregistered packages.

## `❯ cat PkgA/Project.toml`

```julia-auto
name = "PkgA"
uuid = "6bbb1ba1-2d7b-4510-8e93-778dc605bb72"
authors = ["Stefan Krastanov <stefan@krastanov.org>"]
version = "0.1.0"

[weakdeps]
ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7"

[compat]
julia = "1"

```

## `❯ cat PkgA/src/PkgA.jl `

```julia-auto
module PkgA

function __init__ ()
    if VERSION>=v"1.9"
        @eval Main begin # !!! importantly, we evaluate in the Main module, not in PkgA
            import Pkg
            Pkg.add("ExplicitImports")
            using ExplicitImports
        end
    end
end

greetA() = print("Hello World from A!")

end # module PkgA

```

An ugly trick to import `ExplicitImports` when your package is imported, but not have access to it. To actually get access to it, you also need to build out the weakdep.

**Edit: nope, this does not work, it hangs when precompiling the extension… which might be bug in julia?**

---

<div class="post-metadata">

### Author: ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)
#### Post date: [April 4, 2024, 4:54pm UTC](https://discourse.julialang.org/t/work-with-deps-with-more-restrictive-julia-compat/112510/5 "2024-04-04T16:54:32Z")

</div>

Here is the complete solution that also takes care of the precompilation loop for the extension:

`PkgB` is `ExplicitImports` because I did not want to worry about getting something wrong when setting up dependencies between unregistered packages.

**A big assumption of mine here is that you do NOT want to have users of `PkgA` also type `using PkgB`. As you alluded to, if you require the users to simply do `using PkgB`, a weakdep would be a much neater and simpler solution**

## `❯ cat PkgA/src/PkgA.jl`

```julia-auto
module PkgA

function __init__ ()
    if VERSION>=v"1.9"
        @eval Main begin # note that we import in module Main to avoid the dependency error
            import Pkg
            Pkg.add("ExplicitImports")
            using ExplicitImports
        end
    end
end

# some declared function with no methods that will be extended by the weakdep
function f end

end # module PkgA

```

## `❯ cat PkgA/ext/E/E.jl `

```julia-auto
module E

__precompile__ (false) # otherwise the ` __init__ ` causes a bad dependency loop in precompilation
# this will lead to slow import times if this extension contains a lot of code

import PkgA: f
import ExplicitImports
function f()
    println("this module exists")
end
end

```

## `❯ cat PkgA/Project.toml `

```julia-auto
name = "PkgA"
uuid = "6bbb1ba1-2d7b-4510-8e93-778dc605bb72"
authors = ["Stefan Krastanov <stefan@krastanov.org>"]
version = "0.1.0"

[weakdeps]
ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7"

[extensions]
E = "ExplicitImports"

[compat]
julia = "1"

```

---

<div class="post-metadata">

### Author: ![lgoettgens](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lgoettgens/32/203968_2.png) [@lgoettgens](https://discourse.julialang.org/u/lgoettgens)
#### Post date: [April 9, 2024, 10:06am UTC](https://discourse.julialang.org/t/work-with-deps-with-more-restrictive-julia-compat/112510/6 "2024-04-09T10:06:54Z")

</div>

(Afk due to vacation.)  
Thanks for your suggestions. Unfortunately the `@eval Main` thing seems to edit some Project.toml file on execution that should not get touched.

I think julia unfortunately does not offer a suitable solution. What I thought about as a possible workaround is a dummy package to but into the dependency chain that has different major versions depending on the julia versions with different sets of dependencies. This could then have PkgB in the list only for julia 1.7+ or something like this.
