Skip to content

Commit

Permalink
Allow config_schemas to be Sequences (lists and tuples) of config fie…
Browse files Browse the repository at this point in the history
…lds.

* Add an _is_config_sequence() function to validate this and use that in the definition of actor
  metadata.  Note that most of the other validation functions used here can be retrofitted to use
  this implementation as well.
  • Loading branch information
abadger committed Sep 19, 2024
1 parent 22dbc5b commit 8011625
Showing 1 changed file with 30 additions and 12 deletions.
42 changes: 30 additions & 12 deletions leapp/actors/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import functools
import logging
import os
import sys
from collections.abc import Sequence

from leapp.actors.config import Config, retrieve_config
from leapp.compat import string_types
Expand Down Expand Up @@ -402,25 +404,30 @@ def _lint_warn(actor, name, type_name):
logging.getLogger("leapp.linter").warning("Actor %s field %s should be a tuple of %s", actor, name, type_name)


def _is_model_tuple(actor, name, value):
if isinstance(value, type) and issubclass(value, Model):
_lint_warn(actor, name, "Models")
def _is_foo_sequence(cls, cls_name, actor, name, value):
if isinstance(value, type) and issubclass(value, cls):
_lint_warn(actor, name, cls_name)
value = (value,)
_is_type(tuple)(actor, name, value)
if not all([True] + [isinstance(item, type) and issubclass(item, Model) for item in value]):
_is_type(Sequence)(actor, name, value)
if not all([True] + [isinstance(item, type) and issubclass(item, cls) for item in value]):
raise WrongAttributeTypeError(
'Actor {} attribute {} should contain only Models'.format(actor, name))
'Actor {} attribute {} should contain only {}'.format(actor, name, cls_name))
return value


def _is_dialog_tuple(actor, name, value):
if isinstance(value, Dialog):
_lint_warn(actor, name, "Dialogs")
_is_config_sequence = functools.partial(_is_foo_sequence, Config, "Config")


# TODO: model, tag, and api_tuple can be migrated to use _is_foo_sequence.

def _is_model_tuple(actor, name, value):
if isinstance(value, type) and issubclass(value, Model):
_lint_warn(actor, name, "Models")
value = (value,)
_is_type(tuple)(actor, name, value)
if not all([True] + [isinstance(item, Dialog) for item in value]):
if not all([True] + [isinstance(item, type) and issubclass(item, Model) for item in value]):
raise WrongAttributeTypeError(
'Actor {} attribute {} should contain only Dialogs'.format(actor, name))
'Actor {} attribute {} should contain only Models'.format(actor, name))
return value


Expand All @@ -446,6 +453,17 @@ def _is_api_tuple(actor, name, value):
return value


def _is_dialog_tuple(actor, name, value):
if isinstance(value, Dialog):
_lint_warn(actor, name, "Dialogs")
value = (value,)
_is_type(tuple)(actor, name, value)
if not all([True] + [isinstance(item, Dialog) for item in value]):
raise WrongAttributeTypeError(
'Actor {} attribute {} should contain only Dialogs'.format(actor, name))
return value


def _get_attribute(actor, name, validator, required=False, default_value=None, additional_info='', resolve=None):
if resolve:
value = resolve(actor, name)
Expand Down Expand Up @@ -482,7 +500,7 @@ def get_actor_metadata(actor):
_get_attribute(actor, 'dialogs', _is_dialog_tuple, required=False, default_value=()),
_get_attribute(actor, 'description', _is_type(string_types), required=False,
default_value=actor.__doc__ or 'There has been no description provided for this actor.'),
_get_attribute(actor, 'config_schemas', _is_type(Config), required=False,
_get_attribute(actor, 'config_schemas', _is_config_sequence, required=False,
default_value=actor.__doc__ or 'Description of the configuration used by this actor.'),
_get_attribute(actor, 'apis', _is_api_tuple, required=False, default_value=())
])
Expand Down

0 comments on commit 8011625

Please sign in to comment.