diff --git a/src/toolbox_python/bools.py b/src/toolbox_python/bools.py index b81d229..9a8bd43 100644 --- a/src/toolbox_python/bools.py +++ b/src/toolbox_python/bools.py @@ -33,21 +33,12 @@ # ---------------------------------------------------------------------------- # -# ---------------------------------------------------------------------------- # -# Imports #### -# ---------------------------------------------------------------------------- # - - -# ## Local First Party Imports ---- -from toolbox_python.collection_types import str_list - - # ---------------------------------------------------------------------------- # # Exports #### # ---------------------------------------------------------------------------- # -__all__: str_list = ["strtobool", "STR_TO_BOOL_MAP"] +__all__: list[str] = ["strtobool", "STR_TO_BOOL_MAP"] # ---------------------------------------------------------------------------- # diff --git a/src/toolbox_python/checkers.py b/src/toolbox_python/checkers.py index 70451c1..625ff26 100644 --- a/src/toolbox_python/checkers.py +++ b/src/toolbox_python/checkers.py @@ -38,26 +38,19 @@ # ## Python StdLib Imports ---- import operator +from collections.abc import Collection from typing import Any, Callable, Union, overload # ## Python Third Party Imports ---- from typeguard import typechecked -# ## Local First Party Imports ---- -from toolbox_python.collection_types import ( - any_collection, - scalar, - str_collection, - str_list, -) - ## --------------------------------------------------------------------------- # ## Exports #### ## --------------------------------------------------------------------------- # -__all__: str_list = [ +__all__: list[str] = [ "OPERATORS", "is_value_of_type", "is_all_values_of_type", @@ -130,10 +123,8 @@ @overload def is_value_of_type(value: Any, check_type: type) -> bool: ... @overload -def is_value_of_type(value: Any, check_type: tuple[type, ...]) -> bool: ... -@overload -def is_value_of_type(value: Any, check_type: list[type]) -> bool: ... -def is_value_of_type(value: Any, check_type: Union[type, tuple[type, ...], list[type]]) -> bool: +def is_value_of_type(value: Any, check_type: Collection[type]) -> bool: ... +def is_value_of_type(value: Any, check_type: Union[type, Collection[type]]) -> bool: """ !!! note "Summary" Check if a given value is of a specified type or types. @@ -144,8 +135,8 @@ def is_value_of_type(value: Any, check_type: Union[type, tuple[type, ...], list[ Params: value (Any): The value to check. - check_type (Union[type, tuple[type, ...], list[type]]): - The type or tuple of types to check against. + check_type (Union[type, Collection[type]]): + The type or Collection of types to check against. Returns: (bool): @@ -185,20 +176,15 @@ def is_value_of_type(value: Any, check_type: Union[type, tuple[type, ...], list[ - [`is_value_of_type()`][toolbox_python.checkers.is_value_of_type] - [`is_type()`][toolbox_python.checkers.is_type] """ - check_type = tuple(check_type) if isinstance(check_type, list) else check_type + check_type = tuple(check_type) if not isinstance(check_type, type) else check_type return isinstance(value, check_type) @overload -def is_all_values_of_type(values: any_collection, check_type: type) -> bool: ... -@overload -def is_all_values_of_type(values: any_collection, check_type: tuple[type, ...]) -> bool: ... +def is_all_values_of_type(values: Collection[Any], check_type: type) -> bool: ... @overload -def is_all_values_of_type(values: any_collection, check_type: list[type]) -> bool: ... -def is_all_values_of_type( - values: any_collection, - check_type: Union[type, tuple[type, ...], list[type]], -) -> bool: +def is_all_values_of_type(values: Collection[Any], check_type: Collection[type]) -> bool: ... +def is_all_values_of_type(values: Collection[Any], check_type: Union[type, Collection[type]]) -> bool: """ !!! note "Summary" Check if all values in an iterable are of a specified type or types. @@ -207,10 +193,10 @@ def is_all_values_of_type( This function is used to verify if all values in a given iterable match a specified type or any of the types in a tuple of types. Params: - values (any_collection): + values (Collection[Any]): The iterable containing values to check. - check_type (Union[type, tuple[type, ...], list[type]]): - The type or tuple of types to check against. + check_type (Union[type, Collection[type]]): + The type or Collection of types to check against. Returns: (bool): @@ -252,20 +238,15 @@ def is_all_values_of_type( - [`is_type()`][toolbox_python.checkers.is_type] - [`is_all_type()`][toolbox_python.checkers.is_all_type] """ - check_type = tuple(check_type) if isinstance(check_type, list) else check_type + check_type = tuple(check_type) if not isinstance(check_type, type) else check_type return all(isinstance(value, check_type) for value in values) @overload -def is_any_values_of_type(values: any_collection, check_type: type) -> bool: ... +def is_any_values_of_type(values: Collection[Any], check_type: type) -> bool: ... @overload -def is_any_values_of_type(values: any_collection, check_type: tuple[type, ...]) -> bool: ... -@overload -def is_any_values_of_type(values: any_collection, check_type: list[type]) -> bool: ... -def is_any_values_of_type( - values: any_collection, - check_type: Union[type, tuple[type, ...], list[type]], -) -> bool: +def is_any_values_of_type(values: Collection[Any], check_type: Collection[type]) -> bool: ... +def is_any_values_of_type(values: Collection[Any], check_type: Union[type, Collection[type]]) -> bool: """ !!! note "Summary" Check if any value in an iterable is of a specified type or types. @@ -274,10 +255,10 @@ def is_any_values_of_type( This function is used to verify if any value in a given iterable matches a specified type or any of the types in a tuple of types. Params: - values (any_collection): + values (Collection[Any]): The iterable containing values to check. - check_type (Union[type, tuple[type, ...], list[type]]): - The type or tuple of types to check against. + check_type (Union[type, Collection[type]]): + The type or Collection of types to check against. Returns: (bool): @@ -319,15 +300,12 @@ def is_any_values_of_type( - [`is_type()`][toolbox_python.checkers.is_type] - [`is_any_type()`][toolbox_python.checkers.is_any_type] """ - check_type = tuple(check_type) if isinstance(check_type, list) else check_type + check_type = tuple(check_type) if not isinstance(check_type, type) else check_type return any(isinstance(value, check_type) for value in values) @typechecked -def is_value_in_iterable( - value: scalar, - iterable: any_collection, -) -> bool: +def is_value_in_iterable(value: Any, iterable: Collection[Any]) -> bool: """ !!! note "Summary" Check if a given value is present in an iterable. @@ -336,9 +314,9 @@ def is_value_in_iterable( This function is used to verify if a given value exists within an iterable such as a list, tuple, or set. Params: - value (scalar): + value (Any): The value to check. - iterable (any_collection): + iterable (Collection[Any]): The iterable to check within. Raises: @@ -387,10 +365,7 @@ def is_value_in_iterable( @typechecked -def is_all_values_in_iterable( - values: any_collection, - iterable: any_collection, -) -> bool: +def is_all_values_in_iterable(values: Collection[Any], iterable: Collection[Any]) -> bool: """ !!! note "Summary" Check if all values in an iterable are present in another iterable. @@ -399,9 +374,9 @@ def is_all_values_in_iterable( This function is used to verify if all values in a given iterable exist within another iterable. Params: - values (any_collection): + values (Collection[Any]): The iterable containing values to check. - iterable (any_collection): + iterable (Collection[Any]): The iterable to check within. Raises: @@ -452,10 +427,7 @@ def is_all_values_in_iterable( @typechecked -def is_any_values_in_iterable( - values: any_collection, - iterable: any_collection, -) -> bool: +def is_any_values_in_iterable(values: Collection[Any], iterable: Collection[Any]) -> bool: """ !!! note "Summary" Check if any value in an iterable is present in another iterable. @@ -464,9 +436,9 @@ def is_any_values_in_iterable( This function is used to verify if any value in a given iterable exists within another iterable. Params: - values (any_collection): + values (Collection[Any]): The iterable containing values to check. - iterable (any_collection): + iterable (Collection[Any]): The iterable to check within. Raises: @@ -575,13 +547,13 @@ def is_valid_value(value: Any, op: str, target: Any) -> bool: ### Aliases ---- -is_type = is_value_of_type -is_all_type = is_all_values_of_type -is_any_type = is_any_values_of_type -is_in = is_value_in_iterable -is_any_in = is_any_values_in_iterable -is_all_in = is_all_values_in_iterable -is_valid = is_valid_value +is_type: Callable[..., bool] = is_value_of_type +is_all_type: Callable[..., bool] = is_all_values_of_type +is_any_type: Callable[..., bool] = is_any_values_of_type +is_in: Callable[..., bool] = is_value_in_iterable +is_any_in: Callable[..., bool] = is_any_values_in_iterable +is_all_in: Callable[..., bool] = is_all_values_in_iterable +is_valid: Callable[..., bool] = is_valid_value ## --------------------------------------------------------------------------- # @@ -592,13 +564,8 @@ def is_valid_value(value: Any, op: str, target: Any) -> bool: @overload def assert_value_of_type(value: Any, check_type: type) -> None: ... @overload -def assert_value_of_type(value: Any, check_type: tuple[type, ...]) -> None: ... -@overload -def assert_value_of_type(value: Any, check_type: list[type]) -> None: ... -def assert_value_of_type( - value: Any, - check_type: Union[type, tuple[type, ...], list[type]], -) -> None: +def assert_value_of_type(value: Any, check_type: Collection[type]) -> None: ... +def assert_value_of_type(value: Any, check_type: Union[type, Collection[type]]) -> None: """ !!! note "Summary" Assert that a given value is of a specified type or types. @@ -609,8 +576,8 @@ def assert_value_of_type( Params: value (Any): The value to check. - check_type (Union[type, tuple[type, ...], list[type]]): - The type or tuple of types to check against. + check_type (Union[type, Collection[type]]): + The type or Collection of types to check against. Raises: (TypeError): @@ -684,15 +651,10 @@ def assert_value_of_type( @overload -def assert_all_values_of_type(values: any_collection, check_type: type) -> None: ... -@overload -def assert_all_values_of_type(values: any_collection, check_type: tuple[type, ...]) -> None: ... +def assert_all_values_of_type(values: Collection[Any], check_type: type) -> None: ... @overload -def assert_all_values_of_type(values: any_collection, check_type: list[type]) -> None: ... -def assert_all_values_of_type( - values: any_collection, - check_type: Union[type, tuple[type, ...], list[type]], -) -> None: +def assert_all_values_of_type(values: Collection[Any], check_type: Collection[type]) -> None: ... +def assert_all_values_of_type(values: Collection[Any], check_type: Union[type, Collection[type]]) -> None: """ !!! note "Summary" Assert that all values in an iterable are of a specified type or types. @@ -701,10 +663,10 @@ def assert_all_values_of_type( This function is used to assert that all values in a given iterable match a specified type or any of the types in a tuple of types. If any value does not match the specified type(s), a `#!py TypeError` is raised. Params: - values (any_collection): + values (Collection[Any]): The iterable containing values to check. - check_type (Union[type, tuple[type, ...], list[type]]): - The type or tuple of types to check against. + check_type (Union[type, Collection[type]]): + The type or Collection of types to check against. Raises: (TypeError): @@ -771,27 +733,22 @@ def assert_all_values_of_type( - [`is_all_type()`][toolbox_python.checkers.is_all_type] """ if not is_all_type(values=values, check_type=check_type): - invalid_values = [value for value in values if not is_type(value, check_type)] - invalid_types = [f"'{type(value).__name__}'" for value in values if not is_type(value, check_type)] + invalid_values: list[Any] = [value for value in values if not is_type(value, check_type)] + invalid_types: list[str] = [f"'{type(value).__name__}'" for value in values if not is_type(value, check_type)] msg: str = f"Some elements {invalid_values} have the incorrect type {invalid_types}. " if isinstance(check_type, type): - msg += f"Must be '{check_type}'" + msg += f"Must be '{check_type.__name__}'" else: - types: str_list = [f"'{typ.__name__}'" for typ in check_type] + types: list[str] = [f"'{typ.__name__}'" for typ in check_type] msg += f"Must be: {' or '.join(types)}" raise TypeError(msg) @overload -def assert_any_values_of_type(values: any_collection, check_type: type) -> None: ... +def assert_any_values_of_type(values: Collection[Any], check_type: type) -> None: ... @overload -def assert_any_values_of_type(values: any_collection, check_type: tuple[type, ...]) -> None: ... -@overload -def assert_any_values_of_type(values: any_collection, check_type: list[type]) -> None: ... -def assert_any_values_of_type( - values: any_collection, - check_type: Union[type, tuple[type, ...], list[type]], -) -> None: +def assert_any_values_of_type(values: Collection[Any], check_type: Collection[type]) -> None: ... +def assert_any_values_of_type(values: Collection[Any], check_type: Union[type, Collection[type]]) -> None: """ !!! note "Summary" Assert that any value in an iterable is of a specified type or types. @@ -800,10 +757,10 @@ def assert_any_values_of_type( This function is used to assert that at least one value in a given iterable matches a specified type or any of the types in a tuple of types. If none of the values match the specified type(s), a `#!py TypeError` is raised. Params: - values (any_collection): + values (Collection[Any]): The iterable containing values to check. - check_type (Union[type, tuple[type, ...], list[type]]): - The type or tuple of types to check against. + check_type (Union[type, Collection[type]]): + The type or Collection of types to check against. Raises: (TypeError): @@ -870,20 +827,17 @@ def assert_any_values_of_type( - [`is_any_type()`][toolbox_python.checkers.is_any_type] """ if not is_any_type(values=values, check_type=check_type): - invalid_values = [value for value in values if not is_type(value, check_type)] + invalid_values: list[Any] = [value for value in values if not is_type(value, check_type)] msg: str = f"None of the elements in {invalid_values} have the correct type. " if isinstance(check_type, type): msg += f"Must be: '{check_type.__name__}'" else: - types: str_list = [f"'{typ.__name__}'" for typ in check_type] + types: list[str] = [f"'{typ.__name__}'" for typ in check_type] msg += f"Must be: {' or '.join(types)}" raise TypeError(msg) -def assert_value_in_iterable( - value: scalar, - iterable: any_collection, -) -> None: +def assert_value_in_iterable(value: Any, iterable: Collection[Any]) -> None: """ !!! note "Summary" Assert that a given value is present in an iterable. @@ -892,9 +846,9 @@ def assert_value_in_iterable( This function is used to assert that a given value exists within an iterable such as a `#!py list`, `#!py tuple`, or `#!py set`. If the value is not found in the iterable, a `#!py LookupError` is raised. Params: - value (scalar): + value (Any): The value to check. - iterable (any_collection): + iterable (Collection[Any]): The iterable to check within. Raises: @@ -943,10 +897,7 @@ def assert_value_in_iterable( raise LookupError(f"Value '{value}' not found in iterable: {iterable}") -def assert_any_values_in_iterable( - values: any_collection, - iterable: any_collection, -) -> None: +def assert_any_values_in_iterable(values: Collection[Any], iterable: Collection[Any]) -> None: """ !!! note "Summary" Assert that any value in an iterable is present in another iterable. @@ -955,9 +906,9 @@ def assert_any_values_in_iterable( This function is used to assert that at least one value in a given iterable exists within another iterable. If none of the values are found in the iterable, a `#!py LookupError` is raised. Params: - values (any_collection): + values (Collection[Any]): The iterable containing values to check. - iterable (any_collection): + iterable (Collection[Any]): The iterable to check within. Raises: @@ -1008,10 +959,7 @@ def assert_any_values_in_iterable( raise LookupError(f"None of the values in {values} can be found in {iterable}") -def assert_all_values_in_iterable( - values: any_collection, - iterable: any_collection, -) -> None: +def assert_all_values_in_iterable(values: Collection[Any], iterable: Collection[Any]) -> None: """ !!! note "Summary" Assert that all values in an iterable are present in another iterable. @@ -1020,9 +968,9 @@ def assert_all_values_in_iterable( This function is used to assert that all values in a given iterable exist within another iterable. If any value is not found in the iterable, a `#!py LookupError` is raised. Params: - values (any_collection): + values (Collection[Any]): The iterable containing values to check. - iterable (any_collection): + iterable (Collection[Any]): The iterable to check within. Raises: @@ -1070,7 +1018,7 @@ def assert_all_values_in_iterable( - [`is_all_in()`][toolbox_python.checkers.is_all_in] """ if not is_all_in(values=values, iterable=iterable): - missing_values = [value for value in values if not is_in(value, iterable)] + missing_values: list[Any] = [value for value in values if not is_in(value, iterable)] raise LookupError(f"Some values {missing_values} are missing from {iterable}") @@ -1131,16 +1079,16 @@ def assert_is_valid_value(value: Any, op: str, target: Any) -> None: ### Aliases ---- -assert_type = assert_value_of_type -assert_is_type = assert_value_of_type -assert_all_type = assert_all_values_of_type -assert_all_is_type = assert_all_values_of_type -assert_any_type = assert_any_values_of_type -assert_any_is_type = assert_any_values_of_type -assert_in = assert_value_in_iterable -assert_any_in = assert_any_values_in_iterable -assert_all_in = assert_all_values_in_iterable -assert_is_valid = assert_is_valid_value +assert_type: Callable[..., None] = assert_value_of_type +assert_is_type: Callable[..., None] = assert_value_of_type +assert_all_type: Callable[..., None] = assert_all_values_of_type +assert_all_is_type: Callable[..., None] = assert_all_values_of_type +assert_any_type: Callable[..., None] = assert_any_values_of_type +assert_any_is_type: Callable[..., None] = assert_any_values_of_type +assert_in: Callable[..., None] = assert_value_in_iterable +assert_any_in: Callable[..., None] = assert_any_values_in_iterable +assert_all_in: Callable[..., None] = assert_all_values_in_iterable +assert_is_valid: Callable[..., None] = assert_is_valid_value ## --------------------------------------------------------------------------- # @@ -1149,10 +1097,7 @@ def assert_is_valid_value(value: Any, op: str, target: Any) -> None: @typechecked -def any_element_contains( - iterable: str_collection, - check: str, -) -> bool: +def any_element_contains(iterable: Collection[str], check: str) -> bool: """ !!! note "Summary" Check to see if any element in a given iterable contains a given string value. @@ -1162,7 +1107,7 @@ def any_element_contains( This function is helpful for doing a quick check to see if any element in a `#!py list` contains a given `#!py str` value. For example, checking if any column header contains a specific string value. Params: - iterable (str_collection): + iterable (Collection[str]): The iterables to check within. Because this function uses an `#!py in` operation to check if `check` string exists in the elements of `iterable`, therefore all elements of `iterable` must be `#!py str` type. check (str): The string value to check exists in any of the elements in `iterable`. @@ -1209,7 +1154,7 @@ def any_element_contains( @typechecked -def all_elements_contains(iterable: str_collection, check: str) -> bool: +def all_elements_contains(iterable: Collection[str], check: str) -> bool: """ !!! note "Summary" Check to see if all elements in a given iterable contains a given string value. @@ -1219,7 +1164,7 @@ def all_elements_contains(iterable: str_collection, check: str) -> bool: This function is helpful for doing a quick check to see if all element in a `#!py list` contains a given `#!py str` value. For example, checking if all columns in a DataFrame contains a specific string value. Params: - iterable (str_collection): + iterable (Collection[str]): The iterables to check within. Because this function uses an `#!py in` operation to check if `check` string exists in the elements of `iterable`, therefore all elements of `iterable` must be `#!py str` type. check (str): The string value to check exists in any of the elements in `iterable`. @@ -1266,14 +1211,14 @@ def all_elements_contains(iterable: str_collection, check: str) -> bool: @typechecked -def get_elements_containing(iterable: str_collection, check: str) -> tuple[str, ...]: +def get_elements_containing(iterable: Collection[str], check: str) -> tuple[str, ...]: """ !!! note "Summary" Extract all elements in a given iterable which contains a given string value. !!! warning "Note: This check _is_ case sensitive." Params: - iterable (str_collection): + iterable (Collection[str]): The iterables to check within. Because this function uses an `#!py in` operation to check if `check` string exists in the elements of `iterable`, therefore all elements of `iterable` must be `#!py str` type. check (str): The string value to check exists in any of the elements in `iterable`. diff --git a/src/toolbox_python/collection_types.py b/src/toolbox_python/collection_types.py index 60977d4..4cb63e5 100644 --- a/src/toolbox_python/collection_types.py +++ b/src/toolbox_python/collection_types.py @@ -20,7 +20,7 @@ # ## Python StdLib Imports ---- from datetime import datetime -from typing import Any, Literal, Union +from typing import Any, Union ## --------------------------------------------------------------------------- # @@ -40,7 +40,6 @@ "int_list", "int_tuple", "iterable", - "log_levels", "scalar", "str_collection", "str_dict", @@ -128,15 +127,3 @@ ] ``` """ - - -log_levels = Literal["debug", "info", "warning", "error", "critical"] -""" -!!! note "Summary" - To streamline other functions, this `type` alias is created for all of the `log` levels available. -!!! abstract "Details" - The structure of the `type` is as follows: - ```pycon {.py .python linenums="1" title="Type structure"} - Literal["debug", "info", "warning", "error", "critical"] - ``` -""" diff --git a/src/toolbox_python/defaults.py b/src/toolbox_python/defaults.py index 8172401..bf4b892 100644 --- a/src/toolbox_python/defaults.py +++ b/src/toolbox_python/defaults.py @@ -48,7 +48,6 @@ # ## Local First Party Imports ---- from toolbox_python.bools import strtobool from toolbox_python.checkers import is_type -from toolbox_python.collection_types import str_list # ---------------------------------------------------------------------------- # @@ -56,7 +55,7 @@ # ---------------------------------------------------------------------------- # -__all__: str_list = ["defaults", "Defaults"] +__all__: list[str] = ["defaults", "Defaults"] # ---------------------------------------------------------------------------- # @@ -77,6 +76,11 @@ class Defaults: When we create and use Python variables, it is sometimes handy to add a default value for that variable. This class will handle that process. + Methods: + - get(): From the value that is parsed in to the `value` parameter, convert it to `default` if `value` is `#!py None`, and convert it to `cast` if `cast` is not `#!py None`. + - _validate_value_and_default(): Validate to ensure that `value` and `default` are not both `#!py None`. + - _validate_type(): Check to ensure that `check_type` is a valid Python type + ???+ example "Examples" ```pycon {.py .python linenums="1" title="Set up data for examples"} @@ -396,7 +400,7 @@ def _validate_type( ??? tip "See Also" - [`Defaults.get()`][toolbox_python.defaults.Defaults.get] """ - valid_types: str_list = [ + valid_types: list[str] = [ "bool", "dict", "int", diff --git a/src/toolbox_python/dictionaries.py b/src/toolbox_python/dictionaries.py index bdd4a43..b3e02e5 100644 --- a/src/toolbox_python/dictionaries.py +++ b/src/toolbox_python/dictionaries.py @@ -44,15 +44,13 @@ # ## Python Third Party Imports ---- from typeguard import typechecked -# ## Local First Party Imports ---- -from toolbox_python.collection_types import dict_any, dict_str_any, str_list - # ---------------------------------------------------------------------------- # # Exports #### # ---------------------------------------------------------------------------- # -__all__: str_list = ["dict_reverse_keys_and_values", "DotDict"] + +__all__: list[str] = ["dict_reverse_keys_and_values", "DotDict"] # ---------------------------------------------------------------------------- # @@ -63,7 +61,7 @@ @typechecked -def dict_reverse_keys_and_values(dictionary: dict_any) -> dict_str_any: +def dict_reverse_keys_and_values(dictionary: dict[Any, Any]) -> dict[str, Any]: """ !!! note "Summary" Take the `key` and `values` of a dictionary, and reverse them. @@ -72,7 +70,7 @@ def dict_reverse_keys_and_values(dictionary: dict_any) -> dict_str_any: This process is simple enough if the `values` are atomic types, like `#!py str`, `#!py int`, or `#!py float` types. But it is a little more tricky when the `values` are more complex types, like `#!py list` or `#!py dict`; here we need to use some recursion. Params: - dictionary (dict_any): + dictionary (Dict[Any, Any]): The input `#!py dict` that you'd like to have the `keys` and `values` switched. Raises: @@ -82,7 +80,7 @@ def dict_reverse_keys_and_values(dictionary: dict_any) -> dict_str_any: When there are duplicate `values` being coerced to `keys` in the new dictionary. Raised because a Python `#!py dict` cannot have duplicate keys of the same value. Returns: - output_dict (dict_str_int): + output_dict (Dict[str,Any]): The updated `#!py dict`. ???+ example "Examples" @@ -204,7 +202,7 @@ def dict_reverse_keys_and_values(dictionary: dict_any) -> dict_str_any: !!! observation "Here, the process would be to run a recursive process when it recognises that any `value` is a `#!py dict` object. So long as there are no duplicate values in any of the contained `#!py dict`'s, the resulting output will be a big, flat dictionary." """ - output_dict: dict_str_any = dict() + output_dict: dict[str, Any] = dict() for key, value in dictionary.items(): if isinstance(value, (str, int, float)): output_dict[str(value)] = key @@ -219,7 +217,7 @@ def dict_reverse_keys_and_values(dictionary: dict_any) -> dict_str_any: ) output_dict[str(elem)] = key elif isinstance(value, dict): - interim_dict: dict_str_any = dict_reverse_keys_and_values(value) + interim_dict: dict[str, Any] = dict_reverse_keys_and_values(value) output_dict = { **output_dict, **interim_dict, diff --git a/src/toolbox_python/generators.py b/src/toolbox_python/generators.py index e76aaee..856794d 100644 --- a/src/toolbox_python/generators.py +++ b/src/toolbox_python/generators.py @@ -41,7 +41,6 @@ # ## Local First Party Imports ---- from toolbox_python.checkers import assert_is_valid -from toolbox_python.collection_types import str_list ## --------------------------------------------------------------------------- # @@ -49,7 +48,7 @@ ## --------------------------------------------------------------------------- # -__all__: str_list = ["generate_group_cutoffs"] +__all__: list[str] = ["generate_group_cutoffs"] # ---------------------------------------------------------------------------- # diff --git a/src/toolbox_python/lists.py b/src/toolbox_python/lists.py index efcb906..99e0490 100644 --- a/src/toolbox_python/lists.py +++ b/src/toolbox_python/lists.py @@ -39,27 +39,21 @@ # ## Python StdLib Imports ---- +from collections.abc import Collection from itertools import product as itertools_product -from typing import Any, Optional, Union +from typing import Any, Optional # ## Python Third Party Imports ---- from more_itertools import collapse as itertools_collapse from typeguard import typechecked -# ## Local First Party Imports ---- -from toolbox_python.collection_types import ( - any_list, - collection, - scalar, - str_list, -) - # ---------------------------------------------------------------------------- # # Exports #### # ---------------------------------------------------------------------------- # -__all__: str_list = ["flatten", "flat_list", "product"] + +__all__: list[str] = ["flatten", "flat_list", "product"] # ---------------------------------------------------------------------------- # @@ -71,10 +65,10 @@ @typechecked def flatten( - list_of_lists: Union[scalar, collection], + list_of_lists: Collection[Collection[Any]], base_type: Optional[type] = None, levels: Optional[int] = None, -) -> any_list: +) -> list[Any]: """ !!! note "Summary" For a given `#!py list` of `#!py list`'s, flatten it out to be a single `#!py list`. @@ -86,7 +80,7 @@ def flatten( [more_itertools.collapse]: https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.collapse Params: - list_of_lists (Union[scalar, collection]): + list_of_lists (Collection[Collection[Any]]): The input `#!py list` of `#!py list`'s that you'd like to flatten to a single-level `#!py list`. base_type (Optional[type], optional): Binary and text strings are not considered iterable and will not be collapsed. To avoid collapsing other types, specify `base_type`.
@@ -195,7 +189,7 @@ def flatten( """ return list( itertools_collapse( - iterable=list_of_lists, # type: ignore + iterable=list_of_lists, base_type=base_type, levels=levels, ) @@ -203,7 +197,7 @@ def flatten( @typechecked -def flat_list(*inputs: Any) -> any_list: +def flat_list(*inputs: Any) -> list[Any]: """ !!! note "Summary" Take in any number of inputs, and output them all in to a single flat `#!py list`. @@ -217,7 +211,7 @@ def flat_list(*inputs: Any) -> any_list: If any of the inputs parsed to the parameters of this function are not the correct type. Uses the [`@typeguard.typechecked`](https://typeguard.readthedocs.io/en/stable/api.html#typeguard.typechecked) decorator. Returns: - (any_list): + (list[Any]): The input having been coerced to a single flat `#!py list`. ???+ example "Examples" diff --git a/src/toolbox_python/output.py b/src/toolbox_python/output.py index 8a0a38f..ed02c57 100644 --- a/src/toolbox_python/output.py +++ b/src/toolbox_python/output.py @@ -39,7 +39,7 @@ # ## Python StdLib Imports ---- -from collections.abc import Generator +from collections.abc import Collection, Generator from logging import Logger, _nameToLevel from math import ceil from typing import Any, Literal, Optional, Union, overload @@ -54,13 +54,6 @@ assert_is_valid, is_type, ) -from toolbox_python.collection_types import ( - any_list, - any_set, - any_tuple, - log_levels, - str_list, -) # ---------------------------------------------------------------------------- # @@ -68,7 +61,24 @@ # ---------------------------------------------------------------------------- # -__all__: str_list = ["print_or_log_output", "list_columns"] +__all__: list[str] = ["print_or_log_output", "list_columns", "log_levels"] + + +## --------------------------------------------------------------------------- # +## Constants #### +## --------------------------------------------------------------------------- # + + +log_levels = Literal["debug", "info", "warning", "error", "critical"] +""" +!!! note "Summary" + To streamline other functions, this `type` alias is created for all of the `log` levels available. +!!! abstract "Details" + The structure of the `type` is as follows: + ```pycon {.py .python linenums="1" title="Type structure"} + Literal["debug", "info", "warning", "error", "critical"] + ``` +""" # ---------------------------------------------------------------------------- # @@ -265,38 +275,20 @@ def print_or_log_output( return None -@overload -@typechecked -def list_columns( - obj: Union[any_list, any_set, any_tuple, Generator], - cols_wide: int = 4, - columnwise: bool = True, - gap: int = 4, - print_output: Literal[False] = False, -) -> str: ... -@overload -@typechecked -def list_columns( - obj: Union[any_list, any_set, any_tuple, Generator], - cols_wide: int = 4, - columnwise: bool = True, - gap: int = 4, - print_output: Literal[True] = True, -) -> None: ... @typechecked def list_columns( - obj: Union[any_list, any_set, any_tuple, Generator], + obj: Union[Collection[Any], Generator], cols_wide: int = 4, columnwise: bool = True, gap: int = 4, - print_output: bool = False, + print_output: Literal[True, False] = False, ) -> Optional[str]: """ !!! note "Summary" Print the given list in evenly-spaced columns. Params: - obj (Union[any_list, any_set, any_tuple, Generator]): + obj (Union[Collection[Any], Generator]): The list to be formatted. cols_wide (int, optional): @@ -317,7 +309,7 @@ def list_columns( between columns based on the maximum `#!py len()` of the list items.
Defaults to: `#!py 4`. - print_output (bool, optional): + print_output (Literal[True, False], optional): Whether or not to print the output to the terminal. - `#!py True`: Will print and return. @@ -433,7 +425,7 @@ def list_columns( assert_is_valid(gap, ">", 0) # Prepare the string representation of the object - string_list: str_list = [str(item) for item in obj] + string_list: list[str] = [str(item) for item in obj] cols_wide = min(cols_wide, len(string_list)) max_len: int = max(len(item) for item in string_list) @@ -442,7 +434,7 @@ def list_columns( cols_wide = int(ceil(len(string_list) / cols_wide)) # Segment the list into chunks - segmented_list: list[str_list] = [ + segmented_list: list[list[str]] = [ string_list[index : index + cols_wide] for index in range(0, len(string_list), cols_wide) ] @@ -450,7 +442,7 @@ def list_columns( if columnwise: if len(segmented_list[-1]) != cols_wide: segmented_list[-1].extend([""] * (len(string_list) - len(segmented_list[-1]))) - combined_list: Union[list[str_list], Any] = zip(*segmented_list) + combined_list: Union[list[list[str]], Any] = zip(*segmented_list) else: combined_list = segmented_list diff --git a/src/toolbox_python/retry.py b/src/toolbox_python/retry.py index 709decd..91955f2 100644 --- a/src/toolbox_python/retry.py +++ b/src/toolbox_python/retry.py @@ -53,7 +53,6 @@ # ## Local First Party Imports ---- from toolbox_python.checkers import assert_is_valid from toolbox_python.classes import get_full_class_name -from toolbox_python.collection_types import str_list from toolbox_python.output import print_or_log_output @@ -62,7 +61,7 @@ # ---------------------------------------------------------------------------- # -__all__: str_list = ["retry"] +__all__: list[str] = ["retry"] # ---------------------------------------------------------------------------- # @@ -77,11 +76,15 @@ ] """ !!! note "Summary" - This + A type alias for a single or collection of `Exception` types. """ R = TypeVar("R") +""" +!!! note "Summary" + A generic type variable to represent the return type of a function. +""" # ---------------------------------------------------------------------------- # diff --git a/src/toolbox_python/strings.py b/src/toolbox_python/strings.py index e9d3b67..ab37e45 100644 --- a/src/toolbox_python/strings.py +++ b/src/toolbox_python/strings.py @@ -46,14 +46,14 @@ # ## Local First Party Imports ---- from toolbox_python.checkers import is_type -from toolbox_python.collection_types import str_list, str_list_tuple # ---------------------------------------------------------------------------- # # Exports #### # ---------------------------------------------------------------------------- # -__all__: str_list = [ + +__all__: list[str] = [ "str_replace", "str_contains", "str_contains_any", @@ -226,7 +226,7 @@ def str_contains(check_string: str, sub_string: str) -> bool: @typechecked def str_contains_any( check_string: str, - sub_strings: str_list_tuple, + sub_strings: Union[list[str], tuple[str, ...]], ) -> bool: """ !!! note "Summary" @@ -235,7 +235,7 @@ def str_contains_any( Params: check_string (str): The main string to check. - sub_strings (str_list_tuple): + sub_strings (Union[list[str], tuple[str, ...]]): The collection of substrings to check. Raises: @@ -300,7 +300,7 @@ def str_contains_any( @typechecked def str_contains_all( check_string: str, - sub_strings: str_list_tuple, + sub_strings: Union[list[str], tuple[str, ...]], ) -> bool: """ !!! note "Summary" @@ -309,7 +309,7 @@ def str_contains_all( Params: check_string (str): The main string to check. - sub_strings (str_list_tuple): + sub_strings (Union[list[str], tuple[str, ...]]): The collection of substrings to check. Raises: @@ -382,7 +382,7 @@ def str_contains_all( @typechecked -def str_separate_number_chars(text: str) -> str_list: +def str_separate_number_chars(text: str) -> list[str]: """ !!! note "Summary" Take in a string that contains both numbers and letters, and output a list of strings, separated to have each element containing either entirely number or entirely letters. @@ -400,7 +400,7 @@ def str_separate_number_chars(text: str) -> str_list: If any of the inputs parsed to the parameters of this function are not the correct type. Uses the [`@typeguard.typechecked`](https://typeguard.readthedocs.io/en/stable/api.html#typeguard.typechecked) decorator. Returns: - (str_list): + (list[str]): The updated list, with each element of the list containing either entirely characters or entirely numbers. ???+ example "Examples" @@ -474,12 +474,12 @@ def str_separate_number_chars(text: str) -> str_list: @overload @typechecked -def str_to_list(obj: str) -> str_list: ... +def str_to_list(obj: str) -> list[str]: ... @overload @typechecked def str_to_list(obj: Any) -> Any: ... @typechecked -def str_to_list(obj: Any) -> Union[str_list, Any]: +def str_to_list(obj: Any) -> Union[list[str], Any]: """ !!! note "Summary" Convert a string to a list containing that string as the only element. @@ -496,7 +496,7 @@ def str_to_list(obj: Any) -> Union[str_list, Any]: If `obj` is not a string or a list. Returns: - (Union[str_list, Any]): + (Union[list[str], Any]): If `obj` is a string, returns a list containing that string as the only element. If `obj` is not a string, returns it unchanged. ???+ example "Examples"