Skip to content

typing

TypeHint module-attribute

TypeHint: Any

For documentation purposes - to mark type hint arguments.

to38hint module-attribute

to38hint: Dict[Type, Any] = {
    list: List,
    set: Set,
    dict: Dict,
    type: Type,
}

Type hint map for consistent behavior between python versions.

traverse_typehint module-attribute

traverse_typehint = make_tree_traversal(get_args)

Perform depth-first pre-order traversal of a type annotation.

Parameters:

Name Type Description Default
th object

type hint object to be traversed

required

get_type_hints

get_type_hints(cls) -> Mapping[str, Any]

Return type hints of this class.

Source code in src/metador_core/util/typing.py
29
30
31
def get_type_hints(cls) -> Mapping[str, Any]:
    """Return type hints of this class."""
    return te.get_type_hints(cls, include_extras=True)

get_annotations

get_annotations(
    cls, *, all: bool = False
) -> Mapping[str, Any]

Return (non-inherited) annotations (unparsed) of given class.

Source code in src/metador_core/util/typing.py
34
35
36
37
38
def get_annotations(cls, *, all: bool = False) -> Mapping[str, Any]:
    """Return (non-inherited) annotations (unparsed) of given class."""
    if not all:
        return cls.__dict__.get("__annotations__", {})
    return ChainMap(*(c.__dict__.get("__annotations__", {}) for c in cls.__mro__))

make_literal

make_literal(val)

Given a JSON object, return type that parses exactly that object.

Note that dicts can have extra fields that will be ignored and that coercion between bool and int might happen.

Sets and floats are not supported.

Source code in src/metador_core/util/typing.py
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
def make_literal(val):
    """Given a JSON object, return type that parses exactly that object.

    Note that dicts can have extra fields that will be ignored
    and that coercion between bool and int might happen.

    Sets and floats are not supported.
    """
    if val is None:
        return type(None)
    elif isinstance(val, (bool, int, str)):
        return make_typehint(LIT, val)
    elif issubclass(val.__class__, enum.Enum):
        return make_typehint(LIT, val.value)
    elif isinstance(val, (tuple, list)):
        args = tuple(map(make_literal, val))
        return make_typehint(TUP, *args)
    elif isinstance(val, dict):
        d = {k: make_literal(v) for k, v in val.items()}
        # NOTE: the TypedDict must be from typing_extensions for 3.8!
        return TypedDict("AnonConstDict", d)  # type: ignore
    raise ValueError(f"Unsupported value: {val}")

make_tree_traversal

make_tree_traversal(succ_func: Callable[[Any], Iterable])

Return generator to traverse nodes of a tree-shaped object.

Returned function has a boolean keyword argument post_order. If True, will emit the parent node after children instead of before.

Parameters:

Name Type Description Default
succ_func Callable[[Any], Iterable]

Function to be called on each node returning Iterable of children

required
Source code in src/metador_core/util/typing.py
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
def make_tree_traversal(succ_func: Callable[[Any], Iterable]):
    """Return generator to traverse nodes of a tree-shaped object.

    Returned function has a boolean keyword argument `post_order`.
    If True, will emit the parent node after children instead of before.

    Args:
        succ_func: Function to be called on each node returning Iterable of children
    """

    def traverse(obj, *, post_order: bool = False):
        if not post_order:
            yield obj
        for t in succ_func(obj):
            yield from traverse(t, post_order=post_order)
        if post_order:
            yield obj

    return traverse

unoptional

unoptional(th)

Return type hint that is not optional (if it was optional).

Source code in src/metador_core/util/typing.py
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
def unoptional(th):
    """Return type hint that is not optional (if it was optional)."""
    if is_annotated(th):
        # remove inner optional, preserve annotation
        return make_typehint(th, unoptional(get_args(th)[0]))

    if not is_union(th):
        # all optionals are actually unions -> nothing to do
        return th

    # filter out NoneType from the Union arguments
    args = tuple(filter(lambda h: not is_nonetype(h), get_args(th)))
    if len(args) == 1:
        # not a union anymore -> remove type
        return args[0]
    # remove union without NoneType (i.e. not optional)
    return make_typehint(UNION_PROXY, *args)

is_subtype_of

is_subtype_of(t: Any) -> Callable[[Any], bool]

Return a predicate to check issubtype for a given type.

Source code in src/metador_core/util/typing.py
226
227
228
def is_subtype_of(t: Any) -> Callable[[Any], bool]:
    """Return a predicate to check issubtype for a given type."""
    return lambda obj: is_subtype(obj, t)

is_instance_of

is_instance_of(t: Any) -> Callable[[Any], bool]

Return a predicate to check isinstance for a given type.

Source code in src/metador_core/util/typing.py
231
232
233
def is_instance_of(t: Any) -> Callable[[Any], bool]:
    """Return a predicate to check isinstance for a given type."""
    return lambda obj: isinstance(obj, t)

is_subclass_of

is_subclass_of(t: Any) -> Callable[[Any], bool]

Return a predicate to check issubclass for a given type.

Source code in src/metador_core/util/typing.py
236
237
238
def is_subclass_of(t: Any) -> Callable[[Any], bool]:
    """Return a predicate to check issubclass for a given type."""
    return lambda obj: isinstance(obj, type) and issubclass(obj, t)