matplotlib-venn icon indicating copy to clipboard operation
matplotlib-venn copied to clipboard

PyTest matplotlib_venn/_venn2.py failed due to NSInternalInconsistencyException on darwin (macos)

Open Moraxyc opened this issue 10 months ago • 7 comments

Environment

System:

                     ..'          
                 ,xNMM.           
               .OMMMMo            OS: macOS Sequoia 15.2 arm64
               lMM"               Host: Mac mini (2024)
     .;loddo:.  .olloddol;.       Kernel: Darwin 24.2.0
   cKMMMMMMMMMMNWMMMMMMMMMM0:     
 .KMMMMMMMMMMMMMMMMMMMMMMMWd.     Packages: 951 (nix-system), 45 (nix-default), 3 (brew-cask)
 XMMMMMMMMMMMMMMMMMMMMMMMX.       Shell: zsh 5.9
;MMMMMMMMMMMMMMMMMMMMMMMM:        
:MMMMMMMMMMMMMMMMMMMMMMMM:        
.MMMMMMMMMMMMMMMMMMMMMMMMX.       
 kMMMMMMMMMMMMMMMMMMMMMMMMWd.     
 'XMMMMMMMMMMMMMMMMMMMMMMMMMMk    
  'XMMMMMMMMMMMMMMMMMMMMMMMMK.    
    kMMMMMMMMMMMMMMMMMMMMMMd      Terminal: /dev/ttys000
     ;KMMMMMMMWXXWMMMMMMMk.       CPU: Apple M4 (10) @ 4.46 GHz
       "cooc*"    "*coo'"         GPU: Apple M4 (10) @ 1.58 GHz [Integrated]
                                  Memory: 11.79 GiB / 16.00 GiB (74%)
                                  Swap: 12.91 GiB / 14.00 GiB (92%)
                                  Locale: C

Pytest:

pytest flags: -m pytest -k not\ matplotlib_venn.layout.venn3.cost_based.LayoutAlgorithm
============================= test session starts ==============================
platform darwin -- Python 3.12.9, pytest-8.3.4, pluggy-1.5.0

