Are extension packages importable?

The new extension packages functionality looks great! Code Loading · The Julia Language

I get that its intended use is to provide Requires.jl-like functionality, i.e. to run some code when some other package is loaded, e.g. in order to add compatibility methods.

Two questions:

  1. Is there a mechanism to import the module defined in an extension package?
  2. Is there a mechanism to install the packages for an extension? E.g. if package Foo had an extension FooExt depending on ExtPkg say, can I specify to install FooExt somehow (which implicitly installs ExtPkg) instead of specifying ExtPkg explicitly?

If not, are these on the roadmap?

The second suggestion is a lot like Python’s “extras”, which you’d install like

pip install 'Foo[FooExt]'

My vague understanding is that extension packages are true packages on their own. You could probably add them as subdirectory packages.

I think @kristoffer.carlsson would be the one most qualified to clarify this.

Here is the pull request to Julia:

and the corresponding pull request to Pkg.jl:

Here are some example extension modules:

It appears that these modules do not have UUIDs so they may not be bonafide packages in themselves. The example prototypes show the extensions are usually modules which are included as submodules of the base package.

1 Like

You can get the module using get_extension. Using PGFPlotsX as an example:

julia> using PGFPlotsX

julia> Base.get_extension(PGFPlotsX, :ColorsExt)

julia> using Colors

julia> Base.get_extension(PGFPlotsX, :ColorsExt)

So before the extension is loaded get_extension will return nothing.

In general though, you should probably try to make getting the module not required to use the package. It is better to try have the extension add methods via dispatch and make the new functionality available in that way.

They get their UUID by combining the UUID of the parent package and the name of the extension module:

# Get UUID of extension module
julia> Base.PkgId(Base.get_extension(PGFPlotsX, :ColorsExt)).uuid

# Which is computed like this:
julia> Base.uuid5(Base.identify_package("PGFPlotsX").uuid, "ColorsExt")

Thank you for the replies!

I get your point for the intended usage of extensions, I was more wondering if the same mechanism could be co-opted to provide something a bit like Python’s “extras”.

In a way I’m asking if it’s possible to have multiple modules in a single Julia package which can be independently imported and have separate dependencies. The answer to that is seemingly currently “no” - which is fine because you can always create multiple packages instead.

To be concrete, suppose the package Foo has an extension Ext which depends on Bar and Baz.

Then it may be nice to let

pkg> add Foo[Ext]

be a shorthand for

pkg> add Foo, Bar, Baz

(thus allowing the fact that Ext depends on Bar and Baz to be an implementation detail).

And further, it may be nice to let

import Foo[Ext]

be a shorthand for

import Foo, Bar, Baz
const Ext = Base.get_extension(Foo, :Ext)

It still isn’t clear to me if the name of the extension should even be something a user should ever know about.

1 Like

I guess like everything else, it’s up to the package author whether or not a particular extension is part of the API.

Well yes, but I do think that best practices should be to make the functionality exposed by overloading functions in the parent. It can even be a zero method function that is overloaded. So you would not need to access the namespace of the extension.

1 Like