conda-forge / matplotlib-feedstock

A conda-smithy repository for matplotlib.
BSD 3-Clause "New" or "Revised" License
22 stars 57 forks source link

ENH: Switch to PySide6 backend #393

Closed larsoner closed 1 month ago

larsoner commented 2 months ago

Checklist

Switch from pyqt (which is stuck on 5.x and no longer getting updates) to PySide6, which is actively updated and has a cleaner license.

I would like to be able to use matplotlib with PySide6 rather than PyQt5. Installing both bindings side-by-side is problematic and can lead to conflicts (e.g., on Intel macOS), so conda install matplotlib pyside6 is unsafe. Doing conda install matplotlib-base pyside6 "tornado>=5" is fine, but requires keeping track of what else (if it ever changes) is in the matplotilb recipe that isn't in matplotlib-base.

So this PR offers a solution -- allow people to do use build selectors like conda install matplotlib=*=pyside6_* to get full matplotlib but with a pyside6 binding rather than a pyqt binding.

This is really just a proposal-as-PR (that I want to see actually build!), so I'm happy to discuss here first if this even makes sense and close if not the right path forward!

(The only real changes here are to meta.yaml and the new conda_build_config.yaml, about 10 lines. The rest is conda-smithy rerender -c auto'ed.)

conda-forge-webservices[bot] commented 2 months ago

Hi! This is the friendly automated conda-forge-linting service.

I just wanted to let you know that I linted all conda-recipes in your PR (recipe) and found it was in an excellent condition.

conda-forge-webservices[bot] commented 2 months ago

Hi! This is the friendly automated conda-forge-linting service.

I wanted to let you know that I linted all conda-recipes in your PR (recipe) and found some lint.

Here's what I've got...

For recipe:

conda-forge-webservices[bot] commented 2 months ago

Hi! This is the friendly automated conda-forge-linting service.

I just wanted to let you know that I linted all conda-recipes in your PR (recipe) and found it was in an excellent condition.

larsoner commented 2 months ago

Seems to work, for example this pyside6 run produces:

  "matplotlib-3.9.1-pyside6_py311h2c9f595_101.conda": {
    "recipe": {
      "build_variant": "pyside6",
      "channel_targets": "conda-forge main",
      "python": "3.11.* *_cpython",
      "target_platform": "linux-64"
    }
  },

and this pyqt run produces:

  "matplotlib-3.9.1-pyqt_py39hb694d8e_201.conda": {
    "recipe": {
      "build_variant": "pyqt",
      "channel_targets": "conda-forge main",
      "python": "3.9.* *_cpython",
      "target_platform": "linux-64"
    }
  },
tacaswell commented 2 months ago

Installing both bindings side-by-side is problematic and can lead to conflicts (e.g., on Intel macOS), so conda install matplotlib pyside6 is unsafe.

Installing is broken or importing both is broken? I would have expected it to be possible to install both qt5 and qt6 (but I can see a possible conflict if both want to be called just called "qt"). For pyqt/pyside (against the same Qt version) I expect both to be installable at the same time (and even to both be usable at the same time....so long as you do not pass their objects to each other, but as all the "real" state lives in c++ both bindings work).

larsoner commented 2 months ago

Installing is broken or importing both is broken?

Well really what I've observed is that mne sys_info is broken, but this essentially just imports matplotlib.pyplot and qtpy (via pyvistaqt), both of which should import PySide6 (it's higher priority than PyQt5 for both packages I think?), but this happens on macOS Intel (copied here with some extra newlines to aid readability):

Running MNE's sys_info
Matplotlib created a temporary cache directory at /var/folders/h9/l1shxhdd69nct08ylzq0n6q00000gn/T/matplotlib-_5wuw2by
because the default path (/Users/runner/.matplotlib) is not a writable directory;
it is highly recommended to set the MPLCONFIGDIR environment variable to a writable directory,
in particular to speed up the import of Matplotlib and to better support multiprocessing.

objc[5388]: Class QT_ROOT_LEVEL_POOL__THESE_OBJECTS_WILL_BE_RELEASED_WHEN_QAPP_GOES_OUT_OF_SCOPE
is implemented in both
/Applications/MNE-Python/1.7.1_0/.mne-python/lib/libQt5Core.5.15.8.dylib (0x12a3b12e0) and
/Applications/MNE-Python/1.7.1_0/.mne-python/lib/libQt6Core.6.7.2.dylib (0x130ddd558).
One of the two will be used. Which one is undefined.

objc[5388]: Class KeyValueObserver is implemented in both
/Applications/MNE-Python/1.7.1_0/.mne-python/lib/libQt5Core.5.15.8.dylib (0x12a3b1308) and
/Applications/MNE-Python/1.7.1_0/.mne-python/lib/libQt6Core.6.7.2.dylib (0x130ddd580).
One of the two will be used. Which one is undefined.

objc[5388]: Class RunLoopModeTracker is implemented in both
/Applications/MNE-Python/1.7.1_0/.mne-python/lib/libQt5Core.5.15.8.dylib (0x12a3b1358) and
/Applications/MNE-Python/1.7.1_0/.mne-python/lib/libQt6Core.6.7.2.dylib (0x130ddd5d0).
One of the two will be used. Which one is undefined.

./tools/check_installation.sh: line 86:  5388 Segmentation fault: 11  mne sys_info

The segfault is maybe expected because of the warnings that precede it.

I haven't worked this out to a minimal example yet. I suspect this means that importing both is problematic, and I need to find out which package is still importing PyQt5, but I'm not sure. However, regardless of the outcome it just seems like it's cleaner and safer to avoid having both frameworks installed together as much as possible to avoid potential problems like this, so there's value in the build selector.

tacaswell commented 1 month ago

If you can get that down to a qtpy + matplotlib import (which I suspect will depend on the import order), if Matplotlib is the second import please report it as a bug to us!

If this is happening on CI, it may be that there is not actually a valid display so mpl is failing when trying to use qt6, then tries qt5. We may need to be more heavy-handed upstream about poisoning trying additional qt variants is something only partially imported.

larsoner commented 1 month ago

If you can get that down to a qtpy + matplotlib import (which I suspect will depend on the import order), if Matplotlib is the second import please report it as a bug to us!

I got on an intel mac and created and env with matplotlib pyqt pyside6 and everything was fine importing matplotlib.pyplot and qtpy in either order. When I manually imported PyQt5.QtWidgets for example then things broke, so it must have been some other package causing the problem by importing PyQt5.

There is a merge conflict so happy to fix this one up if people think build variants are worthwhile, or feel free to close if not

tacaswell commented 1 month ago

Just to check my understanding, conda does not have a notion of "alternatives" where multiple packages can satisfy a need ?

larsoner commented 1 month ago

I don't think so but I'm not an expert in conda so it's possible I've missed it somewhere. But build variants are how I've seen different "flavors" of packages come out, at least for VTK for example when you can choose between vtk=*=osmesa_* or qt variants:

https://github.com/conda-forge/vtk-feedstock/blob/6c602205cd876d9e00b88213c95e4d77b5e80cc5/recipe/meta.yaml#L6-L13

tacaswell commented 1 month ago

It may also be worth re-opening the discussion of changing which version of qt (if any) the matplotlib package depends on. Depending on matpotlib-base + pyside6 should be enough, but I assume that the odds at least one other package will also depend on matplotlib is high.

Given that Qt5 is already EOL (https://www.qt.io/blog/qt-5.15-extended-support-for-subscription-license-holders) we probably should move matplotlib to depend on pyqt6 (or pyside6).

Given that pyside6 is already packaged (there is an open PR to build pyqt6), that the patch to add input hook support will (soon?) land in pyside6, and there are no possibel GPL issues with pyside6 I think there is a strong case.


When I manually imported PyQt5.QtWidgets for example then things broke, so it must have been some other package causing the problem by importing PyQt5.

This suggests this may not be a completely sufficient fix ?

larsoner commented 1 month ago

we probably should move matplotlib to depend on pyqt6 (or pyside6).

PySide6 is the official binding and has a cleaner license (as you point out) so agreed it's a better choice probably. Just for the sake of completeness, PyQt6 might be an option eventually as well, see e.g. https://github.com/conda-forge/pyqt-feedstock/pull/136 (but who knows when that will land!). I'd be happy to close this in favor of migrating to PySide6 as the matplotlib flavor, and document that for people who want to continue with pyqt the workaround is installing matplotlib-base tornado pyqt instead.

I suspect that making this change will cause some problems for people and packaging, but it might be worth doing anyway to move things forward (and to a supported version of Qt!).

I assume that the odds at least one other package will also depend on matplotlib is high.

This might not be as bad as expected -- the conda-forge linter complains if you depend on matplotlib instead of matplotlib-base so hopefully people have listened :)

Given that pyside6 is already packaged (there is an open PR to build pyqt6), that the patch to add input hook support will (soon?) land in pyside6

Upstream it will come out in 6.7.3 but we backported it to conda-forge so it's in 6.7.2 build 1 via https://github.com/conda-forge/pyside2-feedstock/pull/230, so it should be safe to switch at the conda-forge end already.

This suggests this may not be a completely sufficient fix ?

Yeah there are / were probably other packages installed that required PyQt5, such as mayavi (which I recently refactored to have a pyside6 variant for example), pyface, etc.

tacaswell commented 1 month ago

On a bit more thought, I'll support a PR to switch to using pyside6 as the GUI dependency. I suspect that this is something where we need to get signoff from conda-forge core. @larsoner Are you willing to try and run that process rather than this one?

so it should be safe to switch at the conda-forge end already.

Can you pin to a particular build number or better? My memory is that the solvers treated all builds as equivalent (but my memory is 5-8 years out of date).

larsoner commented 1 month ago

Can you pin to a particular build number or better?

I've force-pushed a commit here with >=6.7.2=*_1, not 100% sure if it will work or not. But in theory even pinning to >=6.7.2 should be enough because there shouldn't be any reason conda would pick _0 over _1 (it should prefer the latter).

larsoner commented 1 month ago

@conda-forge-admin, please rerender

tacaswell commented 1 month ago

But in theory even pinning to >=6.7.2 should be enough because there shouldn't be any reason conda would pick _0 over _1 (it should prefer the latter).

