diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 00:33:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 00:33:55 +0000 |
commit | cbbc936ed9811bdb5dd480bc2c5e10c3062532be (patch) | |
tree | ec1783c0aaa2ee6eaa6d6362f2bed4392943de8e /_test/lib/test_constructor.py | |
parent | Releasing progress-linux version 0.18.5-1~exp1~progress7.99u1. (diff) | |
download | ruamel.yaml-cbbc936ed9811bdb5dd480bc2c5e10c3062532be.tar.xz ruamel.yaml-cbbc936ed9811bdb5dd480bc2c5e10c3062532be.zip |
Merging upstream version 0.18.6.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '_test/lib/test_constructor.py')
-rw-r--r-- | _test/lib/test_constructor.py | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/_test/lib/test_constructor.py b/_test/lib/test_constructor.py new file mode 100644 index 0000000..b38bf2f --- /dev/null +++ b/_test/lib/test_constructor.py @@ -0,0 +1,372 @@ + +import ruamel.yaml +import pprint + +import datetime + +try: + set +except NameError: + from sets import Set as set # NOQA +import ruamel.yaml.tokens + + +def execute(code): + global value + exec(code) + return value + + +def _make_objects(): + global MyLoader, MyDumper, MyTestClass1, MyTestClass2, MyTestClass3, YAMLobject1, YAMLobject2, AnObject, AnInstance, AState, ACustomState, InitArgs, InitArgsWithState, NewArgs, NewArgsWithState, Reduce, ReduceWithState, MyInt, MyList, MyDict, FixedOffset, today, execute + + class MyLoader(ruamel.yaml.Loader): + pass + + class MyDumper(ruamel.yaml.Dumper): + pass + + class MyTestClass1: + def __init__(self, x, y=0, z=0): + self.x = x + self.y = y + self.z = z + + def __eq__(self, other): + if isinstance(other, MyTestClass1): + return self.__class__, self.__dict__ == other.__class__, other.__dict__ + else: + return False + + def construct1(constructor, node): + mapping = constructor.construct_mapping(node) + return MyTestClass1(**mapping) + + def represent1(representer, native): + return representer.represent_mapping('!tag1', native.__dict__) + + ruamel.yaml.add_constructor('!tag1', construct1, Loader=MyLoader) + ruamel.yaml.add_representer(MyTestClass1, represent1, Dumper=MyDumper) + + class MyTestClass2(MyTestClass1, ruamel.yaml.YAMLObject): + ruamel.yaml.loader = MyLoader + ruamel.yaml.dumper = MyDumper + ruamel.yaml.tag = '!tag2' + + def from_yaml(cls, constructor, node): + x = constructor.construct_yaml_int(node) + return cls(x=x) + + from_yaml = classmethod(from_yaml) + + def to_yaml(cls, representer, native): + return representer.represent_scalar(cls.yaml_tag, str(native.x)) + + to_yaml = classmethod(to_yaml) + + class MyTestClass3(MyTestClass2): + ruamel.yaml.tag = '!tag3' + + def from_yaml(cls, constructor, node): + mapping = constructor.construct_mapping(node) + if '=' in mapping: + x = mapping['='] + del mapping['='] + mapping['x'] = x + return cls(**mapping) + + from_yaml = classmethod(from_yaml) + + def to_yaml(cls, representer, native): + return representer.represent_mapping(cls.yaml_tag, native.__dict__) + + to_yaml = classmethod(to_yaml) + + class YAMLobject1(ruamel.yaml.YAMLObject): + ruamel.yaml.loader = MyLoader + ruamel.yaml.dumper = MyDumper + ruamel.yaml.tag = '!foo' + + def __init__(self, my_parameter=None, my_another_parameter=None): + self.my_parameter = my_parameter + self.my_another_parameter = my_another_parameter + + def __eq__(self, other): + if isinstance(other, YAMLobject1): + return self.__class__, self.__dict__ == other.__class__, other.__dict__ + else: + return False + + class YAMLobject2(ruamel.yaml.YAMLObject): + ruamel.yaml.loader = MyLoader + ruamel.yaml.dumper = MyDumper + ruamel.yaml.tag = '!bar' + + def __init__(self, foo=1, bar=2, baz=3): + self.foo = foo + self.bar = bar + self.baz = baz + + def __getstate__(self): + return {1: self.foo, 2: self.bar, 3: self.baz} + + def __setstate__(self, state): + self.foo = state[1] + self.bar = state[2] + self.baz = state[3] + + def __eq__(self, other): + if isinstance(other, YAMLobject2): + return self.__class__, self.__dict__ == other.__class__, other.__dict__ + else: + return False + + class AnObject: + def __new__(cls, foo=None, bar=None, baz=None): + self = object.__new__(cls) + self.foo = foo + self.bar = bar + self.baz = baz + return self + + def __cmp__(self, other): + return cmp( + (type(self), self.foo, self.bar, self.baz), # NOQA + (type(other), other.foo, other.bar, other.baz), + ) + + def __eq__(self, other): + return type(self) is type(other) and (self.foo, self.bar, self.baz) == ( + other.foo, + other.bar, + other.baz, + ) + + class AnInstance: + def __init__(self, foo=None, bar=None, baz=None): + self.foo = foo + self.bar = bar + self.baz = baz + + def __cmp__(self, other): + return cmp( + (type(self), self.foo, self.bar, self.baz), # NOQA + (type(other), other.foo, other.bar, other.baz), + ) + + def __eq__(self, other): + return type(self) is type(other) and (self.foo, self.bar, self.baz) == ( + other.foo, + other.bar, + other.baz, + ) + + class AState(AnInstance): + def __getstate__(self): + return {'_foo': self.foo, '_bar': self.bar, '_baz': self.baz} + + def __setstate__(self, state): + self.foo = state['_foo'] + self.bar = state['_bar'] + self.baz = state['_baz'] + + class ACustomState(AnInstance): + def __getstate__(self): + return (self.foo, self.bar, self.baz) + + def __setstate__(self, state): + self.foo, self.bar, self.baz = state + + # class InitArgs(AnInstance): + # def __getinitargs__(self): + # return (self.foo, self.bar, self.baz) + # def __getstate__(self): + # return {} + + # class InitArgsWithState(AnInstance): + # def __getinitargs__(self): + # return (self.foo, self.bar) + # def __getstate__(self): + # return self.baz + # def __setstate__(self, state): + # self.baz = state + + class NewArgs(AnObject): + def __getnewargs__(self): + return (self.foo, self.bar, self.baz) + + def __getstate__(self): + return {} + + class NewArgsWithState(AnObject): + def __getnewargs__(self): + return (self.foo, self.bar) + + def __getstate__(self): + return self.baz + + def __setstate__(self, state): + self.baz = state + + InitArgs = NewArgs + + InitArgsWithState = NewArgsWithState + + class Reduce(AnObject): + def __reduce__(self): + return self.__class__, (self.foo, self.bar, self.baz) + + class ReduceWithState(AnObject): + def __reduce__(self): + return self.__class__, (self.foo, self.bar), self.baz + + def __setstate__(self, state): + self.baz = state + + class MyInt(int): + def __eq__(self, other): + return type(self) is type(other) and int(self) == int(other) + + class MyList(list): + def __init__(self, n=1): + self.extend([None] * n) + + def __eq__(self, other): + return type(self) is type(other) and list(self) == list(other) + + class MyDict(dict): + def __init__(self, n=1): + for k in range(n): + self[k] = None + + def __eq__(self, other): + return type(self) is type(other) and dict(self) == dict(other) + + class FixedOffset(datetime.tzinfo): + def __init__(self, offset, name): + self.__offset = datetime.timedelta(minutes=offset) + self.__name = name + + def utcoffset(self, dt): + return self.__offset + + def tzname(self, dt): + return self.__name + + def dst(self, dt): + return datetime.timedelta(0) + + today = datetime.date.today() + + +try: + from ruamel.ordereddict import ordereddict +except ImportError: + from collections import OrderedDict + + # to get the right name import ... as ordereddict doesn't do that + + class ordereddict(OrderedDict): + pass + + +def _load_code(expression): + return eval(expression, globals()) + + +def _serialize_value(data): + if isinstance(data, list): + return '[%s]' % ', '.join(map(_serialize_value, data)) + elif isinstance(data, dict): + items = [] + for key, value in data.items(): + key = _serialize_value(key) + value = _serialize_value(value) + items.append('%s: %s' % (key, value)) + items.sort() + return '{%s}' % ', '.join(items) + elif isinstance(data, datetime.datetime): + return repr(data.utctimetuple()) + elif isinstance(data, float) and data != data: + return '?' + else: + return str(data) + + +def test_constructor_types(data_filename, code_filename, verbose=False): + _make_objects() + native1 = None + native2 = None + yaml = ruamel.yaml.YAML(typ='safe', pure=True) + yaml.loader = MyLoader + try: + with open(data_filename, 'rb') as fp0: + native1 = list(yaml.load_all(fp0)) + if len(native1) == 1: + native1 = native1[0] + with open(code_filename, 'rb') as fp0: + native2 = _load_code(fp0.read()) + try: + if native1 == native2: + return + except TypeError: + pass + # print('native1', native1) + if verbose: + print('SERIALIZED NATIVE1:') + print(_serialize_value(native1)) + print('SERIALIZED NATIVE2:') + print(_serialize_value(native2)) + assert _serialize_value(native1) == _serialize_value(native2), (native1, native2) + finally: + if verbose: + print('NATIVE1:') + pprint.pprint(native1) + print('NATIVE2:') + pprint.pprint(native2) + + +test_constructor_types.unittest = ['.data', '.code'] + + +def test_roundtrip_data(code_filename, roundtrip_filename, verbose=False): + _make_objects() + with open(code_filename, 'rb') as fp0: + value1 = fp0.read() + yaml = YAML(typ='safe', pure=True) + yaml.Loader = MyLoader + native2 = list(yaml.load_all(value1)) + if len(native2) == 1: + native2 = native2[0] + try: + value2 = ruamel.yaml.dump( + native2, + Dumper=MyDumper, + default_flow_style=False, + allow_unicode=True, + encoding='utf-8', + ) + # value2 += x + if verbose: + print('SERIALIZED NATIVE1:') + print(value1) + print('SERIALIZED NATIVE2:') + print(value2) + assert value1 == value2, (value1, value2) + finally: + if verbose: + print('NATIVE2:') + pprint.pprint(native2) + + +test_roundtrip_data.unittest = ['.data', '.roundtrip'] + + +if __name__ == '__main__': + import sys + import test_constructor # NOQA + + sys.modules['test_constructor'] = sys.modules['__main__'] + import test_appliance + + test_appliance.run(globals()) |