helpful-lunch-92084
12/02/2020, 4:44 PMERROR: Double requirement given:
message when trying to run a recursive test of a top-level project dir:
For example:
pants test foo::
Imagine the structure of foo as:
foo/
foo//tests
foo//tests/python
foo//tests/python/baz
foo//tests/python/baz/test_baz.py
foo//tests/python/baz/BUILD
foo//tests/python/bar
foo//tests/python/bar/BUILD
foo//tests/python/bar/test_bar.py
foo//src
foo//src/python
foo//src/python/baz
foo//src/python/baz/__init__.py
foo//src/python/baz/BUILD
foo//src/python/bar
foo//src/python/bar/__init__.py
foo//src/python/bar/BUILD
Now in this case, the bar module imports one dependency, say boto3==1.0 and the baz module imports a newer boto, say boto3==2.0.
In our example, imagine that the baz module is a complete refactor-in-progress that doesn’t share any imports with bar.
It seems that the recursive test tries to resolve all dependencies at once, and thus sees those duplicate boto3 deps and bails.
In our real case it’s a py3 upgrade of a project that is using a newer numpy but I feel like the specifics aren’t as important.
I realize we could just simply move baz out of the foo top-level. But it seems like pants should be resolving these dependencies separately? Is there a way to force that? I know in past versions of pants it was possible to specify --no-test-pytest-fast
which would resolve each target’s dependencies separately. Is there something similar for pants v2?helpful-lunch-92084
12/02/2020, 4:48 PMhundreds-father-404
12/02/2020, 4:48 PMfoo==2.0 ; python_version > ‘3’Raúl learned about this syntax a month ago
helpful-lunch-92084
12/02/2020, 4:48 PMhundreds-father-404
12/02/2020, 4:48 PMhelpful-lunch-92084
12/02/2020, 4:49 PMhelpful-lunch-92084
12/02/2020, 4:50 PMhelpful-lunch-92084
12/02/2020, 4:50 PMhundreds-father-404
12/02/2020, 4:52 PMhelpful-lunch-92084
12/02/2020, 4:53 PMpants test foo/tests/python/bar::
and pants test foo/tests/python/baz::
helpful-lunch-92084
12/02/2020, 4:53 PMpants test foo::
that it failshundreds-father-404
12/02/2020, 4:55 PMjolly-midnight-72759
12/02/2020, 4:57 PM./pants dependencies --transitive --type=3rdparty foo::
shows which packages have multiple requirements defined.jolly-midnight-72759
12/02/2020, 4:58 PM./pants test foo::
and pants to know that there are two incompatible projects under that so it runs the tests separately.hundreds-father-404
12/02/2020, 4:59 PMhelpful-lunch-92084
12/02/2020, 5:00 PMhundreds-father-404
12/02/2020, 5:00 PMjolly-midnight-72759
12/02/2020, 5:00 PM./pants dependencies --transitive --type=3rdparty foo:
, yes?helpful-lunch-92084
12/02/2020, 5:02 PMpants dependencies --transitive foo
I get back the list:
3rdparty/python:boto1
3rdparty/python:boto2hundreds-father-404
12/02/2020, 5:05 PMWhen you run these tests, do you get that warning about the constraints file not being used?It impacts the resolve strategy, whether you’re using global resolves where you use the entire contents of
constraints.txt
, vs. multiple more granular resolves.
If you’re able to, it would be useful to run with -ldebug
and share. Totally fine if over DMhelpful-lunch-92084
12/02/2020, 5:14 PMhundreds-father-404
12/02/2020, 5:16 PM./pants filter --target-type=python_tests foo/tests:: | wc -l
./pants filter --target-type=python_tests foo/tests/subdir1:: foo/tests/subdir2:: | wc -l
helpful-lunch-92084
12/02/2020, 5:19 PMhelpful-lunch-92084
12/02/2020, 5:29 PMhundreds-father-404
12/02/2020, 5:31 PMhelpful-lunch-92084
12/02/2020, 5:36 PM$ cat 3rdparty/python/BUILD.numpy
python_requirement_library(
name = "numpy15",
requirements = [
"numpy==1.15.4",
],
)
And pex would do the right thing in selecting 1.15.4. Now it seems that for those special cases, we’ll have to add to constraints.txt something like numpy>=1.15.4,<=1.16.1
hundreds-father-404
12/02/2020, 5:39 PMnumpy>=1.15.4,<=1.16.1
is included in your constraints file, anytime you or a transtitive dep use numpy
, pip will substitute in the constraints value
We need to support multiple constraints files, which was voted pretty highly in Q4 prioritizationhundreds-father-404
12/02/2020, 5:40 PMhelpful-lunch-92084
12/02/2020, 5:44 PMhelpful-lunch-92084
12/02/2020, 5:45 PMhundreds-father-404
12/02/2020, 5:46 PMhelpful-lunch-92084
12/02/2020, 5:46 PMhelpful-lunch-92084
12/02/2020, 5:47 PMnumpy>=1.15.4,<=1.16.1
hundreds-father-404
12/02/2020, 5:57 PMhelpful-lunch-92084
12/02/2020, 5:59 PMhundreds-father-404
12/02/2020, 6:04 PMnumpy>=1.15.4,<1.16 ; python_version == '2.7'
numpy==1.16.1 ; python_version >= '3.5'
The alternative I could think of is to leave off numpy from constraints.txt, so that like v1, each project can decide exactly which python_requirement_library
should be used, and that’s respected rather than the constraints.txt overriding everything
You wouldn’t get to benefit from the global resolve for any projects using NumPy, but your other tests could still leverage ithelpful-lunch-92084
12/02/2020, 6:07 PMhelpful-lunch-92084
12/02/2020, 6:07 PMhundreds-father-404
12/02/2020, 6:10 PM!!
? It might make things even more confusing, but it would allow you to ignore a downstream dependency on numpy so that the call site can choose exactly which one should be used
https://www.pantsbuild.org/docs/targets#dependencies-and-dependency-inferencehelpful-lunch-92084
12/02/2020, 6:12 PMhelpful-lunch-92084
12/02/2020, 6:12 PMhelpful-lunch-92084
12/04/2020, 4:58 AMelasticsearch==6.2.0 requires urllib3<1.23,>=1.21.1 but urllib3 1.25.11 was resolved
There’s no direct dep on urllib3 in this example project so I guess that something else transitively pulled it in. We seem to be in a bind here, some projects pull in a dep that has a transitive dep on say: urllib3>1.24,urllib3<1.25
and another has a transitive like elasticsearch. We can’t increase the range in constraints.txt to urllib3>1.21.1,urllib3<1.25
because then it would always pull in the highest and then something that required a lower range like elasticsearch would fail.
I’m not quite seeing how the transitive exclude would work for this problem. Is there any way to pass an argument through to the underlying pip that is being called to activate the dependency resolver? That way we wouldn’t need to wait for pex to upgrade to pip 20.3.hundreds-father-404
12/04/2020, 6:13 AMIs there any way to pass an argument through to the underlying pip that is being called to activate the dependency resolver?I don’t think so unfortunately. Also, note that the new dependency resolver is stricter than before - from what I understand, I don’t expect it to solve this problem, only to be more consistent and I suspect to have a better error message. Do you know which deps are using urllib3 and resulting in the conflict? The best I can think of would be to tweak the versions used by the direct deps until they’re in alignment - ack that this is a horrible charade
helpful-lunch-92084
12/04/2020, 6:27 AMurllib3>=1.21.1,<1.25
and urllib3==1.23
would choose urllib3==1.23
since it satisfies bothhelpful-lunch-92084
12/04/2020, 6:28 AMhundreds-father-404
12/04/2020, 6:30 AMpip install
of the problematic deps using 20.3 and confirm it does indeed fix this problemhelpful-lunch-92084
12/04/2020, 6:33 AMhelpful-lunch-92084
12/04/2020, 6:39 AM$ pip install 'git+<https://github.com/elastic/elasticsearch-py@6.2.0#egg=elasticsearch>' urllib3==1.25
Collecting elasticsearch
Cloning <https://github.com/elastic/elasticsearch-py> (to revision 6.2.0) to /private/var/folders/vl/cj7hkk853x92cjm1k0vz0mmw0000gn/T/pip-install-e2e9q6xp/elasticsearch_bb469385dabe463ea2da93b16d31979d
Requirement already satisfied: urllib3==1.25 in /Users/nate/.pyenv/versions/3.6.9/lib/python3.6/site-packages (1.25)
ERROR: Cannot install elasticsearch==6.2.0 and urllib3==1.25 because these package versions have conflicting dependencies.
The conflict is caused by:
The user requested urllib3==1.25
elasticsearch 6.2.0 depends on urllib3<1.23 and >=1.21.1
To fix this you could try to:
1. loosen the range of package versions you've specified
2. remove package versions to allow pip attempt to solve the dependency conflict
ERROR: ResolutionImpossible: for help visit <https://pip.pypa.io/en/latest/user_guide/#fixing-conflicting-dependencies>
01:38:32 EST ✘ nate@Nates-MacBook-Pro:(CICD-8/pants-v2 * u+1)~/git/chartbeat
$ pip install 'git+<https://github.com/elastic/elasticsearch-py@6.2.0#egg=elasticsearch>' urllib3==1.22
Collecting elasticsearch
Cloning <https://github.com/elastic/elasticsearch-py> (to revision 6.2.0) to /private/var/folders/vl/cj7hkk853x92cjm1k0vz0mmw0000gn/T/pip-install-4ik48g5v/elasticsearch_b9e440d5bce74e3d9639d53da62e3484
Collecting urllib3==1.22
Using cached urllib3-1.22-py2.py3-none-any.whl (132 kB)
Building wheels for collected packages: elasticsearch
Building wheel for elasticsearch (setup.py) ... done
Created wheel for elasticsearch: filename=elasticsearch-6.2.0-py2.py3-none-any.whl size=71414 sha256=18a5a496cdf043215c81f9911d3d185609903ff6a6f2b739b27033f30848c3c7
Stored in directory: /private/var/folders/vl/cj7hkk853x92cjm1k0vz0mmw0000gn/T/pip-ephem-wheel-cache-uccekbi3/wheels/5a/be/bd/47156a28570e0c035ef23b81e1d9aa1ed8ee284791ce2835f0
Successfully built elasticsearch
Installing collected packages: urllib3, elasticsearch
Attempting uninstall: urllib3
Found existing installation: urllib3 1.25
Uninstalling urllib3-1.25:
Successfully uninstalled urllib3-1.25
Attempting uninstall: elasticsearch
Found existing installation: elasticsearch 6.8.1
Uninstalling elasticsearch-6.8.1:
Successfully uninstalled elasticsearch-6.8.1
Successfully installed elasticsearch-6.2.0 urllib3-1.22
helpful-lunch-92084
12/04/2020, 6:39 AMhelpful-lunch-92084
12/04/2020, 6:41 AMhundreds-father-404
12/04/2020, 6:41 AMhelpful-lunch-92084
12/04/2020, 6:42 AMhelpful-lunch-92084
12/04/2020, 6:55 AM$ pip install 'urllib3>=1.21.1,<1.25' 'git+<https://github.com/elastic/elasticsearch-py@6.2.0#egg=elasticsearch>'
Collecting urllib3<1.25,>=1.21.1
Downloading urllib3-1.24.3-py2.py3-none-any.whl (118 kB)
|████████████████████████████████| 118 kB 873 kB/s
Collecting elasticsearch
Cloning <https://github.com/elastic/elasticsearch-py> (to revision 6.2.0) to /private/var/folders/vl/cj7hkk853x92cjm1k0vz0mmw0000gn/T/pip-install-tkda8gsm/elasticsearch
Running command git clone -q <https://github.com/elastic/elasticsearch-py> /private/var/folders/vl/cj7hkk853x92cjm1k0vz0mmw0000gn/T/pip-install-tkda8gsm/elasticsearch
Running command git checkout -q d46bbdf124a876634ec79e5bfeac0b269a6ba9e6
Building wheels for collected packages: elasticsearch
Building wheel for elasticsearch (setup.py) ... done
Created wheel for elasticsearch: filename=elasticsearch-6.2.0-py2.py3-none-any.whl size=71414 sha256=a6923fd48ac8fe2ec37b6712680c427c2cc7f964908310ce461abc21ffed7665
Stored in directory: /private/var/folders/vl/cj7hkk853x92cjm1k0vz0mmw0000gn/T/pip-ephem-wheel-cache-32s1x_h_/wheels/5a/be/bd/47156a28570e0c035ef23b81e1d9aa1ed8ee284791ce2835f0
Successfully built elasticsearch
ERROR: elasticsearch 6.2.0 has requirement urllib3<1.23,>=1.21.1, but you'll have urllib3 1.24.3 which is incompatible.
Installing collected packages: urllib3, elasticsearch
Successfully installed elasticsearch-6.2.0 urllib3-1.24.3
WARNING: You are using pip version 20.0.1; however, version 20.3.1 is available.
You should consider upgrading via the '/Users/nate/.pyenv/versions/3.6.9/bin/python -m pip install --upgrade pip' command.
And now with pip 20.3.1
$ pip install --no-cache-dir 'urllib3>=1.21.1,<1.25' 'git+<https://github.com/elastic/elasticsearch-py@6.2.0#egg=elasticsearch>'
Collecting elasticsearch
Cloning <https://github.com/elastic/elasticsearch-py> (to revision 6.2.0) to /private/var/folders/vl/cj7hkk853x92cjm1k0vz0mmw0000gn/T/pip-install-5i7l7e9r/elasticsearch_4cf9f64cdc074837859b92a922d327a1
Collecting urllib3<1.25,>=1.21.1
Downloading urllib3-1.22-py2.py3-none-any.whl (132 kB)
|████████████████████████████████| 132 kB 898 kB/s
Building wheels for collected packages: elasticsearch
Building wheel for elasticsearch (setup.py) ... done
Created wheel for elasticsearch: filename=elasticsearch-6.2.0-py2.py3-none-any.whl size=71414 sha256=a43a95deb63864e7e36aa1232c409217dd9a057021f1c2c0abbeaa99b3f287d1
Stored in directory: /private/var/folders/vl/cj7hkk853x92cjm1k0vz0mmw0000gn/T/pip-ephem-wheel-cache-81i0wz99/wheels/5a/be/bd/47156a28570e0c035ef23b81e1d9aa1ed8ee284791ce2835f0
Successfully built elasticsearch
Installing collected packages: urllib3, elasticsearch
Successfully installed elasticsearch-6.2.0 urllib3-1.22
hundreds-father-404
12/04/2020, 6:58 AM(i suspect the key here is to specify urllib3 with the higher range first):Indeed, pip’s old algorithm is “first one seen” 😕 Okay, so sounds like the new pip resolver would truly make a difference here. Plus the much better error message
enough-analyst-54434
12/04/2020, 5:13 PMjolly-midnight-72759
12/10/2020, 7:05 PMenough-analyst-54434
12/10/2020, 7:09 PMjolly-midnight-72759
12/10/2020, 7:10 PMenough-analyst-54434
12/12/2020, 10:31 PM