Яйца в пути до переменной окружения PYTHONPATH
Если у меня есть пакеты, установленные из easy_install, яйца добавляются до sys.path
перед элементами в переменной PYTHONPATH
.
Например, если у меня есть пакет яиц с именем foo, а также пакет с именем foo в текущем каталоге, а затем выполните следующее:
PYTHONPATH="." python
>>> import foo
Это будет использовать версию яйца foo
вместо локального каталога. Проверка sys.path
показывает, что яйца помещаются перед элементами из PYTHONPATH
. Это кажется сломанным. Есть ли способ отменить это поведение?
Ответы
Ответ 1
К сожалению, это делается с жестко закодированным шаблоном внутри setuptools/command/easy_install.py
. Вы можете создать исправленный setuptools с отредактированным шаблоном, но я не нашел чистого способа расширения easy_install извне.
Каждый раз, когда выполняется easy_install, он восстанавливает файл easy_install.pth
. Вот быстрый script, который вы можете запустить после easy_install, чтобы удалить верхний и нижний колонтитулы из easy_install.pth
. Вы можете создать оболочку оболочки script, чтобы запустить ее сразу после easy_install
:
#!/usr/bin/env python
import sys
path = sys.argv[1]
lines = open(path, 'rb').readlines()
if lines and 'import sys' in lines[0]:
open(path, 'wb').write(''.join(lines[1:-1]) + '\n')
Пример:
% easy_install gdata
% PYTHONPATH=xyz python -c 'import sys; print sys.path[:2]'
['', '/Users/pat/virt/lib/python2.6/site-packages/gdata-2.0.14-py2.6.egg']
% ./fix_path ~/virt/lib/python2.6/site-packages/easy_install.pth
% PYTHONPATH=xyz python -c 'import sys; print sys.path[:2]'
['', '/Users/pat/xyz']
Для получения более подробного описания, вот формат easy-install.pth
:
import sys; sys.__plen = len(sys.path)
./gdata-2.0.14-py2.6.egg
import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)
Две строки import sys
являются виновниками, вызывающими появление яиц в начале пути. Мой script просто удаляет те строки sys.path
-munging.
Ответ 2
Я выполнил что-то вроде следующего, чтобы перейти к системному пути при запуске исполняемого файла python верхнего уровня:
import sys
sys.path = ["<your python path>"] + sys.path
Часто для меня "<your python path>"
используется использование атрибута __file__
для относительного поиска пути, который включает модуль верхнего уровня для моего проекта. Это не рекомендуется использовать при производстве яиц, хотя я, похоже, не думаю о последствиях. Может быть другая альтернатива __file__
.
Ответ 3
Рассмотрите возможность использования опции командной строки -S
для подавления обработки *.pth
:
python -c 'import sys; print("\n".join(sys.path))'
python -S -c 'import sys; print("\n".join(sys.path))'
https://docs.python.org/3/library/site.html#site.main
Вы также можете использовать -S
с site.main()
для задержки *.pth
обработки до выполнения, скажем, для захвата исходного sys.path для добавления:
export PYTHONPATH=$(
PYTHONPATH='' \
python -c 'import sys; \
sys.path.extend(sys.argv[1:]); old=list(sys.path); \
import site; site.main(); \
[ old.append(p) for p in sys.path if p not in old ]; \
sys.path=old; \
print ":".join(sys.path)' \
$EXTRA_PATH $ANOTHER_PATH)
python -S ... # using explicit PYTHONPATH
- Начать с явного пустого
PYTHONPATH
- Добавить в sys.path явно с расширением
- Импортировать сайт и позвонить
site.main()
- Добавить новые пути к старому пути, а затем установить его в sys.path
- Печать с помощью ":" для
PYTHONPATH
-
python -S
желательно для последующих запусков только с использованием $PYTHONPATH
-
python -S
может быть или не быть желательным при установке PYTHONPATH
(в зависимости от того, требуется ли вам расширение sys.path до продолжения)