From dd67c48c9e31ddf36eb7d66b4b5188c6493803eb Mon Sep 17 00:00:00 2001 From: Markus Zolliker Date: Thu, 21 Sep 2023 11:13:57 +0200 Subject: [PATCH] bug in Attached (fix after change 31470) An attached property may be defined with mandatory=False. In this case, when no value or an empty string is given, . must return None after initialisation. + remove 'dispatcher' level from the logger hierarchy on modules Change-Id: Icee3ae3f9142cd7a910c579ae1ffaa35f93cee03 Reviewed-on: https://forge.frm2.tum.de/review/c/secop/frappy/+/32187 Tested-by: Jenkins Automated Tests Reviewed-by: Markus Zolliker --- frappy/modules.py | 20 ++++++++++++++------ frappy/protocol/dispatcher.py | 2 +- test/test_server.py | 3 +++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/frappy/modules.py b/frappy/modules.py index fc57d1d1..89f3836c 100644 --- a/frappy/modules.py +++ b/frappy/modules.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # ***************************************************************************** # # This program is free software; you can redistribute it and/or modify it under @@ -925,13 +924,18 @@ class Communicator(HasComlog, Module): """ raise NotImplementedError() + SECoP_BASE_CLASSES = {Readable, Writable, Drivable, Communicator} + class Attached(Property): """a special property, defining an attached module assign a module name to this property in the cfg file, and the server will create an attribute with this module + + When mandatory is set to False, and there is no value or an empty string + given in the config file, the value of the attribute will be None. """ def __init__(self, basecls=Module, description='attached module', mandatory=True): self.basecls = basecls @@ -940,13 +944,17 @@ class Attached(Property): def __get__(self, obj, owner): if obj is None: return self - if self.name not in obj.attachedModules: - modobj = obj.DISPATCHER.get_module(super().__get__(obj, owner)) + modobj = obj.attachedModules.get(self.name) + if not modobj: + modulename = super().__get__(obj, owner) + if not modulename: + return None # happens when mandatory=False and modulename is not given + modobj = obj.DISPATCHER.get_module(modulename) if not isinstance(modobj, self.basecls): - raise ConfigError(f'attached module {self.name}={modobj.name!r} '\ - f'must inherit from {self.basecls.__qualname__!r}') + raise ConfigError(f'attached module {self.name}={modobj.name!r} ' + f'must inherit from {self.basecls.__qualname__!r}') obj.attachedModules[self.name] = modobj - return obj.attachedModules.get(self.name) # return None if not given + return modobj def copy(self): return Attached(self.basecls, self.description, self.mandatory) diff --git a/frappy/protocol/dispatcher.py b/frappy/protocol/dispatcher.py index cc76225e..9ebee71e 100644 --- a/frappy/protocol/dispatcher.py +++ b/frappy/protocol/dispatcher.py @@ -227,7 +227,7 @@ class Dispatcher: return None else: try: - modobj = cls(modulename, self.log.getChild(modulename), opts, self.srv) + modobj = cls(modulename, self.log.parent.getChild(modulename), opts, self.srv) except ConfigError as e: self.errors.append(f'error creating module {modulename}:') for errtxt in e.args[0] if isinstance(e.args[0], list) else [e.args[0]]: diff --git a/test/test_server.py b/test/test_server.py index fad62252..51166145 100644 --- a/test/test_server.py +++ b/test/test_server.py @@ -28,6 +28,9 @@ from .test_config import direc # pylint: disable=unused-import class LoggerStub: + def __init__(self): + self.parent = self + def debug(self, fmt, *args): pass