To be fair this was a while ago (6years?) but we had the same thought, were running conda create name bunch of packages in ~40 different hosts and then had a few very confused days of things sometimes working and sometimes not which came down to the solve being non-deterministic and picking different builds on different hosts combined with a build-specific bug [if I had to guess the cause I suspect it was from the era of "dict iteration is random" and the solver was taking the first acceptable packaging it saw]. Which is a very long way of saying "I don't trust 'should'" ;) .

larsoner commented 1 month ago

Which is a very long way of saying "I don't trust 'should'" ;) .

Agreed unless a conda person can confirm the pinning in this PR is safe then we could just wait for 6.7.3 to land and then pinning to that should be fine.

Next I guess would be to contact some conda-forge folks to see what their opinion is on matplotlib making this switch?

tacaswell commented 1 month ago

@conda-forge/core This seems like something someone should sign off on before we implicitly change a lot of users to pyside6 !

h-vetinari commented 1 month ago

Just to check my understanding, conda does not have a notion of "alternatives" where multiple packages can satisfy a need ?

Not natively, but it's possible to do with a build-string-based mutex like for openmp.

In any case, for qt-related things, I think we should ping @conda-forge/qt-main, and specifically @hmaarrfk, @jschueller & @ccordoba12.

[...] before we implicitly change a lot of users to pyside6

My first instinct would be that we should at least wait for https://github.com/conda-forge/pyqt-feedstock/pull/136, but I'm not so involved in this space...

hmaarrfk commented 1 month ago

I'm ok with this. I've been trying to ensure that qt-main and qt6-main are co-installable. I think 6.7.2 is aggressive, but users can always downgrade the matplotlib version

ccordoba12 commented 1 month ago

Please note that this would prevent Spyder to be installed in the same environment as the latest versions of Matplotlib if Qt 5 and 6 are not really co-installable, which users could find confusing or problematic.

That's because Spyder is not ready for Qt6, much less for Pyside6. The latter is still buggy and unstable (its 6.7.0 version broke star imports, which broke qtpy and all projects that depend on it).

hmaarrfk commented 1 month ago

@ccordoba12 this won't affect anything at runtime for spyder:

On linux:

mamba create --name spyder spyder matplotlib-base "pyside6>=6.7.2" --channel conda-forge --override-channels

Will install:

