File: container.py

package info (click to toggle)
python-returns 0.26.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,652 kB
  • sloc: python: 11,000; makefile: 18
file content (85 lines) | stat: -rw-r--r-- 2,721 bytes parent folder | download | duplicates (2)
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
from abc import ABC
from typing import Any, TypeVar

from typing_extensions import TypedDict

from returns.interfaces.equable import Equable
from returns.primitives.hkt import Kind1
from returns.primitives.types import Immutable

_EqualType = TypeVar('_EqualType', bound=Equable)


class _PickleState(TypedDict):
    """Dict to represent the `BaseContainer` state to be pickled."""

    # TODO: Remove `__slots__` from here when `slotscheck` allow ignore classes
    # by using comments. We don't need the slots here since this class is just
    # a representation of a dictionary and should not be instantiated by any
    # means.
    # See: https://github.com/ariebovenberg/slotscheck/issues/71
    __slots__ = ('container_value',)  # type: ignore

    container_value: Any


class BaseContainer(Immutable, ABC):
    """Utility class to provide all needed magic methods to the context."""

    __slots__ = ('_inner_value',)
    _inner_value: Any

    def __init__(self, inner_value) -> None:
        """
        Wraps the given value in the Container.

        'value' is any arbitrary value of any type including functions.
        """
        object.__setattr__(self, '_inner_value', inner_value)

    def __repr__(self) -> str:
        """Used to display details of object."""
        return '<{}: {}>'.format(
            self.__class__.__qualname__.strip('_'),
            str(self._inner_value),
        )

    def __eq__(self, other: object) -> bool:
        """Used to compare two 'Container' objects."""
        return container_equality(self, other)  # type: ignore

    def __hash__(self) -> int:
        """Used to use this value as a key."""
        return hash(self._inner_value)

    def __getstate__(self) -> _PickleState:
        """That's how this object will be pickled."""
        return {'container_value': self._inner_value}  # type: ignore

    def __setstate__(self, state: _PickleState | Any) -> None:
        """Loading state from pickled data."""
        if isinstance(state, dict) and 'container_value' in state:
            object.__setattr__(
                self,
                '_inner_value',
                state['container_value'],
            )
        else:
            # backward compatibility with 0.19.0 and earlier
            object.__setattr__(self, '_inner_value', state)


def container_equality(
    self: Kind1[_EqualType, Any],
    other: Kind1[_EqualType, Any],
) -> bool:
    """
    Function to compare similar containers.

    Compares both their types and their inner values.
    """
    if type(self) != type(other):  # noqa: WPS516, E721
        return False
    return bool(
        self._inner_value == other._inner_value,  # type: ignore # noqa: SLF001
    )