brainvisa / aims-free

Analysis of Images and Signal for neuroimaging
Other
6 stars 3 forks source link

Python binding of aims.getRoiIterator is missing/broken #85

Closed ylep closed 2 years ago

ylep commented 2 years ago

Describe the bug The Python binding aims.getRoiIterator is missing/broken in a very weird way: under BrainVISA the object exists but is not callable, while under a plain Python shell it is missing altogether.

To Reproduce under BrainVISA:

  1. Launch brainvisa
  2. Open the Python console (BrainVISA / Start Shell...)
  3. aims.getRoiIterator exists but is not usable:

    from soma import aims aims.getRoiIterator()

    TypeError Traceback (most recent call last)

    in () ----> 1 aims.getRoiIterator() TypeError: 'sip.methoddescriptor' object is not callable

To Reproduce in a plain Python shell:

  1. Launch bv ipython
  2. aims.getRoiIterator does not exist:

    In [1]: from soma import aims

    In [2]: aims.getRoiIterator

    AttributeError Traceback (most recent call last)

    in () ----> 1 aims.getRoiIterator AttributeError: 'module' object has no attribute 'getRoiIterator'

Expected behavior aims.getRoiIterator should exist and be callable in all contexts. Note that in both cases aims.aimssip.aims.getRoiIterator exists and works fine.

Workaround

# Work around a bug in BrainVISA 5.0.4
# (https://github.com/brainvisa/aims-free/issues/85)
if not callable(getattr(aims, "getRoiIterator", None)):
    aims.getRoiIterator = aims.aimssip.aims.getRoiIterator

Environment:

denisri commented 2 years ago

sip does strange things that I don't understand, especially for functions in namespaces. I have already struggled with it and could neither explain what is going on (functions appear or disappear during modules import/initialization), nor fix things in a satisfactory way. I also think that the ExtendedImporter object in soma.importer (which makes things visible in soma.aims rather than soma.aims.aimssip.aims, for instance) is too complex, too difficult to understand, and/or breaks things on its side, I don't know and don't understand.

denisri commented 2 years ago

I could add the functions in soma.aims, but they get messed up in brainvisa during processes importation. I don't know if it's caused by a specific process or not.

denisri commented 2 years ago

It's messed up during import of brainvisa.anatomist. I'm looking at it.

denisri commented 2 years ago

which happens in anatomist.api import.

denisri commented 2 years ago

It's once again in the ExtendedImporter: objects are copied from their original location (soma.aims.aimssip.aims for instance) to a "simpler place" (soma.aims). But depending on how we get objects there, we obtain different types. soma.aims.aimssip.aims is a class actually, not a module (it's a C++ namespace). Functions there can be browsed using:

What is strange is that there was already code to take care of this situation in soma.importer:

    # in sip >= 4.8, obj.__dict__[key] and getattr(obj, key)
    # do *not* return the same thing for functions !

But then the code was using object.__getattribute__() which for me returns the same thing as using __dict__. Or maybe something has changed between python2 and python3 ? Anyway I'm going to use getattr() now, and we will see if it fixes things or causes other problems.

ylep commented 2 years ago

I confirm that the issue is fixed in the build from last night, both in plain Python and in BrainVISA. Thanks @denisri, that one was tricky...