# HG changeset patch # User Martin von Zweigbergk # Date 1605817226 28800 # Node ID 8cc9e7f762d6c253e1a5700a855c9494a3fd967f # Parent bb1b7a5bc96b618713ca868c9ee0d8e07a9cda52 errors: move similarity_hint() to error module I want to be able to reuse it from `UnknownIdentifier`'s constructor. Moving it results in a new import of `difflib` in the `error` module. There was a comment at the top of `error.py` saying "Do not import anything but pycompat here, please", which was added (except for the "pycompat" bit) in 08cabecfa8a8 (errors: move revlog errors, 2009-01-11). I don't know the reason for the comment. I'm guessing the point was to not make the module depend on other Mercurial modules. If that was it, then importing `difflib` should be fine. Sorry about the churn (I moved this code from the `dispatch` module to the `scmutil` module very recently). Differential Revision: https://phab.mercurial-scm.org/D9345 diff -r bb1b7a5bc96b -r 8cc9e7f762d6 mercurial/dispatch.py --- a/mercurial/dispatch.py Thu Nov 19 09:19:44 2020 -0800 +++ b/mercurial/dispatch.py Thu Nov 19 12:20:26 2020 -0800 @@ -484,10 +484,10 @@ except (error.UnknownCommand, error.Abort): suggested = False if inst.all_commands: - sim = scmutil.getsimilar(inst.all_commands, inst.command) + sim = error.getsimilar(inst.all_commands, inst.command) if sim: ui.warn(nocmdmsg) - ui.warn(b"(%s)\n" % scmutil.similarity_hint(sim)) + ui.warn(b"(%s)\n" % error.similarity_hint(sim)) suggested = True if not suggested: ui.warn(nocmdmsg) diff -r bb1b7a5bc96b -r 8cc9e7f762d6 mercurial/error.py --- a/mercurial/error.py Thu Nov 19 09:19:44 2020 -0800 +++ b/mercurial/error.py Thu Nov 19 12:20:26 2020 -0800 @@ -13,6 +13,8 @@ from __future__ import absolute_import +import difflib + # Do not import anything but pycompat here, please from . import pycompat @@ -270,6 +272,25 @@ __bytes__ = _tobytes +def getsimilar(symbols, value): + sim = lambda x: difflib.SequenceMatcher(None, value, x).ratio() + # The cutoff for similarity here is pretty arbitrary. It should + # probably be investigated and tweaked. + return [s for s in symbols if sim(s) > 0.6] + + +def similarity_hint(similar): + from .i18n import _ + + if len(similar) == 1: + return _(b"did you mean %s?") % similar[0] + elif similar: + ss = b", ".join(sorted(similar)) + return _(b"did you mean one of %s?") % ss + else: + return None + + class UnknownIdentifier(ParseError): """Exception raised when a {rev,file}set references an unknown identifier""" diff -r bb1b7a5bc96b -r 8cc9e7f762d6 mercurial/scmutil.py --- a/mercurial/scmutil.py Thu Nov 19 09:19:44 2020 -0800 +++ b/mercurial/scmutil.py Thu Nov 19 12:20:26 2020 -0800 @@ -7,7 +7,6 @@ from __future__ import absolute_import -import difflib import errno import glob import os @@ -143,23 +142,6 @@ ui.status(_(b"no changes found\n")) -def getsimilar(symbols, value): - sim = lambda x: difflib.SequenceMatcher(None, value, x).ratio() - # The cutoff for similarity here is pretty arbitrary. It should - # probably be investigated and tweaked. - return [s for s in symbols if sim(s) > 0.6] - - -def similarity_hint(similar): - if len(similar) == 1: - return _(b"did you mean %s?") % similar[0] - elif similar: - ss = b", ".join(sorted(similar)) - return _(b"did you mean one of %s?") % ss - else: - return None - - def formatparse(write, inst): if inst.location is not None: write( @@ -170,8 +152,8 @@ write(_(b"hg: parse error: %s\n") % inst.message) if isinstance(inst, error.UnknownIdentifier): # make sure to check fileset first, as revset can invoke fileset - similar = getsimilar(inst.symbols, inst.function) - hint = similarity_hint(similar) + similar = error.getsimilar(inst.symbols, inst.function) + hint = error.similarity_hint(similar) if hint: write(b"(%s)\n" % hint) elif inst.hint: