File: test_getstate_behaviors.py

package info (click to toggle)
python-atom 0.12.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,616 kB
  • sloc: cpp: 9,040; python: 6,249; makefile: 123
file content (155 lines) | stat: -rw-r--r-- 4,187 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# --------------------------------------------------------------------------------------
# Copyright (c) 2023-2024, Nucleic Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# --------------------------------------------------------------------------------------
"""Test the getstate behaviors

include_handler: tested here
exclude_handler: tested here
include_non_default_handler: tested here
property_handler: tested in test_property
member_method_object_handler: tested here
object_method_name_handler: tested here

"""

import pickle

import pytest

from atom.api import (
    Atom,
    Bool,
    Constant,
    ForwardInstance,
    ForwardTyped,
    GetState,
    Instance,
    ReadOnly,
    Typed,
    Value,
)


@pytest.mark.parametrize(
    "member, mode",
    [
        (Value(), GetState.Include),
        (ReadOnly(), GetState.IncludeNonDefault),
        (Constant(1), GetState.Exclude),
        (Typed(int, optional=True), GetState.Include),
        (Typed(int, optional=False), GetState.IncludeNonDefault),
        (ForwardTyped(lambda: int, optional=True), GetState.Include),
        (ForwardTyped(lambda: int, optional=False), GetState.IncludeNonDefault),
        (Instance(int, optional=True), GetState.Include),
        (Instance(int, optional=False), GetState.IncludeNonDefault),
        (ForwardInstance(lambda: int, optional=True), GetState.Include),
        (ForwardInstance(lambda: int, optional=False), GetState.IncludeNonDefault),
    ],
)
def test_member_getstate_mode(member, mode):
    assert member.getstate_mode[0] == mode


class A(Atom):
    val = Value()


def test_using_include_handler():
    """Test using the include handler."""
    A.val.set_getstate_mode(GetState.Include, None)

    a = A()
    assert A.val.do_should_getstate(a) is True
    assert b"val" in pickle.dumps(a, 0)


def test_using_exclude_handler():
    """Test using the include handler."""
    A.val.set_getstate_mode(GetState.Exclude, None)

    a = A()
    assert A.val.do_should_getstate(a) is False
    assert b"val" not in pickle.dumps(a, 0)


def test_using_include_non_default_handler():
    """Test using the include handler."""

    class A(Atom):
        val = Value()
        val.set_getstate_mode(GetState.IncludeNonDefault, None)

    assert A.val.do_should_getstate(A()) is False
    assert A.val.do_should_getstate(A(val=1)) is True


def test_using_object_method_name():
    """Test using object_method mode."""

    class A(Atom):
        val = Value()
        val2 = Value()
        seen = Value()

        def _getstate_val(self, name: str) -> bool:
            self.seen = name
            return name == "val"

        def _getstate_val2(self, name: str) -> bool:
            self.seen = name
            return name == "val"

    a = A()
    assert A.val.do_should_getstate(a) is True
    assert a.seen == "val"
    assert A.val2.do_should_getstate(a) is False
    assert a.seen == "val2"

    with pytest.raises(TypeError):
        Value().set_getstate_mode(GetState.ObjectMethod_Name, 1)


def test_subclassing_member():
    """Test defining get in a Member subclass"""

    class CustomV(Value):
        def __init__(self):
            super(Value, self).__init__()
            self.set_getstate_mode(GetState.MemberMethod_Object, "getstate")

        def getstate(self, obj):
            return obj.pickle

    class A(Atom):
        v = CustomV()
        pickle = Bool()

    pvt = A()
    assert A.v.do_should_getstate(pvt) is False
    pvt.pickle = True
    assert A.v.do_should_getstate(pvt) is True

    with pytest.raises(TypeError):
        Value().set_getstate_mode(GetState.MemberMethod_Object, 1)


def test_handling_exception_in_getstate():
    """Test handling an exception while pickling."""

    class CustomV(Value):
        def __init__(self):
            super(Value, self).__init__()
            self.set_getstate_mode(GetState.MemberMethod_Object, "getstate")

        def getstate(self, obj):
            raise RuntimeError

    class A(Atom):
        v = CustomV()

    with pytest.raises(RuntimeError):
        pickle.dumps(A())