Log detail

 matplotlib_venn/_arc.py ....................                             [ 35%]
 matplotlib_venn/_common.py .                                             [ 37%]
 matplotlib_venn/_math.py ........                                        [ 51%]
 matplotlib_venn/_region.py .....                                         [ 60%]
 matplotlib_venn/_venn2.py ...*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Critical error: required built-in appearance SystemAppearance not found'
 *** First throw call stack:
 (
         0   CoreFoundation                      0x00000001934d6e80 __exceptionPreprocess + 176
         1   libobjc.A.dylib                     0x0000000192fbecd8 objc_exception_throw + 88
         2   CoreFoundation                      0x00000001934d6d70 +[NSException exceptionWithName:reason:userInfo:] + 0
         3   AppKit                              0x0000000196f9ba30 __33+[NSAppearance _initializeCoreUI]_block_invoke + 88
         4   libdispatch.dylib                   0x00000001931c95b4 _dispatch_client_callout + 20
         5   libdispatch.dylib                   0x00000001931cae00 _dispatch_once_callout + 32
         6   AppKit                              0x0000000196fbc5c0 +[NSAppearance _aquaAppearance] + 60
         7   AppKit                              0x0000000196f9b19c +[NSAppearance appearanceNamed:] + 32
         8   AppKit                              0x0000000196f9a814 -[NSSystemAppearanceProxy init] + 124
         9   AppKit                              0x0000000196f9a788 __38+[NSSystemAppearanceProxy systemProxy]_block_invoke + 24
         10  libdispatch.dylib                   0x00000001931c95b4 _dispatch_client_callout + 20
         11  libdispatch.dylib                   0x00000001931cae00 _dispatch_once_callout + 32
         12  AppKit                              0x0000000196f9a76c +[NSSystemAppearanceProxy systemProxy] + 64
         13  AppKit                              0x0000000196f9a6f8 -[NSApplication(NSApplicationAppearance_Internal) _registerForAppearanceNotifications] + 32
         14  AppKit                              0x0000000196f98314 -[NSApplication init] + 908
         15  AppKit                              0x0000000196f97dbc +[NSApplication sharedApplication] + 128
         16  _macosx.cpython-312-darwin.so       0x000000016ad32d98 FigureCanvas_new + 60
         17  libpython3.12.dylib                 0x0000000104d45840 type_call + 84
         18  libpython3.12.dylib                 0x0000000104caa410 _PyObject_MakeTpCall + 356
         19  libpython3.12.dylib                 0x0000000104e0b540 _PyEval_EvalFrameDefault + 22224
         20  libpython3.12.dylib                 0x0000000104caeae4 method_vectorcall + 180
         21  libpython3.12.dylib                 0x0000000104caac50 _PyVectorcall_Call + 132
         22  libpython3.12.dylib                 0x0000000104e0b320 _PyEval_EvalFrameDefault + 21680
         23  libpython3.12.dylib                 0x0000000104e05c24 PyEval_EvalCode + 508
         24  libpython3.12.dylib                 0x0000000104e01b8c builtin_exec + 1860
         25  libpython3.12.dylib                 0x0000000104e0df54 _PyEval_EvalFrameDefault + 32996
         26  libpython3.12.dylib                 0x0000000104caa0f4 _PyObject_FastCallDictTstate + 160
         27  libpython3.12.dylib                 0x0000000104d4df6c slot_tp_call + 292
         28  libpython3.12.dylib                 0x0000000104cab0c4 _PyObject_Call + 188
         29  libpython3.12.dylib                 0x0000000104e0b320 _PyEval_EvalFrameDefault + 21680
         30  libpython3.12.dylib                 0x0000000104caa0f4 _PyObject_FastCallDictTstate + 160
         31  libpython3.12.dylib                 0x0000000104d4df6c slot_tp_call + 292
         32  libpython3.12.dylib                 0x0000000104caa410 _PyObject_MakeTpCall + 356
         33  libpython3.12.dylib                 0x0000000104e0b540 _PyEval_EvalFrameDefault + 22224
         34  libpython3.12.dylib                 0x0000000104caa0f4 _PyObject_FastCallDictTstate + 160
         35  libpython3.12.dylib                 0x0000000104d4df6c slot_tp_call + 292
         36  libpython3.12.dylib                 0x0000000104caa410 _PyObject_MakeTpCall + 356
         37  libpython3.12.dylib                 0x0000000104e0b540 _PyEval_EvalFrameDefault + 22224
         38  libpython3.12.dylib                 0x0000000104caa0f4 _PyObject_FastCallDictTstate + 160
         39  libpython3.12.dylib                 0x0000000104d4df6c slot_tp_call + 292
         40  libpython3.12.dylib                 0x0000000104caa410 _PyObject_MakeTpCall + 356
         41  libpython3.12.dylib                 0x0000000104e0b540 _PyEval_EvalFrameDefault + 22224
         42  libpython3.12.dylib                 0x0000000104e05c24 PyEval_EvalCode + 508
         43  libpython3.12.dylib                 0x0000000104e01b8c builtin_exec + 1860
         44  libpython3.12.dylib                 0x0000000104d1dabc cfunction_vectorcall_FASTCALL_KEYWORDS + 152
         45  libpython3.12.dylib                 0x0000000104caae10 PyObject_Vectorcall + 88
         46  libpython3.12.dylib                 0x0000000104e0b540 _PyEval_EvalFrameDefault + 22224
         47  libpython3.12.dylib                 0x0000000104eb8930 pymain_run_module + 244
         48  libpython3.12.dylib                 0x0000000104eb8298 Py_RunMain + 2220
         49  libpython3.12.dylib                 0x0000000104eb8700 pymain_main + 552
         50  libpython3.12.dylib                 0x0000000104eb8808 Py_BytesMain + 56
         51  dyld                                0x0000000192ffc274 start + 2840
 )
 libc++abi: terminating due to uncaught exception of type NSException
 Fatal Python error: Aborted

 Current thread 0x00000001fcc5c240 (most recent call first):
   File "/nix/store/a8cd51xb8i81mblraq3hzc3v5d9kw4kx-python3.12-matplotlib-3.10.0/lib/python3.12/site-packages/matplotlib/backend_bases.py", line 2654 in create_with_canvas
   File "/nix/store/a8cd51xb8i81mblraq3hzc3v5d9kw4kx-python3.12-matplotlib-3.10.0/lib/python3.12/site-packages/matplotlib/backend_bases.py", line 1783 in new_manager
   File "/nix/store/a8cd51xb8i81mblraq3hzc3v5d9kw4kx-python3.12-matplotlib-3.10.0/lib/python3.12/site-packages/matplotlib/backend_bases.py", line 3506 in new_figure_manager_given_figure
   File "/nix/store/a8cd51xb8i81mblraq3hzc3v5d9kw4kx-python3.12-matplotlib-3.10.0/lib/python3.12/site-packages/matplotlib/backend_bases.py", line 3501 in new_figure_manager
   File "/nix/store/a8cd51xb8i81mblraq3hzc3v5d9kw4kx-python3.12-matplotlib-3.10.0/lib/python3.12/site-packages/matplotlib/pyplot.py", line 552 in new_figure_manager
   File "/nix/store/a8cd51xb8i81mblraq3hzc3v5d9kw4kx-python3.12-matplotlib-3.10.0/lib/python3.12/site-packages/matplotlib/pyplot.py", line 1042 in figure
   File "/nix/store/a8cd51xb8i81mblraq3hzc3v5d9kw4kx-python3.12-matplotlib-3.10.0/lib/python3.12/site-packages/matplotlib/pyplot.py", line 1108 in gcf
   File "/nix/store/a8cd51xb8i81mblraq3hzc3v5d9kw4kx-python3.12-matplotlib-3.10.0/lib/python3.12/site-packages/matplotlib/pyplot.py", line 2776 in gca
   File "/private/tmp/nix-build-python3.12-matplotlib-venn-1.1.1.drv-0/matplotlib-venn-1.1.1/matplotlib_venn/_venn2.py", line 191 in _render_layout
   File "/private/tmp/nix-build-python3.12-matplotlib-venn-1.1.1.drv-0/matplotlib-venn-1.1.1/matplotlib_venn/_venn2.py", line 173 in venn2
   File "<doctest matplotlib_venn._venn2.venn2[1]>", line 1 in <module>
   File "/nix/store/wwqdmdr2f5wrjnsjs64bny8df471rh9b-python3-3.12.9/lib/python3.12/doctest.py", line 1368 in __run
   File "/nix/store/wwqdmdr2f5wrjnsjs64bny8df471rh9b-python3-3.12.9/lib/python3.12/doctest.py", line 1532 in run
   File "/nix/store/wwqdmdr2f5wrjnsjs64bny8df471rh9b-python3-3.12.9/lib/python3.12/doctest.py", line 1893 in run
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/_pytest/doctest.py", line 301 in runtest
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/_pytest/runner.py", line 174 in pytest_runtest_call
   File "/nix/store/x3n7f1k0rlxc8g9iwbiagljmnagz773d-python3.12-pluggy-1.5.0/lib/python3.12/site-packages/pluggy/_callers.py", line 103 in _multicall
   File "/nix/store/x3n7f1k0rlxc8g9iwbiagljmnagz773d-python3.12-pluggy-1.5.0/lib/python3.12/site-packages/pluggy/_manager.py", line 120 in _hookexec
   File "/nix/store/x3n7f1k0rlxc8g9iwbiagljmnagz773d-python3.12-pluggy-1.5.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 513 in __call__
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/_pytest/runner.py", line 242 in <lambda>
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/_pytest/runner.py", line 341 in from_call
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/_pytest/runner.py", line 241 in call_and_report
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/_pytest/runner.py", line 132 in runtestprotocol
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/_pytest/runner.py", line 113 in pytest_runtest_protocol
   File "/nix/store/x3n7f1k0rlxc8g9iwbiagljmnagz773d-python3.12-pluggy-1.5.0/lib/python3.12/site-packages/pluggy/_callers.py", line 103 in _multicall
   File "/nix/store/x3n7f1k0rlxc8g9iwbiagljmnagz773d-python3.12-pluggy-1.5.0/lib/python3.12/site-packages/pluggy/_manager.py", line 120 in _hookexec
   File "/nix/store/x3n7f1k0rlxc8g9iwbiagljmnagz773d-python3.12-pluggy-1.5.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 513 in __call__
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/_pytest/main.py", line 362 in pytest_runtestloop
   File "/nix/store/x3n7f1k0rlxc8g9iwbiagljmnagz773d-python3.12-pluggy-1.5.0/lib/python3.12/site-packages/pluggy/_callers.py", line 103 in _multicall
   File "/nix/store/x3n7f1k0rlxc8g9iwbiagljmnagz773d-python3.12-pluggy-1.5.0/lib/python3.12/site-packages/pluggy/_manager.py", line 120 in _hookexec
   File "/nix/store/x3n7f1k0rlxc8g9iwbiagljmnagz773d-python3.12-pluggy-1.5.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 513 in __call__
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/_pytest/main.py", line 337 in _main
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/_pytest/main.py", line 283 in wrap_session
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/_pytest/main.py", line 330 in pytest_cmdline_main
   File "/nix/store/x3n7f1k0rlxc8g9iwbiagljmnagz773d-python3.12-pluggy-1.5.0/lib/python3.12/site-packages/pluggy/_callers.py", line 103 in _multicall
   File "/nix/store/x3n7f1k0rlxc8g9iwbiagljmnagz773d-python3.12-pluggy-1.5.0/lib/python3.12/site-packages/pluggy/_manager.py", line 120 in _hookexec
   File "/nix/store/x3n7f1k0rlxc8g9iwbiagljmnagz773d-python3.12-pluggy-1.5.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 513 in __call__
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/_pytest/config/__init__.py", line 175 in main
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/_pytest/config/__init__.py", line 201 in console_main
   File "/nix/store/yj91nnzfhikjzhx8wbs1xsh0095b1zwz-python3.12-pytest-8.3.4/lib/python3.12/site-packages/pytest/__main__.py", line 9 in <module>
   File "<frozen runpy>", line 88 in _run_code
   File "<frozen runpy>", line 198 in _run_module_as_main

 Extension modules: numpy._core._multiarray_umath, numpy.linalg._umath_linalg, PIL._imaging, kiwisolver._cext, scipy._lib._ccallback_c, scipy.linalg._fblas, scipy.linalg._flapack, scipy.linalg.cython_lapack, scipy.linalg._cythonized_array_utils, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._mt19937, numpy.random.mtrand, numpy.random._philox, numpy.random._pcg64, numpy.random._sfc64, numpy.random._generator, scipy.linalg._solve_toeplitz, scipy.linalg._decomp_lu_cython, scipy.linalg._matfuncs_sqrtm_triu, scipy.linalg._matfuncs_expm, scipy.linalg._linalg_pythran, scipy.linalg.cython_blas, scipy.linalg._decomp_update, scipy.sparse._sparsetools, _csparsetools, scipy.sparse._csparsetools, scipy.sparse.linalg._dsolve._superlu, scipy.sparse.linalg._eigen.arpack._arpack, scipy.sparse.linalg._propack._spropack, scipy.sparse.linalg._propack._dpropack, scipy.sparse.linalg._propack._cpropack, scipy.sparse.linalg._propack._zpropack, scipy.sparse.csgraph._tools, scipy.sparse.csgraph._shortest_path, scipy.sparse.csgraph._traversal, scipy.sparse.csgraph._min_spanning_tree, scipy.sparse.csgraph._flow, scipy.sparse.csgraph._matching, scipy.sparse.csgraph._reordering, scipy.optimize._group_columns, scipy._lib.messagestream, scipy.optimize._trlib._trlib, scipy.optimize._lbfgsb, _moduleTNC, scipy.optimize._moduleTNC, scipy.optimize._cobyla, scipy.optimize._slsqp, scipy.optimize._minpack, scipy.optimize._lsq.givens_elimination, scipy.optimize._zeros, scipy.optimize._cython_nnls, scipy._lib._uarray._uarray, scipy.special._ufuncs_cxx, scipy.special._ufuncs, scipy.special._specfun, scipy.special._comb, scipy.special._ellip_harm_2, scipy.linalg._decomp_interpolative, scipy.optimize._bglu_dense, scipy.optimize._lsap, scipy.spatial._ckdtree, scipy.spatial._qhull, scipy.spatial._voronoi, scipy.spatial._distance_wrap, scipy.spatial._hausdorff, scipy.spatial.transform._rotation, scipy.optimize._direct, shapely.lib, shapely._geos, shapely._geometry_helpers, matplotlib.backends._macosx (total: 73)