mamba list ``` # packages in environment at /home/mark/miniforge3/envs/spyder: # # Name Version Build Channel _libgcc_mutex 0.1 conda_forge conda-forge _openmp_mutex 4.5 2_gnu conda-forge alabaster 0.7.16 pyhd8ed1ab_0 conda-forge alsa-lib 1.2.12 h4ab18f5_0 conda-forge arrow 1.3.0 pyhd8ed1ab_0 conda-forge astroid 3.2.3 py312h7900ff3_0 conda-forge asttokens 2.4.1 pyhd8ed1ab_0 conda-forge atomicwrites 1.4.1 pyhd8ed1ab_0 conda-forge attr 2.5.1 h166bdaf_1 conda-forge attrs 23.2.0 pyh71513ae_0 conda-forge autopep8 2.0.4 pyhd8ed1ab_0 conda-forge babel 2.14.0 pyhd8ed1ab_0 conda-forge backports 1.0 pyhd8ed1ab_3 conda-forge backports.tarfile 1.0.0 pyhd8ed1ab_1 conda-forge beautifulsoup4 4.12.3 pyha770c72_0 conda-forge binaryornot 0.4.4 py_1 conda-forge black 24.4.2 py312h7900ff3_0 conda-forge bleach 6.1.0 pyhd8ed1ab_0 conda-forge brotli 1.1.0 hd590300_1 conda-forge brotli-bin 1.1.0 hd590300_1 conda-forge brotli-python 1.1.0 py312h30efb56_1 conda-forge bzip2 1.0.8 h4bc722e_7 conda-forge ca-certificates 2024.7.4 hbcca054_0 conda-forge cairo 1.18.0 hbb29018_2 conda-forge certifi 2024.7.4 pyhd8ed1ab_0 conda-forge cffi 1.16.0 py312hf06ca03_0 conda-forge chardet 5.2.0 py312h7900ff3_1 conda-forge charset-normalizer 3.3.2 pyhd8ed1ab_0 conda-forge click 8.1.7 unix_pyh707e725_0 conda-forge cloudpickle 3.0.0 pyhd8ed1ab_0 conda-forge colorama 0.4.6 pyhd8ed1ab_0 conda-forge comm 0.2.2 pyhd8ed1ab_0 conda-forge contourpy 1.2.1 py312h8572e83_0 conda-forge cookiecutter 2.6.0 pyhca7485f_0 conda-forge cryptography 42.0.8 py312hbcc2302_0 conda-forge cycler 0.12.1 pyhd8ed1ab_0 conda-forge dbus 1.13.6 h5008d03_3 conda-forge debugpy 1.8.2 py312h7070661_0 conda-forge decorator 5.1.1 pyhd8ed1ab_0 conda-forge defusedxml 0.7.1 pyhd8ed1ab_0 conda-forge diff-match-patch 20230430 pyhd8ed1ab_0 conda-forge dill 0.3.8 pyhd8ed1ab_0 conda-forge docstring-to-markdown 0.15 pyhd8ed1ab_0 conda-forge docutils 0.21.2 pyhd8ed1ab_0 conda-forge double-conversion 3.3.0 h59595ed_0 conda-forge entrypoints 0.4 pyhd8ed1ab_0 conda-forge exceptiongroup 1.2.2 pyhd8ed1ab_0 conda-forge executing 2.0.1 pyhd8ed1ab_0 conda-forge expat 2.6.2 h59595ed_0 conda-forge flake8 7.0.0 pyhd8ed1ab_0 conda-forge font-ttf-dejavu-sans-mono 2.37 hab24e00_0 conda-forge font-ttf-inconsolata 3.000 h77eed37_0 conda-forge font-ttf-source-code-pro 2.038 h77eed37_0 conda-forge font-ttf-ubuntu 0.83 h77eed37_2 conda-forge fontconfig 2.14.2 h14ed4e7_0 conda-forge fonts-conda-ecosystem 1 0 conda-forge fonts-conda-forge 1 0 conda-forge fonttools 4.53.1 py312h41a817b_0 conda-forge freetype 2.12.1 h267a509_2 conda-forge gettext 0.22.5 h59595ed_2 conda-forge gettext-tools 0.22.5 h59595ed_2 conda-forge giflib 5.2.2 hd590300_0 conda-forge glib 2.80.2 hf974151_0 conda-forge glib-tools 2.80.2 hb6ce0ca_0 conda-forge graphite2 1.3.13 h59595ed_1003 conda-forge gst-plugins-base 1.24.5 hbaaba92_0 conda-forge gstreamer 1.24.5 haf2f30d_0 conda-forge h2 4.1.0 pyhd8ed1ab_0 conda-forge harfbuzz 8.5.0 hfac3d4d_0 conda-forge hpack 4.0.0 pyh9f0ad1d_0 conda-forge hyperframe 6.0.1 pyhd8ed1ab_0 conda-forge icu 73.2 h59595ed_0 conda-forge idna 3.7 pyhd8ed1ab_0 conda-forge imagesize 1.4.1 pyhd8ed1ab_0 conda-forge importlib-metadata 8.0.0 pyha770c72_0 conda-forge importlib_metadata 8.0.0 hd8ed1ab_0 conda-forge importlib_resources 6.4.0 pyhd8ed1ab_0 conda-forge inflection 0.5.1 pyh9f0ad1d_0 conda-forge intervaltree 3.1.0 pyhd8ed1ab_1 conda-forge ipykernel 6.29.5 pyh3099207_0 conda-forge ipython 8.26.0 pyh707e725_0 conda-forge isort 5.13.2 pyhd8ed1ab_0 conda-forge jaraco.classes 3.4.0 pyhd8ed1ab_1 conda-forge jaraco.context 5.3.0 pyhd8ed1ab_1 conda-forge jaraco.functools 4.0.0 pyhd8ed1ab_0 conda-forge jedi 0.19.1 pyhd8ed1ab_0 conda-forge jeepney 0.8.0 pyhd8ed1ab_0 conda-forge jellyfish 1.0.4 py312h4413252_0 conda-forge jinja2 3.1.4 pyhd8ed1ab_0 conda-forge jsonschema 4.23.0 pyhd8ed1ab_0 conda-forge jsonschema-specifications 2023.12.1 pyhd8ed1ab_0 conda-forge jupyter_client 8.6.2 pyhd8ed1ab_0 conda-forge jupyter_core 5.7.2 py312h7900ff3_0 conda-forge jupyterlab_pygments 0.3.0 pyhd8ed1ab_1 conda-forge keyring 25.2.1 pyha804496_0 conda-forge keyutils 1.6.1 h166bdaf_0 conda-forge kiwisolver 1.4.5 py312h8572e83_1 conda-forge krb5 1.21.3 h659f571_0 conda-forge lame 3.100 h166bdaf_1003 conda-forge lcms2 2.16 hb7c19ff_0 conda-forge ld_impl_linux-64 2.40 hf3520f5_7 conda-forge lerc 4.0.0 h27087fc_0 conda-forge libasprintf 0.22.5 h661eb56_2 conda-forge libasprintf-devel 0.22.5 h661eb56_2 conda-forge libblas 3.9.0 22_linux64_openblas conda-forge libbrotlicommon 1.1.0 hd590300_1 conda-forge libbrotlidec 1.1.0 hd590300_1 conda-forge libbrotlienc 1.1.0 hd590300_1 conda-forge libcap 2.69 h0f662aa_0 conda-forge libcblas 3.9.0 22_linux64_openblas conda-forge libclang-cpp15 15.0.7 default_h127d8a8_5 conda-forge libclang-cpp18.1 18.1.8 default_h36b48a3_0 conda-forge libclang13 18.1.8 default_h6ae225f_0 conda-forge libcups 2.3.3 h4637d8d_4 conda-forge libdeflate 1.20 hd590300_0 conda-forge libdrm 2.4.122 h4ab18f5_0 conda-forge libedit 3.1.20191231 he28a2e2_2 conda-forge libevent 2.1.12 hf998b51_1 conda-forge libexpat 2.6.2 h59595ed_0 conda-forge libffi 3.4.2 h7f98852_5 conda-forge libflac 1.4.3 h59595ed_0 conda-forge libgcc-ng 14.1.0 h77fa898_0 conda-forge libgcrypt 1.11.0 h4ab18f5_0 conda-forge libgettextpo 0.22.5 h59595ed_2 conda-forge libgettextpo-devel 0.22.5 h59595ed_2 conda-forge libgfortran-ng 14.1.0 h69a702a_0 conda-forge libgfortran5 14.1.0 hc5f4f2c_0 conda-forge libglib 2.80.2 hf974151_0 conda-forge libgomp 14.1.0 h77fa898_0 conda-forge libgpg-error 1.50 h4f305b6_0 conda-forge libiconv 1.17 hd590300_2 conda-forge libjpeg-turbo 3.0.0 hd590300_1 conda-forge liblapack 3.9.0 22_linux64_openblas conda-forge libllvm15 15.0.7 hb3ce162_4 conda-forge libllvm18 18.1.8 hc9dba70_0 conda-forge libnsl 2.0.1 hd590300_0 conda-forge libogg 1.3.5 h4ab18f5_0 conda-forge libopenblas 0.3.27 pthreads_hac2b453_1 conda-forge libopus 1.3.1 h7f98852_1 conda-forge libpciaccess 0.18 hd590300_0 conda-forge libpng 1.6.43 h2797004_0 conda-forge libpq 16.3 ha72fbe1_0 conda-forge libsndfile 1.2.2 hc60ed4a_1 conda-forge libsodium 1.0.18 h36c2ea0_1 conda-forge libspatialindex 2.0.0 he02047a_0 conda-forge libsqlite 3.46.0 hde9e2c9_0 conda-forge libstdcxx-ng 14.1.0 hc0a3c3a_0 conda-forge libsystemd0 255 h3516f8a_1 conda-forge libtiff 4.6.0 h1dd3fc0_3 conda-forge libuuid 2.38.1 h0b41bf4_0 conda-forge libvorbis 1.3.7 h9c3ff4c_0 conda-forge libwebp 1.4.0 h2c329e2_0 conda-forge libwebp-base 1.4.0 hd590300_0 conda-forge libxcb 1.16 hd590300_0 conda-forge libxcrypt 4.4.36 hd590300_1 conda-forge libxkbcommon 1.7.0 h2c5496b_1 conda-forge libxml2 2.12.7 h4c95cb1_3 conda-forge libxslt 1.1.39 h76b75d6_0 conda-forge libzlib 1.3.1 h4ab18f5_1 conda-forge lz4-c 1.9.4 hcb278e6_0 conda-forge markdown-it-py 3.0.0 pyhd8ed1ab_0 conda-forge markupsafe 2.1.5 py312h98912ed_0 conda-forge matplotlib-base 3.9.1 py312h9201f00_0 conda-forge matplotlib-inline 0.1.7 pyhd8ed1ab_0 conda-forge mccabe 0.7.0 pyhd8ed1ab_0 conda-forge mdurl 0.1.2 pyhd8ed1ab_0 conda-forge mistune 3.0.2 pyhd8ed1ab_0 conda-forge more-itertools 10.3.0 pyhd8ed1ab_0 conda-forge mpg123 1.32.6 h59595ed_0 conda-forge munkres 1.1.4 pyh9f0ad1d_0 conda-forge mypy_extensions 1.0.0 pyha770c72_0 conda-forge mysql-common 8.3.0 hf1915f5_4 conda-forge mysql-libs 8.3.0 hca2cd23_4 conda-forge nbclient 0.10.0 pyhd8ed1ab_0 conda-forge nbconvert 7.16.4 hd8ed1ab_1 conda-forge nbconvert-core 7.16.4 pyhd8ed1ab_1 conda-forge nbconvert-pandoc 7.16.4 hd8ed1ab_1 conda-forge nbformat 5.10.4 pyhd8ed1ab_0 conda-forge ncurses 6.5 h59595ed_0 conda-forge nest-asyncio 1.6.0 pyhd8ed1ab_0 conda-forge nspr 4.35 h27087fc_0 conda-forge nss 3.102 h593d115_0 conda-forge numpy 2.0.0 py312h22e1c76_0 conda-forge numpydoc 1.7.0 pyhd8ed1ab_1 conda-forge openjpeg 2.5.2 h488ebb8_0 conda-forge openssl 3.3.1 h4ab18f5_1 conda-forge packaging 24.1 pyhd8ed1ab_0 conda-forge pandoc 3.2.1 ha770c72_0 conda-forge pandocfilters 1.5.0 pyhd8ed1ab_0 conda-forge parso 0.8.4 pyhd8ed1ab_0 conda-forge pathspec 0.12.1 pyhd8ed1ab_0 conda-forge pcre2 10.43 hcad00b1_0 conda-forge pexpect 4.9.0 pyhd8ed1ab_0 conda-forge pickleshare 0.7.5 py_1003 conda-forge pillow 10.4.0 py312h287a98d_0 conda-forge pip 24.0 pyhd8ed1ab_0 conda-forge pixman 0.43.2 h59595ed_0 conda-forge pkgutil-resolve-name 1.3.10 pyhd8ed1ab_1 conda-forge platformdirs 4.2.2 pyhd8ed1ab_0 conda-forge pluggy 1.5.0 pyhd8ed1ab_0 conda-forge ply 3.11 pyhd8ed1ab_2 conda-forge prompt-toolkit 3.0.47 pyha770c72_0 conda-forge psutil 6.0.0 py312h9a8786e_0 conda-forge pthread-stubs 0.4 h36c2ea0_1001 conda-forge ptyprocess 0.7.0 pyhd3deb0d_0 conda-forge pulseaudio-client 17.0 hb77b528_0 conda-forge pure_eval 0.2.2 pyhd8ed1ab_0 conda-forge pycodestyle 2.11.1 pyhd8ed1ab_0 conda-forge pycparser 2.22 pyhd8ed1ab_0 conda-forge pydocstyle 6.3.0 pyhd8ed1ab_0 conda-forge pyflakes 3.2.0 pyhd8ed1ab_0 conda-forge pygments 2.18.0 pyhd8ed1ab_0 conda-forge pylint 3.2.5 pyhd8ed1ab_0 conda-forge pylint-venv 3.0.3 pyhd8ed1ab_0 conda-forge pyls-spyder 0.4.0 pyhd8ed1ab_0 conda-forge pyparsing 3.1.2 pyhd8ed1ab_0 conda-forge pyqt 5.15.9 py312h949fe66_5 conda-forge pyqt5-sip 12.12.2 py312h30efb56_5 conda-forge pyqtwebengine 5.15.9 py312hbd9a932_5 conda-forge pyside6 6.7.2 py312hb5137db_1 conda-forge pysocks 1.7.1 pyha2e5f31_6 conda-forge python 3.12.4 h194c7f8_0_cpython conda-forge python-dateutil 2.9.0 pyhd8ed1ab_0 conda-forge python-fastjsonschema 2.20.0 pyhd8ed1ab_0 conda-forge python-lsp-black 2.0.0 pyhd8ed1ab_0 conda-forge python-lsp-jsonrpc 1.1.2 pyhd8ed1ab_0 conda-forge python-lsp-server 1.11.0 pyhd8ed1ab_0 conda-forge python-lsp-server-base 1.11.0 pyhd8ed1ab_0 conda-forge python-slugify 8.0.4 pyhd8ed1ab_0 conda-forge python_abi 3.12 4_cp312 conda-forge pytoolconfig 1.2.5 pyhd8ed1ab_0 conda-forge pytz 2024.1 pyhd8ed1ab_0 conda-forge pyxdg 0.28 pyhd8ed1ab_0 conda-forge pyyaml 6.0.1 py312h98912ed_1 conda-forge pyzmq 26.0.3 py312h8fd38d8_0 conda-forge qdarkstyle 3.2.3 pyhd8ed1ab_0 conda-forge qhull 2020.2 h434a139_5 conda-forge qstylizer 0.2.3 pyhd8ed1ab_0 conda-forge qt-main 5.15.8 ha2b5568_22 conda-forge qt-webengine 5.15.8 h4c5bc8f_7 conda-forge qt6-main 6.7.2 h0f8cd61_2 conda-forge qtawesome 1.3.1 pyh9208f05_0 conda-forge qtconsole 5.5.2 pyhd8ed1ab_0 conda-forge qtconsole-base 5.5.2 pyha770c72_0 conda-forge qtpy 2.4.1 pyhd8ed1ab_0 conda-forge readline 8.2 h8228510_1 conda-forge referencing 0.35.1 pyhd8ed1ab_0 conda-forge requests 2.32.3 pyhd8ed1ab_0 conda-forge rich 13.7.1 pyhd8ed1ab_0 conda-forge rope 1.13.0 pyhd8ed1ab_0 conda-forge rpds-py 0.19.0 py312hf008fa9_0 conda-forge rtree 1.3.0 py312h18067a2_1 conda-forge secretstorage 3.3.3 py312h7900ff3_2 conda-forge setuptools 70.3.0 pyhd8ed1ab_0 conda-forge sip 6.7.12 py312h30efb56_0 conda-forge six 1.16.0 pyh6c4a22f_0 conda-forge snowballstemmer 2.2.0 pyhd8ed1ab_0 conda-forge sortedcontainers 2.4.0 pyhd8ed1ab_0 conda-forge soupsieve 2.5 pyhd8ed1ab_1 conda-forge sphinx 7.3.7 pyhd8ed1ab_0 conda-forge sphinxcontrib-applehelp 1.0.8 pyhd8ed1ab_0 conda-forge sphinxcontrib-devhelp 1.0.6 pyhd8ed1ab_0 conda-forge sphinxcontrib-htmlhelp 2.0.5 pyhd8ed1ab_0 conda-forge sphinxcontrib-jsmath 1.0.1 pyhd8ed1ab_0 conda-forge sphinxcontrib-qthelp 1.0.7 pyhd8ed1ab_0 conda-forge sphinxcontrib-serializinghtml 1.1.10 pyhd8ed1ab_0 conda-forge spyder 5.5.5 py312h7900ff3_0 conda-forge spyder-kernels 2.5.2 unix_pyh707e725_0 conda-forge stack_data 0.6.2 pyhd8ed1ab_0 conda-forge tabulate 0.9.0 pyhd8ed1ab_1 conda-forge text-unidecode 1.3 pyhd8ed1ab_1 conda-forge textdistance 4.6.2 pyhd8ed1ab_0 conda-forge three-merge 0.1.1 pyh9f0ad1d_0 conda-forge tinycss2 1.3.0 pyhd8ed1ab_0 conda-forge tk 8.6.13 noxft_h4845f30_101 conda-forge toml 0.10.2 pyhd8ed1ab_0 conda-forge tomli 2.0.1 pyhd8ed1ab_0 conda-forge tomlkit 0.13.0 pyha770c72_0 conda-forge tornado 6.4.1 py312h9a8786e_0 conda-forge traitlets 5.14.3 pyhd8ed1ab_0 conda-forge types-python-dateutil 2.9.0.20240316 pyhd8ed1ab_0 conda-forge typing-extensions 4.12.2 hd8ed1ab_0 conda-forge typing_extensions 4.12.2 pyha770c72_0 conda-forge tzdata 2024a h0c530f3_0 conda-forge ujson 5.10.0 py312h7070661_0 conda-forge urllib3 2.2.2 pyhd8ed1ab_1 conda-forge watchdog 4.0.1 py312h7900ff3_0 conda-forge wayland 1.23.0 h5291e77_0 conda-forge wcwidth 0.2.13 pyhd8ed1ab_0 conda-forge webencodings 0.5.1 pyhd8ed1ab_2 conda-forge whatthepatch 1.0.6 pyhd8ed1ab_0 conda-forge wheel 0.43.0 pyhd8ed1ab_1 conda-forge wurlitzer 3.1.1 pyhd8ed1ab_0 conda-forge xcb-util 0.4.1 hb711507_2 conda-forge xcb-util-cursor 0.1.4 h4ab18f5_2 conda-forge xcb-util-image 0.4.0 hb711507_2 conda-forge xcb-util-keysyms 0.4.1 hb711507_0 conda-forge xcb-util-renderutil 0.3.10 hb711507_0 conda-forge xcb-util-wm 0.4.2 hb711507_0 conda-forge xkeyboard-config 2.42 h4ab18f5_0 conda-forge xorg-compositeproto 0.4.2 h7f98852_1001 conda-forge xorg-damageproto 1.2.1 h7f98852_1002 conda-forge xorg-fixesproto 5.0 h7f98852_1002 conda-forge xorg-inputproto 2.3.2 h7f98852_1002 conda-forge xorg-kbproto 1.0.7 h7f98852_1002 conda-forge xorg-libice 1.1.1 hd590300_0 conda-forge xorg-libsm 1.2.4 h7391055_0 conda-forge xorg-libx11 1.8.9 hb711507_1 conda-forge xorg-libxau 1.0.11 hd590300_0 conda-forge xorg-libxcomposite 0.4.6 h0b41bf4_1 conda-forge xorg-libxdamage 1.1.5 h7f98852_1 conda-forge xorg-libxdmcp 1.1.3 h7f98852_0 conda-forge xorg-libxext 1.3.4 h0b41bf4_2 conda-forge xorg-libxfixes 5.0.3 h7f98852_1004 conda-forge xorg-libxi 1.7.10 h7f98852_0 conda-forge xorg-libxrandr 1.5.2 h7f98852_1 conda-forge xorg-libxrender 0.9.11 hd590300_0 conda-forge xorg-libxtst 1.2.3 h7f98852_1002 conda-forge xorg-randrproto 1.5.0 h7f98852_1001 conda-forge xorg-recordproto 1.14.2 h7f98852_1002 conda-forge xorg-renderproto 0.11.1 h7f98852_1002 conda-forge xorg-util-macros 1.19.3 h7f98852_0 conda-forge xorg-xextproto 7.3.0 h0b41bf4_1003 conda-forge xorg-xf86vidmodeproto 2.3.1 h7f98852_1002 conda-forge xorg-xproto 7.0.31 h7f98852_1007 conda-forge xz 5.2.6 h166bdaf_0 conda-forge yaml 0.2.5 h7f98852_2 conda-forge yapf 0.40.1 pyhd8ed1ab_0 conda-forge zeromq 4.3.5 h75354e8_4 conda-forge zipp 3.19.2 pyhd8ed1ab_0 conda-forge zlib 1.3.1 h4ab18f5_1 conda-forge zstandard 0.22.0 py312h5b18bf6_1 conda-forge zstd 1.5.6 ha6fb4c9_0 conda-forge ```
$ mamba activate spyder
$ spyder

