По-видимому, импорт python ведет себя по-другому в файле mercurial_keyring.py

Причудливая ошибка import мешает мне устанавливать меркурийное расширение.

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

Я использую Python 2.7.1. Я установил mercurial с двоичным кодом, представленным в https://www.mercurial-scm.org/.

Я установил keyring и mercurial_keyring с помощью pip.

Сначала я попытался добавить расширение, добавив его в ~/.hgrc:

[extensions]
...
mercurial_keyring = 

как указано в инструкциях по установке здесь. Однако, я получил следующую ошибку:

*** failed to import extension mercurial_keyring: No module named mercurial_keyring

Из тех же инструкций по установке, я попытался указать mercurial непосредственно в файл mercurial_keyring.py, который сработал.

[extensions]
...
hgext.mercurial_keyring = /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial_keyring.py

И все, казалось, двигалось.

Однако, когда я пытаюсь выполнить любые команды mercurial, требующие моего пароля, чтобы он был сохранен keyring (например, hg pull, hg push), я получаю сообщение об ошибке

abort: No module named keyring!

Самая запутанная часть состоит в том, что есть ясный

import keyring

в строке 28 из mercurial_keyring.py, которая разрешена без каких-либо проблем. Фактически, любой import keyring удаляет внешние классы и методы и терпит неудачу внутри них!

Как раз для тщательности, я упомянул, что эта ошибка возникает в mercurial_keyring.py в классе PasswordStore в методе get_http_password при попытке выполнить следующее:

return keyring.get_password(...)

Любые мысли?

У меня такое ощущение, что я пропустил что-то очевидное, но я потратил много времени, пытаясь понять это, и google пока не очень полезен. Любой вход будет оценен.

Ответ 1

Скорее всего, hg работает с использованием системного python (2.6), а не с копией 2.7, которую вы установили.

Попробуйте установить mercurial_keyring и keyring под 2.6, и посмотрите, работает ли это так, как ожидалось.

Ответ 2

Mercurial использует функцию "demandimport", которая откладывает импорт модулей до первого использования. Итак, ваш

import keyring

не будет терпеть неудачу в этой строке, но он будет плакать только тогда, когда он использовал первый (i.e)

return keyring.get_password (...)

Ответ 3

Я столкнулся с той же проблемой и разрешил ее, установив расширение с простой установкой: sudo easy_install mercurial_keyring

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

Ответ 4

import в методах оцениваются при их вызове, тогда как импорт верхнего уровня оценивается немедленно. Поведение импорта может быть изменено, посмотрите imp и site, а также sys.path. Вероятно, происходит то, что некоторый код в конце файла (образно, также может быть вызовом функции при инициализации или так) изменяет поведение импорта случайно или предотвращает и замечает непреднамеренные поздние import s.

Ответ 5

Моя проблема заключалась в том, что я установил Mercurial через macports, но расширение через pip. Чтобы решить эту проблему, мне пришлось установить расширение с помощью macports.

sudo port install py-keyring py-mercurial_keyring

Ответ 6

Ответ на

@ncoghlan правильный (для меня, во всяком случае), но неполный, и у меня недостаточно комментариев для комментариев. (Джереми С, я думаю, это отвечает на ваш вопрос.)

Для установки для конкретной версии Python используйте следующие изменения: Вместо

easy_install keyring

Использование

easy_install-2.6 keyring

То же самое относится к любой из команд easy_install или других Python. Я нашел это из примера для pip здесь: Как установить модуль для использования для конкретной версии?