Package manager: what are "explicit requirements"?

Here, it basically means that one of the test dependencies (Plots) is not compatible with the versions resolved for the package (which includes StatsBase 0.30).

https://github.com/JuliaRegistries/General/pull/227 seems to include Plots to be compatible with StatsBase 0.30.

Oki thanks. Unfortunately, I still do not understand how the resolver came to say restricted to versions 0.30.0 by an explicit requirement, leaving only versions 0.30.0, could it be made to say where the explicit requirement came from?

2 Likes

It is basically

(Foo) pkg> st
    Status `C:\Users\Kristoffer\Foo\Project.toml`
  [2913bbd2] StatsBase v0.30.0

(Foo) pkg> add Plots
 Resolving package versions...
ERROR: Unsatisfiable requirements detected for package Plots [91a5bcdd]:
 Plots [91a5bcdd] log:
...
│ └─StatsBase [2913bbd2] log:
    └─restricted to versions 0.30.0 by an explicit requirement, leaving only versions 0.30.0

Pkg doesn’t downgrade packages in the Project file.

(Foo) pkg> rm StatsBase
...

(Foo) pkg> add StatsBase Plots
 Resolving package versions...
  Updating `C:\Users\Kristoffer\Foo\Project.toml`
  [91a5bcdd] + Plots v0.24.0
  [2913bbd2] + StatsBase v0.29.0

So me adding

[compat]
StatsBase = "0.29,0.30"

in Project.toml is not the way to go to say that this particular package supports also v0.29?

The problem is not that the package itself does not support 0.29, it does. The problem is that a test-dependency (Plots) does not support the version that the package would use if that test dependency was not there.

It is basically this issue: https://github.com/JuliaLang/Pkg.jl/issues/110.

Okay, I somewhat understand after reading the discussion in the issue, thanks. So if I would like my tests to pass, the only option I have other than waiting for dependencies to update, is to say that I only support StatsBase v0.29 for now, since Plots only support v0.29 at the moment?

You can also check in a Manifest with StatsBase 0.29 installed.

But I merged the PR now so it should work now.

1 Like

]add Plots and ]test Plots in a clean Julia install still does not work (checked it in a clean Docker). I think this is because https://github.com/JuliaRegistries/General/pull/227 does not change StatsPlots’s compat info. Since StatsPlots does not claim any compat information for StatsBase, I believe the correct behavior is to let it be installed even though the test may fail. I wrote a more detailed explanation for why I thought this was the correct behavior in Dependency problem with FIllArrays - #41 by tkf.

This is an interaction between the upper bounds placed by the METADATA converter and https://github.com/JuliaLang/Pkg.jl/issues/110.

As it is right now, if a test dependency is not compatible with the versions of packages that gets resolved without the test dependency, the package will fail with a resolution error when tested.

The workaround is to check in a Manifest with versions that are compatible with the test dependencies. We should maybe think more about https://github.com/JuliaLang/Pkg.jl/issues/110 and loosen how hard the version of project dependencies are being kept.

1 Like

My understanding about the practicalities of checking in the Manifest.toml into the repo is the following, is this correct?

  1. for users of the package, who installed it via pkg> add or pkg> dev, the Manifest.toml in the package directory is ignored entirely, so this is innocuous,

  2. it is used for pkg> test ThatPackage, so then it is useful (the only harm is that it may fetch some earlier versions of various packages, but again that is fine),

  3. for CI, it will use that exact test environment, which has some benefits, but also negates some of the advantages of CI (testing with package versions which I don’t happen to have installed on my computer). This can be worked around by doing a Pkg.update() in the CI script; if it works it is fine, if it breaks then the manifest works as a backup.

  1. Yes, the manifest is only “active” if the project for that package is the current Project for example by starting with --project in that directory.

  2. It is used when running test on the current active project (which is the case in CI). It is not used for test ThatPackage unless ThatPackage is the current active project.

  3. For CI, if a manifest is checked in, it will be used (since the active project will be that of the package).

Thanks. With the manifest checked in, is it a good idea to do a

Pkg.update()

then in the CI (eg Travis) script? My concern is that I may forget to keep updating the manifest regularly and could be testing a configuration that is no longer relevant as packages moved on.

I think you misunderstand my point. The resolver is a different issue and I’m not asking for a “user-space” workaround.

If I understand correctly, this is a wrong implementation of the specification of REQUIRE file. I understand that it didn’t matter before the full transition to General but I think the current setup of General ignores what was specified in REQUIRE files.

Of course, I don’t know much about packaging system implementation so I may be missing some very obvious. I hope I’m not making unnecessary noise.

I’m not sure if you are replying to me but anyway, I just pointed out the technical reason why test Plots fail. If you didn’t find it useful, perhaps someone else will.

@kristoffer.carlsson Yes, I was replying to you. And I thought your previous comment was a reply to me.

So the core of your post was this then?

I don’t think that is the “correct” behavior. Changing https://github.com/JuliaLang/Pkg.jl/issues/110 seems better to me.

My argument is that introducing upper bounds in General when there is no such declaration in the original REQUIRE files (and not updating them) is wrong.

The sentence you quoted is misleading without the preceding part:

Counterpoint: claiming compatibility with breaking version that doesn’t exist yet is wrong.

1 Like

First of all, I’m not claiming that loose compatibility declaration is the best software practice. I’m talking about the specification of the REQUIRE/Project.toml format and the correctness of the implementation.

Let me ask a genuine question. The documentation of Pkg says

If the compatibility for a dependency is not given, the project is assumed to be compatible with all versions of that dependency.

Does this mean “maximally “semver”-compatible version of the version existed at the time of the registration?” What about the >= specifier? If that’s the case, I think it is better to clarify as such in the documentation.

If that’s not the case, i.e., there is a facility to express “compatible with all versions”, I don’t understand why the information in REQUIRE files is not faithfully translated.

Having said that, I do 100%-agree with

for post-1.0 semver-compatible software. I’m ambivalent about it for pre-1.0.