src.fairreckitlib.core.parsing.parse_config_object

This module contains functionality to parse configuration object name and parameters.

Functions:

parse_config_object: parse an object name and parameters configuration.
parse_config_object_list: parse a list of config objects

This program has been developed by students from the bachelor Computer Science at Utrecht University within the Software Project course. © Copyright Utrecht University (Department of Information and Computing Sciences)

  1"""This module contains functionality to parse configuration object name and parameters.
  2
  3Functions:
  4
  5    parse_config_object: parse an object name and parameters configuration.
  6    parse_config_object_list: parse a list of config objects
  7
  8This program has been developed by students from the bachelor Computer Science at
  9Utrecht University within the Software Project course.
 10© Copyright Utrecht University (Department of Information and Computing Sciences)
 11"""
 12
 13from typing import Any, Dict, List, Tuple, Union
 14
 15from ..config.config_factories import Factory, GroupFactory, resolve_factory
 16from ..config.config_object import ObjectConfig
 17from ..config.config_base_param import ConfigParam
 18from ..core_constants import KEY_NAME, KEY_PARAMS
 19from ..events.event_dispatcher import EventDispatcher
 20from .parse_assert import \
 21    assert_is_container_not_empty, assert_is_key_in_dict, assert_is_one_of_list, assert_is_type
 22from .parse_config_params import parse_config_parameters
 23from .parse_event import ON_PARSE, ParseEventArgs
 24
 25
 26def parse_config_object(
 27        obj_type_name: str,
 28        obj_config: Dict[str, Any],
 29        obj_factory: Union[Factory, GroupFactory],
 30        event_dispatcher: EventDispatcher,
 31        *,
 32        params: Dict[str, ConfigParam]=None,
 33        default_config: ObjectConfig=None) -> Union[Tuple[ObjectConfig, str], Tuple[None, None]]:
 34    """Parse an object name and parameters configuration.
 35
 36    Args:
 37        obj_type_name: name of the object type.
 38        obj_config: dictionary with the object's configuration.
 39        obj_factory: the object (group) factory related to the object config.
 40        event_dispatcher: to dispatch the parse event on failure.
 41        params: dictionary with params that will override validation of existing config params.
 42        default_config: the default configuration (used as default parse event arg on failure).
 43
 44    Returns:
 45        the parsed configuration and object name or None on failure.
 46    """
 47    default_obj_name = default_config.name if bool(default_config) else None
 48    parse_fail = 'PARSE WARNING: ' if bool(default_config) else 'PARSE ERROR: '
 49    # assert obj_config is a dict
 50    if not assert_is_type(
 51        obj_config,
 52        dict,
 53        event_dispatcher,
 54        parse_fail + obj_factory.get_name() + ' ' + obj_type_name + ' invalid config value',
 55        default_value=default_config
 56    ): return None, default_obj_name
 57
 58    # assert obj name is present
 59    if not assert_is_key_in_dict(
 60        KEY_NAME,
 61        obj_config,
 62        event_dispatcher,
 63        parse_fail + obj_factory.get_name() + ' ' + obj_type_name +
 64        ' missing key \'' + KEY_NAME + '\'',
 65        default_value=default_obj_name
 66    ): return None, default_obj_name
 67
 68    obj_name = obj_config[KEY_NAME]
 69    # attempt to resolve the factory that creates the object
 70    obj_create_factory = resolve_factory(obj_name, obj_factory)
 71
 72    # assert object name is available in the object factory
 73    if not assert_is_one_of_list(
 74        obj_name,
 75        (obj_factory if obj_create_factory is None else obj_create_factory).get_available_names(),
 76        event_dispatcher,
 77        parse_fail + obj_factory.get_name() + ' ' + obj_type_name +
 78        ' unknown name: \'' + str(obj_name) + '\'',
 79        default_value=default_obj_name
 80    ): return None, obj_name
 81
 82    obj_config_params = obj_create_factory.create_params(obj_name)
 83    # override any present config params
 84    if params is not None:
 85        for param_name, config_param in params.items():
 86            if param_name in obj_config_params.params:
 87                obj_config_params.params[param_name] = config_param
 88
 89    # start with object default params
 90    obj_params = obj_config_params.get_defaults()
 91
 92    # assert KEY_PARAMS is present
 93    # skip when the object has no parameters at all
 94    if obj_config_params.get_num_params() > 0 and assert_is_key_in_dict(
 95        KEY_PARAMS,
 96        obj_config,
 97        event_dispatcher,
 98        'PARSE WARNING: ' + obj_type_name + ' \'' + obj_name +
 99        '\' missing key \'' + KEY_PARAMS + '\'',
100        default_value=obj_params
101    ):
102        # parse the object parameters
103        obj_params = parse_config_parameters(
104            obj_config[KEY_PARAMS],
105            obj_name,
106            obj_config_params,
107            event_dispatcher
108        )
109
110    parsed_config = ObjectConfig(
111        obj_name,
112        obj_params
113    )
114
115    return parsed_config, obj_name
116
117
118def parse_config_object_list(
119        obj_category_name: str,
120        obj_type_name: str,
121        obj_config_list: List[Dict[str, Any]],
122        obj_factory: GroupFactory,
123        event_dispatcher: EventDispatcher,
124        *,
125        params: Dict[str, ConfigParam]=None) -> List[Tuple[ObjectConfig, Dict[str, Any]]]:
126    """Parse the object configurations for the specified category name.
127
128    Args:
129        obj_category_name: name of the object category.
130        obj_type_name: name of the object type.
131        obj_config_list: list of dictionaries with the object's configuration.
132        obj_factory: the object (group) factory related to the object config.
133        event_dispatcher: to dispatch the parse event on failure.
134        params: dictionary with params that will override validation of existing config params.
135
136    Returns:
137        a tuple list of the successfully parsed ObjectConfig's and their corresponding dictionary.
138    """
139    parsed_objs = []
140
141    # assert obj_config_list is a list
142    if not assert_is_type(
143        obj_config_list,
144        list,
145        event_dispatcher,
146        'PARSE ERROR: ' + obj_category_name + ' invalid config value',
147        default_value=parsed_objs
148    ): return parsed_objs
149
150    # assert obj_config_list has entries
151    if not assert_is_container_not_empty(
152        obj_config_list,
153        event_dispatcher,
154        'PARSE WARNING: ' + obj_category_name + ' ' + obj_type_name + ' list is empty'
155    ): return parsed_objs
156
157    # parse obj config list entries
158    for obj_config in obj_config_list:
159        obj, obj_name = parse_config_object(
160            obj_type_name,
161            obj_config,
162            obj_factory,
163            event_dispatcher,
164            params=params
165        )
166        # skip on failure
167        if obj is None:
168            event_dispatcher.dispatch(ParseEventArgs(
169                ON_PARSE,
170                'PARSE WARNING: failed to parse ' + obj_category_name + ' ' + obj_type_name +
171                ' \'' + str(obj_name) + '\', skipping...'
172            ))
173            continue
174
175        parsed_objs.append((ObjectConfig(obj.name, obj.params), obj_config))
176
177    return parsed_objs
def parse_config_object( obj_type_name: str, obj_config: Dict[str, Any], obj_factory: Union[src.fairreckitlib.core.config.config_factories.Factory, src.fairreckitlib.core.config.config_factories.GroupFactory], event_dispatcher: src.fairreckitlib.core.events.event_dispatcher.EventDispatcher, *, params: Dict[str, src.fairreckitlib.core.config.config_base_param.ConfigParam] = None, default_config: src.fairreckitlib.core.config.config_object.ObjectConfig = None) -> Union[Tuple[src.fairreckitlib.core.config.config_object.ObjectConfig, str], Tuple[NoneType, NoneType]]:
 27def parse_config_object(
 28        obj_type_name: str,
 29        obj_config: Dict[str, Any],
 30        obj_factory: Union[Factory, GroupFactory],
 31        event_dispatcher: EventDispatcher,
 32        *,
 33        params: Dict[str, ConfigParam]=None,
 34        default_config: ObjectConfig=None) -> Union[Tuple[ObjectConfig, str], Tuple[None, None]]:
 35    """Parse an object name and parameters configuration.
 36
 37    Args:
 38        obj_type_name: name of the object type.
 39        obj_config: dictionary with the object's configuration.
 40        obj_factory: the object (group) factory related to the object config.
 41        event_dispatcher: to dispatch the parse event on failure.
 42        params: dictionary with params that will override validation of existing config params.
 43        default_config: the default configuration (used as default parse event arg on failure).
 44
 45    Returns:
 46        the parsed configuration and object name or None on failure.
 47    """
 48    default_obj_name = default_config.name if bool(default_config) else None
 49    parse_fail = 'PARSE WARNING: ' if bool(default_config) else 'PARSE ERROR: '
 50    # assert obj_config is a dict
 51    if not assert_is_type(
 52        obj_config,
 53        dict,
 54        event_dispatcher,
 55        parse_fail + obj_factory.get_name() + ' ' + obj_type_name + ' invalid config value',
 56        default_value=default_config
 57    ): return None, default_obj_name
 58
 59    # assert obj name is present
 60    if not assert_is_key_in_dict(
 61        KEY_NAME,
 62        obj_config,
 63        event_dispatcher,
 64        parse_fail + obj_factory.get_name() + ' ' + obj_type_name +
 65        ' missing key \'' + KEY_NAME + '\'',
 66        default_value=default_obj_name
 67    ): return None, default_obj_name
 68
 69    obj_name = obj_config[KEY_NAME]
 70    # attempt to resolve the factory that creates the object
 71    obj_create_factory = resolve_factory(obj_name, obj_factory)
 72
 73    # assert object name is available in the object factory
 74    if not assert_is_one_of_list(
 75        obj_name,
 76        (obj_factory if obj_create_factory is None else obj_create_factory).get_available_names(),
 77        event_dispatcher,
 78        parse_fail + obj_factory.get_name() + ' ' + obj_type_name +
 79        ' unknown name: \'' + str(obj_name) + '\'',
 80        default_value=default_obj_name
 81    ): return None, obj_name
 82
 83    obj_config_params = obj_create_factory.create_params(obj_name)
 84    # override any present config params
 85    if params is not None:
 86        for param_name, config_param in params.items():
 87            if param_name in obj_config_params.params:
 88                obj_config_params.params[param_name] = config_param
 89
 90    # start with object default params
 91    obj_params = obj_config_params.get_defaults()
 92
 93    # assert KEY_PARAMS is present
 94    # skip when the object has no parameters at all
 95    if obj_config_params.get_num_params() > 0 and assert_is_key_in_dict(
 96        KEY_PARAMS,
 97        obj_config,
 98        event_dispatcher,
 99        'PARSE WARNING: ' + obj_type_name + ' \'' + obj_name +
100        '\' missing key \'' + KEY_PARAMS + '\'',
101        default_value=obj_params
102    ):
103        # parse the object parameters
104        obj_params = parse_config_parameters(
105            obj_config[KEY_PARAMS],
106            obj_name,
107            obj_config_params,
108            event_dispatcher
109        )
110
111    parsed_config = ObjectConfig(
112        obj_name,
113        obj_params
114    )
115
116    return parsed_config, obj_name

