Source code for clinvar_build.utils.general

'''
General utility functions for the clinvar-build module
'''
import os
from typing import (
    Any,
    Callable,
    Optional,
)
from clinvar_build.errors import (
    is_type,
)
from clinvar_build.errors import (
    is_type,
)

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[docs] def assign_empty_default(arguments:list[Any], empty_object:Callable[[],Any], ) -> list[Any]: ''' Takes a list of `arguments`, checks if these are `NoneType` and if so asigns them 'empty_object'. Parameters ---------- arguments: `list` [`any`] A list of arguments which may be set to `NoneType`. empty_object: `Callable` A function that returns a mutable object Examples include a `list` or a `dict`. Returns ------- new_arguments: list List with `NoneType` replaced by empty mutable object. Examples -------- >>> assign_empty_default(['hi', None, 'hello'], empty_object=list) ['hi', [], 'hello'] Notes ----- This function helps deal with the pitfall of assigning an empty mutable object as a default function argument, which would persist through multiple function calls, leading to unexpected/undesired behaviours. ''' # check input is_type(arguments, list) is_type(empty_object, type) # loop over arguments new_args = [empty_object() if arg is None else arg for arg in arguments] # return return new_args
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def _update_kwargs(update_dict:dict[Any, Any], **kwargs:Optional[Any], ) -> dict[Any, Any]: ''' This function will take any number of `kwargs` and add them to an `update_dict`. If there are any duplicate values in the `kwargs` and the `update_dict`, the entries in the `update_dict` will take precedence. Parameters ---------- update_dict : `dict` A dictionary with key - value pairs that should be combined with any of the supplied kwargs. kwargs : `Any` Arbitrary keyword arguments. Returns ------- dict: A dictionary with the update_dict and kwargs combined, where duplicate entries from update_dict overwrite those in kwargs. Examples -------- The function is particularly useful to overwrite `kwargs` that are supplied to a nested function say >>> _update_kwargs(update_dict={'c': 'black'}, c='red', alpha = 0.5) >>> {'c': 'black', 'alpha': 0.5} ''' new_dict = {**kwargs, **update_dict} # returns return new_dict # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def _check_directory(root): """ Does directory exist. """ if os.path.isdir(root) == False: raise IOError('Directory {} does not exist'.format(root)) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def _check_directory_readable(root): """ Do we have read access. Note this should work on a directory or file. """ if os.access(root, os.R_OK) == False: raise PermissionError( 'You do not have read-access to: `{}`'.format(root) ) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def _check_directory_writable(root): """ Check if we have write access to a directory or file. """ if os.access(root, os.W_OK) == False: raise PermissionError( f'You do not have write-access to: `{root}`' )