change FloatRange arguments minval/maxval to min/max

in the previous version FloatRange(max=100) was neither working
properly nor complaining, because the maxval=None default was
overriding the value for max.

possible fixes:
  - raise an error when min/max used as argument (confusing for
    the programmer, as it is a property)
  - allow both versions minval/maxval and min/max (more code)
  - use min/max and a pylint directive here (the only thing to
    take care is not to use the min/max builtin in __init__)

this change uses the last option for the fix

Change-Id: Iff0e0c4d0d7b165003bdeffa67a93a1cd7f29eea
Reviewed-on: https://forge.frm2.tum.de/review/c/secop/frappy/+/31982
Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de>
Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
This commit is contained in:
zolliker 2023-08-18 09:29:32 +02:00
parent 5359f0351f
commit bce88ff343
2 changed files with 25 additions and 24 deletions

View File

@ -191,8 +191,8 @@ class HasUnit:
class FloatRange(HasUnit, DataType): class FloatRange(HasUnit, DataType):
"""(restricted) float type """(restricted) float type
:param minval: (property **min**) :param min: (property **min**)
:param maxval: (property **max**) :param max: (property **max**)
:param kwds: any of the properties below :param kwds: any of the properties below
""" """
min = Property('low limit', Stub('FloatRange'), extname='min', default=-sys.float_info.max) min = Property('low limit', Stub('FloatRange'), extname='min', default=-sys.float_info.max)
@ -203,11 +203,11 @@ class FloatRange(HasUnit, DataType):
relative_resolution = Property('relative resolution', Stub('FloatRange', 0), relative_resolution = Property('relative resolution', Stub('FloatRange', 0),
extname='relative_resolution', default=1.2e-7) extname='relative_resolution', default=1.2e-7)
def __init__(self, minval=None, maxval=None, **kwds): def __init__(self, min=None, max=None, **kwds): # pylint: disable=redefined-builtin
super().__init__() super().__init__()
kwds['min'] = minval if minval is not None else -sys.float_info.max self.set_properties(min=min if min is not None else -sys.float_info.max,
kwds['max'] = maxval if maxval is not None else sys.float_info.max max=max if max is not None else sys.float_info.max,
self.set_properties(**kwds) **kwds)
def checkProperties(self): def checkProperties(self):
self.default = 0 if self.min <= 0 <= self.max else self.min self.default = 0 if self.min <= 0 <= self.max else self.min
@ -247,9 +247,9 @@ class FloatRange(HasUnit, DataType):
def __repr__(self): def __repr__(self):
hints = self.get_info() hints = self.get_info()
if 'min' in hints: if 'min' in hints:
hints['minval'] = hints.pop('min') hints['min'] = hints.pop('min')
if 'max' in hints: if 'max' in hints:
hints['maxval'] = hints.pop('max') hints['max'] = hints.pop('max')
return 'FloatRange(%s)' % (', '.join('%s=%r' % (k, v) for k, v in hints.items())) return 'FloatRange(%s)' % (', '.join('%s=%r' % (k, v) for k, v in hints.items()))
def export_value(self, value): def export_value(self, value):
@ -281,18 +281,18 @@ class FloatRange(HasUnit, DataType):
class IntRange(DataType): class IntRange(DataType):
"""restricted int type """restricted int type
:param minval: (property **min**) :param min: (property **min**)
:param maxval: (property **max**) :param max: (property **max**)
""" """
min = Property('minimum value', Stub('IntRange', -UNLIMITED, UNLIMITED), extname='min', mandatory=True) min = Property('minimum value', Stub('IntRange', -UNLIMITED, UNLIMITED), extname='min', mandatory=True)
max = Property('maximum value', Stub('IntRange', -UNLIMITED, UNLIMITED), extname='max', mandatory=True) max = Property('maximum value', Stub('IntRange', -UNLIMITED, UNLIMITED), extname='max', mandatory=True)
# a unit on an int is now allowed in SECoP, but do we need them in Frappy? # a unit on an int is now allowed in SECoP, but do we need them in Frappy?
# unit = Property('physical unit', StringType(), extname='unit', default='') # unit = Property('physical unit', StringType(), extname='unit', default='')
def __init__(self, minval=None, maxval=None): def __init__(self, min=None, max=None): # pylint: disable=redefined-builtin
super().__init__() super().__init__()
self.set_properties(min=DEFAULT_MIN_INT if minval is None else minval, self.set_properties(min=DEFAULT_MIN_INT if min is None else min,
max=DEFAULT_MAX_INT if maxval is None else maxval) max=DEFAULT_MAX_INT if max is None else max)
def checkProperties(self): def checkProperties(self):
self.default = 0 if self.min <= 0 <= self.max else self.min self.default = 0 if self.min <= 0 <= self.max else self.min
@ -364,8 +364,8 @@ class IntRange(DataType):
class ScaledInteger(HasUnit, DataType): class ScaledInteger(HasUnit, DataType):
"""scaled integer (= fixed resolution float) type """scaled integer (= fixed resolution float) type
:param minval: (property **min**) :param min: (property **min**)
:param maxval: (property **max**) :param max: (property **max**)
:param kwds: any of the properties below :param kwds: any of the properties below
note: limits are for the scaled float value note: limits are for the scaled float value
@ -380,7 +380,8 @@ class ScaledInteger(HasUnit, DataType):
relative_resolution = Property('relative resolution', FloatRange(0), relative_resolution = Property('relative resolution', FloatRange(0),
extname='relative_resolution', default=1.2e-7) extname='relative_resolution', default=1.2e-7)
def __init__(self, scale, minval=None, maxval=None, absolute_resolution=None, **kwds): # pylint: disable=redefined-builtin
def __init__(self, scale, min=None, max=None, absolute_resolution=None, **kwds):
super().__init__() super().__init__()
try: try:
scale = float(scale) scale = float(scale)
@ -390,8 +391,8 @@ class ScaledInteger(HasUnit, DataType):
absolute_resolution = scale absolute_resolution = scale
self.set_properties( self.set_properties(
scale=scale, scale=scale,
min=DEFAULT_MIN_INT * scale if minval is None else float(minval), min=DEFAULT_MIN_INT * scale if min is None else float(min),
max=DEFAULT_MAX_INT * scale if maxval is None else float(maxval), max=DEFAULT_MAX_INT * scale if max is None else float(max),
absolute_resolution=absolute_resolution, absolute_resolution=absolute_resolution,
**kwds) **kwds)
@ -1327,11 +1328,11 @@ DATATYPES = {
'bool': lambda **kwds: 'bool': lambda **kwds:
BoolType(), BoolType(),
'int': lambda min, max, **kwds: 'int': lambda min, max, **kwds:
IntRange(minval=min, maxval=max), IntRange(min=min, max=max),
'scaled': lambda scale, min, max, **kwds: 'scaled': lambda scale, min, max, **kwds:
ScaledInteger(scale=scale, minval=min*scale, maxval=max*scale, **floatargs(kwds)), ScaledInteger(scale=scale, min=min*scale, max=max*scale, **floatargs(kwds)),
'double': lambda min=None, max=None, **kwds: 'double': lambda min=None, max=None, **kwds:
FloatRange(minval=min, maxval=max, **floatargs(kwds)), FloatRange(min=min, max=max, **floatargs(kwds)),
'blob': lambda maxbytes, minbytes=0, **kwds: 'blob': lambda maxbytes, minbytes=0, **kwds:
BLOBType(minbytes=minbytes, maxbytes=maxbytes), BLOBType(minbytes=minbytes, maxbytes=maxbytes),
'string': lambda minchars=0, maxchars=None, isUTF8=False, **kwds: 'string': lambda minchars=0, maxchars=None, isUTF8=False, **kwds:

View File

@ -160,9 +160,9 @@ def test_ScaledInteger():
with pytest.raises(ProgrammingError): with pytest.raises(ProgrammingError):
ScaledInteger('xc', 'Yx') ScaledInteger('xc', 'Yx')
with pytest.raises(ProgrammingError): with pytest.raises(ProgrammingError):
ScaledInteger(scale=0, minval=1, maxval=2) ScaledInteger(scale=0, min=1, max=2)
with pytest.raises(ProgrammingError): with pytest.raises(ProgrammingError):
ScaledInteger(scale=-10, minval=1, maxval=2) ScaledInteger(scale=-10, min=1, max=2)
# check that unit can be changed # check that unit can be changed
dt.setProperty('unit', 'A') dt.setProperty('unit', 'A')
assert dt.export_datatype() == {'type': 'scaled', 'scale':0.01, 'min':-300, 'max':300, assert dt.export_datatype() == {'type': 'scaled', 'scale':0.01, 'min':-300, 'max':300,
@ -563,7 +563,7 @@ def test_get_datatype():
assert isinstance(get_datatype( assert isinstance(get_datatype(
{'type': 'scaled', 'scale':0.03, 'min':-99, 'max':111}), ScaledInteger) {'type': 'scaled', 'scale':0.03, 'min':-99, 'max':111}), ScaledInteger)
dt = ScaledInteger(scale=0.03, minval=0, maxval=9.9) dt = ScaledInteger(scale=0.03, min=0, max=9.9)
assert dt.export_datatype() == {'type': 'scaled', 'max':330, 'min':0, 'scale':0.03} assert dt.export_datatype() == {'type': 'scaled', 'max':330, 'min':0, 'scale':0.03}
assert get_datatype(dt.export_datatype()).export_datatype() == dt.export_datatype() assert get_datatype(dt.export_datatype()).export_datatype() == dt.export_datatype()