Source code for ats_utilities.checker

# -*- coding: UTF-8 -*-

'''
Module
    __init__.py
Copyright
    Copyright (C) 2017 - 2024 Vladimir Roncevic <elektron.ronca@gmail.com>
    ats_utilities is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    ats_utilities is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    See the GNU General Public License for more details.
    You should have received a copy of the GNU General Public License along
    with this program. If not, see <http://www.gnu.org/licenses/>.
Info
    Defines class ATSChecker with attribute(s) and method(s).
    Creates an API for checking parameters for methods and functions.
'''

from inspect import stack
from typing import Any, List, Tuple, OrderedDict
from collections import OrderedDict as OrderedDictionary

__author__ = 'Vladimir Roncevic'
__copyright__ = '(C) 2024, https://vroncevic.github.io/ats_utilities'
__credits__: List[str] = ['Vladimir Roncevic', 'Python Software Foundation']
__license__ = 'https://github.com/vroncevic/ats_utilities/blob/dev/LICENSE'
__version__ = '3.1.3'
__maintainer__ = 'Vladimir Roncevic'
__email__ = 'elektron.ronca@gmail.com'
__status__ = 'Updated'


[docs] class ATSChecker: ''' Defines class ATSChecker with attribute(s) and method(s). Creates an API for checking parameters for methods and functions. Mechanism for checking function or method parameters (type or format). It defines: :attributes: | NO_ERROR - Marks no param error, error id (0). | TYPE_ERROR - Marks type param error, error id (1). | FORMAT_ERROR - Marks wrong format error, error id (2). | _start_message - Start segment of usage message. | _list_of_params - List of params for a method or function. | _error_type - List of mapped errors. | _error_type_index - Error type index. :methods: | __init__ - Initials ATSChecker constructor. | collect_params - Collects all params in one list. | usage_message - Prepares usage for method or function. | check_types - Checks params (types) for method or function. | priority_error - Sets priority error id (TYPE_ERROR). | check_params - Checks params for method or function. ''' NO_ERROR: int = 0 TYPE_ERROR: int = 1 FORMAT_ERROR: int = 2 def __init__(self) -> None: ''' Initials ATSChecker constructor. :exceptions: None ''' self._start_message: str | None = None self._list_of_params: List[str] = [] self._error_type: List[int] = [0, 0] self._error_type_index: List[int] = []
[docs] def collect_params(self, params_desc: OrderedDict[str, Any]) -> bool: ''' Collects all params in one list. :param params_desc: Description for params :type params_desc: <OrderedDict[str, Any]> :return: True (are collected) | False (failed to collect) :rtype: <bool> :exceptions: None ''' if any([not params_desc]): self._error_type[1] = self.FORMAT_ERROR return False for exp_type, inst in params_desc.items(): pname: str = exp_type.split(sep=':')[1] ptype: str = exp_type.split(sep=':')[0] self._list_of_params.append( f'\n expected {pname} <{ptype}> object at {hex(id(inst))}' ) return True
[docs] def usage_message(self) -> str | None: ''' Prepares usage for method or function. :return: Usage message for method or function | None :rtype: <str> | <NoneType> :exceptions: None ''' message: str | None = self._start_message if bool(self._list_of_params): for index, param in enumerate(self._list_of_params): message = f'{message} {param}' if bool(self._error_type_index): if index in set(self._error_type_index): message = f'{message} wrong type' return message
[docs] def check_types(self, params_desc: OrderedDict[str, Any]) -> bool: ''' Checks params (types) for method or function. :param params_desc: Description for params :type params_desc: <OrderedDict[str, Any]> :return: True (type(s) is(are) ok) | False (type(s) is(are) not ok) :rtype: <bool> :exceptions: None ''' if any([not params_desc]): self._error_type[1] = self.FORMAT_ERROR return False for index, (exp_type, inst) in enumerate(params_desc.items()): param_type_name: List[str] = exp_type.split(sep=':') if len(param_type_name) == 2: if type(inst).__name__ != param_type_name[0]: self._error_type[0] = self.TYPE_ERROR self._error_type_index.append(index) return False else: self._error_type[1] = self.FORMAT_ERROR return False return True
[docs] def priority_error(self) -> int | None: ''' Sets priority error id (TYPE_ERROR). :return: Priority error id (0 | 1 | 2) | None :rtype: <int> | <NoneType> :exceptions: None ''' priority_error_id: int | None = None if self._error_type[1] == self.FORMAT_ERROR: return self.FORMAT_ERROR if self._error_type[0] == self.TYPE_ERROR: priority_error_id = self.TYPE_ERROR if all(error_type == 0 for error_type in self._error_type): priority_error_id = self.NO_ERROR return priority_error_id
[docs] def check_params( self, params_desc: List[Tuple[str, Any]] ) -> Tuple[str | None, int | None]: ''' Checks params for method or function. :param params_desc: Description for params :type params_desc: <List[Tuple[str, Any]]> :return: error message, error id (0 | 1 | 2) :rtype: <str> | <NoneType>, <int> | <NoneType> :exceptions: None ''' func: str = stack()[1][3] module: str = stack()[1][1] self._start_message = f'\nmod: {module}\n def: {func}()' fail_any_check: bool = any([ not self.collect_params(OrderedDictionary(params_desc)), not self.check_types(OrderedDictionary(params_desc)) ]) message: str | None = self.usage_message() error_id: int | None = self.priority_error() if any([error_id != 0, fail_any_check]): message = f'{message} format wrong during checking params' return message, error_id