-
-
Notifications
You must be signed in to change notification settings - Fork 597
feat(py_wheel): Normalize name and version #1331
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Instead of following the obsolete PEP 427 escaping procedure for distribution names and versions, use the rules specified by https://packaging.python.org/en/latest/specifications (sections "Package name normalization" and "Binary distribution format"). For the versions, this means normalizing them according to PEP 440. This adds full support for PEP 440-compliant version identifiers, including local version identifiers (the part after "+" in versions such as "1.0+ubuntu.1"). BREAKING CHANGE: - Distribution names have stronger requirements now: "A valid name consists only of ASCII letters and numbers, period, underscore and hyphen. It must start and end with a letter or number." https://packaging.python.org/en/latest/specifications/name-normalization/ - Versions must be valid PEP 440 version identifiers. Previously versions such as "0.1-2-3" would have been accepted; that is no longer the case. - The file name of generated wheels may have changed, if the distribution name or the version identifier wasn't in normalized form. Fixes bazel-contrib#883
Could I get some help with the test failures? They seem to be related to this line: Looks like @alexeagle and @rickeylev were involved in the patch (1722988c) that introduced |
I think by default we are not stamping the builds within the CI, so the Another approach could be to do |
@vonschultz does this change fix this issue: #1132 |
Even in an unstamped build, version placeholders should be replaced by a constant value like |
We need a valid PEP 440 version even if we're doing a non-stamped build, even if there are placeholders (stamping keys) in the version string. In that case, replace the placeholders with 0, and append the original version string, sanitized to dot-separated alphanumerics.
Yes, @chrislovecnm, this fixes #1132. I updated the pull request message accordingly. |
@aignas or @rickeylev PTAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re: requiring pep 440 compliant names: I don't think we should try to perform such strict validation. Doing the basic transforms to make a string more pep 440 compatible (e.g. -
to .
or w/e) makes sense because we want to produce output that other tools can consume. But we don't really care if a user does e.g. .after
instead of .post
, or does .post0.dev4.rc1
.
The wheelmaker now depends on packaging.version, which means the py_wheel user now needs to load pip dependencies in their WORKSPACE.bazel file
I'm pretty sure we call pip_install_dependencies() internally, so users don't need to worry about this. You can remove this from the description.
python/private/py_wheel.bzl
Outdated
) | ||
return escaped | ||
|
||
def normalize_pep440(version): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, wow. Now this is some Starlark!
But, this is very hard to follow -- this looks like a stack-based parser, and there's several hundred lines of nested defs that close over local state and modify that same state.
This is going to take some effort to review, which doesn't bode well for others to figure out, and thus its maintainability. We'll need to change it so that it's more approachable to other devs. I'll give some more concrete feedback after I take a closer look.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a parser, yes. If you have ideas on how to make it more approachable, I'm all for that.
My preference would have been to use a regular expression instead — in particular because PEP 440 includes a regular expression that we could take more or less as it is. But regular expressions aren't supported in Starlark, so here I am writing a parser instead. (Though whether a regular expression is more approachable than a parser is perhaps debatable, unless you're really into regular expressions.)
My apologies for the complexity, but PEP 440 is hundreds of lines of English, so some of the complexity seems unavoidable. On the other hand, PEP 440 is a fixed document. Once we have a normalize_pep440()
function that works to our satisfaction, there will be few (if any) reasons to go back and change it. That's good for maintainability, isn't it, functions that have no conceivable reason to change as the product evolves.
I don't think we in In my mind one of two approaches makes sense. Either we take it upon us to do the normalization, in which case we should do it according to the specification, or we put the responsibility on the user entirely, documenting that the
I tested this. If I just do a minimal
in a toy project, as documented on https://github.com/bazelbuild/rules_python/releases/tag/0.24.0, and then try to use a It's true that we call |
For wheel builds that don't require specific semantic versioning (e.g. for internal tools that are installed in multiple other projects at a company), I think it's pretty common to append a edit: My apologies - was following along on #883 and #1132 but misplaced my comment. Super happy to see this happening! 🎉 |
Not sure I follow @alexmirrington. What you are talking about is a local version identifier. That is not currently supported on the main branch, which is #883. Fixing #883 that is the purpose of this pull request, and the validation that's done here does support local version identifiers: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general the parsing approach LGTM, but the tests could be improved to unit test parts of the parser and then sanity check that the parts work together. Right now we only have integration tests.
I have made some experiments in my branch and created a PR to this branch in vonschultz#1 so that it would be easy for you to review and merge.
@rickeylev, I agree that this looks a little bit daunting at first and may require a few iterations of cleanup whilst we get to understand the code, however, once the nested def
s are removed and we have a stack
-like parser with very few methods it suddenly becomes much easier to grok in my opinion.
python/private/py_wheel.bzl
Outdated
token = version[context["start"]] | ||
|
||
if predicate(token): | ||
if type(value) in ["function", "builtin_function_or_method"]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is called many times, consider optimizing and doing
if type(value) in ["function", "builtin_function_or_method"]: | |
t = type(value) | |
if t == "function" or t == "builtin_function_or_method": |
That way we are not creating a list just for comparison.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure? I'm not measuring any noticeable speed-up. Measuring with
time bazelisk test //tests/py_wheel:test_pep440_normalization
(with bazelisk clean
in between), and sometimes the first approach is faster, sometimes the second approach is faster.
If it's speed we're after, it was noticeably faster before the readability improvements you suggested. (Sorry, I do like the readability improvements.) If we're going for readability over speed, I like the list comprehension.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for being rigorous and checking it. LGTM.
PEP440 normalization code structure suggestions
//python/private:py_wheel.bzl depends on a new file, py_wheel_normalize_pep440.bzl, which therefore needs to be exported by the python/private package and listed in the //docs:packaging_bzl sources.
In the case where the epoch parsed to "0!", it should be reset to the empty string. The previous way of doing that forgot to return acceptance to the caller; the new way of doing it is clearer than manipulating the "start" of the context.
The buildifier-lint checker wants arguments and return values to be documented.
The reviewers apparently like long lines. Not sold on that, but contributors should follow the style of the projects they contribute to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR, @rickeylev, with the new structure of having fewer things being passed via the closure and nested defs, does this look better?
python/private/py_wheel.bzl
Outdated
_escape_filename_segment(ctx.attr.distribution), | ||
_escape_filename_segment(version), | ||
_escape_filename_distribution_name(ctx.attr.distribution), | ||
normalize_pep440(version), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great if we could make this new behaviour optional and gated under a boolean flag so that users that depend on the broken behaviour have more time to migrate.
The plan could be:
- Add a flag named
normalize_version_pep440
which defaults toFalse
for now. - If the flag is set to
True
then the new codepath is used. - In a future release the
incompatible_normalize_version
is set toTrue
but users have ability to set it to False if required.
That way the change is no longer breaking.
Consider adding an extra dictionary with args named:
_feature_flags = {
"incompatible_normalize_version": attr.bool(
default = False,
doc = "Normalize the package version according to PEP440 standard",
),
"incompatible_explicit_distribution_stamp_vars": attr.bool(
default = False,
doc = "Change the format of how the stamp variables can be used to " +
"in the distribution name. With this option set to True, the " +
"user has to pass stamp variables enclosed in '{}', e.g. " +
"'{BUILD_TIMESTAMP}'."
),
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To add some context (I was out and about on my phone when Ignas asked me about this, so I didn't have time to respond in full):
The key point is to decouple upgrading the rules_python version from having to address incompatible changes. This allows a more incremental and manageable upgrade process. A user can upgrade rules_python, opt into behavior where they can, and followup later where they can't. The next version (which has the incompatible behavior by default) blocks them from upgrading, but they're still able to make their current version forward compatible.
To avoid having breaking changes, add feature flags "incompatible_normalize_name" and "incompatible_normalize_version", which default to False for the time being.
Add the "incompatible_normalize_version" and "incompatible_normalize_name" feature flags to the documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for doing the extra work to add the feature flags. I think the only thing remaining before merging is to add a line in the CHANGELOG.md
file.
Add links to the specifications. Note that we have support for placeholders. Co-authored-by: Ignas Anikevicius <240938+aignas@users.noreply.github.com>
Just a `bazelisk run //docs:update` after having changed the description of "incompatible_normalize_name".
Add a note about the two new feature flags in the change log: incompatible_normalize_name and incompatible_normalize_version.
[](https://renovatebot.com) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [rules_python](https://togithub.com/bazelbuild/rules_python) | http_archive | minor | `0.25.0` -> `0.26.0` | --- ### Release Notes <details> <summary>bazelbuild/rules_python (rules_python)</summary> ### [`v0.26.0`](https://togithub.com/bazelbuild/rules_python/releases/tag/0.26.0) [Compare Source](https://togithub.com/bazelbuild/rules_python/compare/0.25.0...0.26.0) #### Using Bzlmod with Bazel 6 **NOTE: bzlmod support is still beta. APIs subject to change.** Add to your `MODULE.bazel` file: ```starlark bazel_dep(name = "rules_python", version = "0.26.0") pip = use_extension("@​rules_python//python/extensions:pip.bzl", "pip") pip.parse( name = "pip", requirements_lock = "//:requirements_lock.txt", ) use_repo(pip, "pip") ``` #### Using WORKSPACE Paste this snippet into your `WORKSPACE` file: ```starlark load("@​bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "rules_python", sha256 = "9d04041ac92a0985e344235f5d946f71ac543f1b1565f2cdbc9a2aaee8adf55b", strip_prefix = "rules_python-0.26.0", url = "https://github.com/bazelbuild/rules_python/releases/download/0.26.0/rules_python-0.26.0.tar.gz", ) load("@​rules_python//python:repositories.bzl", "py_repositories") py_repositories() ``` ##### Gazelle plugin Paste this snippet into your `WORKSPACE` file: ```starlark load("@​bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "rules_python_gazelle_plugin", sha256 = "9d04041ac92a0985e344235f5d946f71ac543f1b1565f2cdbc9a2aaee8adf55b", strip_prefix = "rules_python-0.26.0/gazelle", url = "https://github.com/bazelbuild/rules_python/releases/download/0.26.0/rules_python-0.26.0.tar.gz", ) ### To compile the rules_python gazelle extension from source, ### we must fetch some third-party go dependencies that it uses. load("@​rules_python_gazelle_plugin//:deps.bzl", _py_gazelle_deps = "gazelle_deps") _py_gazelle_deps() ``` #### What's Changed - doc: Note Python version changes in CHANGELOG by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1391](https://togithub.com/bazelbuild/rules_python/pull/1391) - fix: bcr releaser email by [@​f0rmiga](https://togithub.com/f0rmiga) in [https://github.com/bazelbuild/rules_python/pull/1392](https://togithub.com/bazelbuild/rules_python/pull/1392) - Adding kwargs to gazelle_python_manifest by [@​linzhp](https://togithub.com/linzhp) in [https://github.com/bazelbuild/rules_python/pull/1289](https://togithub.com/bazelbuild/rules_python/pull/1289) - docs: Use correct link to build badge image and build status page. by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1390](https://togithub.com/bazelbuild/rules_python/pull/1390) - feat(py_console_script_binary)!: entry points with custom dependencies by [@​aignas](https://togithub.com/aignas) in [https://github.com/bazelbuild/rules_python/pull/1363](https://togithub.com/bazelbuild/rules_python/pull/1363) - fix(whl_library): avoid unnecessary repository rule restarts by [@​aignas](https://togithub.com/aignas) in [https://github.com/bazelbuild/rules_python/pull/1400](https://togithub.com/bazelbuild/rules_python/pull/1400) - refactor: add missing `//python/config_settings/private:distribution` target by [@​philsc](https://togithub.com/philsc) in [https://github.com/bazelbuild/rules_python/pull/1402](https://togithub.com/bazelbuild/rules_python/pull/1402) - Import pycross_wheel_library by [@​philsc](https://togithub.com/philsc) in [https://github.com/bazelbuild/rules_python/pull/1403](https://togithub.com/bazelbuild/rules_python/pull/1403) - refactor: upgrade certifi by [@​cflewis](https://togithub.com/cflewis) in [https://github.com/bazelbuild/rules_python/pull/1397](https://togithub.com/bazelbuild/rules_python/pull/1397) - fix: don't set distribs in version transitioning rule by [@​comius](https://togithub.com/comius) in [https://github.com/bazelbuild/rules_python/pull/1412](https://togithub.com/bazelbuild/rules_python/pull/1412) - fix(gazelle): upgrade rules_go: 0.39.1 -> 0.41.0 to work with upcoming Bazel versions by [@​sgowroji](https://togithub.com/sgowroji) in [https://github.com/bazelbuild/rules_python/pull/1410](https://togithub.com/bazelbuild/rules_python/pull/1410) - fix: gazelle: Fix non-hermetic runfiles lookup by [@​fmeum](https://togithub.com/fmeum) in [https://github.com/bazelbuild/rules_python/pull/1415](https://togithub.com/bazelbuild/rules_python/pull/1415) - feat: create toolchain type for py_proto_library by [@​comius](https://togithub.com/comius) in [https://github.com/bazelbuild/rules_python/pull/1416](https://togithub.com/bazelbuild/rules_python/pull/1416) - internal: copy Starlark rule implementation from Bazel by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1418](https://togithub.com/bazelbuild/rules_python/pull/1418) - feat: add new Python toolchain versions by [@​aignas](https://togithub.com/aignas) in [https://github.com/bazelbuild/rules_python/pull/1414](https://togithub.com/bazelbuild/rules_python/pull/1414) - internal(pystar): make starlark impl (mostly) loadable by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1422](https://togithub.com/bazelbuild/rules_python/pull/1422) - feat: generate py_library per file by [@​raylu](https://togithub.com/raylu) in [https://github.com/bazelbuild/rules_python/pull/1398](https://togithub.com/bazelbuild/rules_python/pull/1398) - chore: bump default python versions by [@​aignas](https://togithub.com/aignas) in [https://github.com/bazelbuild/rules_python/pull/1425](https://togithub.com/bazelbuild/rules_python/pull/1425) - feat: Support netrc-based authentication for python_repository rule by [@​LINKIWI](https://togithub.com/LINKIWI) in [https://github.com/bazelbuild/rules_python/pull/1417](https://togithub.com/bazelbuild/rules_python/pull/1417) - refactor(pystar): load (but don't use) Starlark implementation. by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1428](https://togithub.com/bazelbuild/rules_python/pull/1428) - fix(gazelle): runfiles discovery by [@​aignas](https://togithub.com/aignas) in [https://github.com/bazelbuild/rules_python/pull/1429](https://togithub.com/bazelbuild/rules_python/pull/1429) - feat, refactor(pystar): bzl_library for packaging.bzl; fix pystar doc building and py_wheel by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1432](https://togithub.com/bazelbuild/rules_python/pull/1432) - refactor(toolchain): use a helper method to convert an X.Y version to X.Y.Z by [@​aignas](https://togithub.com/aignas) in [https://github.com/bazelbuild/rules_python/pull/1423](https://togithub.com/bazelbuild/rules_python/pull/1423) - pycross: Rename `pycross_wheel_library` and make it work by [@​philsc](https://togithub.com/philsc) in [https://github.com/bazelbuild/rules_python/pull/1413](https://togithub.com/bazelbuild/rules_python/pull/1413) - fix: Skip printing unneccesary warning. by [@​matts1](https://togithub.com/matts1) in [https://github.com/bazelbuild/rules_python/pull/1407](https://togithub.com/bazelbuild/rules_python/pull/1407) - refactor(bzlmod)!: simplify pip.parse repository layout by [@​aignas](https://togithub.com/aignas) in [https://github.com/bazelbuild/rules_python/pull/1395](https://togithub.com/bazelbuild/rules_python/pull/1395) - feat(bzlmod): mark pip extension as os/arch dependent by [@​aignas](https://togithub.com/aignas) in [https://github.com/bazelbuild/rules_python/pull/1433](https://togithub.com/bazelbuild/rules_python/pull/1433) - chore: bump internal_deps by [@​aignas](https://togithub.com/aignas) in [https://github.com/bazelbuild/rules_python/pull/1322](https://togithub.com/bazelbuild/rules_python/pull/1322) - tests(pystar): CI configs that uses Starlark implementation of rules by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1435](https://togithub.com/bazelbuild/rules_python/pull/1435) - internal(pystar): Copy @​bazel_tools//tools/python files to rules_python by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1437](https://togithub.com/bazelbuild/rules_python/pull/1437) - internal(pystar): Make py_runtime_pair and autodetecting toolchain mostly loadable. by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1439](https://togithub.com/bazelbuild/rules_python/pull/1439) - tests: Move base rule tests under tests instead of //tools/build_defs/python by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1440](https://togithub.com/bazelbuild/rules_python/pull/1440) - tests(pystar): py_runtime_pair and py_runtime analysis tests by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1441](https://togithub.com/bazelbuild/rules_python/pull/1441) - fix(pystar): Use py_internal for runfiles_enabled, declare_shareable_artifact, share_native_deps by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1443](https://togithub.com/bazelbuild/rules_python/pull/1443) - build(deps): bump urllib3 from 1.26.13 to 1.26.17 in /examples/pip_repository_annotations by [@​dependabot](https://togithub.com/dependabot) in [https://github.com/bazelbuild/rules_python/pull/1447](https://togithub.com/bazelbuild/rules_python/pull/1447) - build(deps): bump urllib3 from 1.25.11 to 1.26.17 in /examples/pip_install by [@​dependabot](https://togithub.com/dependabot) in [https://github.com/bazelbuild/rules_python/pull/1444](https://togithub.com/bazelbuild/rules_python/pull/1444) - fix: add missing `@bazel_tools` files to bzl_library dependencies. by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1457](https://togithub.com/bazelbuild/rules_python/pull/1457) - tests(pystar): add analysis tests to cover basic windows building by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1452](https://togithub.com/bazelbuild/rules_python/pull/1452) - docs: move dependency management into respective bzl packages by [@​rickeylev](https://togithub.com/rickeylev) in [https://github.com/bazelbuild/rules_python/pull/1459](https://togithub.com/bazelbuild/rules_python/pull/1459) - feat(py_wheel): Normalize name and version by [@​vonschultz](https://togithub.com/vonschultz) in [https://github.com/bazelbuild/rules_python/pull/1331](https://togithub.com/bazelbuild/rules_python/pull/1331) - chore: add new Python toolchains from indygreg by [@​aignas](https://togithub.com/aignas) in [https://github.com/bazelbuild/rules_python/pull/1461](https://togithub.com/bazelbuild/rules_python/pull/1461) #### New Contributors - [@​cflewis](https://togithub.com/cflewis) made their first contribution in [https://github.com/bazelbuild/rules_python/pull/1397](https://togithub.com/bazelbuild/rules_python/pull/1397) - [@​sgowroji](https://togithub.com/sgowroji) made their first contribution in [https://github.com/bazelbuild/rules_python/pull/1410](https://togithub.com/bazelbuild/rules_python/pull/1410) - [@​raylu](https://togithub.com/raylu) made their first contribution in [https://github.com/bazelbuild/rules_python/pull/1398](https://togithub.com/bazelbuild/rules_python/pull/1398) - [@​LINKIWI](https://togithub.com/LINKIWI) made their first contribution in [https://github.com/bazelbuild/rules_python/pull/1417](https://togithub.com/bazelbuild/rules_python/pull/1417) **Full Changelog**: bazel-contrib/rules_python@0.25.0...0.26.0 </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/bazel-contrib/rules_bazel_integration_test). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4wLjMiLCJ1cGRhdGVkSW5WZXIiOiIzNy4wLjMiLCJ0YXJnZXRCcmFuY2giOiJtYWluIn0=--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Added the
incompatible_normalize_name
feature flag to normalize the package distribution name according to latest Python packaging standards. Defaults toFalse
for the time being.Added the
incompatible_normalize_version
feature flag to normalize the package version according to PEP440 standard. This also adds support for local version specifiers (versions with a+
in them), in accordance with PEP440. Defaults toFalse
for the time being.Instead of following the obsolete PEP 427 escaping procedure for distribution names and versions, we should use the rules specified by https://packaging.python.org/en/latest/specifications (sections "Package name normalization" and "Binary distribution format"). For the versions, this means normalizing them according to PEP 440.
Added as feature flags to avoid forcing the user to deal with breaking changes when upgrading
rules_python
:Distribution names have stronger requirements now: "A valid name consists only of ASCII letters and numbers, period, underscore and hyphen. It must start and end with a letter or number." https://packaging.python.org/en/latest/specifications/name-normalization/
Versions must be valid PEP 440 version identifiers. Previously versions such as "0.1-2-3" would have been accepted; that is no longer the case.
The file name of generated wheels may have changed, if the distribution name or the version identifier wasn't in normalized form.
The wheelmaker now depends on
packaging.version
, which means thepy_wheel
user now needs to load pip dependencies in theirWORKSPACE.bazel
file:Fixes #883. Fixes #1132.