Skip to content

Commit 0139b51

Browse files
Add include_none_values ClassVar to JSONObject; apply to response-only classes (#466)
* Add include_none_values ClassVar to JSONObject; apply to response-only structures * Add unit test case
1 parent f7c6eef commit 0139b51

File tree

4 files changed

+36
-1
lines changed

4 files changed

+36
-1
lines changed

linode_api4/objects/image.py

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ class ImageRegion(JSONObject):
2424
The region and status of an image replica.
2525
"""
2626

27+
include_none_values = True
28+
2729
region: str = ""
2830
status: Optional[ReplicationStatus] = None
2931

linode_api4/objects/lke.py

+6
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ class LKENodePoolTaint(JSONObject):
5555
applied to a node pool.
5656
"""
5757

58+
include_none_values = True
59+
5860
key: Optional[str] = None
5961
value: Optional[str] = None
6062
effect: Optional[str] = None
@@ -103,6 +105,8 @@ class LKEClusterControlPlaneACLAddresses(JSONObject):
103105
to access an LKE cluster's control plane.
104106
"""
105107

108+
include_none_values = True
109+
106110
ipv4: Optional[List[str]] = None
107111
ipv6: Optional[List[str]] = None
108112

@@ -116,6 +120,8 @@ class LKEClusterControlPlaneACL(JSONObject):
116120
NOTE: Control Plane ACLs may not currently be available to all users.
117121
"""
118122

123+
include_none_values = True
124+
119125
enabled: bool = False
120126
addresses: Optional[LKEClusterControlPlaneACLAddresses] = None
121127

linode_api4/objects/serializable.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ class JSONObject(metaclass=JSONFilterableMetaclass):
5858
)
5959
"""
6060

61+
include_none_values: ClassVar[bool] = False
62+
"""
63+
If true, all None values for this class will be explicitly included in
64+
the serialized output for instance of this class.
65+
"""
66+
6167
always_include: ClassVar[Set[str]] = {}
6268
"""
6369
A set of keys corresponding to fields that should always be
@@ -169,7 +175,7 @@ def should_include(key: str, value: Any) -> bool:
169175
Returns whether the given key/value pair should be included in the resulting dict.
170176
"""
171177

172-
if key in cls.always_include:
178+
if cls.include_none_values or key in cls.always_include:
173179
return True
174180

175181
hint = type_hints.get(key)

test/unit/objects/serializable_test.py

+21
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,24 @@ class Foo(JSONObject):
2626
assert foo["foo"] == "test"
2727
assert foo["bar"] == "test2"
2828
assert foo["baz"] == "test3"
29+
30+
def test_serialize_optional_include_None(self):
31+
@dataclass
32+
class Foo(JSONObject):
33+
include_none_values = True
34+
35+
foo: Optional[str] = None
36+
bar: Optional[str] = None
37+
baz: str = None
38+
39+
foo = Foo().dict
40+
41+
assert foo["foo"] is None
42+
assert foo["bar"] is None
43+
assert foo["baz"] is None
44+
45+
foo = Foo(foo="test", bar="test2", baz="test3").dict
46+
47+
assert foo["foo"] == "test"
48+
assert foo["bar"] == "test2"
49+
assert foo["baz"] == "test3"

0 commit comments

Comments
 (0)