Skip to content

Feature: Adding dependencies through CLI #1730

@ntjess

Description

@ntjess

What's the problem this feature will solve?

Some libraries allow many backing modules for the same functionality. Two very popular examples are OpenCv and Qt. The python module cv2 is provided by opencv-python-headless, opencv-python-contrib, opencv-python, and a few more pypi packages. Similarly, Qt APIs are available via PySide5, PySide6, etc.

Often, rather than adding an extra argument to pip installs, developers will simply check if one of many compatible libraries is available and raise an error otherwise. qtpy and pyqtgraph are popular examples of this: Qt is not specified in their requirements file; the user is expected to install this separately and the import fails if it isn't found. pip-compile doesn't handle these cases well -- currently, the only way requirements can be specified is through a requirements file.

TLDR: It is cumbersome to install packages that should exist in the user's environment, but did not come from requirements.txt.

Describe the solution you'd like

Ideally, pip-compile can support cli dependencies in its pip-args flag, since according to the docs:

Any valid pip flags or arguments may be passed on with pip-compile’s --pip-args option

pip-compile ./pyproject.toml --pip-args "pyside6 opencv-python-headless"
# Or a separate flag like --inline-requirements "opencv-python-headless"

This would allow pip-compile to handle these cases without forcing a requirements-tmp.txt for dependencies not managed or specified by the library at hand, and fits within the pip-args capabilities of adding cli dependencies.

Alternative Solutions

Devs can make an additional requirements file that specifies these needs, i.e.:

pip-compile pyproject.toml requirements-cv2.txt

which holds the relevant information. However, this leads to quite a bit of repo bloat if a separate additional requirements file must be specified for each similar (single) dependency. This is why e.g. packages like qtpy don't have an explicit requirements.txt file indicating this information.

Additional context

I would be happy to work on the PR if this idea is positively received.
The solution should be quite easy to implement using pip-compile's existing logic, by simply extending reqs to include these additional options. It has the nice benefit of still printing in the "autogenerated" message, so reproducibility will not be lost.

As a side note, the CLI already has an (undocumented) ability to accept requirements from stdin, so non-requirements.txt dependencies are already considered appropriate with existing logic.

As another side note, stdin dependencies are lost in the "autogeneration" comment! This solution has the added benefit of retaining those dependencies on multiple runs of pip-compile since stdin can simply be directed as a inline-requirements arg.

I.e. run echo pyside6 | pip-compile - -o requirements.txt and you will get a file with this comment at the top:

#
# This file is autogenerated by pip-compile with python 3.9
# To update, run:
#
#    pip-compile --output-file='.\requirements.txt' -

Note! The original stdin text, pyside6, is lost. This would not happen if it was stored as a CLI option.

Metadata

Metadata

Assignees

No one assigned

    Labels

    cliRelated to command line interface thingsfeatureRequest for a new feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions