Read about our upcoming Code of Conduct on this issue

Commit cef4695b authored by Marcin Kasperski's avatar Marcin Kasperski
Browse files

Merge branch 'topic/default/py3-fixes' into 'branch/default'

Topic/default/py3 fixes

See merge request !16
......@@ -13,4 +13,5 @@ syntax: regexp
syntax: glob
.idea
\ No newline at end of file
.idea
.pytype
PYTHON = python
PYTYPE = pytype
HGPATH =
ifneq ($(HGPATH),)
export PYTHONPATH := $(realpath $(HGPATH)):$(PYTHONPATH)
endif
.PHONY: help
help:
@echo 'Commonly used make targets:'
@echo ' pytype - run pytype checks on the source tree'
.PHONY: pytype
pytype: PYTHON_VERSION = 3.7
pytype:
@[ -n "$(HGPATH)" ] || { echo "HGPATH not specified"; false; }
@[ -d "$(HGPATH)" ] || { echo "HGPATH not found: $(HGPATH)"; false; }
$(PYTYPE) -P ".:$(HGPATH):../mercurial-extension_utils" -V "$(PYTHON_VERSION)" -j auto \
--config pytype.cfg
@echo 'pytype crashed while generating the following type stubs:'
find .pytype/pyi -name '*.pyi' | xargs grep -l '# Caught error' | sort
.PHONY: clean
clean:
$(PYTHON) setup.py clean
$(RM) -R .pytype
......@@ -101,7 +101,7 @@ def import_meu():
try:
import mercurial_extension_utils
except ImportError:
raise error.Abort(_("""Can not import mercurial_extension_utils.
raise error.Abort(_(b"""Can not import mercurial_extension_utils.
Please install this module in Python path.
See Installation chapter in https://foss.heptapod.net/mercurial/mercurial_keyring/ for details
(and for info about TortoiseHG on Windows, or other bundled Python)."""))
......@@ -234,7 +234,7 @@ class PasswordStore(object):
except Exception as err:
ui = uimod.ui()
ui.warn(meu.ui_string(
"keyring: keyring backend doesn't seem to work, password can not be restored. Falling back to prompts. Error details: %s\n",
b"keyring: keyring backend doesn't seem to work, password can not be restored. Falling back to prompts. Error details: %s\n",
err))
return b''
# Reverse recoding from next routine
......@@ -259,7 +259,7 @@ class PasswordStore(object):
except Exception as err:
ui = uimod.ui()
ui.warn(meu.ui_string(
"keyring: keyring backend doesn't seem to work, password was not saved. Error details: %s\n",
b"keyring: keyring backend doesn't seem to work, password was not saved. Error details: %s\n",
err))
......@@ -299,7 +299,7 @@ def make_passwordmgr(ui):
if hasattr(ui, 'httppasswordmgrdb'):
return passwordmgr(ui, ui.httppasswordmgrdb)
else:
return passwordmgr(ui)
return passwordmgr(ui) # pytype: disable=missing-parameter
############################################################
# HTTP password management
......@@ -343,7 +343,7 @@ class HTTPPasswordHandler(object):
parsed_url, url_user, url_passwd = self.unpack_url(authuri)
base_url = bytes(parsed_url)
ui.debug(meu.ui_string('keyring: base url: %s, url user: %s, url pwd: %s\n',
ui.debug(meu.ui_string(b'keyring: base url: %s, url user: %s, url pwd: %s\n',
base_url, url_user, url_passwd and b'******' or b''))
# Extract username (or password) stored directly in url
......@@ -368,7 +368,7 @@ class HTTPPasswordHandler(object):
auth_user, auth_pwd, keyring_url = self.get_url_config(
ui, parsed_url, actual_user)
if auth_user and actual_user and (actual_user != auth_user):
raise error.Abort(_('keyring: username for %s specified both in repository path (%s) and in .hg/hgrc/[auth] (%s). Please, leave only one of those' % (base_url, actual_user, auth_user)))
raise error.Abort(_(b'keyring: username for %s specified both in repository path (%s) and in .hg/hgrc/[auth] (%s). Please, leave only one of those' % (base_url, actual_user, auth_user)))
if auth_user and auth_pwd:
return auth_user, auth_pwd, self.SRC_CFGAUTH, keyring_url
......@@ -385,7 +385,7 @@ class HTTPPasswordHandler(object):
# Load from keyring.
if actual_user:
ui.debug(meu.ui_string("keyring: looking for password (user %s, url %s)\n",
ui.debug(meu.ui_string(b"keyring: looking for password (user %s, url %s)\n",
actual_user, keyring_url))
keyring_pwd = password_store.get_http_password(keyring_url, actual_user)
if keyring_pwd:
......@@ -397,23 +397,23 @@ class HTTPPasswordHandler(object):
def prompt_interactively(ui, user, realm, url):
"""Actual interactive prompt"""
if not ui.interactive():
raise error.Abort(_('keyring: http authorization required but program used in non-interactive mode'))
raise error.Abort(_(b'keyring: http authorization required but program used in non-interactive mode'))
if not user:
ui.status(meu.ui_string("keyring: username not specified in hgrc (or in url). Password will not be saved.\n"))
ui.status(meu.ui_string(b"keyring: username not specified in hgrc (or in url). Password will not be saved.\n"))
ui.write(meu.ui_string("http authorization required\n"))
ui.status(meu.ui_string("realm: %s\n",
ui.write(meu.ui_string(b"http authorization required\n"))
ui.status(meu.ui_string(b"realm: %s\n",
realm))
ui.status(meu.ui_string("url: %s\n",
ui.status(meu.ui_string(b"url: %s\n",
url))
if user:
ui.write(meu.ui_string("user: %s (fixed in hgrc or url)\n",
ui.write(meu.ui_string(b"user: %s (fixed in hgrc or url)\n",
user))
else:
user = ui.prompt(meu.ui_string("user:"),
user = ui.prompt(meu.ui_string(b"user:"),
default=None)
pwd = ui.getpass(meu.ui_string("password: "))
pwd = ui.getpass(meu.ui_string(b"password: "))
return user, pwd
def find_auth(self, pwmgr, realm, authuri, req):
......@@ -433,7 +433,7 @@ class HTTPPasswordHandler(object):
if src != self.SRC_MEMCACHE:
self.pwd_cache.store(realm, final_url, user, pwd)
self._note_last_reply(realm, authuri, user, req)
ui.debug(meu.ui_string("keyring: Password found in %s\n",
ui.debug(meu.ui_string(b"keyring: Password found in %s\n",
src))
return user, pwd
......@@ -445,7 +445,7 @@ class HTTPPasswordHandler(object):
# It is done only if username is permanently set.
# Otherwise we won't be able to find the password so it
# does not make much sense to preserve it
ui.debug(meu.ui_string("keyring: Saving password for %s to keyring\n",
ui.debug(meu.ui_string(b"keyring: Saving password for %s to keyring\n",
user))
try:
password_store.set_http_password(final_url, user, pwd)
......@@ -453,14 +453,14 @@ class HTTPPasswordHandler(object):
keyring = import_keyring()
if isinstance(e, keyring.errors.PasswordSetError):
ui.traceback()
ui.warn(meu.ui_string("warning: failed to save password in keyring\n"))
ui.warn(meu.ui_string(b"warning: failed to save password in keyring\n"))
else:
raise e
# Saving password to the memory cache
self.pwd_cache.store(realm, final_url, user, pwd)
self._note_last_reply(realm, authuri, user, req)
ui.debug(meu.ui_string("keyring: Manually entered password\n"))
ui.debug(meu.ui_string(b"keyring: Manually entered password\n"))
return user, pwd
def get_url_config(self, ui, parsed_url, user):
......@@ -473,7 +473,7 @@ class HTTPPasswordHandler(object):
is not found, url itself is returned.
"""
from mercurial.httpconnection import readauthforuri
ui.debug(meu.ui_string("keyring: checking for hgrc info about url %s, user %s\n",
ui.debug(meu.ui_string(b"keyring: checking for hgrc info about url %s, user %s\n",
parsed_url, user))
res = readauthforuri(ui, bytes(parsed_url), user)
......@@ -499,7 +499,7 @@ class HTTPPasswordHandler(object):
password_url = self.password_url(bytes(parsed_url), prefix)
ui.debug(meu.ui_string("keyring: Password url: %s, user: %s, password: %s (prefix: %s)\n",
ui.debug(meu.ui_string(b"keyring: Password url: %s, user: %s, password: %s (prefix: %s)\n",
password_url, username,
b'********' if password else b'',
prefix))
......@@ -528,7 +528,7 @@ class HTTPPasswordHandler(object):
and (self.last_reply['authuri'] == authuri) \
and (self.last_reply['req'] == req):
ui.debug(meu.ui_string(
"keyring: Working after bad authentication, cached passwords not used %s\n",
b"keyring: Working after bad authentication, cached passwords not used %s\n",
str(self.last_reply)))
return True
return False
......@@ -656,13 +656,13 @@ def try_smtp_login(ui, smtp_obj, username, password):
if not password:
return False
try:
ui.note(_('(authenticating to mail server as %s)\n') %
ui.note(_(b'(authenticating to mail server as %s)\n') %
username)
smtp_obj.login(username, password)
return True
except smtplib.SMTPException as inst:
if inst.smtp_code == 535:
ui.status(meu.ui_string("SMTP login failed: %s\n\n",
ui.status(meu.ui_string(b"SMTP login failed: %s\n\n",
inst.smtp_error))
return False
else:
......@@ -683,26 +683,26 @@ def keyring_supported_smtp(ui, username):
try:
from mercurial.utils.stringutil import parsebool
except ImportError:
from mercurial.utils import parsebool
from mercurial.utils import parsebool # pytype: disable=import-error
local_hostname = ui.config('smtp', 'local_hostname')
tls = ui.config('smtp', 'tls', 'none')
local_hostname = ui.config(b'smtp', b'local_hostname')
tls = ui.config(b'smtp', b'tls', b'none')
# backward compatible: when tls = true, we use starttls.
starttls = tls == 'starttls' or parsebool(tls)
smtps = tls == 'smtps'
starttls = tls == b'starttls' or parsebool(tls)
smtps = tls == b'smtps'
if (starttls or smtps) and not util.safehasattr(socket, 'ssl'):
raise error.Abort(_("can't use TLS: Python SSL support not installed"))
mailhost = ui.config('smtp', 'host')
raise error.Abort(_(b"can't use TLS: Python SSL support not installed"))
mailhost = ui.config(b'smtp', b'host')
if not mailhost:
raise error.Abort(_('smtp.host not configured - cannot send mail'))
raise error.Abort(_(b'smtp.host not configured - cannot send mail'))
if getattr(sslutil, 'sslkwargs', None) is None:
sslkwargs = None
elif starttls or smtps:
sslkwargs = sslutil.sslkwargs(ui, mailhost)
sslkwargs = sslutil.sslkwargs(ui, mailhost) # pytype: disable=module-attr
else:
sslkwargs = {}
if smtps:
ui.note(_('(using smtps)\n'))
ui.note(_(b'(using smtps)\n'))
# mercurial 3.8 added a mandatory host arg
if not sslkwargs:
......@@ -724,18 +724,18 @@ def keyring_supported_smtp(ui, username):
defaultport = 465
else:
defaultport = 25
mailport = util.getport(ui.config('smtp', 'port', defaultport))
ui.note(_('sending mail: smtp host %s, port %s\n') %
mailport = util.getport(ui.config(b'smtp', b'port', defaultport))
ui.note(_(b'sending mail: smtp host %s, port %d\n') %
(mailhost, mailport))
s.connect(host=mailhost, port=mailport)
if starttls:
ui.note(_('(using starttls)\n'))
ui.note(_(b'(using starttls)\n'))
s.ehlo()
s.starttls()
s.ehlo()
if starttls or smtps:
if getattr(sslutil, 'validatesocket', None):
ui.note(_('(verifying remote certificate)\n'))
ui.note(_(b'(verifying remote certificate)\n'))
sslutil.validatesocket(s.sock)
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
......@@ -744,7 +744,7 @@ def keyring_supported_smtp(ui, username):
# No need to check whether password was found as try_smtp_login
# just returns False if it is absent.
while not try_smtp_login(ui, s, username, password):
password = ui.getpass(_("Password for %s on %s:%d: ") % (username, mailhost, mailport))
password = ui.getpass(_(b"Password for %s on %s:%d: ") % (username, mailhost, mailport))
if stored != password:
password_store.set_smtp_password(
......@@ -756,7 +756,7 @@ def keyring_supported_smtp(ui, username):
return s.sendmail(sender, recipients, msg)
except smtplib.SMTPRecipientsRefused as inst:
recipients = [r[1] for r in inst.recipients.values()]
raise error.Abort('\n' + '\n'.join(recipients))
raise error.Abort(b'\n' + b'\n'.join(recipients))
except smtplib.SMTPException as inst:
raise error.Abort(inst)
......@@ -776,8 +776,8 @@ def _smtp(ui):
mercurial/mail.py. It calls the original unless username
without password is given in the configuration.
"""
username = ui.config('smtp', 'username')
password = ui.config('smtp', 'password')
username = ui.config(b'smtp', b'username')
password = ui.config(b'smtp', b'password')
if username and not password:
return keyring_supported_smtp(ui, username)
......@@ -795,7 +795,7 @@ command = meu.command(cmdtable)
@command(b'keyring_check',
[],
_("keyring_check [PATH]"),
_(b"keyring_check [PATH]"),
optionalrepo=True)
def cmd_keyring_check(ui, repo, *path_args, **opts): # pylint: disable=unused-argument
"""
......@@ -814,42 +814,42 @@ def cmd_keyring_check(ui, repo, *path_args, **opts): # pylint: disable=unused-
for path_arg in path_args]
else:
if not repo:
ui.status(meu.ui_string("Url to check not specified. Either run ``hg keyring_check https://...``, or run the command inside some repository (to test all defined paths).\n"))
ui.status(meu.ui_string(b"Url to check not specified. Either run ``hg keyring_check https://...``, or run the command inside some repository (to test all defined paths).\n"))
return
paths = [(name, url) for name, url in defined_paths]
if not paths:
ui.status(meu.ui_string("keyring_check: no paths defined\n"))
ui.status(meu.ui_string(b"keyring_check: no paths defined\n"))
return
handler = HTTPPasswordHandler()
ui.status(meu.ui_string("keyring password save status:\n"))
ui.status(meu.ui_string(b"keyring password save status:\n"))
for name, url in paths:
if not is_http_path(url):
if path_args:
ui.status(meu.ui_string(" %s: non-http path (%s)\n",
ui.status(meu.ui_string(b" %s: non-http path (%s)\n",
name, url))
continue
user, pwd, source, final_url = handler.get_credentials(
make_passwordmgr(ui), name, url)
if pwd:
ui.status(meu.ui_string(
" %s: password available, source: %s, bound to user %s, url %s\n",
b" %s: password available, source: %s, bound to user %s, url %s\n",
name, source, user, final_url))
elif user:
ui.status(meu.ui_string(
" %s: password not available, once entered, will be bound to user %s, url %s\n",
b" %s: password not available, once entered, will be bound to user %s, url %s\n",
name, user, final_url))
else:
ui.status(meu.ui_string(
" %s: password not available, user unknown, url %s\n",
b" %s: password not available, user unknown, url %s\n",
name, final_url))
@command(b'keyring_clear',
[],
_('hg keyring_clear PATH-OR-ALIAS'),
_(b'hg keyring_clear PATH-OR-ALIAS'),
optionalrepo=True)
def cmd_keyring_clear(ui, repo, path, **opts): # pylint: disable=unused-argument
"""
......@@ -865,7 +865,7 @@ def cmd_keyring_clear(ui, repo, path, **opts): # pylint: disable=unused-argumen
break
if not is_http_path(path_url):
ui.status(meu.ui_string(
"%s is not a http path (and %s can't be resolved as path alias)\n",
b"%s is not a http path (and %s can't be resolved as path alias)\n",
path, path_url))
return
......@@ -874,21 +874,21 @@ def cmd_keyring_clear(ui, repo, path, **opts): # pylint: disable=unused-argumen
user, pwd, source, final_url = handler.get_credentials(
make_passwordmgr(ui), path, path_url)
if not user:
ui.status(meu.ui_string("Username not configured for url %s\n",
ui.status(meu.ui_string(b"Username not configured for url %s\n",
final_url))
return
if not pwd:
ui.status(meu.ui_string("No password is saved for user %s, url %s\n",
ui.status(meu.ui_string(b"No password is saved for user %s, url %s\n",
user, final_url))
return
if source != handler.SRC_KEYRING:
ui.status(meu.ui_string("Password for user %s, url %s is saved in %s, not in keyring\n",
ui.status(meu.ui_string(b"Password for user %s, url %s is saved in %s, not in keyring\n",
user, final_url, source))
password_store.clear_http_password(final_url, user)
ui.status(meu.ui_string("Password removed for user %s, url %s\n",
ui.status(meu.ui_string(b"Password removed for user %s, url %s\n",
user, final_url))
buglink = 'https://foss.heptapod.net/mercurial/mercurial_keyring/issues'
buglink = b'https://foss.heptapod.net/mercurial/mercurial_keyring/issues'
# NOTE: All relative paths are relative to the location of this file.
[pytype]
# Space-separated list of files or directories to exclude.
exclude =
# Space-separated list of files or directories to process.
inputs =
mercurial_keyring.py
# Keep going past errors to analyze as many files as possible.
keep_going = True
# Run N jobs in parallel.
#jobs = 4
# All pytype output goes here.
output = .pytype
# Paths to source code directories, separated by ':'.
pythonpath =
.
# Python version (major.minor) of the target code.
python_version = 3.7
# Comma separated list of error names to ignore.
disable =
pyi-error
# Don't report errors.
report_errors = True
# Experimental: Infer precise return types even for invalid function calls.
precise_return = False
# Experimental: solve unknown types to label with structural types.
protocols = False
# Experimental: Only load submodules that are explicitly imported.
strict_import = False
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment