Как заставить модуль файловой магии работать в Alpine Linux?

Я пытаюсь использовать файловую магию в Alpine Linux, и она продолжает взрываться AttributeError: Symbol not found: magic_open всякий раз, когда я импортирую модуль magic.

Я заметил, что есть два модуля Python с одним и тем же пространством имен magic, но поскольку большинство дистрибутивов Linux используют file-magic, а не python-magic, я решил сделать свой модуль зависимым от первого. Однако в Alpine работает только python-magic:

Настройте Alpine и установите libmagic:

$ docker run --rm -it python:3-alpine /bin/sh
/ # apk add libmagic
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
(1/1) Installing libmagic (5.32-r0)
OK: 21 MiB in 35 packages

Установить файловую магию:

/ # pip install file-magic
Collecting file-magic
  Downloading https://files.pythonhosted.org/packages/bb/7e/b256e53a6558afd348387c3119dc4a1e3003d36030584a427168c8d72a7a/file_magic-0.4.0-py3-none-any.whl
Installing collected packages: file-magic
Successfully installed file-magic-0.4.0

Однако это не работает:

/ # python
Python 3.7.1 (default, Dec 21 2018, 03:21:42) 
[GCC 6.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import magic
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.7/site-packages/magic.py", line 61, in <module>
    _open = _libraries['magic'].magic_open
  File "/usr/local/lib/python3.7/ctypes/__init__.py", line 369, in __getattr__
    func = self.__getitem__(name)
  File "/usr/local/lib/python3.7/ctypes/__init__.py", line 374, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: Symbol not found: magic_open
>>> 

Замените магию файлов на магию python:

$ pip uninstall file-magic
Uninstalling file-magic-0.4.0:
  Would remove:
    /usr/local/lib/python3.7/site-packages/file_magic-0.4.0.dist-info/*
    /usr/local/lib/python3.7/site-packages/magic.py
Proceed (y/n)? y
  Successfully uninstalled file-magic-0.4.0

/ # pip install python-magic
Collecting python-magic
  Downloading https://files.pythonhosted.org/packages/42/a1/76d30c79992e3750dac6790ce16f056f870d368ba142f83f75f694d93001/python_magic-0.4.15-py2.py3-none-any.whl
Installing collected packages: python-magic
Successfully installed python-magic-0.4.15

Оно работает:

/ # python
Python 3.7.1 (default, Dec 21 2018, 03:21:42) 
[GCC 6.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import magic
>>> 

Я понимаю, что у каждого дистрибутива есть свои особенности, и я хочу приспособиться, но я просто не знаю, как это сделать в данный момент. Есть ли способ определить setup.py модуля, чтобы обойти эту ситуацию? Есть ли способ настроить контейнер Docker для работы с файловой магией? Как правильно поступить в этом случае?


person Daniel Quinn    schedule 26.12.2018    source источник


Ответы (1)


В Python-Magic есть жестко запрограммированный запасной вариант для Alpine Linux, поэтому у вас могут возникнуть проблемы с файловой магией, которая просто использует ctypes.util.find_library('magic') и, по-видимому, не может найти вашу библиотеку.

Точное поведение ctypes.util.find_library довольно сложно но если вы проследите код и увидите, какие методы он пытается использовать на вашей платформе, вы, вероятно, найдете способ заставить его найти библиотеку (вероятно, один из gcc, /sbin/ldconfig или objdump).

Другим решением является исправление ctypes.py для корректной обработки таких систем, как Alpine:

wget https://patch-diff.githubusercontent.com/raw/python/cpython/pull/10461.patch -O - | patch /usr/local/lib/python3.7/ctypes/util.py

Теперь вам просто нужно установить LD_LIBRARY_PATH и Python сможет найти библиотеку:

/ # LD_LIBRARY_PATH="/usr/lib/" python -c "import ctypes.util; print(ctypes.util.find_library('magic'))"
libmagic.so.1
person Blender    schedule 26.12.2018
comment
Ух ты. Должен быть более простой способ, не так ли? Как другие пакеты, которым нужна libmagic, могут быть переносимы между дистрибутивами? - person Daniel Quinn; 27.12.2018
comment
@DanielQuinn: Alpine удается не иметь комбинации пакетов, которые позволяют работать find_library ctypes. Это известно ошибка, так что вы можете либо подождать несколько месяцев (или лет в этом случае), пока она не будет исправлена, либо применить патч самостоятельно. - person Blender; 27.12.2018
comment
Ух ты. Ну хорошо знать! Думаю, я добавлю ваш материал выше в свой Dockerfile и включу ссылку на него в документацию для моего модуля. - person Daniel Quinn; 27.12.2018