Страницы

Поиск по вопросам

суббота, 28 декабря 2019 г.

Python. Подмена библиотеки из site-packages

#python


Есть десктопная программа на Python, которая использует библиотеку (для определенности
- pygments, хотя это не так важно). Чтобы пользователю не нужно было заботиться о зависимостях,
библиотека pygments поставляется вместе с программой и вполне успешно используется.

Но дело в том, что в самом pygments есть много кода вида 

from pygments.bla_bla_bla import ...


Возникают проблемы, если у пользователя в системе уже установлен pygments, тогда
при импорте Python ищет модуль pygments сначала в site-packages и успешно находит.
Но нужно сделать, чтобы независимо от того, установлен ли pygments в системе глобально,
использовалась именно та версия, что прилагается к программе.

Можно ли это сделать, не трогая код библиотеки pygments?
    


Ответы

Ответ 1



Здравствуйте. Вариант "в лоб" import sys sys.path.insert(0,'catalog_with_your_pygments') import pygments Также может помочь virtualenv, или смена архитектуры Вашего приложения.

Ответ 2



Ошибка оказалась у меня в коде. Выше @main правильно ответил, что нужно выполнить функцию sys.path.insert(0,'catalog_with_your_pygments') Но поскольку ошибка, на мой взгляд, интересная, то опишу ее подробнее. Импорт pygments происходил из плагина, в который входит эта библиотека. Плагин состоит из нескольких модулей *.py. Поскольку главная программа не знает заранее, в каком модуле находится главный класс плагина, она последовательно пытается импортировать их все, пока не найдет нужный (главный модуль плагина). Если импорт не удается, то ничего страшного не происходит, программа просто переходит к следующему модулю. Вызов sys.path.insert(0,'catalog_with_your_pygments') происходит после удачного обнаружения главного модуля плагина. Если у нас в системе не установлен pygments, то импорт вспомогательного модуля (в процессе поиска главного модуля плагина), который пытается импортировать pygments, просто проваливается, и основная программа переходит к следующему модулю. Затем будет найден главный модуль плагина, он опять попытается импортировать вспомогательный модуль, тот опять попытается импортировать pygments, уже удачно (т.к. к этому времени будет вызван sys.path.insert(0,'catalog_with_your_pygments')). Если же в системе установлен pygments глобально, то происходит почти то же самое, только вспомогательный модуль удачно импортирует pygments из site-packages, но поскольку главная программа все-равно понимает, что это не главный модуль плагина, то она продолжает искать главный модуль плагина дальше. И когда главный модуль найден, он опять импортирует вспомогательный, а тот уже импортировал pygments, поэтому второй раз его не импортирует, хотя к этому времени был изменен sys.path, и используется pygments, установленный в системе. Проблема решилась переносом импорта pygments внутрь методов, где он непосредственно нужен.

Комментариев нет:

Отправить комментарий