Decorator.__new__()   B
last analyzed

Complexity

Conditions 7

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
c 1
b 0
f 0
dl 0
loc 16
rs 7.3333
1
import os
2
import threading
3
4
import yaml
5
6
MULTITHREADING = True
7
lock = threading.Lock()
8
9
10
class SingletonDecorator:
11
    def __init__(self, klass):
12
        self.klass = klass
13
        self.instance = None
14
15
    def __call__(self, *args, **kwds):
16
        if self.instance is None:
17
            self.instance = self.klass(*args, **kwds)
18
        return self.instance
19
20
21
def yaml_load(filename):
22
    try:
23
        with open(filename + ".old", "r") as file:
24
            res = yaml.load(file)
25
            return res
26
    except FileNotFoundError:
27
        try:
28
            with open(filename, "r") as file:
29
                res = yaml.load(file)
30
                return res
31
        except FileNotFoundError:
32
            return None
33
34
35
def yaml_write(content, filename):
36
    rename = True
37
    try:
38
        os.rename(filename, filename + ".old")
39
    except FileNotFoundError:
40
        rename = False
41
    try:
42
        with open(filename, "w+") as file:
43
            yaml.dump(content, file)
44
    except IOError:
45
        if rename:
46
            os.rename(filename + ".old", filename)
47
    else:
48
        if rename:
49
            os.remove(filename + ".old")
50
    print("finished")
51
52
53
@SingletonDecorator
54
class PersistableStack(object):
55
    def __init__(self, filename, multithreading=True):
56
        self.filename = filename
57
        self.thread = None
58
        self.values = None
59
        self.multithreading = multithreading
60
61
    def getValues(self):
62
        res = yaml_load(self.filename)
63
        if res is not None:
64
            self.values = res
65
        else:
66
            self.values = []
67
68
    def push(self, element):
69
        if not self.values:
70
            self.getValues()
71
        self.values.append(element)
72
        self.persist(yaml_write, self.values, self.filename)
73
74
    def pop(self):
75
        if not self.values:
76
            self.getValues()
77
        res = self.values.pop()
78
        self.persist(yaml_write, self.values, self.filename)
79
        return res
80
81
    def persist(self, func, *args):
82
        if self.multithreading:
83
            with lock:
84
                self.thread = threading.Thread(target=func, args=args)
85
                self.thread.daemon = True
86
                self.thread.start()
87
        else:
88
            func(*args)
89
90
    @property
91
    def count(self):
92
        return len(self.values)
93
94
95
class Decorator:
96
    def __new__(self, *args, **kwargs):
97
        self.decoree = None
98
        self.newargs = args
99
        self.newkwargs = kwargs
100
        self.decorators = {}
101
        if "decorators" in self.newkwargs:
102
            self.decorators = self.newkwargs["decorators"]
103
        if args:
104
            if isinstance(args[0], type):
105
                self.decoree = args[0]
106
            if callable(args[0]):
107
                if len(args) == 1 and len(kwargs) == 0:
108
                    return args[0]
109
            else:
110
                pass
111
        return self
112
113
    def __init__(self, *args, **kwargs):
114
        self.decoree = None
115
        self.initargs = args
116
        self.initkwargs = kwargs
117
        if args and callable(args[0]):
118
            self.decoree = args[0]
119
120
    def __call__(self, *args, **kwargs):
121
        if args and callable(args[0]):
122
            self.decoree = args[0]
123
            if isinstance(self.decoree, type):
124
                return self.create_wrapping_class(self.decoree, self.decorators)
125
            return self.decoree
126
        elif self.decoree:
127
            if isinstance(self.decoree, type):
128
                return self.create_wrapping_class(args[0], self.decorators)(*args, **kwargs)
129
            return self.decoree(*args, **kwargs)
130
131
    @staticmethod
132
    def create_wrapping_class(cls, decorators):
133
        from six import with_metaclass
134
135
        class MetaNewClass(type):
136
            def __repr__(self):
137
                return repr(cls)
138
139
        class NewClass(with_metaclass(MetaNewClass, cls)):
140
            def __init__(self, *args, **kwargs):
141
                self.__instance = cls(*args, **kwargs)
142
143
            """This is the overwritten class"""
144
            def __getattribute__(self, attr_name):
145
                if attr_name == "__class__":
146
                    return cls
147
                obj = super(NewClass, self).__getattribute__(attr_name)
148
                if hasattr(obj, '__call__'):
149
                    if attr_name in decorators:
150
                        for decorator in decorators:
151
                            obj = decorator(obj)
152
                    elif "*" in decorators:
153
                        for decorator in decorators:
154
                            obj = decorator(obj)
155
                    return obj
156
                return obj
157
158
            def __repr__(self):
159
                return repr(self.__instance)
160
161
        return NewClass
162
163
164
def lcs(a, b):
165
    lengths = [[0 for j in range(len(b) + 1)] for i in range(len(a) + 1)]
166
    # row 0 and column 0 are initialized to 0 already
167
    for i, x in enumerate(a):
168
        for j, y in enumerate(b):
169
            if x == y:
170
                lengths[i + 1][j + 1] = lengths[i][j] + 1
171
            else:
172
                lengths[i + 1][j + 1] = max(lengths[i + 1][j], lengths[i][j + 1])
173
    # read the substring out from the matrix
174
    result = ""
175
    x, y = len(a), len(b)
176
    while x != 0 and y != 0:
177
        if lengths[x][y] == lengths[x - 1][y]:
178
            x -= 1
179
        elif lengths[x][y] == lengths[x][y - 1]:
180
            y -= 1
181
        else:
182
            assert a[x - 1] == b[y - 1]
183
            result = a[x - 1] + result
184
            x -= 1
185
            y -= 1
186
    return result
187