Skip to content

Nibabel 2.2.0 cannot be frozen #571

Closed
@pauldmccarthy

Description

@pauldmccarthy

Hey guys,

Problem description

I've just discovered that nibabel 2.2.0 is incompatible with both pyinstaller and py2app, projects for creating standalone (a.k.a. "frozen") python applications.

Here is a stack trace from a frozen version of FSLeyes using nibabel 2.2.0:

[fsluser@localhost dist]$ ./FSLeyes/fsleyes -V
Traceback (most recent call last):
  File "site-packages/wx/core.py", line 3163, in <lambda>
  File "fsleyes/main.py", line 203, in init
  File "site-packages/nibabel/__init__.py", line 38, in <module>
  File "site-packages/nibabel/analyze.py", line 87, in <module>
  File "site-packages/nibabel/volumeutils.py", line 22, in <module>
  File "site-packages/nibabel/casting.py", line 11, in <module>
  File "site-packages/nibabel/testing/__init__.py", line 35, in <module>
  File "site-packages/nibabel/testing/np_features.py", line 19, in <module>
  File "site-packages/nibabel/testing/np_features.py", line 12, in _memmap_after_ufunc
FileNotFoundError: [Errno 2] No such file or directory: '/home/fsluser/dist/FSLeyes/nibabel/testing/np_features.pyc'

Cause

This occurs because nibabel.testing.np_features is now imported when the nibabel package is imported*. The nibabel.testing.np_features._memmap_after_ufunc function is called on import, and attempts to open the file nibabel/testing/np_features.py. The catch is that this source file doesn't exist when the code is executed from a frozen application.

* The import in the stack trace above (nibabel/casting.py) is, ironically, an unused import. But nibabel.testing is explicitly imported innibabel/__init__.py a little later on, so this error would still occur if the unused imports were removed.

Solutions

First of all, I'm not sure if this should be fixed within nibabel, or rather if it should be the responsibility of pyinstaller/py2app to explicitly handle nibabel (they have hooks for various other projects, e.g. matplotlib, numpy, etc).

Having said that, it would be easy to fix within nibabel - here are a couple of ideas:

  • Open a different file, one which is known to exist
  • Test to see if the file exists before opening it. If it doesn't, fall back to a more primitive test (e.g. checking the numpy version number)

What do you think? I'm happy to start a PR if you think that this should be handled in nibabel.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions