File: annotated.py

package info (click to toggle)
python-web-poet 0.23.2-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 908 kB
  • sloc: python: 6,112; makefile: 19
file content (62 lines) | stat: -rw-r--r-- 1,797 bytes parent folder | download | duplicates (3)
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
58
59
60
61
62
from __future__ import annotations

from dataclasses import dataclass
from typing import Annotated, Any


def annotation_encode(obj: Any) -> Any:
    """Encodes *obj* for :obj:`~typing.Annotated`.

    Annotated params must be hashable. This function converts dicts and lists
    into hashable alternatives (tuples and frozensets).

    For example:

    .. code-block:: python

        foo = Annotated(Bar, annotation_encode({"a": [1, 2, 3]}))

    *obj* must not contain tuples or frozensets, or unhashable data besides
    dicts and lists.
    """
    if isinstance(obj, (tuple, list)):
        return tuple(annotation_encode(e) for e in obj)
    if isinstance(obj, dict):
        return frozenset(
            (annotation_encode(k), annotation_encode(v)) for k, v in obj.items()
        )
    return obj


def annotation_decode(obj: Any) -> Any:
    """Converts a result of :func:`annotation_encode` back to original form."""
    if isinstance(obj, tuple):
        return [annotation_decode(o) for o in obj]
    if isinstance(obj, frozenset):
        return {annotation_decode(k): annotation_decode(v) for k, v in obj}
    return obj


@dataclass
class AnnotatedInstance:
    """Wrapper for instances of annotated dependencies.

    It is used when both the dependency value and the dependency annotation are
    needed.

    :param result: The wrapped dependency instance.
    :type result: Any

    :param metadata: The copy of the annotation.
    :type metadata: Tuple[Any, ...]
    """

    result: Any
    metadata: tuple[Any, ...]

    def get_annotated_cls(self) -> Annotated[Any, ...]:
        """Returns a re-created :class:`typing.Annotated` type."""
        return Annotated[(type(self.result), *self.metadata)]


__all__: list[str] = []  # Prefer imports from web_poet.__init__.py