How to test if package is installed

What’s the recommended API for testing if a package (which may not be registed) is installed? I have seen two versions floating around:

"somepackage" ∈ keys(Pkg.installed())

and

isdir(Pkg.dir("somepackage"))

The second one feels hackish. First I thought checking Pkg.installed("somepackage") but that can return an error for unregistered, uninstalled packages.

(This is for use in .juliarc.jl, when running different versions.)

3 Likes

The second one is very similar to how Pkg itself does it, so I would not say it’s hackish (unless you believe the approach of Pkg itself to be hackish). If you want to match exactly how Pkg determines if a package is installed, use

isinstalled(pkg::AbstractString) =
    pkg != "METADATA" && pkg != "REQUIRE" && pkg[1] != '.' && Pkg.cd(isdir, pkg)
1 Like

Pkg doesn’t have the most useful conception of what “installed” means at the moment. What are you trying to accomplish? Modules can be used from anywhere on LOAD_PATH without Pkg knowing anything about them.

basically, something like this in .juliarc:

if (SomePackage is installed) && (VERSION >= v"0.6-")
   eval(quote
           import SomePackage
           SomePackage.dostuff(...)
        end)
end

ie using a package but not causing an error if it is not available.

Can’t you just use a try catch?

3 Likes

With Julia v0.7.0 and v1.0.0 releases, I want to revive this topic. The reason is that Pkg.installed does not exist anymore in these new releases. Moreover, executing, say, Pkg.dir("OhMyREPL) gives us the following warning on v0.7.0:

WARNING: Base.Pkg is deprecated, run `using Pkg` instead
  likely near /Users/xxx/.julia/config/startup.jl:1
┌ Warning: `Pkg.dir(pkgname, paths...)` is deprecated; instead, do `import OhMyREPL; joinpath(dirname(pathof(OhMyREPL)), "..", paths...)`.
└ @ Pkg.API /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v0.7/Pkg/src/API.jl:454

This system suggestion is not good since we want to do isdir(Pkg.dir("OhMyREPL")) and if OhMyREPL.jl is not installed, import OhMyREPL in the suggested solution generates error of course.
So what would be a good solution for v0.7.0 and v1.0.0?
Thanks!

So I’m inferring that your use case is that you want to check whether OhMyREPL is installed in your startup.jl, perhaps so that you can use it if it’s installed. I used to do this because I was changing JULIA_PKGDIR to get separate package environments, and OhMyREPL might not be installed in all of them. If you were doing the same thing, I can recommend simply installing OhMyREPL to your default package environment. If you do that, then running julia --project in some other directory will still result in OhMyREPL being on the LOAD_PATH, so it’s available regardless of your active project and you don’t need to check.

But maybe I’m wrong and you have a different use case.

Thanks a lot! However, if I put using OhMyREPL directly in my ~/.julia/config/startup.jl (v0.7/v1.0 replacement of ~/.juliarc.jl), then for normal Julia sessions, I don’t have any problem, but when I try to build Conda.jl, it somehow says that it cannot find OhMyREPL package and suggests that I should run Pkg.add("OhMyREPL") although I already added it.
But then, I found an excellent solution posted by @Simon_Bolland:

After putting this one in startup.jl, I haven’t got any error when building Conda.

Yeah, this is a known bug (Building packages call `startup.jl` with every build · Issue #609 · JuliaLang/Pkg.jl · GitHub) which will be adressed in Julia 1.0.1.

1 Like

Thanks a lot! Good to know that it would be addressed in Julia 1.0.1!

I don’t think try catch is a good idea, I mean, I’ll avoid using it if there is any other way to know if a package is intalled,

1 Like

There is a recent issue

but, with Pkg(3), I am no longer sure that this functionality should be used by other packages, except in exceptional circumstances.

If a package is needed, one can just specify it as a dependency in Project.toml, and let Pkg take care of the details. If functionality is conditional on a package being installed, we have

What I originally wanted to accomplish when I asked this question is solved by the latter.

Hi, I am confused with Pkg.installed.
I understand the function is no more existing in v1.0 but I get the list of installed packages when I ask Pkg.installed(). However, when I ask for a specific package like Pkg.installed(“Colors”), then I get an error.

**julia>** Pkg.installed("Colors")
**ERROR:** MethodError: no method matching installed(::String)
Closest candidates are:
installed() at /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v1.0/Pkg/src/API.jl:278
Stacktrace:
 [1] top-level scope at **none:0**

What is your recommandation?
Thanks for your help.

Pkg.installed() returns a Dict, it does not take arguments. So if you want to check for a specific package, use haskey. For example: haskey(Pkg.installed(), "Colors")

1 Like

Pkg.installed() returns a Dict, it does not take arguments. So if you want to check for a specific package, use haskey. For example: haskey(Pkg.installed(), "Colors")


Visit Topic or reply to this email to respond.

To unsubscribe from these emails, click here.

So with Julia 1.4, I got deprecation warnings when I tried to use Pkg.installed() and Pkg.dir(). Question is, what’s the standard way of checking if a package has been installed and instantiated in the current environment, programmatically, without using try… catch…?

My use case: I made a package and posted it to the company’s internal Bitbucket server. Many scripts I made need to use that package. However, some of the users of those scripts do not have the knowledge or patience of opening up Bitbucket account with IT, installing Git, setting up the SSH public key, etc. Instead, they are more used to just getting the source in a local folder (which is source controlled by Perforce).

Therefore, in my script I will always check if the package has been installed; if yes, I’ll directly use it; if not, I will add the conventional Perforce folder to LOAD_PATH, and use the package from there.

I don’t want to use “try… catch…” because I often use the visual debugger and have it break at any exception (even if caught), and I figure my users will do similar as they come from the .NET / Matlab world. However breaking at this package not found exception every time is not fun… :slight_smile:

Thank you for the help!

Just instantiate the project.

https://julialang.github.io/Pkg.jl/dev/environments/#Using-someone-else’s-project-1

Hi Tamas, thanks for quick reply.

As I mentioned in the use case, some users don’t have Bitbucket account and SSH access set up, so they cannot instantiate the package on the Bitbucket server.

In addition, even if they can, when they are traveling, they won’t be able to update any Julia packages without logging into the company VPN, as Julia package manager will stop when it cannot access the Bitbucket server which is behind the company’s firewall. Therefore some consider it annoying to even have any Bitbucket package installed. Instead they prefer to just push the source controlled folder to LOAD_PATH and use it there. I personally prefer instantiating the proper environment, but for my users coming from .NET / Matlab / Python 2 (which means almost everybody :)), I don’t want to force them, because they will just refuse to use Julia and stay with Matlab / Python.

Besides, I think checking if a package is installed sounds like a very reasonable feature for a package manager to have.

Thanks!

It is supported interactively, but the intended use is declarative: a project declares what it needs, and then the package manager takes care of it.

I think there are two things being conflated here: making a consistent environment available, and updating packages. As for the second, I am not sure how you are planning to do it with some access to the git repository. But for the first, you can deliver a project with relative paths in the manifest, and just activate it. Or deliver a binary, see

Thanks, I will try “deliver a project with relative paths in the manifest”.

Regarding the access to the git, my script only depends on one package I made that is on company’s Bitbucket server behind corporate firewalls; all other packages are open source packages on Github. (I guess this would be the most common use case for Julia users from a company.)

Therefore I am just trying to programmatically support both ways of package access: if the user has Bitbucket SSH access, use it; otherwise, use from a local directory. I guess this is not “a consistent” way since sometimes the package could be from LOAD_PATH instead of the environment; but I still think this is a very practical use case for those pushing Julia to Matlab and Python 2 users in a company. (Actually most do not even want to move to Python 3 due to the changes invovled, which I thought is a chance for pushing Julia. :slight_smile: But virtual environment is also hard for them to pick up.)

I guess I got the point of having package manager manage the environment completely. For these special cases I’ll try to figure something out myself. Thanks!