From: Ondrej Lichtner olichtne@redhat.com
When initializing a Recipe instance, we're looking for class Param and HostReq objects to copy and instantiate into the Recipe instance. However while looping throught the dir() of an instance we can sometimes attempt to access a "property" or other attributes which aren't valid during the init method.
The solution is to filter out the type of attributes from the class itself based on the type that we want to work with. This also simplifies the code a little.
Signed-off-by: Ondrej Lichtner olichtne@redhat.com --- lnst/Controller/Recipe.py | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/lnst/Controller/Recipe.py b/lnst/Controller/Recipe.py index 5a0a347..53e316b 100644 --- a/lnst/Controller/Recipe.py +++ b/lnst/Controller/Recipe.py @@ -85,28 +85,28 @@ class BaseRecipe(object): self.runs = [] self.req = _Requirements() self.params = Parameters() - for attr in dir(self): - val = getattr(self, attr) - if isinstance(val, Param): - if attr in kwargs: - param_val = kwargs.pop(attr) - param_val = val.type_check(param_val) - setattr(self.params, attr, param_val) - else: - try: - param_val = copy.deepcopy(val.default) - setattr(self.params, attr, param_val) - except AttributeError: - if val.mandatory: - raise RecipeError("Parameter {} is mandatory" - .format(attr)) - - for attr in dir(self): - val = getattr(self, attr) - if isinstance(val, HostReq): - new_val = copy.deepcopy(val) - new_val.reinit_with_params(self.params) - setattr(self.req, attr, new_val) + + attrs = {name: getattr(type(self), name) for name in dir(type(self))} + + params = ((name, val) for name, val in attrs.items() if isinstance(val, Param)) + for name, val in params: + if name in kwargs: + param_val = kwargs.pop(name) + param_val = val.type_check(param_val) + setattr(self.params, name, param_val) + else: + try: + param_val = copy.deepcopy(val.default) + setattr(self.params, name, param_val) + except AttributeError: + if val.mandatory: + raise RecipeError("Parameter {} is mandatory".format(name)) + + reqs = ((name, val) for name, val in attrs.items() if isinstance(val, HostReq)) + for name, val in reqs: + new_val = copy.deepcopy(val) + new_val.reinit_with_params(self.params) + setattr(self.req, name, new_val)
if len(kwargs): for key in kwargs.keys():
Fri, Apr 05, 2019 at 05:17:50PM CEST, olichtne@redhat.com wrote:
From: Ondrej Lichtner olichtne@redhat.com
When initializing a Recipe instance, we're looking for class Param and HostReq objects to copy and instantiate into the Recipe instance. However while looping throught the dir() of an instance we can sometimes attempt to access a "property" or other attributes which aren't valid during the init method.
The solution is to filter out the type of attributes from the class itself based on the type that we want to work with. This also simplifies the code a little.
Signed-off-by: Ondrej Lichtner olichtne@redhat.com
Acked-by: Jan Tluka jtluka@redhat.com
On Mon, Apr 08, 2019 at 10:19:30AM +0200, Jan Tluka wrote:
Fri, Apr 05, 2019 at 05:17:50PM CEST, olichtne@redhat.com wrote:
From: Ondrej Lichtner olichtne@redhat.com
When initializing a Recipe instance, we're looking for class Param and HostReq objects to copy and instantiate into the Recipe instance. However while looping throught the dir() of an instance we can sometimes attempt to access a "property" or other attributes which aren't valid during the init method.
The solution is to filter out the type of attributes from the class itself based on the type that we want to work with. This also simplifies the code a little.
Signed-off-by: Ondrej Lichtner olichtne@redhat.com
Acked-by: Jan Tluka jtluka@redhat.com
pushed, thanks for review.
-Ondrej
lnst-developers@lists.fedorahosted.org