1a5f9918aSopenharmony_ci
2a5f9918aSopenharmony_ciimport yaml
3a5f9918aSopenharmony_ciimport pprint
4a5f9918aSopenharmony_ci
5a5f9918aSopenharmony_ciimport datetime
6a5f9918aSopenharmony_ciimport yaml.tokens
7a5f9918aSopenharmony_ci
8a5f9918aSopenharmony_ci# Import any packages here that need to be referenced in .code files.
9a5f9918aSopenharmony_ciimport signal
10a5f9918aSopenharmony_ci
11a5f9918aSopenharmony_cidef execute(code):
12a5f9918aSopenharmony_ci    global value
13a5f9918aSopenharmony_ci    exec(code)
14a5f9918aSopenharmony_ci    return value
15a5f9918aSopenharmony_ci
16a5f9918aSopenharmony_cidef _make_objects():
17a5f9918aSopenharmony_ci    global MyLoader, MyDumper, MyTestClass1, MyTestClass2, MyTestClass3, YAMLObject1, YAMLObject2,  \
18a5f9918aSopenharmony_ci            AnObject, AnInstance, AState, ACustomState, InitArgs, InitArgsWithState,    \
19a5f9918aSopenharmony_ci            NewArgs, NewArgsWithState, Reduce, ReduceWithState, Slots, MyInt, MyList, MyDict,  \
20a5f9918aSopenharmony_ci            FixedOffset, today, execute, MyFullLoader
21a5f9918aSopenharmony_ci
22a5f9918aSopenharmony_ci    class MyLoader(yaml.Loader):
23a5f9918aSopenharmony_ci        pass
24a5f9918aSopenharmony_ci    class MyDumper(yaml.Dumper):
25a5f9918aSopenharmony_ci        pass
26a5f9918aSopenharmony_ci
27a5f9918aSopenharmony_ci    class MyTestClass1:
28a5f9918aSopenharmony_ci        def __init__(self, x, y=0, z=0):
29a5f9918aSopenharmony_ci            self.x = x
30a5f9918aSopenharmony_ci            self.y = y
31a5f9918aSopenharmony_ci            self.z = z
32a5f9918aSopenharmony_ci        def __eq__(self, other):
33a5f9918aSopenharmony_ci            if isinstance(other, MyTestClass1):
34a5f9918aSopenharmony_ci                return self.__class__, self.__dict__ == other.__class__, other.__dict__
35a5f9918aSopenharmony_ci            else:
36a5f9918aSopenharmony_ci                return False
37a5f9918aSopenharmony_ci
38a5f9918aSopenharmony_ci    def construct1(constructor, node):
39a5f9918aSopenharmony_ci        mapping = constructor.construct_mapping(node)
40a5f9918aSopenharmony_ci        return MyTestClass1(**mapping)
41a5f9918aSopenharmony_ci    def represent1(representer, native):
42a5f9918aSopenharmony_ci        return representer.represent_mapping("!tag1", native.__dict__)
43a5f9918aSopenharmony_ci
44a5f9918aSopenharmony_ci    def my_time_constructor(constructor, node):
45a5f9918aSopenharmony_ci        seq = constructor.construct_sequence(node)
46a5f9918aSopenharmony_ci        dt = seq[0]
47a5f9918aSopenharmony_ci        tz = None
48a5f9918aSopenharmony_ci        try:
49a5f9918aSopenharmony_ci            tz = dt.tzinfo.tzname(dt)
50a5f9918aSopenharmony_ci        except:
51a5f9918aSopenharmony_ci            pass
52a5f9918aSopenharmony_ci        return [dt, tz]
53a5f9918aSopenharmony_ci
54a5f9918aSopenharmony_ci    yaml.add_constructor("!tag1", construct1, Loader=MyLoader)
55a5f9918aSopenharmony_ci    yaml.add_constructor("!MyTime", my_time_constructor, Loader=MyLoader)
56a5f9918aSopenharmony_ci    yaml.add_representer(MyTestClass1, represent1, Dumper=MyDumper)
57a5f9918aSopenharmony_ci
58a5f9918aSopenharmony_ci    class MyTestClass2(MyTestClass1, yaml.YAMLObject):
59a5f9918aSopenharmony_ci        yaml_loader = MyLoader
60a5f9918aSopenharmony_ci        yaml_dumper = MyDumper
61a5f9918aSopenharmony_ci        yaml_tag = "!tag2"
62a5f9918aSopenharmony_ci        def from_yaml(cls, constructor, node):
63a5f9918aSopenharmony_ci            x = constructor.construct_yaml_int(node)
64a5f9918aSopenharmony_ci            return cls(x=x)
65a5f9918aSopenharmony_ci        from_yaml = classmethod(from_yaml)
66a5f9918aSopenharmony_ci        def to_yaml(cls, representer, native):
67a5f9918aSopenharmony_ci            return representer.represent_scalar(cls.yaml_tag, str(native.x))
68a5f9918aSopenharmony_ci        to_yaml = classmethod(to_yaml)
69a5f9918aSopenharmony_ci
70a5f9918aSopenharmony_ci    class MyTestClass3(MyTestClass2):
71a5f9918aSopenharmony_ci        yaml_tag = "!tag3"
72a5f9918aSopenharmony_ci        def from_yaml(cls, constructor, node):
73a5f9918aSopenharmony_ci            mapping = constructor.construct_mapping(node)
74a5f9918aSopenharmony_ci            if '=' in mapping:
75a5f9918aSopenharmony_ci                x = mapping['=']
76a5f9918aSopenharmony_ci                del mapping['=']
77a5f9918aSopenharmony_ci                mapping['x'] = x
78a5f9918aSopenharmony_ci            return cls(**mapping)
79a5f9918aSopenharmony_ci        from_yaml = classmethod(from_yaml)
80a5f9918aSopenharmony_ci        def to_yaml(cls, representer, native):
81a5f9918aSopenharmony_ci            return representer.represent_mapping(cls.yaml_tag, native.__dict__)
82a5f9918aSopenharmony_ci        to_yaml = classmethod(to_yaml)
83a5f9918aSopenharmony_ci
84a5f9918aSopenharmony_ci    class YAMLObject1(yaml.YAMLObject):
85a5f9918aSopenharmony_ci        yaml_loader = MyLoader
86a5f9918aSopenharmony_ci        yaml_dumper = MyDumper
87a5f9918aSopenharmony_ci        yaml_tag = '!foo'
88a5f9918aSopenharmony_ci        def __init__(self, my_parameter=None, my_another_parameter=None):
89a5f9918aSopenharmony_ci            self.my_parameter = my_parameter
90a5f9918aSopenharmony_ci            self.my_another_parameter = my_another_parameter
91a5f9918aSopenharmony_ci        def __eq__(self, other):
92a5f9918aSopenharmony_ci            if isinstance(other, YAMLObject1):
93a5f9918aSopenharmony_ci                return self.__class__, self.__dict__ == other.__class__, other.__dict__
94a5f9918aSopenharmony_ci            else:
95a5f9918aSopenharmony_ci                return False
96a5f9918aSopenharmony_ci
97a5f9918aSopenharmony_ci    class YAMLObject2(yaml.YAMLObject):
98a5f9918aSopenharmony_ci        yaml_loader = MyLoader
99a5f9918aSopenharmony_ci        yaml_dumper = MyDumper
100a5f9918aSopenharmony_ci        yaml_tag = '!bar'
101a5f9918aSopenharmony_ci        def __init__(self, foo=1, bar=2, baz=3):
102a5f9918aSopenharmony_ci            self.foo = foo
103a5f9918aSopenharmony_ci            self.bar = bar
104a5f9918aSopenharmony_ci            self.baz = baz
105a5f9918aSopenharmony_ci        def __getstate__(self):
106a5f9918aSopenharmony_ci            return {1: self.foo, 2: self.bar, 3: self.baz}
107a5f9918aSopenharmony_ci        def __setstate__(self, state):
108a5f9918aSopenharmony_ci            self.foo = state[1]
109a5f9918aSopenharmony_ci            self.bar = state[2]
110a5f9918aSopenharmony_ci            self.baz = state[3]
111a5f9918aSopenharmony_ci        def __eq__(self, other):
112a5f9918aSopenharmony_ci            if isinstance(other, YAMLObject2):
113a5f9918aSopenharmony_ci                return self.__class__, self.__dict__ == other.__class__, other.__dict__
114a5f9918aSopenharmony_ci            else:
115a5f9918aSopenharmony_ci                return False
116a5f9918aSopenharmony_ci
117a5f9918aSopenharmony_ci    class AnObject:
118a5f9918aSopenharmony_ci        def __new__(cls, foo=None, bar=None, baz=None):
119a5f9918aSopenharmony_ci            self = object.__new__(cls)
120a5f9918aSopenharmony_ci            self.foo = foo
121a5f9918aSopenharmony_ci            self.bar = bar
122a5f9918aSopenharmony_ci            self.baz = baz
123a5f9918aSopenharmony_ci            return self
124a5f9918aSopenharmony_ci        def __cmp__(self, other):
125a5f9918aSopenharmony_ci            return cmp((type(self), self.foo, self.bar, self.baz),
126a5f9918aSopenharmony_ci                    (type(other), other.foo, other.bar, other.baz))
127a5f9918aSopenharmony_ci        def __eq__(self, other):
128a5f9918aSopenharmony_ci            return type(self) is type(other) and    \
129a5f9918aSopenharmony_ci                    (self.foo, self.bar, self.baz) == (other.foo, other.bar, other.baz)
130a5f9918aSopenharmony_ci
131a5f9918aSopenharmony_ci    class AnInstance:
132a5f9918aSopenharmony_ci        def __init__(self, foo=None, bar=None, baz=None):
133a5f9918aSopenharmony_ci            self.foo = foo
134a5f9918aSopenharmony_ci            self.bar = bar
135a5f9918aSopenharmony_ci            self.baz = baz
136a5f9918aSopenharmony_ci        def __cmp__(self, other):
137a5f9918aSopenharmony_ci            return cmp((type(self), self.foo, self.bar, self.baz),
138a5f9918aSopenharmony_ci                    (type(other), other.foo, other.bar, other.baz))
139a5f9918aSopenharmony_ci        def __eq__(self, other):
140a5f9918aSopenharmony_ci            return type(self) is type(other) and    \
141a5f9918aSopenharmony_ci                    (self.foo, self.bar, self.baz) == (other.foo, other.bar, other.baz)
142a5f9918aSopenharmony_ci
143a5f9918aSopenharmony_ci    class AState(AnInstance):
144a5f9918aSopenharmony_ci        def __getstate__(self):
145a5f9918aSopenharmony_ci            return {
146a5f9918aSopenharmony_ci                '_foo': self.foo,
147a5f9918aSopenharmony_ci                '_bar': self.bar,
148a5f9918aSopenharmony_ci                '_baz': self.baz,
149a5f9918aSopenharmony_ci            }
150a5f9918aSopenharmony_ci        def __setstate__(self, state):
151a5f9918aSopenharmony_ci            self.foo = state['_foo']
152a5f9918aSopenharmony_ci            self.bar = state['_bar']
153a5f9918aSopenharmony_ci            self.baz = state['_baz']
154a5f9918aSopenharmony_ci
155a5f9918aSopenharmony_ci    class ACustomState(AnInstance):
156a5f9918aSopenharmony_ci        def __getstate__(self):
157a5f9918aSopenharmony_ci            return (self.foo, self.bar, self.baz)
158a5f9918aSopenharmony_ci        def __setstate__(self, state):
159a5f9918aSopenharmony_ci            self.foo, self.bar, self.baz = state
160a5f9918aSopenharmony_ci
161a5f9918aSopenharmony_ci    class NewArgs(AnObject):
162a5f9918aSopenharmony_ci        def __getnewargs__(self):
163a5f9918aSopenharmony_ci            return (self.foo, self.bar, self.baz)
164a5f9918aSopenharmony_ci        def __getstate__(self):
165a5f9918aSopenharmony_ci            return {}
166a5f9918aSopenharmony_ci
167a5f9918aSopenharmony_ci    class NewArgsWithState(AnObject):
168a5f9918aSopenharmony_ci        def __getnewargs__(self):
169a5f9918aSopenharmony_ci            return (self.foo, self.bar)
170a5f9918aSopenharmony_ci        def __getstate__(self):
171a5f9918aSopenharmony_ci            return self.baz
172a5f9918aSopenharmony_ci        def __setstate__(self, state):
173a5f9918aSopenharmony_ci            self.baz = state
174a5f9918aSopenharmony_ci
175a5f9918aSopenharmony_ci    InitArgs = NewArgs
176a5f9918aSopenharmony_ci
177a5f9918aSopenharmony_ci    InitArgsWithState = NewArgsWithState
178a5f9918aSopenharmony_ci
179a5f9918aSopenharmony_ci    class Reduce(AnObject):
180a5f9918aSopenharmony_ci        def __reduce__(self):
181a5f9918aSopenharmony_ci            return self.__class__, (self.foo, self.bar, self.baz)
182a5f9918aSopenharmony_ci
183a5f9918aSopenharmony_ci    class ReduceWithState(AnObject):
184a5f9918aSopenharmony_ci        def __reduce__(self):
185a5f9918aSopenharmony_ci            return self.__class__, (self.foo, self.bar), self.baz
186a5f9918aSopenharmony_ci        def __setstate__(self, state):
187a5f9918aSopenharmony_ci            self.baz = state
188a5f9918aSopenharmony_ci
189a5f9918aSopenharmony_ci    class Slots:
190a5f9918aSopenharmony_ci        __slots__ = ("foo", "bar", "baz")
191a5f9918aSopenharmony_ci        def __init__(self, foo=None, bar=None, baz=None):
192a5f9918aSopenharmony_ci            self.foo = foo
193a5f9918aSopenharmony_ci            self.bar = bar
194a5f9918aSopenharmony_ci            self.baz = baz
195a5f9918aSopenharmony_ci
196a5f9918aSopenharmony_ci        def __eq__(self, other):
197a5f9918aSopenharmony_ci            return type(self) is type(other) and \
198a5f9918aSopenharmony_ci                (self.foo, self.bar, self.baz) == (other.foo, other.bar, other.baz)
199a5f9918aSopenharmony_ci
200a5f9918aSopenharmony_ci    class MyInt(int):
201a5f9918aSopenharmony_ci        def __eq__(self, other):
202a5f9918aSopenharmony_ci            return type(self) is type(other) and int(self) == int(other)
203a5f9918aSopenharmony_ci
204a5f9918aSopenharmony_ci    class MyList(list):
205a5f9918aSopenharmony_ci        def __init__(self, n=1):
206a5f9918aSopenharmony_ci            self.extend([None]*n)
207a5f9918aSopenharmony_ci        def __eq__(self, other):
208a5f9918aSopenharmony_ci            return type(self) is type(other) and list(self) == list(other)
209a5f9918aSopenharmony_ci
210a5f9918aSopenharmony_ci    class MyDict(dict):
211a5f9918aSopenharmony_ci        def __init__(self, n=1):
212a5f9918aSopenharmony_ci            for k in range(n):
213a5f9918aSopenharmony_ci                self[k] = None
214a5f9918aSopenharmony_ci        def __eq__(self, other):
215a5f9918aSopenharmony_ci            return type(self) is type(other) and dict(self) == dict(other)
216a5f9918aSopenharmony_ci
217a5f9918aSopenharmony_ci    class FixedOffset(datetime.tzinfo):
218a5f9918aSopenharmony_ci        def __init__(self, offset, name):
219a5f9918aSopenharmony_ci            self.__offset = datetime.timedelta(minutes=offset)
220a5f9918aSopenharmony_ci            self.__name = name
221a5f9918aSopenharmony_ci        def utcoffset(self, dt):
222a5f9918aSopenharmony_ci            return self.__offset
223a5f9918aSopenharmony_ci        def tzname(self, dt):
224a5f9918aSopenharmony_ci            return self.__name
225a5f9918aSopenharmony_ci        def dst(self, dt):
226a5f9918aSopenharmony_ci            return datetime.timedelta(0)
227a5f9918aSopenharmony_ci
228a5f9918aSopenharmony_ci    class MyFullLoader(yaml.FullLoader):
229a5f9918aSopenharmony_ci        def get_state_keys_blacklist(self):
230a5f9918aSopenharmony_ci            return super().get_state_keys_blacklist() + ['^mymethod$', '^wrong_.*$']
231a5f9918aSopenharmony_ci
232a5f9918aSopenharmony_ci    today = datetime.date.today()
233a5f9918aSopenharmony_ci
234a5f9918aSopenharmony_cidef _load_code(expression):
235a5f9918aSopenharmony_ci    return eval(expression)
236a5f9918aSopenharmony_ci
237a5f9918aSopenharmony_cidef _serialize_value(data):
238a5f9918aSopenharmony_ci    if isinstance(data, list):
239a5f9918aSopenharmony_ci        return '[%s]' % ', '.join(map(_serialize_value, data))
240a5f9918aSopenharmony_ci    elif isinstance(data, dict):
241a5f9918aSopenharmony_ci        items = []
242a5f9918aSopenharmony_ci        for key, value in data.items():
243a5f9918aSopenharmony_ci            key = _serialize_value(key)
244a5f9918aSopenharmony_ci            value = _serialize_value(value)
245a5f9918aSopenharmony_ci            items.append("%s: %s" % (key, value))
246a5f9918aSopenharmony_ci        items.sort()
247a5f9918aSopenharmony_ci        return '{%s}' % ', '.join(items)
248a5f9918aSopenharmony_ci    elif isinstance(data, datetime.datetime):
249a5f9918aSopenharmony_ci        return repr(data.utctimetuple())
250a5f9918aSopenharmony_ci    elif isinstance(data, float) and data != data:
251a5f9918aSopenharmony_ci        return '?'
252a5f9918aSopenharmony_ci    else:
253a5f9918aSopenharmony_ci        return str(data)
254a5f9918aSopenharmony_ci
255a5f9918aSopenharmony_cidef test_constructor_types(data_filename, code_filename, verbose=False):
256a5f9918aSopenharmony_ci    _make_objects()
257a5f9918aSopenharmony_ci    native1 = None
258a5f9918aSopenharmony_ci    native2 = None
259a5f9918aSopenharmony_ci    try:
260a5f9918aSopenharmony_ci        with open(data_filename, 'rb') as file:
261a5f9918aSopenharmony_ci            native1 = list(yaml.load_all(file, Loader=MyLoader))
262a5f9918aSopenharmony_ci        if len(native1) == 1:
263a5f9918aSopenharmony_ci            native1 = native1[0]
264a5f9918aSopenharmony_ci        with open(code_filename, 'rb') as file:
265a5f9918aSopenharmony_ci            native2 = _load_code(file.read())
266a5f9918aSopenharmony_ci        try:
267a5f9918aSopenharmony_ci            if native1 == native2:
268a5f9918aSopenharmony_ci                return
269a5f9918aSopenharmony_ci        except TypeError:
270a5f9918aSopenharmony_ci            pass
271a5f9918aSopenharmony_ci        if verbose:
272a5f9918aSopenharmony_ci            print("SERIALIZED NATIVE1:")
273a5f9918aSopenharmony_ci            print(_serialize_value(native1))
274a5f9918aSopenharmony_ci            print("SERIALIZED NATIVE2:")
275a5f9918aSopenharmony_ci            print(_serialize_value(native2))
276a5f9918aSopenharmony_ci        assert _serialize_value(native1) == _serialize_value(native2), (native1, native2)
277a5f9918aSopenharmony_ci    finally:
278a5f9918aSopenharmony_ci        if verbose:
279a5f9918aSopenharmony_ci            print("NATIVE1:")
280a5f9918aSopenharmony_ci            pprint.pprint(native1)
281a5f9918aSopenharmony_ci            print("NATIVE2:")
282a5f9918aSopenharmony_ci            pprint.pprint(native2)
283a5f9918aSopenharmony_ci
284a5f9918aSopenharmony_citest_constructor_types.unittest = ['.data', '.code']
285a5f9918aSopenharmony_ci
286a5f9918aSopenharmony_cidef test_subclass_blacklist_types(data_filename, verbose=False):
287a5f9918aSopenharmony_ci    _make_objects()
288a5f9918aSopenharmony_ci    try:
289a5f9918aSopenharmony_ci        with open(data_filename, 'rb') as file:
290a5f9918aSopenharmony_ci            yaml.load(file.read(), MyFullLoader)
291a5f9918aSopenharmony_ci    except yaml.YAMLError as exc:
292a5f9918aSopenharmony_ci        if verbose:
293a5f9918aSopenharmony_ci            print("%s:" % exc.__class__.__name__, exc)
294a5f9918aSopenharmony_ci    else:
295a5f9918aSopenharmony_ci        raise AssertionError("expected an exception")
296a5f9918aSopenharmony_ci
297a5f9918aSopenharmony_citest_subclass_blacklist_types.unittest = ['.subclass_blacklist']
298a5f9918aSopenharmony_ci
299a5f9918aSopenharmony_ciif __name__ == '__main__':
300a5f9918aSopenharmony_ci    import sys, test_constructor
301a5f9918aSopenharmony_ci    sys.modules['test_constructor'] = sys.modules['__main__']
302a5f9918aSopenharmony_ci    import test_appliance
303a5f9918aSopenharmony_ci    test_appliance.run(globals())
304a5f9918aSopenharmony_ci
305