You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
WIP: Add a loading mechanism for compat-dependent API sets
This is a first WIP implementation for providing the underlying
mechanism for a #54905. I haven't fully designed out what I want the
final thing to look like, but I've thought about it enough that I think
we need some hands-on examples for further design exploration, which is
what this PR is designed to support.
The core idea here is that if you specify in your package
```
[compact]
julia = "0.14"
MyDependency = "0.3,0.4"
```
Then this mechanism will ask `MyDependency` to provide you a view of its
API that is compatible with its 0.3 version, even if 0.4 is installed.
The objective of this mechanism is that downstreams of widely used packages
(including `Base` and standard libraries) can be upgraded more gradually
by allowing some portion of the packages in project to use the new 0.4
API set, while packages that have not yet upgraded can continue to use
the 0.3 API set. Currently, whenever a widely used package changes an
API there's a big frenzied rush to update downstreams, which just isn't
sustainable as the ecosystem grows.
In other languages, problems like these are solved by allowing multiple
versions of the same package to be loaded. However, in julia, this is
not particularly feasible by default because packages may have generic
functions that need to be extended and unified and which break if there
are multiple copies of such resources.
That said, for simple packages, this mechanism could be used to emulate
the multiple-version-loading strategy on an opt-in basis.
The way that this works is that `loading` gains an additional layer of
indirection that is provided the `compat` specification of the loading
package. Packages can opt into this by providing a
```
function _get_versioned_api(compat)
end
```
function. Where the default is equivalent to
`_get_versioned_api(compat) = @__MODULE__`.
The loader makes no further assumptions on either the structure of
`compat` or how the package processes it. This is intentional to
allow evolution without impacting the core loading logic (of course
Pkg also looks at the structure of compat, as would the
`_get_versioned_api` implementation in Base, so there are some
constraints).
That said, the envisioned usage of this is that we create a standard
(in the sense of being widely used, not in the sense of it being
a stdlib) package to help package authors define the APIs of their
packages more precisely and with version information. This package
would then create a set of modules under the hood that describe
these APIs to the sytem and would set up `_get_versioned_api`
appropriately (i.e. the mechanism is not intended to be used
directly in most cases).
To actually make this useful, we will likely need some additional
features in the binding system, in particular:
1. #59859 and a few variants
thereon to make the API modueles look more transparent.
2. A mechanism to intercept extension of generic function overloads
in order to be able to provide compatibility (Design/PR for this
forthcoming).
Note that this PR itself is WIP, it is not yet fully complete and
there is also a Pkg.jl side of this required to put compat info
into the manifest.
0 commit comments