dipy / dipy

DIPY is the paragon 3D/4D+ imaging library in Python. Contains generic methods for spatial normalization, signal processing, machine learning, statistical analysis and visualization of medical images. Additionally, it contains specialized methods for computational anatomy including diffusion, perfusion and structural imaging.
https://dipy.org
Other
700 stars 436 forks source link

Python 3.13: `TypeError: cannot remove variables from FrameLocalsProxy` in tests #3292

Closed sanjayankur31 closed 1 week ago

sanjayankur31 commented 2 months ago

Description

Fedora is testing out our packages with Python 3.13. Dipy failed to build because tests fail. Here's the stack trace of an example test failure. Full log attached:

build.log.txt

=================================== FAILURES ===================================
_________________________________ test_reslice _________________________________

    def test_reslice():

        with TemporaryDirectory() as out_dir:
            data_path, _, _ = get_fnames('small_25')
            volume = load_nifti_data(data_path)

            reslice_flow = ResliceFlow()
>           reslice_flow.run(data_path, [1.5, 1.5, 1.5], out_dir=out_dir)

../../BUILDROOT/usr/lib64/python3.13/site-packages/dipy/workflows/tests/test_align.py:34:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../BUILDROOT/usr/lib64/python3.13/site-packages/dipy/workflows/align.py:92: in run
    io_it = self.get_io_iterator()
../../BUILDROOT/usr/lib64/python3.13/site-packages/dipy/workflows/workflow.py:36: in get_io_iterator
    io_it = io_iterator_(frame, self.run,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

frame = <frame at 0x7f6ef74cbac0, file '/builddir/build/BUILD/python-dipy-1.9.0-build/BUILDROOT/usr/lib64/python3.13/site-packages/dipy/workflows/align.py', line 92, code run>
fnc = <bound method ResliceFlow.run of <dipy.workflows.align.ResliceFlow object at 0x7f6ef78c2cf0>>
output_strategy = 'absolute', mix_names = False

    def io_iterator_(frame, fnc, output_strategy='absolute', mix_names=False):
        """Create an IOIterator using introspection.

        Parameters
        ----------
        frame : frameobject
            Contains the info about the current local variables values.
        fnc : function
            The function to inspect
        output_strategy : string
            Controls the behavior of the IOIterator for output paths.
        mix_names : bool
            Whether or not to append a mix of input names at the beginning.

        Returns
        -------
            Properly instantiated IOIterator object.

        """
        args, _, _, values = inspect.getargvalues(frame)
        args.remove('self')
>       del values['self']
E       TypeError: cannot remove variables from FrameLocalsProxy

../../BUILDROOT/usr/lib64/python3.13/site-packages/dipy/workflows/multi_io.py:177: TypeError

Way to reproduce

  python3-numpy-1.26.4-7.fc41.x86_64
  python3-numpy-f2py-1.26.4-7.fc41.x86_64
  python3-scipy-1.11.3-13.fc41.x86_64
  python3-nibabel-5.2.1-4.fc41.noarch
  python3-h5py-3.11.0-2.fc41.x86_64

Downstream bug:

https://bugzilla.redhat.com/show_bug.cgi?id=2280596

It may be related to this PEP 667 change, but I've not yet had a chance to properly investigate:

https://docs.python.org/3.13/whatsnew/3.13.html#defined-mutation-semantics-for-locals

penguinpee commented 1 month ago

I have been trying to put my finger on a specific commit in the 3.13.0b1 release that's causing the tests to regress. So far, I haven't been able to.

Since the error message is mentioning FrameLocalsProxy, I'm pretty sure the regression is related to the implementation of PEP 667 that was merged into the first beta release. Maybe that helps in finding out what needs changing.