fix missing import in change message
Transported values in a change must be converted first. As this is only relevant for the exotic "scaled" and "blob" datatypes, this was not detected yet. - add tests - suppress warning PytestUnhandledThreadExceptionWarning in tests + change import_value methods to raise no other exceptions than WrongTypeError and RangeError + simplify Command.do: as import_value already raises the appropriate error, no more try/except is needed Change-Id: I299e511468dc0fcecff4c20cf8a917da38b70786 Reviewed-on: https://forge.frm2.tum.de/review/c/secop/frappy/+/32743 Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de> Reviewed-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de> Reviewed-by: Alexander Zaft <a.zaft@fz-juelich.de> Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
This commit is contained in:
@@ -105,7 +105,7 @@ class DataType(HasProperties):
|
||||
note: for importing from gui/configfile/commandline use :meth:`from_string`
|
||||
instead.
|
||||
"""
|
||||
return value
|
||||
return self(value)
|
||||
|
||||
def format_value(self, value, unit=None):
|
||||
"""format a value of this type into a str string
|
||||
@@ -259,10 +259,6 @@ class FloatRange(HasUnit, DataType):
|
||||
"""returns a python object fit for serialisation"""
|
||||
return float(value)
|
||||
|
||||
def import_value(self, value):
|
||||
"""returns a python object from serialisation"""
|
||||
return float(value)
|
||||
|
||||
def from_string(self, text):
|
||||
value = float(text)
|
||||
return self(value)
|
||||
@@ -341,10 +337,6 @@ class IntRange(DataType):
|
||||
"""returns a python object fit for serialisation"""
|
||||
return int(value)
|
||||
|
||||
def import_value(self, value):
|
||||
"""returns a python object from serialisation"""
|
||||
return int(value)
|
||||
|
||||
def from_string(self, text):
|
||||
value = int(text)
|
||||
return self(value)
|
||||
@@ -461,7 +453,10 @@ class ScaledInteger(HasUnit, DataType):
|
||||
|
||||
def import_value(self, value):
|
||||
"""returns a python object from serialisation"""
|
||||
return self.scale * int(value)
|
||||
try:
|
||||
return self.scale * int(value)
|
||||
except Exception:
|
||||
raise WrongTypeError(f'can not import {shortrepr(value)} to scaled') from None
|
||||
|
||||
def from_string(self, text):
|
||||
value = float(text)
|
||||
@@ -513,10 +508,6 @@ class EnumType(DataType):
|
||||
"""returns a python object fit for serialisation"""
|
||||
return int(self(value))
|
||||
|
||||
def import_value(self, value):
|
||||
"""returns a python object from serialisation"""
|
||||
return self(value)
|
||||
|
||||
def __call__(self, value):
|
||||
"""accepts integers and strings, converts to EnumMember (may be used like an int)"""
|
||||
try:
|
||||
@@ -588,7 +579,10 @@ class BLOBType(DataType):
|
||||
|
||||
def import_value(self, value):
|
||||
"""returns a python object from serialisation"""
|
||||
return b64decode(value)
|
||||
try:
|
||||
return b64decode(value)
|
||||
except Exception:
|
||||
raise WrongTypeError(f'can not b64decode {shortrepr(value)}') from None
|
||||
|
||||
def from_string(self, text):
|
||||
value = text
|
||||
@@ -659,10 +653,6 @@ class StringType(DataType):
|
||||
"""returns a python object fit for serialisation"""
|
||||
return f'{value}'
|
||||
|
||||
def import_value(self, value):
|
||||
"""returns a python object from serialisation"""
|
||||
return str(value)
|
||||
|
||||
def from_string(self, text):
|
||||
value = str(text)
|
||||
return self(value)
|
||||
@@ -723,10 +713,6 @@ class BoolType(DataType):
|
||||
"""returns a python object fit for serialisation"""
|
||||
return self(value)
|
||||
|
||||
def import_value(self, value):
|
||||
"""returns a python object from serialisation"""
|
||||
return self(value)
|
||||
|
||||
def from_string(self, text):
|
||||
value = text
|
||||
return self(value)
|
||||
|
||||
@@ -499,7 +499,7 @@ class Command(Accessible):
|
||||
"""perform function call
|
||||
|
||||
:param module_obj: the module on which the command is to be executed
|
||||
:param argument: the argument from the do command
|
||||
:param argument: the argument from the do command (transported value!)
|
||||
:returns: the return value converted to the result type
|
||||
|
||||
- when the argument type is TupleOf, the function is called with multiple arguments
|
||||
@@ -514,13 +514,9 @@ class Command(Accessible):
|
||||
f'{module_obj.__class__.__name__}.{self.name} needs an'
|
||||
f' argument of type {self.argument}!'
|
||||
)
|
||||
try:
|
||||
argument = self.argument.import_value(argument)
|
||||
except TypeError:
|
||||
pass # validate will raise appropriate message
|
||||
except ValueError:
|
||||
pass # validate will raise appropriate message
|
||||
|
||||
# convert transported value to internal value
|
||||
argument = self.argument.import_value(argument)
|
||||
# verify range
|
||||
self.argument.validate(argument)
|
||||
if isinstance(self.argument, TupleOf):
|
||||
res = func(*argument)
|
||||
|
||||
@@ -162,7 +162,9 @@ class Dispatcher:
|
||||
if pobj.readonly:
|
||||
raise ReadOnlyError(f"Parameter {modulename}:{pname} can not be changed remotely")
|
||||
|
||||
# validate!
|
||||
# convert transported value to internal value
|
||||
value = pobj.datatype.import_value(value)
|
||||
# verify range
|
||||
value = pobj.datatype.validate(value, previous=pobj.value)
|
||||
# note: exceptions are handled in handle_request, not here!
|
||||
getattr(moduleobj, 'write_' + pname)(value)
|
||||
|
||||
Reference in New Issue
Block a user