Moraxyc avatar Feb 20 '25 17:02 Moraxyc

I feel like it's more related to a specific function in matplotlib (probably gca in matplotlib.pyplot), which is incompatible with the newer versions of macOS UI frameworks.

Aleksanaa avatar Feb 24 '25 11:02 Aleksanaa

I can't reproduce the issue on the one Mac around that I have, so if there's a code-fix on the library side that could help, I'd welcome a PR from someone who could debug this.

konstantint avatar Feb 25 '25 10:02 konstantint

I hit a related issue to this and reported it upstream to matplotlib: https://github.com/matplotlib/matplotlib/issues/30666.

My hitting this is probably using the library in an incorrect way, but I can probably come up with a reasonable real use-case that would trigger issues due to use of global state in pyplot in the _venn2.py plotting code.

@konstantint IMO, instead of relying on pyplot as a fallback and a concept of a global "active plot", you should instead refactor things so that you explicitly create and pass around figure and axes objects.

ngoldbaum avatar Oct 21 '25 19:10 ngoldbaum

@konstantint IMO, instead of relying on pyplot as a fallback and a concept of a global "active plot", you should instead refactor things so that you explicitly create and pass around figure and axes objects.

See also https://github.com/matplotlib/matplotlib/issues/30666#issuecomment-3429582257

timhoffm avatar Oct 21 '25 21:10 timhoffm

@konstantint IMO, instead of relying on pyplot as a fallback and a concept of a global "active plot", you should instead refactor things so that you explicitly create and pass around figure and axes objects.

See also matplotlib/matplotlib#30666 (comment)

I believe all plotting functions do allow the user to pass an axes object, but the mode where the current axes are used by default must also be supported as that is a typical pattern of usage for matplotlob.

It feels that the problem is somewhere on MacOS or Matplotlob side rather. I could probably work around it in a test, but then it is probably a good thing that a test catches an existing problem, hoping it will eventually be fixed?

konstantint avatar Oct 22 '25 07:10 konstantint

Just to be clear: I think the original issue here and https://github.com/konstantint/matplotlib-venn/issues/87#issuecomment-3429254593 are unrelated. The latter is a result of parallelizing pytest and simultaneously using a GUI backend. See https://github.com/matplotlib/matplotlib/issues/30666#issuecomment-3429765198

timhoffm avatar Oct 22 '25 14:10 timhoffm

I think you could hit this issue if you try to create plots in a multithreaded workflow in parallel on a Mac without explicitly setting a backend. I hit it during testing but you could definitely trigger it in a real workflow if thread workers create plots simultaneously.

Personally, when I work with matplotlib as a library author, I try to avoid using pyplot as much as possible because of issues like this one that ultimately come from relying on global state.

In the end I agree the best place to fix this is in matplotlib, by converting the crash users currently see into a runtime error telling them they're using matplotlib incorrectly.

ngoldbaum avatar Oct 22 '25 14:10 ngoldbaum