Skip to content

Instantly share code, notes, and snippets.

@dutc
Created October 23, 2014 16:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dutc/3f2c79048d95287be138 to your computer and use it in GitHub Desktop.
Save dutc/3f2c79048d95287be138 to your computer and use it in GitHub Desktop.
Did you mean? in Python
#!/usr/bin/env python
from re import search
from itertools import chain
# levenshtein
def distance(x, y):
if not len(x): return len(y)
if not len(y): return len(x)
return min(distance(x[1:], y[1:]) + (x[0] != y[0]), distance(x[1:], y) + 1, distance(x, y[1:]) + 1)
import sys
def didyoumean(exc_type, value, traceback, excepthook=sys.excepthook):
if issubclass(exc_type, AttributeError):
terms = search("'(\w+)' object has no attribute '(\w+)'", value.message)
if terms:
type_name, attr = terms.groups()
type_obj = next((t for t in
chain(traceback.tb_frame.f_locals.values(),
traceback.tb_frame.f_globals.values())
if type_name == type(t).__name__), None)
if type_obj:
candidate = min(dir(type_obj), key=lambda x: distance(attr, x))
value = AttributeError(value.message +
'\nMaybe you meant: {}.{}'.format(type_name, candidate))
return excepthook(exc_type, value, traceback)
sys.excepthook = didyoumean
class Foo(object):
def bar(self):
pass
if __name__ == '__main__':
foo = Foo()
foo.baz
#!/usr/bin/env python
# levenshtein
def distance(x, y):
if not len(x): return len(y)
if not len(y): return len(x)
return min(distance(x[1:], y[1:]) + (x[0] != y[0]), distance(x[1:], y) + 1, distance(x, y[1:]) + 1)
class Foo(object):
def bar(self):
pass
def __getattr__(self, attr):
if not attr.startswith('__'):
candidate = min(dir(self), key=lambda x: distance(attr, x))
raise AttributeError('Did you mean? .{}'.format(candidate))
if __name__ == '__main__':
foo = Foo()
foo.baz
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment