Skip to content
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

--global-option for a specific requirement in requirements file disables use of wheels globally #4118

Open
fillest opened this issue Nov 17, 2016 · 16 comments
Labels
project: setuptools Related to setuptools type: bug A confirmed bug or unintended behavior

Comments

@fillest
Copy link

fillest commented Nov 17, 2016

  • Pip version: 7.1.2 (tested with 9.0.1 with the same result)
  • Python version: 2.7.6
  • Operating System: Ubuntu 14.04

Description:

We have a big requirements file and use wheels. Now we've added a new package and need to pass some build arguments to it. I've figured out it can be placed into requirements file this way:

confluent-kafka==0.9.2 --global-option=build_ext --global-option="--rpath=/opt/librdkafka/lib/"

Pip is invoked like this:

/home/x/venv/bin/pip --disable-pip-version-check --cache-dir ~/pipcache wheel --build /tmp/pipbuild_x --src /tmp/pipsrc_x --find-links ~/pip_wheels_x -i https://our-pip-index-using-devpi --wheel-dir ~/pip_wheels_x --requirement deploy/requirements/all.txt

This message is printed:

/home/x/venv/local/lib/python2.7/site-packages/pip/req/req_file.py:129: UserWarning: Disabling all use of wheels due to the use of --build-options / --global-options / --install-options.
   cmdoptions.check_install_build_global(options, opts)

I expected it to use wheels for other packages but it stopped to use wheels for all the packages mentioned in deploy/requirements/all.txt. This breaks the installation process for us, because we use some private wheel-only packages uploaded to our devpi transparent index mirror.

Is it intended (why then?) or per-requirement handling is not implemented yet?

(Also after upgrading pip to 9.0.1 and reverting pip version back to 7.1.2 in our requirements file I got Could not find a version that satisfies the requirement pip==7.1.2 (from -r deploy/requirements/pip.txt (line 1)) (from versions: ) but this one may be a devpi issue, not sure yet)

@pradyunsg
Copy link
Member

Hey @fillest! Thanks for filing this issue and sorry for the lack of a response all this while.

Could someone try reproducing this on the current master, with a small test case? I'm not sure why this is this way. Looking at the code, I don't see any hints as to why it was done. My suggestion would be to split up the requirements to install all the wheel-only dependencies in a separate pip run from one using --global-option.

Thanks and sorry again for the wait.

@pradyunsg pradyunsg added project: setuptools Related to setuptools S: awaiting response Waiting for a response/more information labels Mar 5, 2018
@pradyunsg pradyunsg added the S: needs triage Issues/PRs that need to be triaged label May 11, 2018
@iwanb
Copy link

iwanb commented May 28, 2018

I have the same issue with pip 10.0.1.

It can be reproduced if you have a package which fails to install if it is not from a wheel, e.g. because of missing include files. For example with lxml, on CentOS I do not have libxml2-devel installed, so if I have the requirement:

lxml
other --install-option="--my-option"

It fails to compile lxml, while it works without the --install-option on the other package.

@pradyunsg pradyunsg added type: bug A confirmed bug or unintended behavior and removed S: awaiting response Waiting for a response/more information labels May 28, 2018
iwanb pushed a commit to iwanb/pip that referenced this issue Jul 10, 2018
@iwanb
Copy link

iwanb commented Jul 10, 2018

Is there any update on this?

I created a functional test for it and attempted a fix in this commit:
iwanb@6ead47f

I am not familiar with the code so if somebody could have a look at it :)

leohemsted added a commit to alphagov/notifications-api that referenced this issue Oct 3, 2018
you need to `pip install celery[sqs]` to get the additional
dependencies that celery needs to use SQS queues - there are two libs -
boto3 and pycurl.

pycurl is a bunch of python handles around curl, so needs to be
installed from source so it can link to your curl/ssl libs. On paas and
in docker this works fine (needed to add `libcurl4-openssl-dev` to the
docker container), but on macos it can't find openssl. We need to pass
a couple of flags in:

* set the environment variable PYCURL_SSL_LIBRARY=openssl
* pass in the global options `build_ext` and `-I{openssl_headers_path}`.

As shown here:
pycurl/pycurl#530 (comment)

Env var is no biggie, but using any install-option flags disables
wheels for the whole pip install run. (See
pypa/pip#2677 and
pypa/pip#4118 for more context on the
install-options flags). A whole bunch of our dependencies don't
install nicely from source (but do from wheel), so this commit installs
pycurl separately as an initial step, with the requisite flags, and
then installs the rest of the requirements as before.

I've updated the makefile and bootstrap.sh files to reflect this, but
if you run `pip install -r requirements.txt` from scratch you will run
into issues.
leohemsted added a commit to alphagov/notifications-api that referenced this issue Oct 3, 2018
you need to `pip install celery[sqs]` to get the additional
dependencies that celery needs to use SQS queues - there are two libs -
boto3 and pycurl.

pycurl is a bunch of python handles around curl, so needs to be
installed from source so it can link to your curl/ssl libs. On paas and
in docker this works fine (needed to add `libcurl4-openssl-dev` to the
docker container), but on macos it can't find openssl. We need to pass
a couple of flags in:

* set the environment variable PYCURL_SSL_LIBRARY=openssl
* pass in the global options `build_ext` and `-I{openssl_headers_path}`.

As shown here:
pycurl/pycurl#530 (comment)

Env var is no biggie, but using any install-option flags disables
wheels for the whole pip install run. (See
pypa/pip#2677 and
pypa/pip#4118 for more context on the
install-options flags). A whole bunch of our dependencies don't
install nicely from source (but do from wheel), so this commit installs
pycurl separately as an initial step, with the requisite flags, and
then installs the rest of the requirements as before.

I've updated the makefile and bootstrap.sh files to reflect this, but
if you run `pip install -r requirements.txt` from scratch you will run
into issues.
@chrahunt
Copy link
Member

Related to #2677, where I think the motivation for the current behavior is indicated.

@pradyunsg
Copy link
Member

#5795 notes that this is the case for --install-options.

@BNMetrics
Copy link

I'm stuck on this too.
The reason is from this line: https://github.com/pypa/pip/blame/master/src/pip/_internal/req/req_file.py#L199

@pradyunsg is there any reason why disabling wheels if there is option for the line itself?

@pradyunsg
Copy link
Member

Honestly, I don't know it off the top of my head. I'm pretty sure this entire area needs a whole suite of changes, and #2677 should cover that entire discussion.

@uranusjr
Copy link
Member

uranusjr commented Sep 15, 2020

My guess is that pip needs to disable wheel for the specified requirement (and perhaps its dependencies, see #1883), but that’s very tedious to do and requires significant work in the dependency resolver (e.g. the resolver selects a wheel, but later on discovers it should have built from source with custom options instead), so the original implementation decided to cut corners and disables all binaries outright. This isn’t unreasonable since binary distributions were not nearly as prevalent back then (it’s possible wheels might not even exist at the time).

@BNMetrics
Copy link

I think it'd be more reasonable to disable wheel if the --install-option is specified on the global level, instead of individual packages(lines in requirements.txt)
Especially for the use case of when you need to install a package locally, you'd specify a local path, and sometimes you want to have --install-option, especially if you have custom options or flags added too.
I think it's not reasonable to disable it on a global level if only a specific package has --install-options...Just my personal take.

@uranusjr
Copy link
Member

It’s no that simple. pip currently pass down --install-option to a package’s dependencies, but what should happen, for example, if the resolver selects a wheel, but later on discovers it should have built from source with custom options instead? The extra work gets complicated very fast in practical dependency graphs, and the current behaviour is a reasonable engineering compromise under the current design IMO.

I’d say that we need to decide on #1883 first. If we decide pip should pass down options to dependencies, the current behaviour is “good enough” since the dependency resolution work would be too significant. But if we don’t (i.e. --install-option and --global-option only apply to that specific package), it may be worth to change the logic here along with that.

@BNMetrics
Copy link

I’d say that we need to decide on #1883 first. If we decide pip should pass down options to dependencies, the current behaviour is “good enough” since the dependency resolution work would be too significant. But if we don’t (i.e. --install-option and --global-option only apply to that specific package), it may be worth to change the logic here along with that.

That's a good point. Someone in the thread did mention --global-option may be allowed to pass down to dependencies, but --install-option should be only apply to that specific package itself, not the dependencies.
I think it makes sense to have the --install-option to apply to only per line. I'm not sure how much work is involved in making this work. I'm happy to help and chip in. 😄

@uranusjr
Copy link
Member

Honestly I’m not sure either. As mentioned above, the whole hunk of logic here needs some rework. And now there’s also PEP 517 to consider. This needs someone to sit down and think through to derive a workable plan going forward. 😥

@pfmoore
Copy link
Member

pfmoore commented Sep 15, 2020

This needs someone to sit down and think through to derive a workable plan going forward.

Agreed. The current situation has basically arisen because we've gone through a process of adding functionality on a case by case basis, looking only at local considerations. That was historically a reasonable approach, but it has downsides, which people are now discovering (this issue being a concrete example). We can of course make another "local" assumption on how best to address this one case - and that would almost certainly give the people here something usable. But we'd just be accumulating yet more technical debt by doing so, and at some point pip will become unmaintainable due to the weight of all those individually justifiable decisions. Particularly given how short of manpower the pip development team is.

Finding someone with the expertise, time and energy¹ to undertake a full redesign of pip's build option logic is not going to be easy, especially given that the existing mechanisms don't map properly onto PEP 517's config option logic (and backends have been slow in adopting the new logic). But nor is dealing with the consequences of adding another "local" fix. I don't know the right answer, to be honest.

¹ The biggest drain in a redesign exercise like this is not coding - it's making sense of all the demands that every edge case is critically important to someone, making hard judgements on what not to support, and enduring the subsequent negative feedback.

martey added a commit to mobolic/pip that referenced this issue Mar 1, 2021
See pypa#4118. Update documentation to state that using command line options
on any requirements will disable all usage of wheels. Since this is
unexpected behavior, move text to a warning.
martey added a commit to mobolic/pip that referenced this issue Mar 1, 2021
See pypa#4118. Update documentation to state that using command line options
on any requirements will disable all usage of wheels. Since this is
unexpected behavior, move text to a warning.
martey added a commit to mobolic/pip that referenced this issue Mar 1, 2021
See pypa#4118. Update documentation to state that using command line options
on any requirements will disable all usage of wheels. Since this is
unexpected behavior, move text to a warning.
@kuraga
Copy link

kuraga commented May 7, 2021

Facing the same issue with --install-option...

@dmirecki
Copy link

Same here...

@kuraga
Copy link

kuraga commented Feb 12, 2024

#11325 (comment) by @sbidoul :

Currently we can specify --install-options and --global-options per requirement in requirement files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
project: setuptools Related to setuptools type: bug A confirmed bug or unintended behavior
Projects
None yet
Development

No branches or pull requests

9 participants