Clarifying package compatibility rules

The way that Julia manages package compatibilities (and incompatibilities) is superb, but also leads to situations that may be difficult to understand if you don’t know how it works. Actually I’m not totally sure of my understanding it correctly. :slightly_smiling_face: So let me introduce a simple (theoretical) use case, and please tell me if what I think that happens is correct or not.

This is the story:

There’s a package Dep, and a couple of packages Foo and Bar that depend on it. In their first version - (let’s say it is 1.0.0 for all of them), that dependency is upper-bounded to the first version of Dep as well, e.g. the Project.toml of Foo and Bar says:

[compat]
Dep = "1"

Then, Dep grows to a version with new features but also breaking changes that is released as 2.0.0. For the time being Foo remains without changes, living happily with Dep v1, but the maintainers of Bar decide to use some of those features, so they release Bar 1.1.0 with:

[compat]
Dep = "2"

Now, if I had added Bar v1.0.0 in my Julia environment, and I do pkg> up, Dep will be updated to v2.0.0 so that Bar can be updated to v1.1.0. But if I also had added Foo, none of those updates will happen, because Foo does not allow Dep to change to v2, so Bar is locked to v1.0.0.

Or if Foo had not been added, but I add it after having updated Bar, then Bar and Dep will be downgraded to the earlier versions that are compatible with Foo.

… Is this correct?

(And a side question: is it ok for Bar to tag its new version as 1.1.0 if its public API is not broken, in spite of changing the compatibility to a different major version of another package?)

Now, let’s introduce into the play yet another package Baz whose first version also depends on Dep, but with Dep = "2" as lower compat. bound. This package is incompatible with Foo and with Bar v1.0. If I have Foo in my environment, Baz won’t be installed (and viceversa), and Bar will be locked in v1.1 or higher.

The nice thing is that can still use both Foo and Baz, as long as I keep them in different environments so that they don’t have to play together, isn’t it?

And a final question – assuming that most of the previous is correct: what happens if I am working in an environment with Foo, and I try to pkg> activate the environment with Baz in the same session? Can I switch between environments with incompatible versions of packages without killing the session?

I think your understanding is correct about the first two things.

As for loading package from an incompatible environment: my understanding is that disallowing this is an open issue. Eg

https://github.com/JuliaLang/julia/issues/32906