seems to open fine image

tacaswell commented 1 month ago

The latter is still buggy and unstable (its 6.7.0 version broke star imports, which broke qtpy and all projects that depend on it).

This is a bit worrying.

I think we need a decision on how we are going to make this decision.

From the mpl side, I see no problem and am happy to be "the decider" on it, however given that if there is a blast radius from this it will fall on the CF folks not me I don't think I should be the final say on this PR.

@hmaarrfk can you propose who should make the call (and how!)?

hmaarrfk commented 1 month ago

I don’t think there is a problem with having matplotlib depend on PySide6 and spyder depend on PyQt5

packages should depend on matplotlib-base and that should not bring in any qt dependency.

I and others are very invested in making both python qt binding co-installable.

I say go for it. I’ve been using PySide6 for a while and it seems to be getting better in each version. So if you want it to be the default when you install matplotlib i don’t see a problem with it.

To note, we’ve made open by default to qt6-main

tacaswell commented 1 month ago

To note, we’ve made open by default to qt6-main

What does this mean?

hmaarrfk commented 1 month ago

Re opencv (on phone hard to quote) I’ve built 3 versions, one with qt6 bindings, one with qt5 and one without bindings.

On Linux. If you type

conda install opencv

it should pick out the qt6 bindings since that has a higher build number.

