PyTest matplotlib_venn/_venn2.py failed due to NSInternalInconsistencyException on darwin (macos)
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)
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.
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.
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.
@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
@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.
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?
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
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.