From 6772455dbaf362318246e4ae380ae69bc06b450e Mon Sep 17 00:00:00 2001 From: Markus Zolliker Date: Mon, 19 Aug 2019 17:41:45 +0200 Subject: [PATCH] changes according to new syntax decided on vidconf 2019-08-07 - modules and accessibles are changed back to a JSON object - datatype is changed from a JSON array with 2 elements to a JSON object with one element, with the basic type as key - the client side is kept compatible with the old syntax Change-Id: Icd640bbcdec26a895c96720e107e874529340a73 Reviewed-on: https://forge.frm2.tum.de/review/c/sine2020/secop/playground/+/21032 Tested-by: JenkinsCodeReview Reviewed-by: Markus Zolliker --- secop/datatypes.py | 75 +++++++------ secop/protocol/dispatcher.py | 14 +-- secop/protocol/messages.py | 2 +- test/test_datatypes.py | 201 +++++++++++++++++------------------ test/test_params.py | 10 +- 5 files changed, 150 insertions(+), 152 deletions(-) diff --git a/secop/datatypes.py b/secop/datatypes.py index 8fd0f9e..9058ff2 100644 --- a/secop/datatypes.py +++ b/secop/datatypes.py @@ -136,8 +136,8 @@ class FloatRange(DataType): raise BadValueError(u'relative_resolution MUST be >=0') def export_datatype(self): - return [u'double', {k: getattr(self, k) for k, v in self._defaults.items() - if v != getattr(self, k)}] + return {u'double': {k: getattr(self, k) for k, v in self._defaults.items() + if v != getattr(self, k)}} def __call__(self, value): try: @@ -147,11 +147,11 @@ class FloatRange(DataType): prec = max(abs(value * self.relative_resolution), self.absolute_resolution) if self.min - prec <= value <= self.max + prec: return min(max(value, self.min), self.max) - raise BadValueError(u'%g should be a float between %g and %g' % + raise BadValueError(u'%.14g should be a float between %.14g and %.14g' % (value, self.min, self.max)) def __repr__(self): - items = [u'%s=%r' % (k,v) for k,v in self.export_datatype()[1].items()] + items = [u'%s=%r' % (k,v) for k,v in self.export_datatype()['double'].items()] return u'FloatRange(%s)' % (', '.join(items)) def export_value(self, value): @@ -187,7 +187,7 @@ class IntRange(DataType): raise BadValueError(u'Max must be larger then min!') def export_datatype(self): - return [u'int', {"min": self.min, "max": self.max}] + return {u'int': {"min": self.min, "max": self.max}} def __call__(self, value): try: @@ -260,7 +260,7 @@ class ScaledInteger(DataType): info['scale'] = self.scale info['min'] = int((self.min + self.scale * 0.5) // self.scale) info['max'] = int((self.max + self.scale * 0.5) // self.scale) - return [u'scaled', info] + return {u'scaled': info} def __call__(self, value): try: @@ -279,7 +279,7 @@ class ScaledInteger(DataType): return value # return 'actual' value (which is more discrete than a float) def __repr__(self): - hints = self.export_datatype()[1] + hints = self.export_datatype()['scaled'] hints.pop('scale') items = ['%g' % self.scale] for k,v in hints.items(): @@ -322,7 +322,7 @@ class EnumType(DataType): return EnumType(self._enum) def export_datatype(self): - return [u'enum'] + [{u"members":dict((m.name, m.value) for m in self._enum.members)}] + return {u'enum': {u"members":dict((m.name, m.value) for m in self._enum.members)}} def __repr__(self): return u"EnumType(%r, %s)" % (self._enum.name, ', '.join(u'%s=%d' %(m.name, m.value) for m in self._enum.members)) @@ -367,7 +367,7 @@ class BLOBType(DataType): self.default = b'\0' * self.minsize def export_datatype(self): - return [u'blob', dict(min=self.minsize, max=self.maxsize)] + return {u'blob': dict(min=self.minsize, max=self.maxsize)} def __repr__(self): return u'BLOB(%d, %d)' % (self.minsize, self.maxsize) @@ -418,7 +418,7 @@ class StringType(DataType): self.default = u' ' * self.minsize def export_datatype(self): - return [u'string', dict(min=self.minsize, max=self.maxsize)] + return {u'string': dict(min=self.minsize, max=self.maxsize)} def __repr__(self): return u'StringType(%d, %d)' % (self.minsize, self.maxsize) @@ -479,7 +479,7 @@ class BoolType(DataType): default = False def export_datatype(self): - return [u'bool', {}] + return {u'bool': {}} def __repr__(self): return u'BoolType()' @@ -541,8 +541,8 @@ class ArrayOf(DataType): self.default = [members.default] * self.minsize def export_datatype(self): - return [u'array', dict(min=self.minsize, max=self.maxsize, - members=self.members.export_datatype())] + return {u'array': dict(min=self.minsize, max=self.maxsize, + members=self.members.export_datatype())} def __repr__(self): return u'ArrayOf(%s, %s, %s)' % ( @@ -600,7 +600,7 @@ class TupleOf(DataType): self.default = tuple(el.default for el in members) def export_datatype(self): - return [u'tuple', dict(members=[subtype.export_datatype() for subtype in self.members])] + return {u'tuple': dict(members=[subtype.export_datatype() for subtype in self.members])} def __repr__(self): return u'TupleOf(%s)' % u', '.join([repr(st) for st in self.members]) @@ -659,10 +659,10 @@ class StructOf(DataType): self.default = dict((k,el.default) for k, el in members.items()) def export_datatype(self): - res = [u'struct', dict(members=dict((n, s.export_datatype()) - for n, s in list(self.members.items())))] + res = {u'struct': dict(members=dict((n, s.export_datatype()) + for n, s in list(self.members.items())))} if self.optional: - res[1]['optional'] = self.optional + res['struct']['optional'] = self.optional return res def __repr__(self): @@ -728,11 +728,12 @@ class CommandType(DataType): def export_datatype(self): a, r = self.argument, self.result + props = {} if a is not None: - a = a.export_datatype() + props['argument'] = a.export_datatype() if r is not None: - r = r.export_datatype() - return [u'command', dict(argument=a, result=r)] + props['result'] = r.export_datatype() + return {u'command': props} def __repr__(self): argstr = repr(self.argument) if self.argument else '' @@ -875,12 +876,12 @@ DATATYPES = dict( int =lambda min, max, **kwds: IntRange(minval=min, maxval=max, **kwds), scaled =lambda scale, min, max, **kwds: ScaledInteger(scale=scale, minval=min*scale, maxval=max*scale, **kwds), double =lambda min=None, max=None, **kwds: FloatRange(minval=min, maxval=max, **kwds), - blob =lambda min=0, max=None: BLOBType(minsize=min, maxsize=max), - string =lambda min=0, max=None: StringType(minsize=min, maxsize=max), - array =lambda min, max, members: ArrayOf(get_datatype(members), minsize=min, maxsize=max), - tuple =lambda members=[]: TupleOf(*map(get_datatype, members)), - enum =lambda members={}: EnumType('', members=members), - struct =lambda optional=None, members=None: StructOf(optional, + blob =lambda max, min=0: BLOBType(minsize=min, maxsize=max), + string =lambda max, min=0: StringType(minsize=min, maxsize=max), + array =lambda max, members, min=0: ArrayOf(get_datatype(members), minsize=min, maxsize=max), + tuple =lambda members: TupleOf(*map(get_datatype, members)), + enum =lambda members: EnumType('', members=members), + struct =lambda members, optional=None: StructOf(optional, **dict((n, get_datatype(t)) for n, t in list(members.items()))), command = lambda argument=None, result=None: CommandType(get_datatype(argument), get_datatype(result)), ) @@ -894,15 +895,13 @@ def get_datatype(json): """ if json is None: return json - if not isinstance(json, list): - raise BadValueError( - u'Can not interpret datatype %r, it should be a list!' % json) - if len(json) != 2: - raise BadValueError(u'Can not interpret datatype %r, it should be a list of 2 elements!' % json) - base, args = json - if base in DATATYPES: - try: - return DATATYPES[base](**args) - except (TypeError, AttributeError): - raise BadValueError(u'Invalid datatype descriptor in %r' % json) - raise BadValueError(u'can not convert %r to datatype: unknown descriptor!' % json) + if isinstance(json, list) and len(json) == 2: + base, args = json # still allow old syntax + elif isinstance(json, dict) and len(json) == 1: + base, args = tuple(json.items())[0] + else: + raise BadValueError('a data descriptor must be a dict (len=1), not %r' % json) + try: + return DATATYPES[base](**args) + except (TypeError, AttributeError, KeyError): + raise BadValueError(u'invalid data descriptor: %r' % json) diff --git a/secop/protocol/dispatcher.py b/secop/protocol/dispatcher.py index 4371728..e1638cf 100644 --- a/secop/protocol/dispatcher.py +++ b/secop/protocol/dispatcher.py @@ -39,6 +39,7 @@ Interface to the modules: from __future__ import division, print_function import threading +from collections import OrderedDict from time import time as currenttime from secop.errors import SECoPServerError as InternalError @@ -173,21 +174,20 @@ class Dispatcher(object): self.log.debug(u'export_accessibles(%r)' % modulename) if modulename in self._export: # omit export=False params! - res = [] + res = OrderedDict() for aobj in self.get_module(modulename).accessibles.values(): if aobj.export: - res.append([aobj.export, aobj.for_export()]) + res[aobj.export] = aobj.for_export() self.log.debug(u'list accessibles for module %s -> %r' % (modulename, res)) return res self.log.debug(u'-> module is not to be exported!') - return [] + return OrderedDict() def get_descriptive_data(self): """returns a python object which upon serialisation results in the descriptive data""" # XXX: be lazy and cache this? - # format: {[{[{[, specific entries first - result = {u'modules': []} + result = {u'modules': OrderedDict()} for modulename in self._export: module = self.get_module(modulename) if not module.properties.get('export', False): @@ -196,10 +196,10 @@ class Dispatcher(object): mod_desc = {u'accessibles': self.export_accessibles(modulename)} mod_desc.update(module.exportProperties()) mod_desc.pop('export', False) - result[u'modules'].append([modulename, mod_desc]) + result[u'modules'][modulename] = mod_desc result[u'equipment_id'] = self.equipment_id result[u'firmware'] = u'FRAPPY - The Python Framework for SECoP' - result[u'version'] = u'2019.05' + result[u'version'] = u'2019.08' result.update(self.nodeprops) return result diff --git a/secop/protocol/messages.py b/secop/protocol/messages.py index fd27bf9..a9d41fe 100644 --- a/secop/protocol/messages.py +++ b/secop/protocol/messages.py @@ -26,7 +26,7 @@ from __future__ import division, print_function IDENTREQUEST = u'*IDN?' # literal # literal! first part is fixed! -IDENTREPLY = u'SINE2020&ISSE,SECoP,V2019-03-20,v1.0 RC1' +IDENTREPLY = u'SINE2020&ISSE,SECoP,V2019-08-20,v1.0 RC2' DESCRIPTIONREQUEST = u'describe' # literal DESCRIPTIONREPLY = u'describing' # + +json diff --git a/test/test_datatypes.py b/test/test_datatypes.py index 4f1f497..2315f6b 100644 --- a/test/test_datatypes.py +++ b/test/test_datatypes.py @@ -49,7 +49,7 @@ def test_DataType(): def test_FloatRange(): dt = FloatRange(-3.14, 3.14) copytest(dt) - assert dt.export_datatype() == [u'double', {u'min':-3.14, u'max':3.14}] + assert dt.export_datatype() == {u'double': {u'min':-3.14, u'max':3.14}} with pytest.raises(ValueError): dt(9) @@ -68,18 +68,18 @@ def test_FloatRange(): FloatRange(u'x', u'Y') # check that unit can be changed dt.unit = u'K' - assert dt.export_datatype() == [u'double', {u'min':-3.14, u'max':3.14, u'unit': u'K'}] + assert dt.export_datatype() == {u'double': {u'min':-3.14, u'max':3.14, u'unit': u'K'}} dt = FloatRange() copytest(dt) - assert dt.export_datatype() == [u'double', {}] + assert dt.export_datatype() == {u'double': {}} dt = FloatRange(unit=u'X', fmtstr=u'%.2f', absolute_resolution=1, relative_resolution=0.1) copytest(dt) - assert dt.export_datatype() == [u'double', {u'unit':u'X', u'fmtstr':u'%.2f', + assert dt.export_datatype() == {u'double': {u'unit':u'X', u'fmtstr':u'%.2f', u'absolute_resolution':1.0, - u'relative_resolution':0.1}] + u'relative_resolution':0.1}} assert dt(4) == 4 assert dt.format_value(3.14) == u'3.14 X' assert dt.format_value(3.14, u'') == u'3.14' @@ -89,7 +89,7 @@ def test_FloatRange(): def test_IntRange(): dt = IntRange(-3, 3) copytest(dt) - assert dt.export_datatype() == [u'int', {u'min':-3, u'max':3}] + assert dt.export_datatype() == {u'int': {u'min':-3, u'max':3}} with pytest.raises(ValueError): dt(9) @@ -106,16 +106,16 @@ def test_IntRange(): dt = IntRange() copytest(dt) - assert dt.export_datatype()[0] == u'int' - assert dt.export_datatype()[1][u'min'] < 0 < dt.export_datatype()[1][u'max'] - assert dt.export_datatype() == [u'int', {u'max': 16777216, u'min': -16777216}] + assert tuple(dt.export_datatype()) == ('int',) + assert dt.export_datatype()['int'][u'min'] < 0 < dt.export_datatype()['int'][u'max'] + assert dt.export_datatype() == {u'int': {u'max': 16777216, u'min': -16777216}} assert dt.format_value(42) == u'42' def test_ScaledInteger(): dt = ScaledInteger(0.01, -3, 3) copytest(dt) # serialisation of datatype contains limits on the 'integer' value - assert dt.export_datatype() == [u'scaled', {u'scale':0.01, u'min':-300, u'max':300}] + assert dt.export_datatype() == {u'scaled': {u'scale':0.01, u'min':-300, u'max':300}} with pytest.raises(ValueError): dt(9) @@ -135,7 +135,7 @@ def test_ScaledInteger(): ScaledInteger(scale=-10, minval=1, maxval=2) # check that unit can be changed dt.unit = u'A' - assert dt.export_datatype() == [u'scaled', {u'scale':0.01, u'min':-300, u'max':300, u'unit': u'A'}] + assert dt.export_datatype() == {u'scaled': {u'scale':0.01, u'min':-300, u'max':300, u'unit': u'A'}} assert dt.export_value(0.0001) == int(0) assert dt.export_value(2.71819) == int(272) @@ -144,10 +144,10 @@ def test_ScaledInteger(): dt = ScaledInteger(0.003, 0, 1, unit=u'X', fmtstr=u'%.1f', absolute_resolution=0.001, relative_resolution=1e-5) copytest(dt) - assert dt.export_datatype() == [u'scaled', {u'scale':0.003, u'min':0, u'max':333, + assert dt.export_datatype() == {u'scaled': {u'scale':0.003, u'min':0, u'max':333, u'unit':u'X', u'fmtstr':u'%.1f', u'absolute_resolution':0.001, - u'relative_resolution':1e-5}] + u'relative_resolution':1e-5}} assert dt(0.4) == 0.399 assert dt.format_value(0.4) == u'0.4 X' assert dt.format_value(0.4, u'') == u'0.4' @@ -166,7 +166,7 @@ def test_EnumType(): dt = EnumType(u'dt', a=3, c=7, stuff=1) copytest(dt) - assert dt.export_datatype() == [u'enum', dict(members=dict(a=3, c=7, stuff=1))] + assert dt.export_datatype() == {u'enum': dict(members=dict(a=3, c=7, stuff=1))} with pytest.raises(ValueError): dt(9) @@ -201,14 +201,14 @@ def test_BLOBType(): # test constructor catching illegal arguments dt = BLOBType() copytest(dt) - assert dt.export_datatype() == [u'blob', {u'min':0, u'max':255}] + assert dt.export_datatype() == {u'blob': {u'min':0, u'max':255}} dt = BLOBType(10) copytest(dt) - assert dt.export_datatype() == [u'blob', {u'min':10, u'max':10}] + assert dt.export_datatype() == {u'blob': {u'min':10, u'max':10}} dt = BLOBType(3, 10) copytest(dt) - assert dt.export_datatype() == [u'blob', {u'min':3, u'max':10}] + assert dt.export_datatype() == {u'blob': {u'min':3, u'max':10}} with pytest.raises(ValueError): dt(9) @@ -235,11 +235,11 @@ def test_StringType(): copytest(dt) dt = StringType(12) copytest(dt) - assert dt.export_datatype() == [u'string', {u'min':12, u'max':12}] + assert dt.export_datatype() == {u'string': {u'min':12, u'max':12}} dt = StringType(4, 11) copytest(dt) - assert dt.export_datatype() == [u'string', {u'min':4, u'max':11}] + assert dt.export_datatype() == {u'string': {u'min':4, u'max':11}} with pytest.raises(ValueError): dt(9) @@ -264,7 +264,8 @@ def test_StringType(): def test_TextType(): # test constructor catching illegal arguments dt = TextType(12) - assert dt.export_datatype() == [u'string', {u'min':0, u'max':12}] + copytest(dt) + assert dt.export_datatype() == {u'string': {u'min':0, u'max':12}} with pytest.raises(ValueError): dt(9) @@ -286,7 +287,7 @@ def test_BoolType(): # test constructor catching illegal arguments dt = BoolType() copytest(dt) - assert dt.export_datatype() == [u'bool', {}] + assert dt.export_datatype() == {u'bool': {}} with pytest.raises(ValueError): dt(9) @@ -318,16 +319,16 @@ def test_ArrayOf(): ArrayOf(-3, IntRange(-10,10)) dt = ArrayOf(IntRange(-10, 10), 5) copytest(dt) - assert dt.export_datatype() == [u'array', {u'min':5, u'max':5, - u'members':[u'int', {u'min':-10, - u'max':10}]}] + assert dt.export_datatype() == {u'array': {u'min':5, u'max':5, + u'members':{u'int': {u'min':-10, + u'max':10}}}} dt = ArrayOf(FloatRange(-10, 10, unit=u'Z'), 1, 3) copytest(dt) - assert dt.export_datatype() == [u'array', {u'min':1, u'max':3, - u'members':[u'double', {u'min':-10, + assert dt.export_datatype() == {u'array': {u'min':1, u'max':3, + u'members':{u'double': {u'min':-10, u'max':10, - u'unit':u'Z'}]}] + u'unit':u'Z'}}}} with pytest.raises(ValueError): dt(9) with pytest.raises(ValueError): @@ -350,9 +351,9 @@ def test_TupleOf(): dt = TupleOf(IntRange(-10, 10), BoolType()) copytest(dt) - assert dt.export_datatype() == [u'tuple', {u'members':[[u'int', {u'min':-10, - u'max':10}], - [u'bool', {}]]}] + assert dt.export_datatype() == {u'tuple': {u'members':[{u'int': {u'min':-10, + u'max':10}}, + {u'bool': {}}]}} with pytest.raises(ValueError): dt(9) @@ -377,12 +378,12 @@ def test_StructOf(): dt = StructOf(a_string=StringType(0, 55), an_int=IntRange(0, 999), optional=[u'an_int']) copytest(dt) - assert dt.export_datatype() == [u'struct', {u'members':{u'a_string': - [u'string', {u'min':0, u'max':55}], + assert dt.export_datatype() == {u'struct': {u'members':{u'a_string': + {u'string': {u'min':0, u'max':55}}, u'an_int': - [u'int', {u'min':0, u'max':999}],}, + {u'int': {u'min':0, u'max':999}},}, u'optional':[u'an_int'], - }] + }} with pytest.raises(ValueError): dt(9) @@ -403,14 +404,14 @@ def test_StructOf(): def test_Command(): dt = CommandType() - assert dt.export_datatype() == [u'command', {u'argument':None, u'result':None}] + assert dt.export_datatype() == {u'command': {}} dt = CommandType(IntRange(-1,1)) - assert dt.export_datatype() == [u'command', {u'argument':[u'int', {u'min':-1, u'max':1}], u'result':None}] + assert dt.export_datatype() == {u'command': {u'argument':{u'int': {u'min':-1, u'max':1}}}} dt = CommandType(IntRange(-1,1), IntRange(-3,3)) - assert dt.export_datatype() == [u'command', {u'argument':[u'int', {u'min':-1, u'max':1}], - u'result':[u'int', {u'min':-3, u'max':3}]}] + assert dt.export_datatype() == {u'command': {u'argument':{u'int': {u'min':-1, u'max':1}}, + u'result':{u'int': {u'min':-3, u'max':3}}}} def test_get_datatype(): @@ -421,148 +422,146 @@ def test_get_datatype(): with pytest.raises(ValueError): get_datatype(str) with pytest.raises(ValueError): - get_datatype([u'undefined']) + get_datatype({u'undefined': {}}) - assert isinstance(get_datatype([u'bool', {}]), BoolType) + assert isinstance(get_datatype({u'bool': {}}), BoolType) with pytest.raises(ValueError): get_datatype([u'bool']) with pytest.raises(ValueError): - get_datatype([u'bool', 3]) + get_datatype({u'bool': 3}) with pytest.raises(ValueError): - get_datatype([u'int', {u'min':-10}]) + get_datatype({u'int': {u'min':-10}}) with pytest.raises(ValueError): - get_datatype([u'int', {u'max':10}]) - assert isinstance(get_datatype([u'int', {u'min':-10, u'max':10}]), IntRange) + get_datatype({u'int': {u'max':10}}) + assert isinstance(get_datatype({u'int': {u'min':-10, u'max':10}}), IntRange) with pytest.raises(ValueError): - get_datatype([u'int', {u'min':10, u'max':-10}]) + get_datatype({u'int': {u'min':10, u'max':-10}}) with pytest.raises(ValueError): get_datatype([u'int']) with pytest.raises(ValueError): - get_datatype([u'int', {}]) + get_datatype({u'int': {}}) with pytest.raises(ValueError): - get_datatype([u'int', 1, 2]) + get_datatype({u'int': 1, u'x': 2}) - assert isinstance(get_datatype([u'double', {}]), FloatRange) - assert isinstance(get_datatype([u'double', {u'min':-2.718}]), FloatRange) - assert isinstance(get_datatype([u'double', {u'max':3.14}]), FloatRange) - assert isinstance(get_datatype([u'double', {u'min':-9.9, u'max':11.1}]), + assert isinstance(get_datatype({u'double': {}}), FloatRange) + assert isinstance(get_datatype({u'double': {u'min':-2.718}}), FloatRange) + assert isinstance(get_datatype({u'double': {u'max':3.14}}), FloatRange) + assert isinstance(get_datatype({u'double': {u'min':-9.9, u'max':11.1}}), FloatRange) with pytest.raises(ValueError): get_datatype([u'double']) with pytest.raises(ValueError): - get_datatype([u'double', {u'min':10, u'max':-10}]) + get_datatype({u'double': {u'min':10, u'max':-10}}) with pytest.raises(ValueError): - get_datatype([u'double', 1, 2]) + get_datatype({u'double': {}, u'x': 2}) with pytest.raises(ValueError): - get_datatype([u'scaled', {u'scale':0.01,u'min':-2.718}]) + get_datatype({u'scaled': {u'scale':0.01,u'min':-2.718}}) with pytest.raises(ValueError): - get_datatype([u'scaled', {u'scale':0.02,u'max':3.14}]) - assert isinstance(get_datatype([u'scaled', {u'scale':0.03, + get_datatype({u'scaled': {u'scale':0.02,u'max':3.14}}) + assert isinstance(get_datatype({u'scaled': {u'scale':0.03, u'min':-99, - u'max':111}]), ScaledInteger) + u'max':111}}), ScaledInteger) dt = ScaledInteger(scale=0.03, minval=0, maxval=9.9) - assert dt.export_datatype() == [u'scaled', {u'max':330, u'min':0, u'scale':0.03}] + assert dt.export_datatype() == {u'scaled': {u'max':330, u'min':0, u'scale':0.03}} assert get_datatype(dt.export_datatype()).export_datatype() == dt.export_datatype() with pytest.raises(ValueError): get_datatype([u'scaled']) # dict missing with pytest.raises(ValueError): - get_datatype([u'scaled', {u'min':-10, u'max':10}]) # no scale + get_datatype({u'scaled': {u'min':-10, u'max':10}}) # no scale with pytest.raises(ValueError): - get_datatype([u'scaled', {u'min':10, u'max':-10}]) # limits reversed + get_datatype({u'scaled': {u'min':10, u'max':-10}}) # limits reversed with pytest.raises(ValueError): - get_datatype([u'scaled', {}, 1, 2]) # trailing data + get_datatype({u'scaled': {u'min':10, u'max':-10, u'x': 2}}) with pytest.raises(ValueError): get_datatype([u'enum']) with pytest.raises(ValueError): - get_datatype([u'enum', dict(a=-2)]) - assert isinstance(get_datatype([u'enum', {u'members':dict(a=-2)}]), EnumType) + get_datatype({u'enum': dict(a=-2)}) + assert isinstance(get_datatype({u'enum': {u'members':dict(a=-2)}}), EnumType) with pytest.raises(ValueError): - get_datatype([u'enum', 10, -10]) - with pytest.raises(ValueError): - get_datatype([u'enum', [1, 2, 3]]) + get_datatype({u'enum': dict(a=-2), u'x': 1}) - assert isinstance(get_datatype([u'blob', {u'max':1}]), BLOBType) - assert isinstance(get_datatype([u'blob', {u'min':1, u'max':10}]), BLOBType) + assert isinstance(get_datatype({u'blob': {u'max':1}}), BLOBType) + assert isinstance(get_datatype({u'blob': {u'min':1, u'max':10}}), BLOBType) with pytest.raises(ValueError): - get_datatype([u'blob', {u'min':10, u'max':1}]) + get_datatype({u'blob': {u'min':10, u'max':1}}) with pytest.raises(ValueError): - get_datatype([u'blob', {u'min':10, u'max':-10}]) + get_datatype({u'blob': {u'min':10, u'max':-10}}) with pytest.raises(ValueError): - get_datatype([u'blob', 10, -10, 1]) + get_datatype({u'blob': {u'min':10, u'max':-10}, u'x': 0}) with pytest.raises(ValueError): get_datatype([u'string']) - assert isinstance(get_datatype([u'string', {u'min':1}]), StringType) - assert isinstance(get_datatype([u'string', {u'min':1, u'max':10}]), StringType) + assert isinstance(get_datatype({u'string': {u'max':1}}), StringType) + assert isinstance(get_datatype({u'string': {u'min':1, u'max':10}}), StringType) with pytest.raises(ValueError): - get_datatype([u'string', {u'min':10, u'max':1}]) + get_datatype({u'string': {u'min':10, u'max':1}}) with pytest.raises(ValueError): - get_datatype([u'string', {u'min':10, u'max':-10}]) + get_datatype({u'string': {u'min':10, u'max':-10}}) with pytest.raises(ValueError): - get_datatype([u'string', 10, -10, 1]) + get_datatype({u'string': {u'min':10, u'max':-10, u'x': 0}}) with pytest.raises(ValueError): get_datatype([u'array']) with pytest.raises(ValueError): - get_datatype([u'array', 1]) + get_datatype({u'array': 1}) with pytest.raises(ValueError): - get_datatype([u'array', [1], 2, 3]) - assert isinstance(get_datatype([u'array', {u'min':1, u'max':1, - u'members':[u'blob', {u'max':1}]}] + get_datatype({u'array': [1]}) + assert isinstance(get_datatype({u'array': {u'min':1, u'max':1, + u'members':{u'blob': {u'max':1}}}} ), ArrayOf) - assert isinstance(get_datatype([u'array', {u'min':1, u'max':1, - u'members':[u'blob', {u'max':1}]}] + assert isinstance(get_datatype({u'array': {u'min':1, u'max':1, + u'members':{u'blob': {u'max':1}}}} ).members, BLOBType) with pytest.raises(ValueError): - get_datatype([u'array', {u'members':[u'blob', {u'max':1}], u'min':-10}]) + get_datatype({u'array': {u'members':{u'blob': {u'max':1}}, u'min':-10}}) with pytest.raises(ValueError): - get_datatype([u'array', {u'members':[u'blob', {u'max':1}], - u'min':10, 'max':1}]) + get_datatype({u'array': {u'members':{u'blob': {u'max':1}}, + u'min':10, 'max':1}}) with pytest.raises(ValueError): - get_datatype([u'array', [u'blob', 1], 10, -10]) + get_datatype({u'array': {u'blob': dict(max=4)}, u'max': 10}) with pytest.raises(ValueError): get_datatype([u'tuple']) with pytest.raises(ValueError): - get_datatype([u'tuple', 1]) + get_datatype({u'tuple': 1}) with pytest.raises(ValueError): get_datatype([u'tuple', [1], 2, 3]) - assert isinstance(get_datatype([u'tuple', {u'members':[[u'blob', - {u'max':1}]]}]), TupleOf) - assert isinstance(get_datatype([u'tuple', {u'members':[[u'blob', - {u'max':1}]]}]).members[0], BLOBType) + assert isinstance(get_datatype({u'tuple': {u'members':[{u'blob': + {u'max':1}}]}}), TupleOf) + assert isinstance(get_datatype({u'tuple': {u'members':[{u'blob': + {u'max':1}}]}}).members[0], BLOBType) with pytest.raises(ValueError): - get_datatype([u'tuple', {}]) + get_datatype({u'tuple': {}}) with pytest.raises(ValueError): get_datatype([u'tuple', 10, -10]) - assert isinstance(get_datatype([u'tuple', {u'members':[[u'blob', {u'max':1}], - [u'bool',{}]]}]), TupleOf) + assert isinstance(get_datatype({u'tuple': {u'members':[{u'blob': {u'max':1}}, + {u'bool':{}}]}}), TupleOf) with pytest.raises(ValueError): get_datatype([u'struct']) with pytest.raises(ValueError): - get_datatype([u'struct', 1]) + get_datatype({u'struct': 1}) with pytest.raises(ValueError): get_datatype([u'struct', [1], 2, 3]) - assert isinstance(get_datatype([u'struct', {u'members': - {u'name': [u'blob', {u'max':1}]}}]), StructOf) - assert isinstance(get_datatype([u'struct', {u'members': - {u'name': [u'blob', {u'max':1}]}}]).members[u'name'], BLOBType) + assert isinstance(get_datatype({u'struct': {u'members': + {u'name': {u'blob': {u'max':1}}}}}), StructOf) + assert isinstance(get_datatype({u'struct': {u'members': + {u'name': {u'blob': {u'max':1}}}}}).members[u'name'], BLOBType) with pytest.raises(ValueError): - get_datatype([u'struct', {}]) + get_datatype({u'struct': {}}) with pytest.raises(ValueError): - get_datatype([u'struct', {u'members':[1,2,3]}]) + get_datatype({u'struct': {u'members':[1,2,3]}}) diff --git a/test/test_params.py b/test/test_params.py index a3f8f09..a80bff9 100644 --- a/test/test_params.py +++ b/test/test_params.py @@ -36,18 +36,18 @@ def test_Command(): assert cmd.ctr assert cmd.argument is None assert cmd.result is None - assert cmd.for_export() == {u'datatype': [u'command', {u'argument': None, u'result': None}], + assert cmd.for_export() == {u'datatype': {u'command': {}}, u'description': u'do_something'} cmd = Command(u'do_something', argument=IntRange(-9,9), result=IntRange(-1,1)) assert cmd.description assert isinstance(cmd.argument, IntRange) assert isinstance(cmd.result, IntRange) - assert cmd.for_export() == {u'datatype': [u'command', {u'argument': [u'int', {u'min':-9, u'max':9}], - u'result': [u'int', {u'min':-1, u'max':1}]}], + assert cmd.for_export() == {u'datatype': {u'command': {u'argument': {u'int': {u'min':-9, u'max':9}}, + u'result': {u'int': {u'min':-1, u'max':1}}}}, u'description': u'do_something'} - assert cmd.exportProperties() == {u'datatype': [u'command', {u'argument': [u'int', {u'max': 9, u'min': -9}], - u'result': [u'int', {u'max': 1, u'min': -1}]}], + assert cmd.exportProperties() == {u'datatype': {u'command': {u'argument': {u'int': {u'max': 9, u'min': -9}}, + u'result': {u'int': {u'max': 1, u'min': -1}}}}, u'description': u'do_something'}