aboutsummaryrefslogtreecommitdiffstats
path: root/bsfs/utils/commons.py
blob: e9f0b7f5e5c936b2da077fd59de412232ead7a23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"""

Part of the BlackStar filesystem (bsfs) module.
A copy of the license is provided with the project.
Author: Matthias Baumgartner, 2022
"""
# imports
from collections import abc
import typing

# exports
__all__: typing.Sequence[str] = (
    'normalize_args',
    'typename',
    )


## code ##

def typename(obj) -> str:
    """Return the type name of *obj*."""
    return type(obj).__name__

# argument type in `normalize_args`.
ArgType = typing.TypeVar('ArgType') # pylint: disable=invalid-name # type vars don't follow the usual convention

def normalize_args(
        *args: typing.Union[ArgType, typing.Iterable[ArgType], typing.Iterator[ArgType]]
        ) -> typing.Tuple[ArgType, ...]:
    """Arguments to a function can be passed as individual arguments, list-like
    structures, or iterables. This function processes any of these styles and
    returns a tuple of the respective items. Typically used within a function
    provide a flexible interface but sill have parameters in a normalized form.

    Examples:

    >>> normalize_args(0,1,2)
    (1,2,3)
    >>> normalize_args([0,1,2])
    (1,2,3)
    >>> normalize_args(range(3))
    (1,2,3)

    """
    if len(args) == 0: # foo()
        return tuple()
    if len(args) > 1: # foo(0, 1, 2)
        return tuple(args) # type: ignore [arg-type] # we assume that argument styles (arg vs. iterable) are not mixed.
    if isinstance(args[0], abc.Iterator): # foo(iter([0,1,2]))
        return tuple(args[0])
    if isinstance(args[0], abc.Iterable) and not isinstance(args[0], str): # foo([0, 1, 2])
        return tuple(args[0])
    # foo(0)
    return (args[0], ) # type: ignore [return-value] # if args[0] is a str, we assume that ArgType was str.


## EOF ##