Skip to content

Commit 65310a6

Browse files
committed
Making tests more complete, with cleanup.
1 parent a72fe86 commit 65310a6

File tree

2 files changed

+73
-60
lines changed

2 files changed

+73
-60
lines changed

tests/test_class_sh_property.cpp

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,11 @@ TEST_SUBMODULE(class_sh_property, m) {
5050
;
5151

5252
py::class_<ClassicOuter, std::unique_ptr<ClassicOuter>>(m, "ClassicOuter")
53-
.def(py::init<>()) //
54-
.def_readwrite("m_mptr", &ClassicOuter::m_mptr) //
55-
.def_readwrite("m_cptr", &ClassicOuter::m_cptr) //
53+
.def(py::init<>())
54+
.def_readonly("m_mptr_readonly", &ClassicOuter::m_mptr)
55+
.def_readwrite("m_mptr_readwrite", &ClassicOuter::m_mptr)
56+
.def_readwrite("m_cptr_readonly", &ClassicOuter::m_cptr)
57+
.def_readwrite("m_cptr_readwrite", &ClassicOuter::m_cptr) //
5658
;
5759

5860
py::classh<Field>(m, "Field") //
@@ -61,45 +63,41 @@ TEST_SUBMODULE(class_sh_property, m) {
6163
;
6264

6365
py::classh<Outer>(m, "Outer") //
64-
.def(py::init<>()) //
65-
.def_readonly("m_valu_readonly", &Outer::m_valu) //
66-
.def_readwrite("m_valu", &Outer::m_valu) //
67-
.def_property( //
68-
"m_mptr_property",
69-
[](const std::shared_ptr<Outer> &self) {
70-
return std::shared_ptr<Field>(self, self->m_mptr);
71-
},
72-
[](Outer &self, Field *mptr) { self.m_mptr = mptr; })
73-
.def_property( //
74-
"m_cptr_property",
75-
[](const std::shared_ptr<Outer> &self) {
76-
return std::shared_ptr<const Field>(self, self->m_cptr);
77-
},
78-
[](Outer &self, const Field *cptr) { self.m_cptr = cptr; })
66+
.def(py::init<>())
67+
68+
.def_readonly("m_valu_readonly", &Outer::m_valu)
69+
.def_readwrite("m_valu_readwrite", &Outer::m_valu)
70+
7971
.def_readonly("m_mptr_readonly", &Outer::m_mptr)
80-
.def_readwrite("m_mptr", &Outer::m_mptr)
72+
.def_readwrite("m_mptr_readwrite", &Outer::m_mptr)
8173
.def_readonly("m_cptr_readonly", &Outer::m_cptr)
82-
.def_readwrite("m_cptr", &Outer::m_cptr)
74+
.def_readwrite("m_cptr_readwrite", &Outer::m_cptr)
75+
8376
.def_property( //
84-
"m_uqmp_property",
77+
"m_uqmp_readwrite",
8578
[](const std::shared_ptr<Outer> &self) {
8679
return std::unique_ptr<Field>(std::move(self->m_uqmp));
8780
},
8881
[](Outer &self, std::unique_ptr<Field> uqmp) {
8982
self.m_uqmp = std::move(uqmp); //
9083
})
9184
.def_property( //
92-
"m_uqcp_property",
85+
"m_uqcp_readwrite",
9386
[](const std::shared_ptr<Outer> &self) {
9487
return std::unique_ptr<const Field>(std::move(self->m_uqcp));
9588
},
9689
[](Outer &self, std::unique_ptr<const Field> uqcp) {
9790
self.m_uqcp = std::move(uqcp); //
9891
})
99-
// .def_readwrite("m_uqmp", &Outer::m_uqmp) //
100-
// .def_readwrite("m_uqcp", &Outer::m_uqcp) //
101-
.def_readwrite("m_shmp", &Outer::m_shmp) //
102-
.def_readwrite("m_shcp", &Outer::m_shcp) //
92+
// .def_readonly("m_uqmp_readonly", &Outer::m_uqmp) // Compilation Error.
93+
// .def_readwrite("m_uqmp_readwrite", &Outer::m_uqmp)
94+
// .def_readonly("m_uqcp_readonly", &Outer::m_uqcp) // Compilation Error.
95+
// .def_readwrite("m_uqcp_readwrite", &Outer::m_uqcp)
96+
97+
.def_readwrite("m_shmp_readonly", &Outer::m_shmp)
98+
.def_readwrite("m_shmp_readwrite", &Outer::m_shmp)
99+
.def_readwrite("m_shcp_readonly", &Outer::m_shcp)
100+
.def_readwrite("m_shcp_readwrite", &Outer::m_shcp) //
103101
;
104102

105103
m.def("DisownOuter", DisownOuter);

tests/test_class_sh_property.py

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@
66

77

88
@pytest.mark.xfail("env.PYPY", reason="gc after `del field` is apparently deferred")
9-
def test_valu_getter(msg):
9+
@pytest.mark.parametrize("m_attr", ("m_valu_readonly", "m_valu_readwrite"))
10+
def test_valu_getter(msg, m_attr):
1011
# Reduced from PyCLIF test:
1112
# https://github.com/google/clif/blob/c371a6d4b28d25d53a16e6d2a6d97305fb1be25a/clif/testing/python/nested_fields_test.py#L56
1213
outer = m.Outer()
13-
field = outer.m_valu
14+
field = getattr(outer, m_attr)
1415
assert field.num == -99
1516
with pytest.raises(ValueError) as excinfo:
1617
m.DisownOuter(outer)
1718
assert msg(excinfo.value) == "Cannot disown use_count != 1 (loaded_as_unique_ptr)."
1819
del field
1920
m.DisownOuter(outer)
2021
with pytest.raises(ValueError) as excinfo:
21-
outer.m_valu
22+
getattr(outer, m_attr)
2223
assert (
2324
msg(excinfo.value)
2425
== "Missing value for wrapped C++ type: Python instance was disowned."
@@ -27,58 +28,65 @@ def test_valu_getter(msg):
2728

2829
def test_valu_setter():
2930
outer = m.Outer()
30-
assert outer.m_valu.num == -99
31+
assert outer.m_valu_readonly.num == -99
32+
assert outer.m_valu_readwrite.num == -99
3133
field = m.Field()
3234
field.num = 35
33-
outer.m_valu = field
34-
assert outer.m_valu.num == 35
35+
outer.m_valu_readwrite = field
36+
assert outer.m_valu_readonly.num == 35
37+
assert outer.m_valu_readwrite.num == 35
3538

3639

3740
@pytest.mark.parametrize(
38-
"field_type, num_default, outer_type, attr_suffix", # TODO: rm attr_suffix
41+
"field_type, num_default, outer_type",
3942
[
40-
(m.ClassicField, -88, m.ClassicOuter, ""),
41-
(m.Field, -99, m.Outer, ""),
43+
(m.ClassicField, -88, m.ClassicOuter),
44+
(m.Field, -99, m.Outer),
4245
],
4346
)
4447
@pytest.mark.parametrize("m_attr", ("m_mptr", "m_cptr"))
45-
def test_ptr(field_type, num_default, outer_type, attr_suffix, m_attr):
46-
m_attr += attr_suffix
48+
def test_ptr(field_type, num_default, outer_type, m_attr):
49+
m_attr_readonly = m_attr + "_readonly"
50+
m_attr_readwrite = m_attr + "_readwrite"
4751
outer = outer_type()
48-
assert getattr(outer, m_attr) is None
52+
assert getattr(outer, m_attr_readonly) is None
53+
assert getattr(outer, m_attr_readwrite) is None
4954
field = field_type()
5055
assert field.num == num_default
51-
setattr(outer, m_attr, field)
52-
assert getattr(outer, m_attr).num == num_default
56+
setattr(outer, m_attr_readwrite, field)
57+
assert getattr(outer, m_attr_readonly).num == num_default
58+
assert getattr(outer, m_attr_readwrite).num == num_default
5359
field.num = 76
54-
assert getattr(outer, m_attr).num == 76
60+
assert getattr(outer, m_attr_readonly).num == 76
61+
assert getattr(outer, m_attr_readwrite).num == 76
5562
# Change to -88 or -99 to demonstrate Undefined Behavior (dangling pointer).
5663
if num_default == 88 and m_attr == "m_mptr":
5764
del field
58-
assert getattr(outer, m_attr).num == 76
65+
assert getattr(outer, m_attr_readonly).num == 76
66+
assert getattr(outer, m_attr_readwrite).num == 76
5967

6068

61-
@pytest.mark.parametrize("m_attr_disown", ("m_uqmp_property", "m_uqcp_property"))
62-
def test_uqp(m_attr_disown, msg):
69+
@pytest.mark.parametrize("m_attr_readwrite", ("m_uqmp_readwrite", "m_uqcp_readwrite"))
70+
def test_uqp(m_attr_readwrite, msg):
6371
outer = m.Outer()
64-
assert getattr(outer, m_attr_disown) is None
72+
assert getattr(outer, m_attr_readwrite) is None
6573
field_orig = m.Field()
6674
field_orig.num = 39
67-
setattr(outer, m_attr_disown, field_orig)
75+
setattr(outer, m_attr_readwrite, field_orig)
6876
with pytest.raises(ValueError) as excinfo:
6977
field_orig.num
7078
assert (
7179
msg(excinfo.value)
7280
== "Missing value for wrapped C++ type: Python instance was disowned."
7381
)
74-
field_retr1 = getattr(outer, m_attr_disown)
75-
assert getattr(outer, m_attr_disown) is None
82+
field_retr1 = getattr(outer, m_attr_readwrite)
83+
assert getattr(outer, m_attr_readwrite) is None
7684
assert field_retr1.num == 39
7785
field_retr1.num = 93
78-
setattr(outer, m_attr_disown, field_retr1)
86+
setattr(outer, m_attr_readwrite, field_retr1)
7987
with pytest.raises(ValueError):
8088
field_retr1.num
81-
field_retr2 = getattr(outer, m_attr_disown)
89+
field_retr2 = getattr(outer, m_attr_readwrite)
8290
assert field_retr2.num == 93
8391

8492

@@ -108,21 +116,22 @@ def __delattr__(self, *args, **kwargs):
108116
return _dereference(self, delattr, *args, **kwargs)
109117

110118

111-
@pytest.mark.parametrize("m_attr_disown", ("m_uqmp_property", "m_uqcp_property"))
112-
def test_unique_ptr_field_proxy_poc(m_attr_disown, msg):
119+
@pytest.mark.parametrize("m_attr", ("m_uqmp", "m_uqcp"))
120+
def test_unique_ptr_field_proxy_poc(m_attr, msg):
121+
m_attr_readwrite = m_attr + "_readwrite"
113122
outer = m.Outer()
114123
field_orig = m.Field()
115124
field_orig.num = 45
116-
setattr(outer, m_attr_disown, field_orig)
117-
field_proxy = unique_ptr_field_proxy_poc(outer, m_attr_disown)
125+
setattr(outer, m_attr_readwrite, field_orig)
126+
field_proxy = unique_ptr_field_proxy_poc(outer, m_attr_readwrite)
118127
assert field_proxy.num == 45
119128
assert field_proxy.num == 45
120129
with pytest.raises(AttributeError):
121130
field_proxy.xyz
122131
assert field_proxy.num == 45
123132
field_proxy.num = 82
124133
assert field_proxy.num == 82
125-
field_proxy = unique_ptr_field_proxy_poc(outer, m_attr_disown)
134+
field_proxy = unique_ptr_field_proxy_poc(outer, m_attr_readwrite)
126135
assert field_proxy.num == 82
127136
with pytest.raises(AttributeError):
128137
del field_proxy.num
@@ -131,13 +140,19 @@ def test_unique_ptr_field_proxy_poc(m_attr_disown, msg):
131140

132141
@pytest.mark.parametrize("m_attr", ("m_shmp", "m_shcp"))
133142
def test_shp(m_attr):
143+
m_attr_readonly = m_attr + "_readonly"
144+
m_attr_readwrite = m_attr + "_readwrite"
134145
outer = m.Outer()
135-
assert getattr(outer, m_attr) is None
146+
assert getattr(outer, m_attr_readonly) is None
147+
assert getattr(outer, m_attr_readwrite) is None
136148
field = m.Field()
137149
field.num = 43
138-
setattr(outer, m_attr, field)
139-
assert getattr(outer, m_attr).num == 43
140-
getattr(outer, m_attr).num = 57
150+
setattr(outer, m_attr_readwrite, field)
151+
assert getattr(outer, m_attr_readonly).num == 43
152+
assert getattr(outer, m_attr_readwrite).num == 43
153+
getattr(outer, m_attr_readonly).num = 57
154+
getattr(outer, m_attr_readwrite).num = 57
141155
assert field.num == 57
142156
del field
143-
assert getattr(outer, m_attr).num == 57
157+
assert getattr(outer, m_attr_readonly).num == 57
158+
assert getattr(outer, m_attr_readwrite).num == 57

0 commit comments

Comments
 (0)