##// END OF EJS Templates
Delaying keyring import as long as possible
Marcin Kasperski -
r149:0c05e644 default
parent child Browse files
Show More
@@ -46,65 +46,72 b' except:'
46 from mercurial import mail
46 from mercurial import mail
47 from mercurial.mail import SMTPS, STARTTLS
47 from mercurial.mail import SMTPS, STARTTLS
48 from mercurial import encoding
48 from mercurial import encoding
49 from urllib2 import AbstractBasicAuthHandler, AbstractDigestAuthHandler
49 from urlparse import urlparse
50 import urllib2
51 import smtplib
52 import socket
53 import os
54 import sys
55
50
56
51 # mercurial.demandimport incompatibility workaround.
57 def import_keyring():
52 # various keyring backends fail as they can't properly import helper
58 """
53 # modules (as demandimport modifies python import behaviour).
59 Importing keyring happens to be costly if wallet is slow, so we delay it
54 # If you get import errors with demandimport in backtrace, try
60 until really needed.
55 # guessing what to block and extending the list below.
61 """
56 from mercurial import demandimport
62 if 'keyring' in sys.modules:
57 for blocked_module in [
63 return
58 "gobject._gobject",
64 # mercurial.demandimport incompatibility workaround.
59 "configparser",
65 # various keyring backends fail as they can't properly import helper
60 "json",
66 # modules (as demandimport modifies python import behaviour).
61 "abc",
67 # If you get import errors with demandimport in backtrace, try
62 "io",
68 # guessing what to block and extending the list below.
63 "keyring",
69 from mercurial import demandimport
64 "gdata.docs.service",
70 for blocked_module in [
65 "gdata.service",
71 "gobject._gobject",
66 "types",
72 "configparser",
67 "atom.http",
73 "json",
68 "atom.http_interface",
74 "abc",
69 "atom.service",
75 "io",
70 "atom.token_store",
76 "keyring",
71 "ctypes",
77 "gdata.docs.service",
72 "secretstorage.exceptions",
78 "gdata.service",
73 "fs.opener",
79 "types",
80 "atom.http",
81 "atom.http_interface",
82 "atom.service",
83 "atom.token_store",
84 "ctypes",
85 "secretstorage.exceptions",
86 "fs.opener",
74 ]:
87 ]:
75 if blocked_module not in demandimport.ignore:
88 if blocked_module not in demandimport.ignore:
76 demandimport.ignore.append(blocked_module)
89 demandimport.ignore.append(blocked_module)
77
78 try:
79 is_demandimport_enabled = demandimport.isenabled
80 except AttributeError:
81 # Mercurial < 2.9.1
82 try:
90 try:
83 orig_demandimport = demandimport.demandimport
91 is_demandimport_enabled = demandimport.isenabled
84 except AttributeError:
92 except AttributeError:
85 orig_demandimport = demandimport._demandimport
93 # Mercurial < 2.9.1
86 def is_demandimport_enabled():
94 try:
87 return __import__ == orig_demandimport
95 orig_demandimport = demandimport.demandimport
88
96 except AttributeError:
89 # Shut up warning about uninitialized logging for new keyring versions
97 orig_demandimport = demandimport._demandimport
90 import logging
98 def is_demandimport_enabled():
91 logging.getLogger("keyring").addHandler(logging.NullHandler())
99 return __import__ == orig_demandimport
92
100
93 # Temporarily disable demandimport to make the need of extending
101 # Shut up warning about uninitialized logging for new keyring versions
94 # the list above less likely.
102 import logging
95 if is_demandimport_enabled():
103 logging.getLogger("keyring").addHandler(logging.NullHandler())
96 demandimport.disable()
104
97 try:
105 # Temporarily disable demandimport to make the need of extending
106 # the list above less likely.
107 if is_demandimport_enabled():
108 demandimport.disable()
109 try:
110 import keyring
111 finally:
112 demandimport.enable()
113 else:
98 import keyring
114 import keyring
99 finally:
100 demandimport.enable()
101 else:
102 import keyring
103
104 from urlparse import urlparse
105 import urllib2
106 import smtplib, socket
107 import os
108
115
109 KEYRING_SERVICE = "Mercurial"
116 KEYRING_SERVICE = "Mercurial"
110
117
@@ -152,12 +159,14 b' class PasswordStore(object):'
152 def _format_smtp_key(self, machine, port, username):
159 def _format_smtp_key(self, machine, port, username):
153 return "%s@@%s:%s" % (username, machine, str(port))
160 return "%s@@%s:%s" % (username, machine, str(port))
154 def _read_password_from_keyring(self, pwdkey):
161 def _read_password_from_keyring(self, pwdkey):
162 import_keyring()
155 password = keyring.get_password(KEYRING_SERVICE, pwdkey)
163 password = keyring.get_password(KEYRING_SERVICE, pwdkey)
156 # Reverse recoding from next routine
164 # Reverse recoding from next routine
157 if isinstance(password, unicode):
165 if isinstance(password, unicode):
158 return encoding.tolocal(password.encode('utf-8'))
166 return encoding.tolocal(password.encode('utf-8'))
159 return password
167 return password
160 def _save_password_to_keyring(self, pwdkey, password):
168 def _save_password_to_keyring(self, pwdkey, password):
169 import_keyring()
161 # keyring in general expects unicode. Mercurial provides "local" encoding. See #33
170 # keyring in general expects unicode. Mercurial provides "local" encoding. See #33
162 password = encoding.fromlocal(password).decode('utf-8')
171 password = encoding.fromlocal(password).decode('utf-8')
163 keyring.set_password(KEYRING_SERVICE,
172 keyring.set_password(KEYRING_SERVICE,
@@ -409,7 +418,7 b' def find_user_password(self, realm, auth'
409
418
410 return self._pwd_handler.find_auth(self, realm, authuri, req)
419 return self._pwd_handler.find_auth(self, realm, authuri, req)
411
420
412 @monkeypatch_method(AbstractBasicAuthHandler, "http_error_auth_reqed")
421 @monkeypatch_method(urllib2.AbstractBasicAuthHandler, "http_error_auth_reqed")
413 def basic_http_error_auth_reqed(self, authreq, host, req, headers):
422 def basic_http_error_auth_reqed(self, authreq, host, req, headers):
414 self.passwd._http_req = req
423 self.passwd._http_req = req
415 try:
424 try:
@@ -417,7 +426,7 b' def basic_http_error_auth_reqed(self, au'
417 finally:
426 finally:
418 self.passwd._http_req = None
427 self.passwd._http_req = None
419
428
420 @monkeypatch_method(AbstractDigestAuthHandler, "http_error_auth_reqed")
429 @monkeypatch_method(urllib2.AbstractDigestAuthHandler, "http_error_auth_reqed")
421 def digest_http_error_auth_reqed(self, authreq, host, req, headers):
430 def digest_http_error_auth_reqed(self, authreq, host, req, headers):
422 self.passwd._http_req = req
431 self.passwd._http_req = req
423 try:
432 try:
General Comments 0
You need to be logged in to leave comments. Login now