File: string_.py

package info (click to toggle)
tryton-server 7.0.40-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 7,748 kB
  • sloc: python: 53,502; xml: 5,194; sh: 803; sql: 217; makefile: 28
file content (123 lines) | stat: -rw-r--r-- 3,864 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# This file is part of Tryton.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.

# Code come from python-Levenshtein

__all__ = ['StringMatcher', 'StringPartitioned', 'LazyString']

from warnings import warn

try:
    from Levenshtein import distance, editops, matching_blocks, opcodes, ratio

    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 __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_seq1(self, seq1):
            self._str1 = seq1
            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_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 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 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
except ImportError:
    from difflib import SequenceMatcher as StringMatcher


class StringPartitioned(str):
    "A string subclass that stores parts that composes itself."
    __slots__ = ('_parts',)

    def __init__(self, base):
        super().__init__()
        if isinstance(base, StringPartitioned):
            self._parts = base._parts
        else:
            self._parts = (base,)

    def __iter__(self):
        return iter(self._parts)

    def __add__(self, other):
        new = self.__class__(str(self) + other)
        new._parts = self._parts + (other,)
        return new

    def __radd__(self, other):
        new = self.__class__(other + str(self))
        new._parts = (other,) + self._parts
        return new


class LazyString():
    def __init__(self, func, *args, **kwargs):
        self._func = func
        self._args = args
        self._kwargs = kwargs

    def __str__(self):
        return self._func(*self._args, **self._kwargs)

    def __add__(self, other):
        return str(self) + other

    def __radd__(self, other):
        return other + str(self)