Bug#1092083: mayavi2 ftbfs with Python 3.13 as the default

Colin Watson cjwatson at debian.org
Tue Jan 7 15:35:10 GMT 2025


Control: clone -1 -2
Control: reassign -2 python3-vtk9
Control: retitle -2 python3-vtk9: segfault on Python 3.13
Control: tags -2 patch

On Sat, Jan 04, 2025 at 12:36:21PM +0100, Matthias Klose wrote:
> mayavi2 ftbfs with Python 3.13 as the default
> 
> [...]
>  debian/rules binary
> dh binary --buildsystem=pybuild
>    dh_update_autotools_config -O--buildsystem=pybuild
>    dh_autoreconf -O--buildsystem=pybuild
>    dh_auto_configure -O--buildsystem=pybuild
> 	pybuild --configure -i python{version} -p 3.13
> I: pybuild base:311: python3.13 setup.py config
> running config
>    debian/rules override_dh_auto_build
> make[1]: Entering directory '/<<PKGBUILDDIR>>'
> find /<<PKGBUILDDIR>>/* -name '*.pyx' -exec cython3 '{}' ';'
> LD_PRELOAD=libgomp.so.1 xvfb-run --auto-servernum --server-args="-screen 0
> 1024x768x24" dh_auto_build
> 	pybuild --build -i python{version} -p 3.13
> I: pybuild base:311: /usr/bin/python3 setup.py build
> running build
> running build_py
> Segmentation fault (core dumped)

Most of this is due to vtk9.  I've attached a patch cherry-picked from
upstream which fixes this.

There's one remaining problem after this, which I haven't been able to
figure out myself so far.  Here's the test log:

     dh_auto_test -O--buildsystem=pybuild
          pybuild --test -i python{version} -p 3.13
  I: pybuild base:311: cd /build/reproducible-path/mayavi2-4.8.2/.pybuild/cpython3_3.13/build; cd /build/reproducible-path/mayavi2-4.8.2/.pybuild/cpython3_3.13/build ; LD_PRELOAD=libgomp.so.1 xvfb-run --auto-servernum --server-args="-screen 0 1024x768x24" python3.13 -m pytest -k 'not test_array2vtk'
  ============================= test session starts ==============================
  platform linux -- Python 3.13.1, pytest-8.3.4, pluggy-1.5.0
  rootdir: /build/reproducible-path/mayavi2-4.8.2/.pybuild/cpython3_3.13/build
  configfile: setup.cfg
  plugins: typeguard-4.4.1
  collected 444 items / 1 deselected / 443 selected
  
  mayavi/tests/test_array_source.py .........                              [  2%]
  mayavi/tests/test_builtin_image.py ...                                   [  2%]
  mayavi/tests/test_builtin_surface.py ...                                 [  3%]
  mayavi/tests/test_composite_data.py ....                                 [  4%]
  mayavi/tests/test_contour.py ....                                        [  5%]
  mayavi/tests/test_core_common.py ........                                [  6%]
  mayavi/tests/test_core_utils.py ...                                      [  7%]
  mayavi/tests/test_csv_sniff.py .....................                     [ 12%]
  mayavi/tests/test_customize.py .                                         [ 12%]
  mayavi/tests/test_cut_plane.py ..                                        [ 13%]
  mayavi/tests/test_dataset_manager.py ........                            [ 14%]
  mayavi/tests/test_engine_manager.py .........                            [ 16%]
  mayavi/tests/test_extract_grid_filter.py ss                              [ 17%]
  mayavi/tests/test_file_timestep.py ......                                [ 18%]
  mayavi/tests/test_filters.py .                                           [ 18%]
  mayavi/tests/test_garbage_collection.py ......                           [ 20%]
  mayavi/tests/test_glyph.py ......                                        [ 21%]
  mayavi/tests/test_grid_plane.py ...                                      [ 22%]
  mayavi/tests/test_image_data_probe.py ...                                [ 23%]
  mayavi/tests/test_image_data_reader.py ......                            [ 24%]
  mayavi/tests/test_image_plane_widget.py ....                             [ 25%]
  mayavi/tests/test_ipw_multiple_scalars.py .                              [ 25%]
  mayavi/tests/test_mayavi_traits.py .......                               [ 27%]
  mayavi/tests/test_mlab_integration.py .............................      [ 33%]
  mayavi/tests/test_mlab_null_engine.py ..                                 [ 34%]
  mayavi/tests/test_mlab_scene_model.py .                                  [ 34%]
  mayavi/tests/test_mlab_source.py ....................................... [ 43%]
                                                                           [ 43%]
  mayavi/tests/test_mlab_source_integration.py .......                     [ 44%]
  mayavi/tests/test_mouse_pick_dispatcher.py .                             [ 44%]
  mayavi/tests/test_no_ui_toolkit.py .                                     [ 45%]
  mayavi/tests/test_optional_collection.py ...                             [ 45%]
  mayavi/tests/test_pipeline_info.py ..                                    [ 46%]
  mayavi/tests/test_plot3d_mb_reader.py ...                                [ 46%]
  mayavi/tests/test_poly_data_reader.py ...........................        [ 53%]
  mayavi/tests/test_preferences_mirror.py ....                             [ 53%]
  mayavi/tests/test_pylab_luts.py s                                        [ 54%]
  mayavi/tests/test_recorder.py .............                              [ 57%]
  mayavi/tests/test_registry.py .....                                      [ 58%]
  mayavi/tests/test_script_recording.py .                                  [ 58%]
  mayavi/tests/test_set_active_attribute.py ...                            [ 59%]
  mayavi/tests/test_sources.py .                                           [ 59%]
  mayavi/tests/test_streamline.py ....                                     [ 60%]
  mayavi/tests/test_text3d.py ...                                          [ 60%]
  mayavi/tests/test_threshold_filter.py ....                               [ 61%]
  mayavi/tests/test_unstructured_data_reader.py ...s...                    [ 63%]
  mayavi/tests/test_user_defined.py ...                                    [ 64%]
  mayavi/tests/test_volume.py .                                            [ 64%]
  mayavi/tests/test_vtk_data_source.py .........                           [ 66%]
  mayavi/tests/test_vtk_file_reader.py ......                              [ 67%]
  mayavi/tests/test_vtk_object_source.py .....                             [ 68%]
  mayavi/tests/test_vtk_xml_reader.py ...                                  [ 69%]
  tvtk/tests/test_array_ext.py ..                                          [ 69%]
  tvtk/tests/test_array_handler.py .........                               [ 72%]
  tvtk/tests/test_browser.py ......                                        [ 73%]
  tvtk/tests/test_class_tree.py ......                                     [ 74%]
  tvtk/tests/test_ctf_util.py X.                                           [ 75%]
  tvtk/tests/test_garbage_collection.py ...F                               [ 76%]
  tvtk/tests/test_indenter.py .........                                    [ 78%]
  tvtk/tests/test_messenger.py .....                                       [ 79%]
  tvtk/tests/test_misc.py .....                                            [ 80%]
  tvtk/tests/test_movie_maker.py ....                                      [ 81%]
  tvtk/tests/test_pyface_utils.py ..                                       [ 81%]
  tvtk/tests/test_tvtk.py .........s..............s.....................   [ 92%]
  tvtk/tests/test_tvtk_base.py .............                               [ 95%]
  tvtk/tests/test_tvtk_scene.py .                                          [ 95%]
  tvtk/tests/test_visual.py ..........                                     [ 97%]
  tvtk/tests/test_vtk_parser.py ........                                   [ 99%]
  tvtk/tests/test_wrapper_gen.py ...                                       [100%]
  
  =================================== FAILURES ===================================
  __________________ TestTVTKGarbageCollection.test_tvtk_scene ___________________
  tvtk/tests/test_garbage_collection.py:50: in test_tvtk_scene
      self.check_object_garbage_collected(create_fn, close_fn)
  tvtk/tests/common.py:61: in check_object_garbage_collected
      self.assertTrue(object_collected[0])
  E   IndexError: list index out of range
  =============================== warnings summary ===============================
  ../../../../../../usr/lib/python3/dist-packages/traits/observation/_generated_parser.py:258
    /usr/lib/python3/dist-packages/traits/observation/_generated_parser.py:258: DeprecationWarning: module 'sre_parse' is deprecated
      import sre_parse
  
  ../../../../../../usr/lib/python3/dist-packages/traits/observation/_generated_parser.py:259
    /usr/lib/python3/dist-packages/traits/observation/_generated_parser.py:259: DeprecationWarning: module 'sre_constants' is deprecated
      import sre_constants
  
  mayavi/tests/test_composite_data.py: 1 warning
  mayavi/tests/test_contour.py: 34 warnings
  mayavi/tests/test_image_data_probe.py: 16 warnings
  mayavi/tests/test_mlab_integration.py: 4 warnings
  mayavi/tests/test_mlab_null_engine.py: 1 warning
  mayavi/tests/test_optional_collection.py: 6 warnings
  mayavi/tests/test_script_recording.py: 2 warnings
  mayavi/tests/test_set_active_attribute.py: 6 warnings
  mayavi/tests/test_vtk_data_source.py: 31 warnings
  mayavi/tests/test_vtk_xml_reader.py: 21 warnings
    /build/reproducible-path/mayavi2-4.8.2/.pybuild/cpython3_3.13/build/mayavi/components/contour.py:222: DeprecationWarning: In the future, lists will no longer be accepted by the Tuple trait type. Lists should be converted to tuples prior to validation.
      self._current_range = rng
  
  mayavi/tests/test_mlab_integration.py::TestMlabNullEngineMisc::test_user_defined_filter
    /build/reproducible-path/mayavi2-4.8.2/.pybuild/cpython3_3.13/build/tvtk/tools/tvtk_doc.py:77: DeprecationWarning: Call to deprecated class vtkOutputWindowCleanup. (`vtkOutputWindowCleanup` is no longer necessary) -- Deprecated since version 9.3.0.
      c = klass()
  
  mayavi/tests/test_mlab_integration.py::TestMlabModules::test_volume
  mayavi/tests/test_mlab_integration.py::TestMlabModules::test_volume
  mayavi/tests/test_mlab_integration.py::TestMlabModules::test_volume
  mayavi/tests/test_mlab_integration.py::TestMlabModules::test_volume
  mayavi/tests/test_mlab_integration.py::TestMlabModules::test_volume
  mayavi/tests/test_volume.py::TestVolumeWorksWithProbe::test_volume_works_with_probe
    /build/reproducible-path/mayavi2-4.8.2/.pybuild/cpython3_3.13/build/mayavi/modules/volume.py:469: DeprecationWarning: In the future, lists will no longer be accepted by the Tuple trait type. Lists should be converted to tuples prior to validation.
      self.current_range = rng
  
  tvtk/tests/test_array_handler.py::TestArrayHandler::test_arr2cell_array
  tvtk/tests/test_array_handler.py::TestArrayHandler::test_arr2cell_array
    /usr/lib/python3.13/unittest/case.py:606: DeprecationWarning: `alltrue` is deprecated as of NumPy 1.25.0, and will be removed in NumPy 2.0. Please use `all` instead.
      if method() is not None:
  
  tvtk/tests/test_tvtk.py::TestTVTKModule::test_all_instantiable
  tvtk/tests/test_tvtk.py::TestTVTKModule::test_all_traits_can_be_obtained
  tvtk/tests/test_tvtk.py::TestTVTKModule::test_no_trait_has_ptr_address_as_value
  tvtk/tests/test_tvtk.py::TestTVTKModule::test_trait_with_range
    /build/reproducible-path/mayavi2-4.8.2/.pybuild/cpython3_3.13/build/tvtk/tvtk_base.py:575: DeprecationWarning: Call to deprecated method GetPreserveInputEntityGroups. (PreserveInputEntityGroups is no longer needed.) -- Deprecated since version 9.3.0.
      val = getattr(vtk_obj, getter)()
  
  tvtk/tests/test_tvtk.py::TestTVTKModule::test_all_instantiable
  tvtk/tests/test_tvtk.py::TestTVTKModule::test_all_traits_can_be_obtained
  tvtk/tests/test_tvtk.py::TestTVTKModule::test_no_trait_has_ptr_address_as_value
  tvtk/tests/test_tvtk.py::TestTVTKModule::test_trait_with_range
    /build/reproducible-path/mayavi2-4.8.2/.pybuild/cpython3_3.13/build/tvtk/tvtk_base.py:575: DeprecationWarning: Call to deprecated method GetOptimizeForRealInput. (Function has been renamed GetReturnOnesided) -- Deprecated since version 9.3.0.
      val = getattr(vtk_obj, getter)()
  
  tvtk/tests/test_tvtk.py::TestTVTKModule::test_all_instantiable
  tvtk/tests/test_tvtk.py::TestTVTKModule::test_all_traits_can_be_obtained
  tvtk/tests/test_tvtk.py::TestTVTKModule::test_no_trait_has_ptr_address_as_value
  tvtk/tests/test_tvtk.py::TestTVTKModule::test_trait_with_range
    /build/reproducible-path/mayavi2-4.8.2/.pybuild/cpython3_3.13/build/tvtk/tvtk_base.py:575: DeprecationWarning: Call to deprecated method GetNumberOfBlock. (Block behavior is not controlled using BlockSize and BlockOverlap properties.) -- Deprecated since version 9.3.0.
      val = getattr(vtk_obj, getter)()
  
  tvtk/tests/test_vtk_parser.py::TestVTKParser::test_parse_all
    /build/reproducible-path/mayavi2-4.8.2/.pybuild/cpython3_3.13/build/tvtk/vtk_parser.py:536: DeprecationWarning: Call to deprecated method GetPreserveInputEntityGroups. (PreserveInputEntityGroups is no longer needed.) -- Deprecated since version 9.3.0.
      tm[key] = getattr(obj, 'Get%s'%key)()
  
  tvtk/tests/test_vtk_parser.py::TestVTKParser::test_parse_all
    /build/reproducible-path/mayavi2-4.8.2/.pybuild/cpython3_3.13/build/tvtk/vtk_parser.py:536: DeprecationWarning: Call to deprecated method GetOptimizeForRealInput. (Function has been renamed GetReturnOnesided) -- Deprecated since version 9.3.0.
      tm[key] = getattr(obj, 'Get%s'%key)()
  
  tvtk/tests/test_vtk_parser.py::TestVTKParser::test_parse_all
    /build/reproducible-path/mayavi2-4.8.2/.pybuild/cpython3_3.13/build/tvtk/vtk_parser.py:713: DeprecationWarning: Call to deprecated method GetNumberOfBlock. (Block behavior is not controlled using BlockSize and BlockOverlap properties.) -- Deprecated since version 9.3.0.
      default = getattr(obj, 'Get%s' % key)()
  
  -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
  =================================== XPASSES ====================================
  ============================= slowest 20 durations =============================
  5.08s call     tvtk/tests/test_tvtk.py::TestTVTKModule::test_trait_with_range
  1.93s call     tvtk/tests/test_vtk_parser.py::TestVTKParser::test_parse_all
  1.39s call     tvtk/tests/test_tvtk.py::TestTVTK::test_contextdevice2d_matrix_api
  0.54s call     tvtk/tests/test_tvtk.py::TestTVTKModule::test_import_tvtk_does_not_import_gui
  0.31s call     mayavi/tests/test_core_common.py::test_core_common_pyface_import_honors_env_var
  0.30s call     mayavi/tests/test_vtk_data_source.py::TestVTKDataSource::test_deepcopied
  0.29s call     mayavi/tests/test_mlab_null_engine.py::TestRealMlabNullEngine::test_test_backend_clf
  0.24s call     tvtk/tests/test_tvtk.py::TestTVTKModule::test_all_traits_can_be_obtained
  0.23s call     tvtk/tests/test_tvtk.py::TestTVTKModule::test_no_trait_has_ptr_address_as_value
  0.23s call     tvtk/tests/test_tvtk.py::TestTVTKModule::test_all_instantiable
  0.22s call     tvtk/tests/test_tvtk.py::TestTVTK::test_object_cache
  0.21s call     mayavi/tests/test_image_plane_widget.py::TestImagePlaneWidget::test_save_and_restore
  0.19s call     mayavi/tests/test_mlab_integration.py::TestMlabModules::test_volume
  0.15s call     mayavi/tests/test_vtk_data_source.py::TestVTKDataSource::test_save_and_restore
  0.15s call     mayavi/tests/test_contour.py::TestContour::test_save_and_restore
  0.13s call     mayavi/tests/test_mlab_integration.py::TestMlabNullEngineMisc::test_user_defined_filter
  0.13s call     tvtk/tests/test_garbage_collection.py::TestTVTKGarbageCollection::test_tvtk_scene
  0.13s call     mayavi/tests/test_streamline.py::TestStreamline::test_save_and_restore
  0.12s call     mayavi/tests/test_filters.py::TestFilters::test_cell_to_point_data
  0.12s call     mayavi/tests/test_contour.py::TestContour::test_deepcopied
  =========================== short test summary info ============================
  SKIPPED [1] mayavi/tests/test_extract_grid_filter.py:101: actor.bounds returns incorrect values
  SKIPPED [1] mayavi/tests/test_extract_grid_filter.py:137: actor.bounds returns incorrect values
  SKIPPED [1] mayavi/tests/test_pylab_luts.py:9: mayavi.core.lut_manager is already loaded in another tests. Can't run this test.
  SKIPPED [1] mayavi/tests/test_unstructured_data_reader.py:65: ExodusIIReader support is disabled for now.
  SKIPPED [1] tvtk/tests/test_tvtk.py:710: ContextDevice2D has a subclass. This may cause the TVTK API to be different from if it had not
  SKIPPED [1] tvtk/tests/test_tvtk.py:690: ObjectFactory has a subclass. This may cause the TVTK API to be different from if it had not
  XPASS tvtk/tests/test_ctf_util.py::TestCTFUtil::test_rescale_ctf - Failing on osmesa / headless tests
  FAILED tvtk/tests/test_garbage_collection.py::TestTVTKGarbageCollection::test_tvtk_scene
  = 1 failed, 435 passed, 6 skipped, 1 deselected, 1 xpassed, 148 warnings in 18.15s =
  E: pybuild pybuild:389: test: plugin distutils failed with: exit code=1: cd /build/reproducible-path/mayavi2-4.8.2/.pybuild/cpython3_3.13/build; cd {build_dir} ; LD_PRELOAD=libgomp.so.1 xvfb-run --auto-servernum --server-args="-screen 0 1024x768x24" {interpreter} -m pytest -k 'not test_array2vtk'

Any clues?  It's possible that some other cherry-pick in VTK would help,
I suppose, but given the long build times I haven't tried this myself.
I didn't see anything immediately obvious in mayavi or VTK upstream git
repositories; however, this looks like the sort of integration test that
might be quite sensitive to subtle changes in various places.

Thanks,

-- 
Colin Watson (he/him)                              [cjwatson at debian.org]
-------------- next part --------------
diff -Nru vtk9-9.3.0+dfsg1/debian/changelog vtk9-9.3.0+dfsg1/debian/changelog
--- vtk9-9.3.0+dfsg1/debian/changelog	2024-11-22 10:49:45.000000000 +0000
+++ vtk9-9.3.0+dfsg1/debian/changelog	2025-01-07 13:22:11.000000000 +0000
@@ -1,3 +1,10 @@
+vtk9 (9.3.0+dfsg1-1.2) UNRELEASED; urgency=medium
+
+  * Non-maintainer upload.
+  * Python 3.13 fix for missing dict segfault (closes: #1092083).
+
+ -- Colin Watson <cjwatson at debian.org>  Tue, 07 Jan 2025 13:22:11 +0000
+
 vtk9 (9.3.0+dfsg1-1.1) unstable; urgency=medium
 
   * Non-maintainer upload.
diff -Nru vtk9-9.3.0+dfsg1/debian/patches/130_py313-missing-dict-segfault.patch vtk9-9.3.0+dfsg1/debian/patches/130_py313-missing-dict-segfault.patch
--- vtk9-9.3.0+dfsg1/debian/patches/130_py313-missing-dict-segfault.patch	1970-01-01 01:00:00.000000000 +0100
+++ vtk9-9.3.0+dfsg1/debian/patches/130_py313-missing-dict-segfault.patch	2025-01-07 13:21:47.000000000 +0000
@@ -0,0 +1,52 @@
+From: David Gobbi <david.gobbi at gmail.com>
+Date: Tue, 7 Jan 2025 13:21:44 +0000
+Subject: Python 3.13 fix for missing dict segfault
+
+Python 3.13 removed a safety net from PyModule_Type's tp_init slot
+that created the module's md_dict member if it was NULL.  This
+safety net was removed because, since Python 3.11, the md_dict is
+created by tp_new and is never expected to be NULL.  So, in our
+own code, we must ensure that tp_new is called before tp_init.
+
+Origin: upstream, https://gitlab.kitware.com/vtk/vtk/-/commit/675929762a09ad0b40cb2667918a7061c47a418c
+Bug-Debian: https://bugs.debian.org/1092083
+Last-Update: 2025-01-07
+---
+ Wrapping/PythonCore/PyVTKNamespace.cxx | 6 ++++--
+ Wrapping/PythonCore/PyVTKTemplate.cxx  | 6 ++++--
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/Wrapping/PythonCore/PyVTKNamespace.cxx b/Wrapping/PythonCore/PyVTKNamespace.cxx
+index bed60dc..c182308 100644
+--- a/Wrapping/PythonCore/PyVTKNamespace.cxx
++++ b/Wrapping/PythonCore/PyVTKNamespace.cxx
+@@ -112,8 +112,10 @@ PyObject* PyVTKNamespace_New(const char* name)
+   {
+     // make sure python has readied the type object
+     PyType_Ready(&PyVTKNamespace_Type);
+-    // call the allocator provided by python for this type
+-    self = PyVTKNamespace_Type.tp_alloc(&PyVTKNamespace_Type, 0);
++    // call the superclass new function
++    PyObject* empty = PyTuple_New(0);
++    self = PyVTKNamespace_Type.tp_base->tp_new(&PyVTKNamespace_Type, empty, nullptr);
++    Py_DECREF(empty);
+     // call the superclass init function
+     PyObject* pyname = PyUnicode_FromString(name);
+     PyObject* args = PyTuple_Pack(1, pyname);
+diff --git a/Wrapping/PythonCore/PyVTKTemplate.cxx b/Wrapping/PythonCore/PyVTKTemplate.cxx
+index 26421f6..e7780bf 100644
+--- a/Wrapping/PythonCore/PyVTKTemplate.cxx
++++ b/Wrapping/PythonCore/PyVTKTemplate.cxx
+@@ -761,8 +761,10 @@ PyObject* PyVTKTemplate_New(const char* name, const char* docstring)
+ {
+   // make sure python has readied the type object
+   PyType_Ready(&PyVTKTemplate_Type);
+-  // call the allocator provided by python for this type
+-  PyObject* self = PyVTKTemplate_Type.tp_alloc(&PyVTKTemplate_Type, 0);
++  // call the superclass new function
++  PyObject* empty = PyTuple_New(0);
++  PyObject* self = PyVTKTemplate_Type.tp_base->tp_new(&PyVTKTemplate_Type, empty, nullptr);
++  Py_DECREF(empty);
+   // call the superclass init function
+   PyObject* pyname = PyUnicode_FromString(name);
+   PyObject* pydoc = PyUnicode_FromString(docstring);
diff -Nru vtk9-9.3.0+dfsg1/debian/patches/series vtk9-9.3.0+dfsg1/debian/patches/series
--- vtk9-9.3.0+dfsg1/debian/patches/series	2024-06-06 06:04:23.000000000 +0100
+++ vtk9-9.3.0+dfsg1/debian/patches/series	2025-01-07 13:21:47.000000000 +0000
@@ -12,3 +12,4 @@
 99_fix_ftbfs.patch
 100_add_missing_gl_header.patch
 121_add_support_for_loong64.patch
+130_py313-missing-dict-segfault.patch


More information about the debian-science-maintainers mailing list