The blast has been “minimal” (I was mostly concerned about end users and not so much maintainers).

Opencv uses qt for their highgui frontend. Not sure how widely used it is.

tacaswell commented 1 month ago

I'll merge this tomorrow (this seems like the thing to do on Friday afternoon!) unless there is a protest.

tacaswell commented 1 month ago

Do I need to do any sort of announcement or documentation?

hmaarrfk commented 1 month ago

Do I need to do any sort of announcement or documentation?

Honestly. Not really. Downstream packages should all depend on matplotlib-base. This is a convenience for your users that read your matplotlib documentation

conda-forge-webservices[bot] commented 1 month ago

Hi! This is the friendly automated conda-forge-linting service.

I was trying to look for recipes to lint for you, but it appears we have a merge conflict. Please try to merge or rebase with the base branch to resolve this conflict.

Please ping the 'conda-forge/core' team (using the @ notation in a comment) if you believe this is a bug.

conda-forge-webservices[bot] commented 1 month ago

Hi! This is the friendly automated conda-forge-linting service.

I just wanted to let you know that I linted all conda-recipes in your PR (recipe/meta.yaml) and found it was in an excellent condition.

larsoner commented 1 month ago

@conda-forge-admin, please rerender

github-actions[bot] commented 1 month ago

Hi! This is the friendly automated conda-forge-webservice.

