update 2023-05-30 from gitmlz

Change-Id: I0b1eb2941692fde5c9d98f107fc38315625dcfdb
This commit is contained in:
zolliker 2023-05-31 14:16:12 +02:00
parent dc0cc590ed
commit 37d28c9f35
8 changed files with 111 additions and 11 deletions

73
debian/changelog vendored
View File

@ -1,3 +1,76 @@
frappy-core (0.17.11) focal; urgency=medium
[ Alexander Zaft ]
* Add __format__ to EnumMember
[ Markus Zolliker ]
* fix error from manual %-format conversion
[ Alexander Zaft ]
* specify minimum pyqt5 version
[ Markus Zolliker ]
* make io device visible as expert by default
[ Jens Krüger ]
* MLZ/Entangle: Fix formatting issues
[ Markus Zolliker ]
* improve error handling on callbacks
* fix issues with lakeshore 370
* frappy_psi: two small fixes in k2601b/ppmssim
* a playground for debugging drivers
* issues with StructOf
* improve mercury temperature loop
* improve interactive client
[ Jens Krüger ]
* Server: add missing 'restart_hook' missing
* MLZ/Entangle: Add unit init in AnalogOutput
* MLZ/Entangle: Fix user limits handling
[ Alexander Zaft ]
* Improve address and connection handling
* Add Stopgap handling of cfg files in cfg-editor
[ Markus Zolliker ]
* fix in frappy_psi.historywriter
* improve mercury driver
* driver for the triton dilution refrigerator
* fixes on HasConvergence and HasOutputModule
* improve and fix errors with parameter limits
* add HasOffset feature
[ Alexander Zaft ]
* Fix interface class list
[ Markus Zolliker ]
* mixins should not inherit Module
* fix interplay mercury.TemperatureLoop and HasConvergence
[ Alexander Zaft ]
* Fix lower limit checking of FloatRange
[ Markus Zolliker ]
* improve traceback while processing config file
* driver for mercury IPS
* add sea driver
[ Georg Brandl ]
* debian: add new executable
[ Markus Zolliker ]
* move more code from bin/frappy-cli to frappy/client/interactive.py
* add unit=s to pollinterval
* client.interactive: fix error when interface_classes empty
* phytron motor driver
* client: timestamps must never lie in the future
[ Alexander Zaft ]
* Fix rstrip misuse in frappy-generator
-- Alexander Zaft <jenkins@frm2.tum.de> Thu, 25 May 2023 09:38:24 +0200
frappy-core (0.17.10) focal; urgency=medium frappy-core (0.17.10) focal; urgency=medium
* Change leftover %-logging calls to lazy * Change leftover %-logging calls to lazy

View File

@ -1,5 +1,6 @@
usr/bin/frappy-cli usr/bin/frappy-cli
usr/bin/frappy-server usr/bin/frappy-server
usr/bin/frappy-play
usr/lib/python3.*/dist-packages/frappy/*.py usr/lib/python3.*/dist-packages/frappy/*.py
usr/lib/python3.*/dist-packages/frappy/lib usr/lib/python3.*/dist-packages/frappy/lib
usr/lib/python3.*/dist-packages/frappy/client usr/lib/python3.*/dist-packages/frappy/client

View File

@ -39,7 +39,7 @@ def main():
frappy_unit = '/lib/systemd/system/frappy@.service' frappy_unit = '/lib/systemd/system/frappy@.service'
wants_dir = normal_dir + '/frappy.target.wants' wants_dir = normal_dir + '/frappy.target.wants'
all_servers = [base.rstrip('_cfg') for (base, ext) in all_servers = [base[:-4] if base.endswith('_cfg') else base for (base, ext) in
map(path.splitext, os.listdir(config_dir)) if ext == '.py'] map(path.splitext, os.listdir(config_dir)) if ext == '.py']
all_servers.sort() all_servers.sort()

View File

@ -22,10 +22,12 @@
import os import os
import re import re
from collections import Counter
from frappy.errors import ConfigError from frappy.errors import ConfigError
from frappy.lib import generalConfig from frappy.lib import generalConfig
class Undef: class Undef:
pass pass
@ -126,7 +128,7 @@ class Config(dict):
self.modules.append(mod) self.modules.append(mod)
def process_file(filename): def process_file(filename, log):
with open(filename, 'rb') as f: with open(filename, 'rb') as f:
config_text = f.read() config_text = f.read()
node = NodeCollector() node = NodeCollector()
@ -135,6 +137,13 @@ def process_file(filename):
# pylint: disable=exec-used # pylint: disable=exec-used
exec(compile(config_text, filename, 'exec'), ns) exec(compile(config_text, filename, 'exec'), ns)
# check for duplicates in the file itself. Between files comes later
duplicates = [name for name, count in Counter([mod['name']
for mod in mods.list]).items() if count > 1]
if duplicates:
log.warning('Duplicate module name in file \'%s\': %s',
filename, ','.join(duplicates))
return Config(node, mods) return Config(node, mods)
@ -177,7 +186,7 @@ def load_config(cfgfiles, log):
for cfgfile in cfgfiles.split(','): for cfgfile in cfgfiles.split(','):
filename = to_config_path(cfgfile, log) filename = to_config_path(cfgfile, log)
log.debug('Parsing config file %s...', filename) log.debug('Parsing config file %s...', filename)
cfg = process_file(filename) cfg = process_file(filename, log)
if config: if config:
config.merge_modules(cfg) config.merge_modules(cfg)
else: else:

