CX_Freeze и guiqwt работают в Windows, а не в Linux

Я использую CX_Freeze, чтобы заморозить одну из моих программ на Python. Система сборки отлично работает в Windows. Я могу создать каталог с исполняемым файлом и необходимыми зависимостями, который будет работать в любой системе Windows.

Когда я пытаюсь сделать то же самое в Linux, часть сборки

python setup.py

работает отлично. Но когда я пытаюсь запустить встроенный исполняемый файл, он выдает следующую ошибку.

 File "/usr/local/lib/python2.7/dist-packages/cx_Freeze/initscripts/Console.py", line 27, in <module>
exec code in m.__dict__
File "test.py", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/guidata/__init__.py", line 540, in <module>
import guidata.config
File "/usr/local/lib/python2.7/dist-packages/guidata/config.py", line 19, in <module>
add_image_module_path("guidata", "images")
File "/usr/local/lib/python2.7/dist-packages/guidata/configtools.py", line 100, in add_image_module_path
add_image_path(get_module_data_path(modname, relpath=relpath), subfolders)
File "/usr/local/lib/python2.7/dist-packages/guidata/configtools.py", line 86, in add_image_path
for fileobj in os.listdir(path):
OSError: [Errno 20] Not a directory: '/home/user/tmp/dist/library.zip/guidata/images'

Похоже, что guidata пытается найти изображения в несуществующем каталоге library.zip/guidata/images. Я убедился, что запускаю одни и те же версии guidata, cx_Freeze как на Windows, так и на Linux. Любая помощь в решении проблемы приветствуется.

Минимальный пример

import guidata                                                                                                                              
_app = guidata.qapplication() # not required if a QApplication has already been created

import guidata.dataset.datatypes as dt
import guidata.dataset.dataitems as di

class Processing(dt.DataSet):
    """Example"""
    a = di.FloatItem("Parameter #1", default=2.3)
    b = di.IntItem("Parameter #2", min=0, max=10, default=5)
    type = di.ChoiceItem("Processing algorithm",
                     ("type 1", "type 2", "type 3"))

param = Processing()
param.edit()

установочный файл

import sys
import os

"""Create a stand-alone executable"""

try:
    import guidata
    from guidata.disthelpers import Distribution
except ImportError:
    raise ImportError, "This script requires guidata 1.4+"



def create_executable():
    """Build executable using ``guidata.disthelpers``"""
    dist = Distribution()
    dist.setup(name='Foo', version='0.1',
           description='bar',
           script="test.py", target_name='test.exe')
    dist.add_modules('guidata', 'guiqwt')
    # Building executable
    dist.build('cx_Freeze')

if __name__ == '__main__':
    create_executable()

person user1941055    schedule 01.01.2013    source источник


Ответы (1)


ХОРОШО. Вот ответ на мой собственный вопрос. После долгих раскопок я понял, что это ошибка в модуле guidata и/или os.path python. Происходит вот что. В модуле guidata в файле configtools.py есть функция get_module_data_path, которая проверяет, является ли родительский «каталог» пути, такого как /foo/bar/library.zip/yap, файлом.

    import os.path as osp
...
...
    datapath = get_module_path(modname)
    parentdir = osp.join(datapath, osp.pardir)
    if osp.isfile(parentdir):
        # Parent directory is not a directory but the 'library.zip' file:
        # this is either a py2exe or a cx_Freeze distribution
        datapath = ...

Теперь тест

osp.isfile("/foo/bar/library.zip/yap/..")

возвращает True в Windows, но False в Linux. Это нарушает код. В документации Python неясно, является ли это ошибкой или предполагаемым поведением.

На данный момент у меня нет решения, но есть хак. Я изменил приведенный выше код следующим образом:

    import os.path as osp
...
...
    datapath = get_module_path(modname)
    parentdir = osp.join(datapath, osp.pardir)
    parentdir2 = osp.split(datapath.rstrip(os.path.sep))[0]
    if osp.isfile(parentdir) or osp.isfile(parentdir2):
        # Parent directory is not a directory but the 'library.zip' file:
        # this is either a py2exe or a cx_Freeze distribution
        datapath = ...

и все в порядке.

person user1941055    schedule 02.01.2013