Parse an object name and parameters configuration.

Args: obj_type_name: name of the object type. obj_config: dictionary with the object's configuration. obj_factory: the object (group) factory related to the object config. event_dispatcher: to dispatch the parse event on failure. params: dictionary with params that will override validation of existing config params. default_config: the default configuration (used as default parse event arg on failure).

Returns: the parsed configuration and object name or None on failure.

def parse_config_object_list( obj_category_name: str, obj_type_name: str, obj_config_list: List[Dict[str, Any]], obj_factory: src.fairreckitlib.core.config.config_factories.GroupFactory, event_dispatcher: src.fairreckitlib.core.events.event_dispatcher.EventDispatcher, *, params: Dict[str, src.fairreckitlib.core.config.config_base_param.ConfigParam] = None) -> List[Tuple[src.fairreckitlib.core.config.config_object.ObjectConfig, Dict[str, Any]]]:
119def parse_config_object_list(
120        obj_category_name: str,
121        obj_type_name: str,
122        obj_config_list: List[Dict[str, Any]],
123        obj_factory: GroupFactory,
124        event_dispatcher: EventDispatcher,
125        *,
126        params: Dict[str, ConfigParam]=None) -> List[Tuple[ObjectConfig, Dict[str, Any]]]:
127    """Parse the object configurations for the specified category name.
128
129    Args:
130        obj_category_name: name of the object category.
131        obj_type_name: name of the object type.
132        obj_config_list: list of dictionaries with the object's configuration.
133        obj_factory: the object (group) factory related to the object config.
134        event_dispatcher: to dispatch the parse event on failure.
135        params: dictionary with params that will override validation of existing config params.
136
137    Returns:
138        a tuple list of the successfully parsed ObjectConfig's and their corresponding dictionary.
139    """
140    parsed_objs = []
141
142    # assert obj_config_list is a list
143    if not assert_is_type(
144        obj_config_list,
145        list,
146        event_dispatcher,
147        'PARSE ERROR: ' + obj_category_name + ' invalid config value',
148        default_value=parsed_objs
149    ): return parsed_objs
150
151    # assert obj_config_list has entries
152    if not assert_is_container_not_empty(
153        obj_config_list,
154        event_dispatcher,
155        'PARSE WARNING: ' + obj_category_name + ' ' + obj_type_name + ' list is empty'
156    ): return parsed_objs
157
158    # parse obj config list entries
159    for obj_config in obj_config_list:
160        obj, obj_name = parse_config_object(
161            obj_type_name,
162            obj_config,
163            obj_factory,
164            event_dispatcher,
165            params=params
166        )
167        # skip on failure
168        if obj is None:
169            event_dispatcher.dispatch(ParseEventArgs(
170                ON_PARSE,
171                'PARSE WARNING: failed to parse ' + obj_category_name + ' ' + obj_type_name +
172                ' \'' + str(obj_name) + '\', skipping...'
173            ))
174            continue
175
176        parsed_objs.append((ObjectConfig(obj.name, obj.params), obj_config))
177
178    return parsed_objs

Parse the object configurations for the specified category name.

Args: obj_category_name: name of the object category. obj_type_name: name of the object type. obj_config_list: list of dictionaries with the object's configuration. obj_factory: the object (group) factory related to the object config. event_dispatcher: to dispatch the parse event on failure. params: dictionary with params that will override validation of existing config params.

Returns: a tuple list of the successfully parsed ObjectConfig's and their corresponding dictionary.