View File

@ -405,8 +405,4 @@ def merge_status(*args):
texts matching maximal code are joined with ', ' texts matching maximal code are joined with ', '
""" """
maxcode = max(a[0] for a in args) maxcode = max(a[0] for a in args)
# take status value matching highest status code return maxcode, ', '.join([a[1] for a in args if a[0] == maxcode and a[1]])
merged = [a[1] for a in args if a[0] == maxcode and a[1]]
# merge the split texts. use dict instead of set for keeping order
merged = {m: 0 for mm in merged for m in mm.split(', ')}
return maxcode, ', '.join(merged)

View File

@ -27,7 +27,7 @@ import inspect
from frappy.datatypes import BoolType, CommandType, DataType, \ from frappy.datatypes import BoolType, CommandType, DataType, \
DataTypeType, EnumType, NoneOr, OrType, FloatRange, \ DataTypeType, EnumType, NoneOr, OrType, FloatRange, \
StringType, StructOf, TextType, TupleOf, ValueType StringType, StructOf, TextType, TupleOf, ValueType, ArrayOf
from frappy.errors import BadValueError, WrongTypeError, ProgrammingError from frappy.errors import BadValueError, WrongTypeError, ProgrammingError
from frappy.properties import HasProperties, Property from frappy.properties import HasProperties, Property
from frappy.lib import generalConfig from frappy.lib import generalConfig
@ -168,6 +168,9 @@ class Parameter(Accessible):
or the minimum time between updates of equal values [sec]''', or the minimum time between updates of equal values [sec]''',
OrType(FloatRange(0), EnumType(always=0, never=999999999, default=-1)), OrType(FloatRange(0), EnumType(always=0, never=999999999, default=-1)),
export=False, default=-1) export=False, default=-1)
influences = Property(
'optional hint about effected parameters', ArrayOf(StringType()),
extname='influences', export=True, mandatory=False, default=[])
# used on the instance copy only # used on the instance copy only
# value = None # value = None
@ -363,6 +366,9 @@ class Command(Accessible):
result = Property( result = Property(
'datatype of the result from the command, or None', NoneOr(DataTypeType()), 'datatype of the result from the command, or None', NoneOr(DataTypeType()),
export=False, mandatory=True) export=False, mandatory=True)
influences = Property(
'optional hint about effected parameters', ArrayOf(StringType()),
extname='influences', export=True, mandatory=False, default=[])
func = None func = None

View File

@ -658,6 +658,7 @@ def test_get_datatype():
(FloatRange(-10, 10), FloatRange()), (FloatRange(-10, 10), FloatRange()),
(IntRange(-10, 10), FloatRange()), (IntRange(-10, 10), FloatRange()),
(IntRange(-10, 10), IntRange(-20, 10)), (IntRange(-10, 10), IntRange(-20, 10)),
(FloatRange(-10, 10), FloatRange(-15, 10)),
(StringType(), StringType(isUTF8=True)), (StringType(), StringType(isUTF8=True)),
(StringType(10, 10), StringType()), (StringType(10, 10), StringType()),
(ArrayOf(StringType(), 3, 5), ArrayOf(StringType(), 3, 6)), (ArrayOf(StringType(), 3, 5), ArrayOf(StringType(), 3, 6)),

View File

@ -28,7 +28,7 @@ import pytest
from frappy.datatypes import BoolType, FloatRange, StringType, IntRange, ScaledInteger from frappy.datatypes import BoolType, FloatRange, StringType, IntRange, ScaledInteger
from frappy.errors import ProgrammingError, ConfigError, RangeError from frappy.errors import ProgrammingError, ConfigError, RangeError
from frappy.modules import Communicator, Drivable, Readable, Module from frappy.modules import Communicator, Drivable, Readable, Module, Writable
from frappy.params import Command, Parameter, Limit from frappy.params import Command, Parameter, Limit
from frappy.rwhandler import ReadHandler, WriteHandler, nopoll from frappy.rwhandler import ReadHandler, WriteHandler, nopoll
from frappy.lib import generalConfig from frappy.lib import generalConfig
@ -245,7 +245,7 @@ def test_ModuleMagic():
'group', 'export', 'relative_resolution', 'group', 'export', 'relative_resolution',
'visibility', 'unit', 'default', 'value', 'datatype', 'fmtstr', 'visibility', 'unit', 'default', 'value', 'datatype', 'fmtstr',
'absolute_resolution', 'max', 'min', 'readonly', 'constant', 'absolute_resolution', 'max', 'min', 'readonly', 'constant',
'description', 'needscfg', 'update_unchanged'} 'description', 'needscfg', 'update_unchanged', 'influences'}
# check on the level of classes # check on the level of classes
# this checks Newclass1 too, as it is inherited by Newclass2 # this checks Newclass1 too, as it is inherited by Newclass2
@ -902,3 +902,17 @@ def test_limit_inheritance():
with pytest.raises(ValueError): with pytest.raises(ValueError):
mod2.write_a(0) mod2.write_a(0)
@pytest.mark.parametrize('bases, iface_classes', [
([Module], ()),
([Communicator], ('Communicator',)),
([Readable], ('Readable',)),
([Writable], ('Writable',)),
([Drivable], ('Drivable',)),
])
def test_interface_classes(bases, iface_classes):
srv = ServerStub({})
class Mod(*bases):
pass
m = Mod('mod', LoggerStub(), {'description': 'test'}, srv)
assert m.interface_classes == iface_classes