PIP dependency support #1
Conversation
This is broken off of my prototype repository, and there are a handful of TODOs left to resolve.
Elaborate on why the TODO to rewrite {pip,whl}.sh as Python is harder than it looks.
|
No big remarks, except adding the bazel ci configuration. |
| @@ -0,0 +1,39 @@ | |||
| # Compiled Object files | |||
damienmg
Sep 6, 2017
Why have all those parts? emacs exclude belongs to the ~/.gitignore, all the bin files should not be generated by bazel
Why have all those parts? emacs exclude belongs to the ~/.gitignore, all the bin files should not be generated by bazel
mattmoor
Sep 6, 2017
Author
Contributor
This is just my standard .gitignore file I copy from repo to repo. I never touch it again.
This is just my standard .gitignore file I copy from repo to repo. I never touch it again.
damienmg
Sep 6, 2017
Repo .gitignore are supposed to be repo specific, so not includes things like *~...
Repo .gitignore are supposed to be repo specific, so not includes things like *~...
duggelz
Sep 8, 2017
•
Collaborator
I advice I got, didn't like, but eventually learned to appreciate the wisdom of, is to create a ~/.gitignore_global with all the editor autosave filenames, etc (things that are particular to me, not to the repo I'm working on), and do git config --global core.excludesfile ~/.gitignore_global
Otherwise, you're like "What part of this Python program creates Fortran executables?!"
I advice I got, didn't like, but eventually learned to appreciate the wisdom of, is to create a ~/.gitignore_global with all the editor autosave filenames, etc (things that are particular to me, not to the repo I'm working on), and do git config --global core.excludesfile ~/.gitignore_global
Otherwise, you're like "What part of this Python program creates Fortran executables?!"
| @@ -0,0 +1,27 @@ | |||
| sudo: required | |||
damienmg
Sep 6, 2017
Add .ci/rules_python.json for CI. see https://github.com/bazelbuild/continuous-integration/blob/master/docs/owner.md#customizing-a-project
Seeing the build, you probably just want:
[
{
"variation": "",
"configurations": [
{"node": "linux-x86_64"},
{"node": "ubuntu_16.04-x86_64"},
{"node": "darwin-x86_64"}
]
}
]
Add .ci/rules_python.json for CI. see https://github.com/bazelbuild/continuous-integration/blob/master/docs/owner.md#customizing-a-project
Seeing the build, you probably just want:
[
{
"variation": "",
"configurations": [
{"node": "linux-x86_64"},
{"node": "ubuntu_16.04-x86_64"},
{"node": "darwin-x86_64"}
]
}
]
mattmoor
Sep 6, 2017
Author
Contributor
Done
Done
| which can be used directly in `deps=[]` to reference an imported `py_library`. | ||
|
|
||
| ```python | ||
| load("@my_deps//:requirements.txt", "packages") |
damienmg
Sep 6, 2017
You probably meant requirements.bzl here
You probably meant requirements.bzl here
mattmoor
Sep 6, 2017
Author
Contributor
Thanks
Thanks
damienmg
Sep 11, 2017
Not updated? Maybe you just want to delete that part all in profit of the skydoc generated.
Not updated? Maybe you just want to delete that part all in profit of the skydoc generated.
mattmoor
Sep 11, 2017
Author
Contributor
Ha, I think this bug was in two places. thanks for catching it again :)
Ha, I think this bug was in two places. thanks for catching it again :)
| @@ -0,0 +1,84 @@ | |||
| #!/bin/bash -e | |||
damienmg
Sep 6, 2017
General comment for this file: the file already complex, why not in python instead?
General comment for this file: the file already complex, why not in python instead?
mattmoor
Sep 6, 2017
Author
Contributor
See line 17. I was halfway through rewriting one of these scripts in Python before I realized: I can't invoke a py_binary during WORKSPACE, I'd have to publish a PAR file. I immediately git stashed and rewrote my TODO instead. :(
See line 17. I was halfway through rewriting one of these scripts in Python before I realized: I can't invoke a py_binary during WORKSPACE, I'd have to publish a PAR file. I immediately git stashed and rewrote my TODO instead. :(
damienmg
Sep 6, 2017
:( I actually do things without py_binary for simple python_script (I know that is a shame) using simply python <script.py>. Anyway up to you.
:( I actually do things without py_binary for simple python_script (I know that is a shame) using simply python <script.py>. Anyway up to you.
mattmoor
Sep 6, 2017
Author
Contributor
I suppose that is true. I want to be able to factor libraries and have a clean separation of unit tests etc. I'll experiment with my stashed changes with this in mind.
I suppose that is true. I want to be able to factor libraries and have a clean separation of unit tests etc. I'll experiment with my stashed changes with this in mind.
duggelz
Sep 12, 2017
Collaborator
I would say it's ok to use shell here, not Python. But you actually need Python inside the script to parse json, so yeah.
I would say it's ok to use shell here, not Python. But you actually need Python inside the script to parse json, so yeah.
duggelz
Sep 12, 2017
Collaborator
For historical reasons that are still sometimes relevant, don't put the -e in the shebang line, instead add set -euo pipefail around line 16
For historical reasons that are still sometimes relevant, don't put the -e in the shebang line, instead add set -euo pipefail around line 16
mattmoor
Sep 12, 2017
Author
Contributor
The only remaining shell script now does this (I copied it from you :D)
The only remaining shell script now does this (I copied it from you :D)
| @@ -0,0 +1,82 @@ | |||
| #!/bin/bash -e | |||
|
|
|||
damienmg
Sep 6, 2017
Same here, bash can become quickly hard to read...
Same here, bash can become quickly hard to read...
mattmoor
Sep 6, 2017
Author
Contributor
Ack
Ack
|
@duggelz Do you have any suggestions on the best way to download and invoke |
|
@sebgoa You'd asked for this at one point, if you are still interested I'd love your feedback. |
| See Bazel core [documentation](https://docs.bazel.build/versions/master/be/python.html#py_test). | ||
|
|
||
| <a name="pip_import"></a> | ||
| ## pip_import |
duggelz
Sep 8, 2017
•
Collaborator
There's a thing called skydoc that will turn structured docstrings into Bazel documentation. However, it's kind of basic and a bit, well, not beautiful. https://google.github.io/subpar/subpar.html
There's a thing called skydoc that will turn structured docstrings into Bazel documentation. However, it's kind of basic and a bit, well, not beautiful. https://google.github.io/subpar/subpar.html
mattmoor
Sep 8, 2017
Author
Contributor
I'll TAL at skydoc for this repo, but in rules_docker and rules_k8s I'm blocked on this
I'll TAL at skydoc for this repo, but in rules_docker and rules_k8s I'm blocked on this
mattmoor
Sep 8, 2017
Author
Contributor
Ok, I've switched over to skydoc for the docs here (based on how google/subpar does it). Feedback welcome :)
Ok, I've switched over to skydoc for the docs here (based on how google/subpar does it). Feedback welcome :)
76a4bcb
to
91f1f9b
|
I moved I have not moved
What if we build / publish a I still haven't found a clean process for doing this from a single repo ( |
e2267eb
to
c1dbfa0
This migrates the logic from pip.sh into piptool.py, which should improve portability by removing the bash dependency. This also has the beginnings of wrapping piptool as a closed redistributable that doesn't rely on a system-installed copy of PIP, but instead uses these rules to pull pip into a PAR bundle. Besides needing to work out the details of releasing and redistributing the PAR, we have two unresolved issues: * When bundled as a PAR (vs. py_binary), piptool seems to pick up the system-installed version of pip. * When bundled as a PAR, piptool sometimes sees cert issues resolving requirements (similar to what we see with httplib2).
|
@damienmg Can we add a buildifier check to the Jenkins job, or do I have to set up Travis for that? |
|
Not right now unfortunately. I want to add it (bazelbuild/continuous-integration#13) but we kind of need bazelbuild/continuous-integration#100. |
|
Design question for you: Assumption: Bazel isn't doing some super-clever multi-level hierarchical WORKSPACE namespacing that I'm not aware of. Scenario setup: Workspace A depends on pip package P1 at version V1. Workspace B depends on pip package P1 at version V2. Workspace C depends on A and B via Scenario 1: V1 = V2 Result: Bazel rejects the configuration because a_install and b_install create duplicate targets. Question: Can B detect that it doesn't need to create P1 target? Scenario 2: V1 != V2 Result: Same as Scenario 1 Scenario 3: V1 != V2, and we only create P1 once Result: Build succeeds, but Python programs in C might get V1 or V2 depending on the order of things in c/WORKSPACE. Scenario 4: V1 != V2, and we incorporate versions into target labels like Now assume a py_binary in C depends on a py_library from A and another py_library from B. Result: Build succeeds, but Python programs in C can depend on P1.V1 and P1.V2 without Bazel realizing there is a clash. Python import semantics mean that the program might get files from V1, V2, or both, at runtime, in fairly hard to predict ways. Note that current Google repos that manually depend on pip packages in WORKSPACE via Scenario 5: We require that V1 = V2, and make it work correctly. Result: A, B and C are now version-deadlocked. C can never update unless A and B happen to both update to the same V3. Now multiply by the combinatorial explosion of dependencies and versions that we find in the real world. Suggestion: I don't think this can be completely solved without making new py_library() and py_binary() rules that delay resolving py_library() deps until the final py_binary() step. In the meantime: I prefer baking version numbers into package labels (e.g. |
|
|
||
| def test_version(self): | ||
| parts = pip.__version__.split('.') | ||
| self.assertEqual(3, len(parts)) |
duggelz
Sep 12, 2017
Collaborator
self.assertEqual(pip.__version__, '9.0.1')? You might be overthinking this :) There's no standard format for __version__, as you discovered, sometimes it's a tuple, sometimes a string, sometimes it doesn't exist.
self.assertEqual(pip.__version__, '9.0.1')? You might be overthinking this :) There's no standard format for __version__, as you discovered, sometimes it's a tuple, sometimes a string, sometimes it doesn't exist.
| # being invoked as a raw .py file. Once bundled, we should be able | ||
| # to remove this fallback on a stub implementation of Wheel. | ||
| try: | ||
| from python.whl import Wheel |
duggelz
Sep 12, 2017
Collaborator
I feel like you're really playing with fire calling your package python.
I feel like you're really playing with fire calling your package python.
move python tools under a top-level rules_python package simplify version_test
|
@duggelz I think that's a very good question, and I think it breaks down where you have:
As you are clearly driving at, we have 3 sets of requirements that are being merged after the constraints have been solved, which I think is a losing proposition. I think that my expectation is that instead of This story is only half-baked because:
I think the crux of this issue is that
The analogs to this outside of Bazel are things like I think the guidance should be for users not to mix independently resolved external dependencies, but I'm not 100% sure if/how we can enforce it. Perhaps we can do this through Bazel's constraint system, but I have not looked any further at how we might express this. Is what I'm describing clear? Does my logic make sense? |
|
@mattmoor I agree with what you wrote. Some additional points:
I don't think we need to make a tool that tries to merge A and B automatically or anything. I think it's reasonable to say that C must provide a After reading some discussions about Java/Maven, I do think that we should put the names in a canonical format that we document and agree on. Specifically, I think we should have the literal prefix |
`whl_library` rules generated by `pip_import` are now named as:
```
pypi__{distribution}_{version}
```
Substituting illegal characters (e.g. `-`, `.`) with underscores.
|
@duggelz Given that things are hidden behind I've gone with |
af2c63f
to
182554f
Add a script for updating the tools and document this and the docs script.
|
@duggelz Hooray, green CI :) |
7f4cc92
into
bazelbuild:master
Update whl.bzl
Tensorflow patch
This looks like it's left over from before the switch to buildkite. The Travis tests are not run in precommit now, and I can't even tell if they were run in PR bazelbuild#1. This causes pre-commit errors in forks if folks have Travis enabled in other projects.
This looks like it's left over from before the switch to buildkite. The Travis tests are not run in precommit now, and I can't even tell if they were run in PR #1. This causes pre-commit errors in forks if folks have Travis enabled in other projects.
This is a proposal for some PIP rules that are heavily based on a prototype I wrote a month or two back. Very open to suggestions here, but it seems to work across a number of examples I've tried so far.