I tried to rerender for you, but it looks like there was nothing to do.

This message was generated by GitHub actions workflow run https://github.com/conda-forge/matplotlib-feedstock/actions/runs/10216572449.

larsoner commented 1 month ago

Okay all green and I think this has the selector we converged on:

        - pyside6 >=6.7.2  # [python_impl == "cpython" and not osx and not ppc64le]
hmaarrfk commented 1 month ago

could we instead write "1 OS per line"

- pyside6 >=6.7.2  # [python_impl == "cpython" and win]
- pyside6 >=6.7.2  # [python_impl == "cpython" and linux64]
- pyside6 >=6.7.2  # [python_impl == "cpython" and aarch64]
# We avoid the PySide6 dependency on OSX since they use the native backend by default
hmaarrfk commented 1 month ago

If you want. You can add a few run constraints to omit the problematic build of 6.7.2 that you all helped resolve upstream

h-vetinari commented 1 month ago

Sorry, I was on a phone before, I hadn't seen @hmaarrfk asking basically the opposite of what I did. I'll let you figure it out -- my preference was as I commented (one line, with an explanatory comment).

As I mentioned in one of the threads further up, I don't think it's worth hacking around the _0 build, just >=6.7.2 is good enough, because the solver has absolutely no reason to ever prefer the old _0 build over _1 (as all their constraints are identical; down to the exact versions from all run-exports; I checked).

