1 # SPDX-License-Identifier: LGPL-3-or-later
2 # Copyright 2022 Jacob Lifshay programmerjake@gmail.com
7 from nmutil
.plain_data
import FrozenPlainDataError
, plain_data
10 @plain_data(order
=True)
15 @plain_data(order
=True)
17 __slots__
= "a", "b", "x", "y"
19 def __init__(self
, a
, b
, *, x
, y
):
26 @plain_data(order
=True)
27 class PlainData2(PlainData1
):
30 def __init__(self
, a
, b
, *, x
, y
, z
):
31 super().__init
__(a
, b
, x
=x
, y
=y
)
35 @plain_data(order
=True, frozen
=True, unsafe_hash
=True)
40 @plain_data(order
=True, frozen
=True, unsafe_hash
=True)
42 __slots__
= "a", "b", "x", "y"
44 def __init__(self
, a
, b
, *, x
, y
):
51 @plain_data(order
=True, frozen
=True, unsafe_hash
=True)
52 class PlainDataF2(PlainDataF1
):
55 def __init__(self
, a
, b
, *, x
, y
, z
):
56 super().__init
__(a
, b
, x
=x
, y
=y
)
60 class TestPlainData(unittest
.TestCase
):
61 def test_fields(self
):
62 self
.assertEqual(PlainData0
._fields
, ())
63 self
.assertEqual(PlainData1
._fields
, ("a", "b", "x", "y"))
64 self
.assertEqual(PlainData2
._fields
, ("a", "b", "x", "y", "z"))
65 self
.assertEqual(PlainDataF0
._fields
, ())
66 self
.assertEqual(PlainDataF1
._fields
, ("a", "b", "x", "y"))
67 self
.assertEqual(PlainDataF2
._fields
, ("a", "b", "x", "y", "z"))
70 self
.assertTrue(PlainData0() == PlainData0())
71 self
.assertFalse('a' == PlainData0())
72 self
.assertFalse(PlainDataF0() == PlainData0())
73 self
.assertTrue(PlainData1(1, 2, x
="x", y
="y")
74 == PlainData1(1, 2, x
="x", y
="y"))
75 self
.assertFalse(PlainData1(1, 2, x
="x", y
="y")
76 == PlainData1(1, 2, x
="x", y
="z"))
77 self
.assertFalse(PlainData1(1, 2, x
="x", y
="y")
78 == PlainData2(1, 2, x
="x", y
="y", z
=3))
81 def check_op(v
, tuple_v
):
82 with self
.subTest(v
=v
, tuple_v
=tuple_v
):
83 self
.assertEqual(hash(v
), hash(tuple_v
))
85 def check(a
, b
, x
, y
, z
):
86 tuple_v
= a
, b
, x
, y
, z
87 v
= PlainDataF2(a
=a
, b
=b
, x
=x
, y
=y
, z
=z
)
90 check(1, 2, "x", "y", "z")
92 check(1, 2, "x", "y", "a")
93 check(1, 2, "x", "y", "zz")
95 check(1, 2, "x", "a", "z")
96 check(1, 2, "x", "zz", "z")
98 check(1, 2, "a", "y", "z")
99 check(1, 2, "zz", "y", "z")
101 check(1, -10, "x", "y", "z")
102 check(1, 10, "x", "y", "z")
104 check(-10, 2, "x", "y", "z")
105 check(10, 2, "x", "y", "z")
107 def test_order(self
):
108 def check_op(l
, r
, tuple_l
, tuple_r
, op
):
109 with self
.subTest(l
=l
, r
=r
,
110 tuple_l
=tuple_l
, tuple_r
=tuple_r
, op
=op
):
111 self
.assertEqual(op(l
, r
), op(tuple_l
, tuple_r
))
112 self
.assertEqual(op(r
, l
), op(tuple_r
, tuple_l
))
114 def check(a
, b
, x
, y
, z
):
115 tuple_l
= 1, 2, "x", "y", "z"
116 l
= PlainData2(a
=1, b
=2, x
="x", y
="y", z
="z")
117 tuple_r
= a
, b
, x
, y
, z
118 r
= PlainData2(a
=a
, b
=b
, x
=x
, y
=y
, z
=z
)
119 check_op(l
, r
, tuple_l
, tuple_r
, operator
.eq
)
120 check_op(l
, r
, tuple_l
, tuple_r
, operator
.ne
)
121 check_op(l
, r
, tuple_l
, tuple_r
, operator
.lt
)
122 check_op(l
, r
, tuple_l
, tuple_r
, operator
.le
)
123 check_op(l
, r
, tuple_l
, tuple_r
, operator
.gt
)
124 check_op(l
, r
, tuple_l
, tuple_r
, operator
.ge
)
126 check(1, 2, "x", "y", "z")
128 check(1, 2, "x", "y", "a")
129 check(1, 2, "x", "y", "zz")
131 check(1, 2, "x", "a", "z")
132 check(1, 2, "x", "zz", "z")
134 check(1, 2, "a", "y", "z")
135 check(1, 2, "zz", "y", "z")
137 check(1, -10, "x", "y", "z")
138 check(1, 10, "x", "y", "z")
140 check(-10, 2, "x", "y", "z")
141 check(10, 2, "x", "y", "z")
144 self
.assertEqual(repr(PlainData0()), "PlainData0()")
145 self
.assertEqual(repr(PlainData1(1, 2, x
="x", y
="y")),
146 "PlainData1(a=1, b=2, x='x', y='y')")
147 self
.assertEqual(repr(PlainData2(1, 2, x
="x", y
="y", z
=3)),
148 "PlainData2(a=1, b=2, x='x', y='y', z=3)")
149 self
.assertEqual(repr(PlainDataF2(1, 2, x
="x", y
="y", z
=3)),
150 "PlainDataF2(a=1, b=2, x='x', y='y', z=3)")
152 def test_frozen(self
):
153 not_frozen
= PlainData0()
155 frozen0
= PlainDataF0()
156 with self
.assertRaises(AttributeError):
158 frozen1
= PlainDataF1(1, 2, x
="x", y
="y")
159 with self
.assertRaises(FrozenPlainDataError
):
162 def test_pickle(self
):
164 with self
.subTest(v
=v
):
165 self
.assertEqual(v
, pickle
.loads(pickle
.dumps(v
)))
168 check(PlainData1(a
=1, b
=2, x
="x", y
="y"))
169 check(PlainData2(a
=1, b
=2, x
="x", y
="y", z
="z"))
171 check(PlainDataF1(a
=1, b
=2, x
="x", y
="y"))
172 check(PlainDataF2(a
=1, b
=2, x
="x", y
="y", z
="z"))
175 if __name__
== "__main__":