conda-forge.github.io icon indicating copy to clipboard operation
conda-forge.github.io copied to clipboard

Qt bindings mutex?

Open jaimergp opened this issue 3 years ago • 9 comments

Your question:

Hey everyone, I'd like to discuss the possibility of adding a qt_bindings_mutex package to conda-forge, similar to what we do with BLAS, MPI and others.

qt can be used from Python via two different bindings: pyqt (GPL) and pyside (LGPL). A Python interpreter process can only use one of them at a time, as far as I know. There are some wrappers (e.g. qtpy) that abstract away the differences between the two bindings, so developers can target both with a single codebase.

qtpy allows choosing the backend via QT_API. Since you can choose, qtpy does not depend on either pyqt or pyside. Still, one of them is needed, so maintainers usually add pyqt next to it. There are 47 recipes that rely on both pyqt and qtpy, which means that they could possibly work with pyside right now, but pyqt is being chosen regardless. Conversely, only 15 results show up if we query for pyside2 and qtpy.

Right now, napari is distributed with two variants to cater this use case. However, this does not prevent pyqt and pyside from being co-installed. We are considering adding run_constrained metadata to prevent this, but given the amount of packages that decided to depend on pyqt by default, this might introduce solving conflicts (when they shouldn't be any because qtpy is supposed to make projects bindings agnostic!).

So my question is the following: would it make sense to have a qt_bindings_mutex to implement this option conda-forge wide? That way, recipes that rely on qtpy (or similar) can simply add the mutex as the dependency, and end-users can choose which one should be installed?

jaimergp avatar Jun 08 '22 12:06 jaimergp

I don't think it makes sense to constrain the installation of both in the same environment.

I may want to have an GPL application co-installed with an LGPL application that speaks through interprocess communication means.

There also used to be issues with PySide2 for certain applications and vice versa.

hmaarrfk avatar Jun 08 '22 12:06 hmaarrfk

I guess a big issue in the past was that PySide2 had missing features from PyQt, significant enough that spyder would not work. It seems that those have been addressed. I seem to be able to run Spyder and PySide2 today (barring https://github.com/spyder-ide/spyder/issues/18174)

hmaarrfk avatar Jun 08 '22 14:06 hmaarrfk

qtpy allows choosing the backend via QT_API. Since you can choose, qtpy does not depend on either pyqt or pyside. Still, one of them is needed, so maintainers usually add pyqt next to it

As a maintainer of one of those projects, I'd like to share my rationale for this. We depend on pyqt, besides qtpy, because without a binding package installed, Spyder doesn't even start (and pyqt was way more stable than pyside for a long time). So we'd get tons of complaints for that if we'd leave the choice to users.

For me, this is an implementation detail (i.e. which binding to use per license you want to rely on) that regular users don't need to take care of by themselves (nor they need to know, I'd say). That's why we make the choice for them, so they can use Spyder out of the box.

I guess most other project maintainers think the same. In other words, they want their apps to be usable right away.

I seem to be able to run Spyder and PySide2 today

Yep, Spyder is mostly compatible with PySide2 now thanks to a volunteer who put the effort to make that the case.

ccordoba12 avatar Jun 08 '22 16:06 ccordoba12

Matplotlib is in the same situation in that the matplotlib metapackage requires pyqt to provide a backend out of the box, but pyside2 would work fine too.

dopplershift avatar Jun 08 '22 19:06 dopplershift

I guess I'm not opposed to having a default. But i am opposed to having a mutex.

I think that alot of work has been made to install pyside2 and qtpy side by side. I think that should remain an option.

Though im not sure how to structure such a package.

hmaarrfk avatar Jun 20 '22 15:06 hmaarrfk

I think the mutex would be making pyside and pyqt mutually exclusive to each other, not qtpy which is a wrapper on top of them. If what @jaimergp said is true

A Python interpreter process can only use one of them at a time, as far as I know.

then it's similar to MPI and a mutex would be necessary to avoid both packages from coexisting, but I don't know enough here to judge.

leofang avatar Jun 20 '22 17:06 leofang

But the thing is, that many different applications may be installed in the same environment.

I would routinely have one application using pyside2 and the other sing pyqt in the same environment.

I was thinking of this today, I think having 3 packages:

qtpy pyqt5_h10923810_40#      <---- not which which one you want preferred
qtpy pyside2_h10923019_20#    <---- I kinda like pyside2 more.
qtpy none_h109283021_#    <---- This is a catchall until we get to pyqt5 and pyside6

would allow:

  1. users of conda-forge to pick a default qt implemenation based on build numbers.
  2. It would allow users to have all 3 packages installed at the same time.

~Maybe this~ <--- edit (strikeout)

hmaarrfk avatar Jun 20 '22 23:06 hmaarrfk

@hmaarrfk, so you're saying that packages should drop their direct dependency on pyqt/pyside and instead move that to different qtpy versions?

ccordoba12 avatar Jun 21 '22 00:06 ccordoba12

The packages themselves, in my opinion, should only depend on qtpy, no build string specified if they can.

In truth. Maybe we should create a qt-provider package. Separate from qtpy. I think creating a metapackage is a good idea. But i don't think it should create a mutex.

Distributions, installers, environment.yaml, should specify exact package combinations.

hmaarrfk avatar Jun 21 '22 01:06 hmaarrfk