See [here](https://conda-metadata-app.streamlit.app/?q=conda-forge%2Flinux-64%2Fpyside6-6.7.2-py39h8242bd1_1.conda) (and then navigate to the various builds; these are all for `py39_{0,1}`) ``` linux-64: __glibc >=2.17,<3.0.a0 libclang13 >=18.1.8 libgcc-ng >=12 libstdcxx-ng >=12 libxml2 >=2.12.7,<3.0a0 libxslt >=1.1.39,<2.0a0 python >=3.9,<3.10.0a0 python_abi 3.9.* *_cp39 qt6-main 6.7.2.* qt6-main >=6.7.2,<6.8.0a0 win-64: libclang13 >=18.1.8 libxml2 >=2.12.7,<3.0a0 libxslt >=1.1.39,<2.0a0 python >=3.9,<3.10.0a0 python_abi 3.9.* *_cp39 qt6-main 6.7.2.* qt6-main >=6.7.2,<6.8.0a0 ucrt >=10.0.20348.0 vc >=14.2,<15 vc14_runtime >=14.29.30139 ```
larsoner commented 1 month ago

Okay pushed your verison @h-vetinari, okay for you @hmaarrfk ?

h-vetinari commented 1 month ago

We may want to raise a conda issue though. I don't see why the run-constraint to forbid a specific build shouldn't work in principle.

(The one way I can think of that the solver might get tricked into using _0 is if a user already has that pyside build in their environment, but if anyone comes with with such an issue, conda update pyside6 will fix it)