fix inheritance problem with mixin

- a mixin should not inherit from module then it has Parameters
- Parameters in mixins must be complete, not just overrides
- check precedence of read_<param> or handler

Change-Id: I72d9355a1982770d1a99d9552a20330103c97edb
This commit is contained in:
2021-03-18 13:32:54 +01:00
parent 6538500881
commit 48230334af
9 changed files with 55 additions and 24 deletions

View File

@ -495,9 +495,12 @@ class SecopClient(ProxyClient):
def _set_state(self, online, state=None):
# treat reconnecting as online!
state = state or self.state
self.callback(None, 'nodeStateChange', online, state)
for mname in self.modules:
self.callback(mname, 'nodeStateChange', online, state)
try:
self.callback(None, 'nodeStateChange', online, state)
for mname in self.modules:
self.callback(mname, 'nodeStateChange', online, state)
except Exception as e:
self.log.error('ERROR in nodeStateCallback %s', e)
# set online attribute after callbacks -> callback may check for old state
self.online = online
self.state = state

View File

@ -98,14 +98,17 @@ def clamp(_min, value, _max):
def get_class(spec):
"""loads a class given by string in dotted notaion (as python would do)"""
"""loads a class given by string in dotted notation (as python would do)"""
modname, classname = spec.rsplit('.', 1)
if modname.startswith('secop'):
module = importlib.import_module(modname)
else:
# rarely needed by now....
module = importlib.import_module('secop.' + modname)
return getattr(module, classname)
try:
return getattr(module, classname)
except AttributeError:
raise AttributeError('no such class') from None
def mkthread(func, *args, **kwds):

View File

@ -93,10 +93,13 @@ class HasAccessibles(HasProperties):
rfunc_handler = pobj.handler.get_read_func(cls, pname) if pobj.handler else None
wrapped = hasattr(rfunc, '__wrapped__')
if rfunc_handler:
if rfunc and not wrapped:
raise ProgrammingError("parameter '%s' can not have a handler "
"and read_%s" % (pname, pname))
rfunc = rfunc_handler
if 'read_' + pname in cls.__dict__:
if pname in cls.__dict__:
raise ProgrammingError("parameter '%s' can not have a handler "
"and read_%s" % (pname, pname))
# read_<pname> overwrites inherited handler
else:
rfunc = rfunc_handler
wrapped = False
# create wrapper except when read function is already wrapped

View File

@ -101,10 +101,10 @@ class Parameter(Accessible):
description = Property(
'mandatory description of the parameter', TextType(),
extname='description', mandatory=True)
extname='description', mandatory=True, export='always')
datatype = Property(
'datatype of the Parameter (SECoP datainfo)', DataTypeType(),
extname='datainfo', mandatory=True)
extname='datainfo', mandatory=True, export='always')
readonly = Property(
'not changeable via SECoP (default True)', BoolType(),
extname='readonly', default=True, export='always')
@ -283,7 +283,7 @@ class Command(Accessible):
description = Property(
'description of the Command', TextType(),
extname='description', export=True, mandatory=True)
extname='description', export='always', mandatory=True)
group = Property(
'optional command group of the command.', StringType(),
extname='group', export=True, default='')

View File

@ -228,11 +228,15 @@ class Server:
errors.append(self.unknown_options(cls, opts))
self.modules = OrderedDict()
badclass = None
failed = set() # python modules failed to load
self.lastError = None
for modname, options in self.module_cfg.items():
opts = dict(options)
try:
classname = opts.pop('class')
pymodule = classname.rpartition('.')[0]
if pymodule in failed:
continue
cls = get_class(classname)
modobj = cls(modname, self.log.getChild(modname), opts, self)
# all used args should be popped from opts!
@ -242,8 +246,12 @@ class Server:
except ConfigError as e:
errors.append(str(e))
except Exception as e:
badclass = classname
errors.append('error while loading %s' % badclass)
if str(e) == 'no such class':
errors.append('%s not found' % classname)
else:
failed.add(pymodule)
badclass = classname
errors.append('error importing %s' % pymodule)
poll_table = dict()
# all objs created, now start them up and interconnect