Repository navigation
feat: support and check minver - #801
Conversation
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
Coverage report —
|
| Name | Stmts | Miss | Cover | Missing |
|---|---|---|---|---|
| src/kernels/__init__.py | 14 | 0 | 100% | |
| src/kernels/_system.py | 6 | 1 | 83% | 10 |
| src/kernels/_versions.py | 78 | 9 | 88% | 47, 53-54, 57-58, 97, 119, 130, 136 |
| src/kernels/archs.py | 56 | 1 | 98% | 95 |
| src/kernels/backends.py | 212 | 62 | 71% | 40, 44, 48-51, 68, 90, 108, 117, 121, 125-127, 148, 157, 161, 165-167, 188, 199, 201, 208-211, 224, 228, 232-252, 260, 283-303 |
| src/kernels/compat.py | 8 | 1 | 88% | 5 |
| src/kernels/deps.py | 81 | 1 | 99% | 58 |
| src/kernels/hf_hub.py | 62 | 3 | 95% | 18, 20, 114 |
| src/kernels/importer.py | 76 | 6 | 92% | 119, 164, 168, 171, 185-186 |
| src/kernels/install.py | 21 | 7 | 67% | 78-102 |
| src/kernels/layer/__init__.py | 6 | 0 | 100% | |
| src/kernels/layer/_interval_tree.py | 103 | 4 | 96% | 23, 52, 147, 150 |
| src/kernels/layer/device.py | 48 | 14 | 71% | 42, 47-49, 91, 96-98, 101, 149, 152, 155-157 |
| src/kernels/layer/func.py | 87 | 6 | 93% | 91, 122, 194, 314, 340, 368 |
| src/kernels/layer/globals.py | 5 | 0 | 100% | |
| src/kernels/layer/kernelize.py | 74 | 8 | 89% | 255, 281, 289-290, 296, 300, 316-318 |
| src/kernels/layer/layer.py | 216 | 15 | 93% | 178, 223, 249, 367, 447-448, 460, 469, 477, 488, 517, 521, 534, 587, 617 |
| src/kernels/layer/mode.py | 14 | 0 | 100% | |
| src/kernels/layer/repos.py | 144 | 42 | 71% | 27, 33, 36-43, 63-64, 70, 73-76, 90, 94, 103-104, 110, 113-116, 123-124, 130, 133-136, 143-144, 150, 153-156, 163-164, 170, 173-176, 257 |
| src/kernels/load.py | 69 | 2 | 97% | 326, 365 |
| src/kernels/locking.py | 89 | 64 | 28% | 35-83, 91-98, 102-125, 137, 152-159, 165-175, 179-186 |
| src/kernels/python_deps.py | 58 | 6 | 90% | 59-60, 64-65, 101, 104 |
| src/kernels/resolver.py | 141 | 2 | 99% | 182, 188 |
| src/kernels/status.py | 49 | 2 | 96% | 23, 81 |
| src/kernels/variants.py | 278 | 19 | 93% | 64, 95, 116, 146, 255-256, 298-301, 303, 387-394, 400-406, 437-443, 455-461 |
| src/kernels/verify.py | 88 | 1 | 99% | 32 |
| TOTAL | 2083 | 276 | 87% |
Updated by the Test kernels workflow on commit 74806977ef9cb8a5fa07057a2d82c78b073011e4.
| - `source`: Git-compatible URL (passable to `git clone`) of the kernel-builder | ||
| formatted source repository. This repository must contain a `build.toml` and | ||
| `flake.nix` so that it can be pulled and built with the kernel builder. | ||
| - `minver`: the minimum version of the `kernels` Python library required |
There was a problem hiding this comment.
I don't think we want this inbuild.toml at all? The kernel builder should determine the minimum version, not the user. They will with a very high probability set the wrong version, e.g.:
- Not realizing that a kernel with dependencies requires 0.17, setting it to something old (or not at all).
- Setting it to current version because that's the only thing they tested on, 'just to be safe', not making the kernel work older kernels versions.
I think the best way to tackle this is to add a method to Config:
fn required_kernels_version(&self, backend: Backend) -> Version<3> {
// ...
}
That determines based on the features used inside Config what to set the version to. The default would be 0.14, but e.g. if there is a non-empty list of kernel dependencies for the given backend, set it to 0.17.
There was a problem hiding this comment.
makes sense, removed it from build.toml. the builder now derives it with Build::required_kernels_version(backend), defaulting to 0.14.0 and bumping to 0.17.0 when the backend has kernel dependencies. since [general] denies unknown fields, setting minver in build.toml is now a parse error rather than a silently ignored key
| pub id: String, | ||
| pub version: usize, | ||
| #[serde(skip_serializing_if = "Option::is_none")] | ||
| pub minver: Option<Version<3>>, |
There was a problem hiding this comment.
I think we should be explicit and use kernels_minver.
There was a problem hiding this comment.
renamed to kernels_minver (kernels-minver in metadata.json). kept it optional so metadata written before the key existed still parses
| id: String, | ||
| name: PyKernelName, | ||
| version: usize, | ||
| minver: Option<String>, |
There was a problem hiding this comment.
| minver: Option<String>, | |
| minver: Option<PyVersion>, |
We still need a conversion from Version<N>, but I intentionally made PyVersion store a Box<[usize]> so that Version<N> can be boxed and used inside PyVersion.
There was a problem hiding this comment.
updated to Option<PyVersion> with a From<Version<N>> impl. the trailing zero stripping moved into a shared helper so a converted Version<3> and a parsed version compare equal
| # Avoid an import cycle. | ||
| from kernels import __version__ | ||
|
|
||
| if parse(__version__) < parse(minver): |
There was a problem hiding this comment.
For minver, we shouldn't rely on parse but the fact that we already have a typed version in Rust-land (see comments above).
For the __version__, we might also have to strip dev tags and such, otherwise we'll get not-matching versions on our development branch:
❯ python3 -c 'from packaging.version import parse; print(parse("0.17.0.dev0") < parse("0.17.0"))'
True
This would be really annoying, since I don't think we want to write dev versions to metadata.
There was a problem hiding this comment.
the check now compares two kernels_data.Version
parse is only used on our own __version__ to take the release segment, so 0.17.0.dev0 satisfies a 0.17.0 requirement (the warning still prints the verbatim __version__)
note: if __version__ is not pep 440 (e.g. a vcs derived version) the check is skipped, since a warning should not be able to break the import
e78a05f to
c235f23
Compare
| } | ||
|
|
||
| impl PyVersion { | ||
| /// Construct a version from its components, stripping trailing zeros so |
There was a problem hiding this comment.
If what we are wrapping is a Version<3> and the versions are identical, there will always be the same number of trailing zeros. Version<N> is there to strongly type versions.
There was a problem hiding this comment.
removed the trailing zero stripping and the normalized helper, versions are stored as is now
| fn from(version: Version<N>) -> Self { | ||
| PyVersion::normalized(version.to_vec()) | ||
| } |
There was a problem hiding this comment.
Directly put the Version<N> in the box. We keep all the guarantees of it.
There was a problem hiding this comment.
done, From<Version<N>> now boxes the components directly through the [usize] deref, no copy into a Vec first
| Ok(Self { | ||
| inner: parts.into_boxed_slice(), | ||
| }) | ||
| Ok(PyVersion::normalized(parts)) |
There was a problem hiding this comment.
So, we can't have the same guarantees in Python-land since we get a string. Maybe we can require another argument for the expected length?
Or put the trailing zero logic in Eq/Ord.
There was a problem hiding this comment.
went with the Eq/Ord option to keep from_str a single argument. comparisons are component-wise with missing components counting as zero, so 0.17 and 0.17.0 compare as equal (Hash skips trailing zeros to stay consistent with Eq). storage is untouched, str() round trips what was parsed
note: this also covers the pep 440 release segment in _installed_version, parse("0.17").release is (0, 17) and would otherwise compare below a 0.17.0 minver
this pr adds
minverto the metadata so the client library can check if the current version meets the kernel metadata requirements