Source code for boa.utils

from __future__ import annotations

import inspect
from collections.abc import Iterable, Mapping
from typing import Callable, Optional


[docs]def get_callable_signature(callable: Callable) -> inspect.Signature: return inspect.signature(callable)
[docs]def get_dictionary_matching_signature( signature: inspect.Signature, d: dict, match_private: bool = False, exclude_fields: Optional[list[str]] = None, accept_all_kwargs: bool = True, ) -> dict: args = {} exclude_fields = exclude_fields or [] params = signature.parameters if accept_all_kwargs: for param in params.values(): if param.kind == param.VAR_KEYWORD: # this accepts **kwargs, therefore let everything through for key, value in d.items(): if match_private and (key.startswith("_") or key.startswith("__")): key = key.lstrip("_") if key not in exclude_fields: args[key] = value return args for key, value in d.items(): if match_private and (key.startswith("_") or key.startswith("__")): key = key.lstrip("_") if key in params and key not in exclude_fields: args[key] = value return args
[docs]def get_dictionary_from_callable(callable: Callable, d: dict, **kwargs) -> dict: signature = get_callable_signature(callable) return get_dictionary_matching_signature(signature, d, **kwargs)
[docs]def serialize_init_args(instance, *, parents, match_private: bool = False, **kwargs): parents = parents or [] args = vars(instance) # TODO don't use vars? kw = {} parents_init = [parent.__init__ for parent in parents] callable_ls = [instance.__class__.__init__, *parents_init] for callable in callable_ls: kw.update(get_dictionary_from_callable(callable, args, match_private=match_private, **kwargs)) return kw
[docs]def convert_type(maybe_iterable, conversion: dict, new_dict: dict = None): new_dict = new_dict or {} if isinstance(maybe_iterable, Iterable) and not isinstance(maybe_iterable, str): if isinstance(maybe_iterable, Mapping): for key, value in maybe_iterable.items(): new_dict[_convert_type(key, conversion)] = convert_type(value, conversion, {}) else: for index, item in enumerate(maybe_iterable): maybe_iterable[index] = convert_type(item, conversion, new_dict) return maybe_iterable else: return _convert_type(maybe_iterable, conversion) return new_dict
def _convert_type(item, conversion: dict): for type_ in conversion: if isinstance(item, type_): if type(item) in conversion: return conversion[type(item)](item) # directly use the item passed in return conversion[type_](item) return item