ws_e_c421
ws_e_c421

Reputation: 1113

How to support alternate dependencies in a Python package?

I have written a utility library in Python that works with the Qt framework. My code is pure Python and is compatible with both PyQt5 and PySide2. My main module could either be run on its own from the command line with python -m or it could be imported into another project. Is there a clean way to specify that the project needs either PyQt5 or PySide2 in its a wheel distribution?

Here is what I have found in my research but I am asking in case there is a better way to package the project than these options:

I could add logic to setup.py in a source distribution of the project to check for PyQt5 and PySide2. However, wheels are recommended way to distribute Python projects, and from what I can tell this kind of install-time logic is not possible with wheels. Alternatively, I could not specify either PySide2 or PyQt5 as dependencies and recommend in the install instructions that one of them be installed together with my project.

Upvotes: 3

Views: 604

Answers (3)

ws_e_c421
ws_e_c421

Reputation: 1113

My particular case is somewhat niche (so I am not accepting this as the answer). I realized the package was really doing two things: acting as a library and as a command line tool. I decided to split it into two packages: package and package-cli. package does not explicitly depend on PyQt5 or PySide2 but specifies that one of them must be installed in the documentation. Since package is a library, it is intended to be integrated into another project where it is easy to list package and PyQt5 together in the requirements.txt. For package-cli, I just choose one of PyQt5 or PySide2 to be the explicit dependency. package-cli depends on package and PyQt5 and just adds a console_script to call the main module in package.

Upvotes: 0

phd
phd

Reputation: 94827

Use extras_require:

setup(
    …
    extras_require={
        'pyqt5': ['PyQt5'],
        'pyside2': ['PySide2'],
    },
)

and teach your users to run either

pip install 'yourpackage[pyqt5]'

or

pip install 'yourpackage[pyside2]'

Upvotes: 6

robinsax
robinsax

Reputation: 1220

If you don't want to make either a strict requirement (which makes sense), I'd just throw a runtime error if neither is available.

For example

try:
   import PyQt5 as some_common_name
except ImportError:
   try:
       import PySide2 as some_common_name
   except ImportError:
       raise ImportError('Please install either PyQt5 or PySide2') from None

Upvotes: 0

Related Questions