Подтвердить что ты не робот

Деактивировать конфликт в virtualenvwapper и anaconda

Я использую virtualenv для переключения моего python dev env. Но когда я запускаю workon my_env, я встречаю такое сообщение об ошибке:

Error: deactivate must be sourced. Run 'source deactivate'
instead of 'deactivate'.

Usage: source deactivate

removes the 'bin' directory of the environment activated with 'source
activate' from PATH.

После некоторых поисков в google кажется, что workon, который определен в /usr/local/bin/virtualenvwrapper.sh, вызывает deactivate. И есть script с тем же именем, что и в Anaconda bin, поэтому он ошибочно вызван workon.

Любое предложение для работы над этим конфликтом?

4b9b3361

Ответ 1

Одним из решений, которое работает для меня, является переименование deactivate в Anaconda bin:

mv deactivate conda-deactivate

Ответ 2

Я согласен с комментарием @FredrikHedman о том, что переименование скриптов в каталоге anaconda/miniconda bin может быть хрупким. Его полное сообщение привело меня к тому, что я считаю более надежным ответом. (Спасибо!)

Вместо того, чтобы просто отбрасывать любые ошибки, вызванные вызовом deactivate, мы могли бы просто условиться, чтобы вызвать, будет ли функция вызываться в сравнении с файлом. Как уже упоминалось, virtualenv и virtualenvwrapper создают функцию с именем deactivate; * condas вызывают файл script с тем же именем.

Итак, в virtualenvwrapper.sh script мы можем изменить следующие две строки, которые проверяют, является ли deactivate просто вызываемым:

type deactivate >/dev/null 2>&1
if [ $? -eq 0 ]

с более строгим испытанием на то, является ли это функцией оболочки:

nametype="$(type -t deactivate)"
if [ "${nametype##* }" == "function" ]

Это изменение позволяет избежать ложной ошибки, указанной в исходном вопросе, но не рискует перенаправлять другие полезные ошибки или выводить их в молчаливое забвение.

Обратите внимание на замещение переменных на nametype в сравнении. Это связано с тем, что вывод type -f под zsh возвращает нечто вроде "name: type", а не bash, которое возвращает просто "type". Подстановка удаляет все до последнего символа пробела, если существуют какие-либо пробелы, оставляя только значение типа. Это безвредно ничего не делает в bash. (Я был бы в восторге, чтобы получить подсказки по кодированию кросс-оболочки на этом.)

Как всегда, я ценю конструктивную обратную связь и комментарии!

Ответ 3

Вы можете отредактировать /usr/local/bin/virtualenvwrapper.sh, чтобы сделать deactivate указателем на абсолютный путь к любому deactivate, на который он должен ссылаться.

Ответ 4

В anaconda activate есть исполняемый файл script, расположенный в каталоге anaconda bin, но является функцией в virtualenvwrapper.sh. Таким образом, это своего рода проблема столкновения пространства имен, но также случай перекрытия функциональности.

Anacondas - это дистрибутив python и, помимо прочего, имеет поддержку для работы с виртуальной средой через conda env, в то время как virtualenvwrapper ориентирован на работу с различными виртуальными средами. Просто переименование anaconda/bin/activate script является хрупким решением и может сломаться conda.

Код virtualenvwrapper.sh (function workon) выполняет deactivate, который используется для использования anaconda script. Этот script возвращает ошибку. Затем код workon продолжается и удаляет имя deactivate и генерирует его собственный deactivate, а также создает функцию deactivate на лету.

Вкратце, он делает правильную вещь, а "ошибка" может рассматриваться скорее как предупреждение. Если вы хотите, чтобы это ушло, вы можете изменить функцию workon (искать строку # Deactivate any current environment "destructively")

deactivate
-->
deactivate >/dev/null 2>&1

(Я предложил это изменение для поддерживающего virtualenvwrapper)

Ответ 5

Поскольку у меня недостаточно репутаций, чтобы добавить комментарий: Предложение Томаса Капота прекрасное (спасибо 4 that), кроме "zsh" не имеет опции "-t" для команды встроенного "типа <. Поэтому необходимо добавить еще одно условное утверждение для получения желаемого результата для" nametype":

# Anaconda workaround for "source deactivate" message:
# Start of workaround:
#type deactivate >/dev/null 2>&1
#if [ $? -eq 0 ]
if [ -n $ZSH_VERSION ] ; then
    nametype="$(type -w deactivate)"
else
    nametype="$(type -t deactivate)"
fi
if [ "${nametype##* }" == "function" ]
# End of workaround

Надеюсь, что это поможет другим пользователям zsh.