Skip to content

Commit 6ba2d10

Browse files
fix: Always load object values when converting MappedObjects to dict (#400)
* Always load object values when converting MappedObjects to dict * Prevent overriding identifier attributes during construction * make format * Update unit test to cover parent_id issue
1 parent 23d41fd commit 6ba2d10

File tree

4 files changed

+36
-7
lines changed

4 files changed

+36
-7
lines changed

linode_api4/objects/base.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import time
22
from datetime import datetime, timedelta
3+
from typing import Any, Dict, Optional
34

45
from linode_api4.objects.serializable import JSONObject
56

@@ -99,6 +100,18 @@ def _expand_vals(self, target, **vals):
99100
def __repr__(self):
100101
return "Mapping containing {}".format(vars(self).keys())
101102

103+
@staticmethod
104+
def _flatten_base_subclass(obj: "Base") -> Optional[Dict[str, Any]]:
105+
if obj is None:
106+
return None
107+
108+
# If the object hasn't already been lazy-loaded,
109+
# manually refresh it
110+
if not getattr(obj, "_populated", False):
111+
obj._api_get()
112+
113+
return obj._raw_json
114+
102115
@property
103116
def dict(self):
104117
result = vars(self).copy()
@@ -112,12 +125,17 @@ def dict(self):
112125
(
113126
item.dict
114127
if isinstance(item, cls)
115-
else item._raw_json if isinstance(item, Base) else item
128+
else (
129+
self._flatten_base_subclass(item)
130+
if isinstance(item, Base)
131+
else item
132+
)
116133
)
117134
for item in v
118135
]
119136
elif isinstance(v, Base):
120-
result[k] = v._raw_json
137+
result[k] = self._flatten_base_subclass(v)
138+
121139
return result
122140

123141

@@ -140,7 +158,10 @@ def __init__(self, client: object, id: object, json: object = {}) -> object:
140158
#: be updated on access.
141159
self._set("_raw_json", None)
142160

143-
for k in type(self).properties:
161+
for k, v in type(self).properties.items():
162+
if v.identifier:
163+
continue
164+
144165
self._set(k, None)
145166

146167
self._set("id", id)

linode_api4/objects/dbase.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ class DerivedBase(Base):
1212
parent_id_name = "parent_id" # override in child classes
1313

1414
def __init__(self, client, id, parent_id, json={}):
15-
Base.__init__(self, client, id, json=json)
16-
1715
self._set(type(self).parent_id_name, parent_id)
1816

17+
Base.__init__(self, client, id, json=json)
18+
1919
@classmethod
2020
def _api_get_derived(cls, parent, client):
2121
base_url = "{}/{}".format(

linode_api4/objects/object_storage.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ class ObjectStorageBucket(DerivedBase):
3131
id_attribute = "label"
3232

3333
properties = {
34-
"cluster": Property(),
34+
"cluster": Property(identifier=True),
3535
"created": Property(is_datetime=True),
3636
"hostname": Property(),
37-
"label": Property(),
37+
"label": Property(identifier=True),
3838
"objects": Property(),
3939
"size": Property(),
4040
}

test/unit/objects/linode_test.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,14 @@ def test_interface_ipv4(self):
554554
self.assertEqual(ipv4.vpc, "10.0.0.1")
555555
self.assertEqual(ipv4.nat_1_1, "any")
556556

557+
def test_config_devices_unwrap(self):
558+
"""
559+
Tests that config devices can be successfully converted to a dict.
560+
"""
561+
562+
inst = Instance(self.client, 123)
563+
assert inst.configs[0].devices.dict.get("sda").get("id") == 12345
564+
557565

558566
class StackScriptTest(ClientBaseCase):
559567
"""

0 commit comments

Comments
 (0)