Do not fail on importing string tools if missing python-Levenshtein

python-Levenshtein is an optional dependency so trytond.tools.string_ should
not fail on import.

issue8040
This commit is contained in:
Cédric Krier
2019-03-15 13:37:17 +01:00
parent e2318257bb
commit 65c896b1f0
2 changed files with 63 additions and 60 deletions
+1 -4
View File
@@ -24,10 +24,7 @@ from ..pyson import Bool, Eval, PYSONDecoder
from ..rpc import RPC
from ..protocols.jsonrpc import JSONDecoder, JSONEncoder
from ..tools import is_instance_method, cursor_dict, grouped_slice
try:
from ..tools.string import StringMatcher
except ImportError:
from difflib import SequenceMatcher as StringMatcher
from ..tools.string_ import StringMatcher
__all__ = [
'Model', 'ModelField', 'ModelAccess', 'ModelFieldAccess', 'ModelButton',
+62 -56
View File
@@ -3,76 +3,82 @@
# Code come from python-Levenshtein
from Levenshtein import opcodes, editops, matching_blocks, ratio, distance
__all__ = ['StringMatcher', 'StringPartitioned']
from warnings import warn
try:
from Levenshtein import opcodes, editops, matching_blocks, ratio, distance
class StringMatcher:
"""A SequenceMatcher-like class built on the top of Levenshtein"""
class StringMatcher:
"""A SequenceMatcher-like class built on the top of Levenshtein"""
def _reset_cache(self):
self._ratio = self._distance = None
self._opcodes = self._editops = self._matching_blocks = None
def _reset_cache(self):
self._ratio = self._distance = None
self._opcodes = self._editops = self._matching_blocks = None
def __init__(self, isjunk=None, seq1='', seq2=''):
if isjunk:
warn("isjunk not NOT implemented, it will be ignored")
self._str1, self._str2 = seq1, seq2
self._reset_cache()
def __init__(self, isjunk=None, seq1='', seq2=''):
if isjunk:
warn("isjunk not NOT implemented, it will be ignored")
self._str1, self._str2 = seq1, seq2
self._reset_cache()
def set_seqs(self, seq1, seq2):
self._str1, self._str2 = seq1, seq2
self._reset_cache()
def set_seqs(self, seq1, seq2):
self._str1, self._str2 = seq1, seq2
self._reset_cache()
def set_seq1(self, seq1):
self._str1 = seq1
self._reset_cache()
def set_seq1(self, seq1):
self._str1 = seq1
self._reset_cache()
def set_seq2(self, seq2):
self._str2 = seq2
self._reset_cache()
def set_seq2(self, seq2):
self._str2 = seq2
self._reset_cache()
def get_opcodes(self):
if not self._opcodes:
if self._editops:
self._opcodes = opcodes(
self._editops, self._str1, self._str2)
else:
self._opcodes = opcodes(self._str1, self._str2)
return self._opcodes
def get_opcodes(self):
if not self._opcodes:
if self._editops:
self._opcodes = opcodes(self._editops, self._str1, self._str2)
else:
self._opcodes = opcodes(self._str1, self._str2)
return self._opcodes
def get_editops(self):
if not self._editops:
if self._opcodes:
self._editops = editops(
self._opcodes, self._str1, self._str2)
else:
self._editops = editops(self._str1, self._str2)
return self._editops
def get_editops(self):
if not self._editops:
if self._opcodes:
self._editops = editops(self._opcodes, self._str1, self._str2)
else:
self._editops = editops(self._str1, self._str2)
return self._editops
def get_matching_blocks(self):
if not self._matching_blocks:
self._matching_blocks = matching_blocks(self.get_opcodes(),
self._str1, self._str2)
return self._matching_blocks
def get_matching_blocks(self):
if not self._matching_blocks:
self._matching_blocks = matching_blocks(self.get_opcodes(),
self._str1, self._str2)
return self._matching_blocks
def ratio(self):
if not self._ratio:
self._ratio = ratio(self._str1, self._str2)
return self._ratio
def ratio(self):
if not self._ratio:
self._ratio = ratio(self._str1, self._str2)
return self._ratio
def quick_ratio(self):
# This is usually quick enough :o)
if not self._ratio:
self._ratio = ratio(self._str1, self._str2)
return self._ratio
def quick_ratio(self):
# This is usually quick enough :o)
if not self._ratio:
self._ratio = ratio(self._str1, self._str2)
return self._ratio
def real_quick_ratio(self):
len1, len2 = len(self._str1), len(self._str2)
return 2.0 * min(len1, len2) / (len1 + len2)
def real_quick_ratio(self):
len1, len2 = len(self._str1), len(self._str2)
return 2.0 * min(len1, len2) / (len1 + len2)
def distance(self):
if not self._distance:
self._distance = distance(self._str1, self._str2)
return self._distance
def distance(self):
if not self._distance:
self._distance = distance(self._str1, self._str2)
return self._distance
except ImportError:
from difflib import SequenceMatcher as StringMatcher
class StringPartitioned(str):