55import znfields
66
77
8- def example1_parameter_getter (self , name ):
8+ def getter_01 (self , name ):
99 return f"{ name } :{ self .__dict__ [name ]} "
1010
1111
12+ def setter_01 (self , name , value ):
13+ if not isinstance (value , float ):
14+ raise ValueError (f"Value { value } is not a float" )
15+ self .__dict__ [name ] = value
16+
17+
1218def stringify_list (self , name ):
1319 content = self .__dict__ [name ]
1420 self .__dict__ [name ] = [str (x ) for x in content ]
1521 # Can not return a copy to append to, but must be the same object
1622 return self .__dict__ [name ]
1723
1824
25+ @dataclasses .dataclass
26+ class SetterGetterNoInit (znfields .Base ):
27+ parameter : float = znfields .field (getter = getter_01 , setter = setter_01 , init = False )
28+
29+
30+ @dataclasses .dataclass
31+ class SetterOnly (znfields .Base ):
32+ parameter : float = znfields .field (setter = setter_01 )
33+
34+
1935@dataclasses .dataclass
2036class Example1 (znfields .Base ):
21- parameter : float = znfields .field (getter = example1_parameter_getter )
37+ parameter : float = znfields .field (getter = getter_01 )
2238
2339
2440@dataclasses .dataclass
2541class Example1WithDefault (znfields .Base ):
26- parameter : float = znfields .field (getter = example1_parameter_getter , default = 1 )
42+ parameter : float = znfields .field (getter = getter_01 , default = 1 )
2743
2844
2945@dataclasses .dataclass
3046class Example1WithDefaultFactory (znfields .Base ):
3147 parameter : list = znfields .field (getter = stringify_list , default_factory = list )
3248
3349
50+ class NoDataClass (znfields .Base ):
51+ parameter : float = znfields .field (getter = getter_01 , setter = setter_01 )
52+
53+
3454def test_example1 ():
3555 example = Example1 (parameter = 1 )
3656 assert example .parameter == "parameter:1"
@@ -58,14 +78,15 @@ def test_example2():
5878
5979def test_wrong_metadata ():
6080 with pytest .raises (TypeError ):
61- znfields .field (getter = example1_parameter_getter , metadata = "Hello" )
81+ znfields .field (getter = getter_01 , metadata = "Hello" )
82+
83+ with pytest .raises (TypeError ):
84+ znfields .field (setter = setter_01 , metadata = "Hello" )
6285
6386
6487@dataclasses .dataclass
6588class Example3 (znfields .Base ):
66- parameter : float = znfields .field (
67- getter = example1_parameter_getter , metadata = {"category" : "test" }
68- )
89+ parameter : float = znfields .field (getter = getter_01 , metadata = {"category" : "test" })
6990
7091
7192def test_example3 ():
@@ -75,7 +96,7 @@ def test_example3():
7596 field = dataclasses .fields (example )[0 ]
7697 assert field .metadata == {
7798 "category" : "test" ,
78- znfields .ZNFIELDS_GETTER_TYPE : example1_parameter_getter ,
99+ znfields .ZNFIELDS_GETTER_TYPE : getter_01 ,
79100 }
80101
81102
@@ -154,3 +175,104 @@ def test_default_factory():
154175 assert example .parameter == []
155176 example .parameter .append (1 )
156177 assert example .parameter == ["1" ]
178+
179+
180+ def test_getter_setter_no_init ():
181+ example = SetterGetterNoInit ()
182+ with pytest .raises (ValueError ):
183+ example .parameter = "text"
184+
185+ example .parameter = 3.14
186+ assert example .parameter == "parameter:3.14"
187+
188+ # test non-field attributes
189+ example .some_attribute = 42
190+ assert example .some_attribute == 42
191+
192+
193+ @dataclasses .dataclass
194+ class ParentClass (znfields .Base ):
195+ parent_field : str = znfields .field (getter = getter_01 )
196+
197+
198+ @dataclasses .dataclass
199+ class ChildClass (ParentClass ):
200+ child_field : str = znfields .field (getter = getter_01 )
201+
202+
203+ def test_inherited_getter ():
204+ instance = ChildClass (parent_field = "parent" , child_field = "child" )
205+ assert instance .parent_field == "parent_field:parent"
206+ assert instance .child_field == "child_field:child"
207+
208+
209+ def test_setter_validation ():
210+ example = SetterGetterNoInit ()
211+
212+ with pytest .raises (ValueError ):
213+ example .parameter = "invalid value"
214+
215+ with pytest .raises (KeyError ):
216+ # dict is not set, getter raises KeyError instead of AttributeError
217+ assert example .parameter is None
218+
219+ example .parameter = 2.71
220+ assert example .parameter == "parameter:2.71"
221+
222+
223+ @dataclasses .dataclass
224+ class NoDefaultField (znfields .Base ):
225+ parameter : float = znfields .field (getter = getter_01 , setter = setter_01 )
226+
227+
228+ def test_no_default_field ():
229+ with pytest .raises (TypeError ):
230+ NoDefaultField () # should raise because no default is provided
231+ obj = NoDefaultField (parameter = 1.23 )
232+ assert obj .parameter == "parameter:1.23"
233+
234+
235+ @dataclasses .dataclass
236+ class CombinedGetterSetter (znfields .Base ):
237+ parameter : float = znfields .field (getter = getter_01 , setter = setter_01 )
238+
239+
240+ def test_combined_getter_setter ():
241+ obj = CombinedGetterSetter (parameter = 2.5 )
242+ assert obj .parameter == "parameter:2.5"
243+ obj .parameter = 3.5
244+ assert obj .parameter == "parameter:3.5"
245+
246+ with pytest .raises (ValueError ):
247+ obj .parameter = "invalid value"
248+
249+
250+ @dataclasses .dataclass
251+ class Nested (znfields .Base ):
252+ inner_field : float = znfields .field (getter = getter_01 )
253+
254+
255+ @dataclasses .dataclass
256+ class Outer (znfields .Base ):
257+ outer_field : Nested = dataclasses .field (default_factory = lambda : Nested (1.0 ))
258+
259+
260+ def test_nested_dataclass ():
261+ obj = Outer ()
262+ assert obj .outer_field .inner_field == "inner_field:1.0"
263+
264+
265+ def test_no_dataclass ():
266+ x = NoDataClass ()
267+ with pytest .raises (TypeError , match = "is not a dataclass" ):
268+ x .parameter = 5
269+
270+ with pytest .raises (TypeError , match = "is not a dataclass" ):
271+ assert x .parameter is None
272+
273+
274+ def test_setter_only ():
275+ x = SetterOnly (parameter = 5.5 )
276+ with pytest .raises (ValueError ):
277+ x .parameter = "5"
278+ assert x .parameter == 5.5
0 commit comments