Source code for masci_tools.util.parse_tasks_decorators

# -*- coding: utf-8 -*-
###############################################################################
# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany.         #
#                All rights reserved.                                         #
# This file is part of the Masci-tools package.                               #
# (Material science tools)                                                    #
#                                                                             #
# The code is hosted on GitHub at https://github.com/judftteam/masci-tools.   #
# For further information on the license, see the LICENSE.txt file.           #
# For further information please visit http://judft.de/.                      #
#                                                                             #
###############################################################################
"""
This module defines decorators for the ParseTasks class to make extending/modifying the parser
more convenient

Up till now 3 decorators are defined:
    - ```register_migration``` marks a function of making backwards incompatible changes
      to the parsing tasks
    - ```register_parsing_function``` gives a mappimg between available parsing functions
      and the keywords in the parsing tasks
    - ```conversion_function``` makes the decorated function available to be called easily
      after a certain parsing task has occured
"""
from masci_tools.util.parse_tasks import ParseTasks
from functools import wraps


[docs]def register_migration(base_version, target_version): """ Decorator to add migration for task definition dictionary to the ParseTasks class The function should only take the dict of task definitions as an argument :param base_version: str of the version, from which the migration starts :param target_version: str or list of str with the versions that work after the migration has been performed """ def migration_decorator(func): """ Return decorated ParseTasks object with _migrations dict attribute Here all registered migrations are inserted """ @wraps(func) def migration(*args): """Decorator for migration function""" return func(*args) if not hasattr(ParseTasks, '_migrations'): ParseTasks._migrations = {} # pylint: disable=protected-access if not base_version in ParseTasks._migrations: ParseTasks._migrations[base_version] = {} target_version_list = target_version if not isinstance(target_version_list, list): target_version_list = [target_version_list] for valid_version in target_version_list: ParseTasks._migrations[base_version][valid_version] = migration # pylint: disable=protected-access for valid_version_2 in target_version_list: if valid_version == valid_version_2: continue if int(valid_version.split('.')[1]) > int(valid_version_2.split('.')[1]): if valid_version not in ParseTasks._migrations: ParseTasks._migrations[valid_version] = {} ParseTasks._migrations[valid_version][valid_version_2] = 'compatible' else: if valid_version_2 not in ParseTasks._migrations: ParseTasks._migrations[valid_version_2] = {} ParseTasks._migrations[valid_version_2][valid_version] = 'compatible' return migration return migration_decorator
[docs]def register_parsing_function(parse_type_name, all_attribs_keys=False): """ Decorator to add parse type for task definition dictionary. :param parse_type_name: str, the function can be selected in task defintions via this string :param all_attribs_keys: bool, if True the arguments for parsing multiple attributes are valid The decorated function has to have the following arguments: :param node: etree Element, on which to execute the xpath evaluations :param schema_dict: dict, containing all the path information and more :param name: str, name of the tag/attribute :param parser_info_out: dict, with warnings, info, errors, ... :param kwargs: here all other keyword arguments are collected """ def parse_type_decorator(func): """ Return decorated ParseTasks object with _parse_functions dict attribute Here all registered migrations are inserted """ @wraps(func) def parse_type(*args, **kwargs): """Decorator for parse_type function""" return func(*args, **kwargs) if not hasattr(ParseTasks, '_parse_functions'): ParseTasks._parse_functions = {} # pylint: disable=protected-access ParseTasks._all_attribs_function = set() ParseTasks._parse_functions[parse_type_name] = parse_type # pylint: disable=protected-access if all_attribs_keys: ParseTasks._all_attribs_function.add(parse_type_name) return parse_type return parse_type_decorator
[docs]def conversion_function(func): """ Marks a function as a conversion function, which can be called after performing a parsing task. The function can be specified via the _conversions control key in the task definitions. A conversion function has to have the following arguments: :param out_dict: dict with the previously parsed information :param parser_info_out: dict, with warnings, info, errors, ... and return only the modified output dict """ @wraps(func) def convert_func(*args, **kwargs): """Decorator for parse_type function""" return func(*args, **kwargs) if not hasattr(ParseTasks, '_conversion_functions'): ParseTasks._conversion_functions = {} # pylint: disable=protected-access ParseTasks._conversion_functions[func.__name__] = convert_func # pylint: disable=protected-access return convert_func