La importación de Python parece comportarse de manera diferente en el archivo mercurial_keyring.py

Un extraño error de import impide que instale una extensión comercial.

Estoy intentando ejecutar la extensión mercurial_keyring para no tener que escribir mi nombre de usuario y contraseña cada vez que uso mercurial para un proyecto.

Estoy usando Python 2.7.1. Instalé Mercurial con el binario proporcionado en https://www.mercurial-scm.org/ .

Instalé keyring y keyring mercurial_keyring con pip .

Primero intenté agregar la extensión agregando esto a ~/.hgrc :

 [extensions] ... mercurial_keyring = 

como se indica en las instrucciones de instalación aquí . Sin embargo, tengo el siguiente error:

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

Desde las mismas instrucciones de instalación, intenté apuntar mercurial directamente al archivo mercurial_keyring.py , que funcionó.

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

Y las cosas parecían estar avanzando.

Sin embargo, cuando bash ejecutar comandos mercuriales que requieren mi contraseña para que se guarden mediante un keyring de keyring ( p . Ej. hg pull , hg push ) obtengo el error

 abort: No module named keyring! 

La parte más confusa es que hay una clara

 import keyring 

en la línea 28 de mercurial_keyring.py que se resuelve sin ningún problema. De hecho, cualquier import keyring tiene éxito fuera de las clases y los métodos y falla dentro de ellos!

Solo por razones de minuciosidad, mencionaré que este error surge en mercurial_keyring.py en la clase PasswordStore en el método get_http_password cuando se intenta lo siguiente

 return keyring.get_password(...) 

¿Alguna idea?

Tengo la sensación de que me estoy perdiendo algo obvio, pero he pasado mucho tiempo tratando de resolver esto y Google no ha sido particularmente útil hasta ahora. Cualquier entrada será muy apreciada.

Lo más probable es que hg se ejecute utilizando el sistema python (2.6) en lugar de la copia de 2.7 que ha instalado.

Intente instalar mercurial_keyring y keyring en 2.6, y vea si eso funciona como se esperaba.

Mercurial utiliza una función llamada ‘demandimport’ que pospone la importación de módulos, hasta la primera vez que se utilizan. Entonces tus

llavero de importación

no fallará en esa línea, pero se lamentará solo cuando se use primero (es decir)

devuelve keyring.get_password (…)

Encontré el mismo problema y lo resolví instalando la extensión con una instalación fácil: sudo easy_install mercurial_keyring

Esto lo instala bajo el mismo python que utiliza mercurial.

La respuesta de @ncoghlan es correcta (para mí, de todos modos), pero está incompleta y no tengo suficientes puntos de representación para comentar. (Jeremy S, creo que esto responde a tu pregunta).

Para instalar una versión específica de Python, use las siguientes modificaciones: En lugar de

 easy_install keyring 

Utilizar

 easy_install-2.6 keyring 

Lo mismo se aplica a cualquiera de los comandos de instalación fácil u otros comandos de Python. Encontré esto en un ejemplo para pip aquí: ¿Cómo instalar un módulo, usar pip para una versión específica de?

import en los métodos se evalúan cuando se llaman, mientras que las importaciones de nivel superior se evalúan inmediatamente. El comportamiento de las importaciones se puede modificar, eche un vistazo a los módulos imp y site , así como a sys.path . Lo que probablemente está sucediendo es que algún código al final del archivo (en sentido figurado, también puede ser una llamada de la función en la inicialización) modifica el comportamiento de la importación por accidente o para prevenir y advertir las import tardías inadvertidas.

Mi problema fue que instalé Mercurial través de macports , pero la extensión a través de pip . Para resolverlo, también tuve que instalar la extensión a través de macports .

 sudo port install py-keyring py-mercurial_keyring