From d080b04666178aa3bed1df68f6ea9931b408bfe8 Mon Sep 17 00:00:00 2001 From: jo Date: Thu, 13 Nov 2025 19:43:54 +0100 Subject: [PATCH] fix: support reloading sub resource bound models Sub resource bound models cannot be reloaded using `get_by_id`, a custom function must be implemented. --- hcloud/core/client.py | 9 ++++++--- hcloud/zones/client.py | 7 +++++++ tests/unit/conftest.py | 4 ++++ tests/unit/zones/test_client.py | 22 ++++++++++++++++++++++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/hcloud/core/client.py b/hcloud/core/client.py index c33b0352..f0e67a7f 100644 --- a/hcloud/core/client.py +++ b/hcloud/core/client.py @@ -103,10 +103,13 @@ def __getattr__(self, name: str): # type: ignore[no-untyped-def] value = getattr(self.data_model, name) return value - def reload(self) -> None: - """Reloads the model and tries to get all data from the APIx""" + def _get_self(self) -> BoundModelBase: assert hasattr(self._client, "get_by_id") - bound_model = self._client.get_by_id(self.data_model.id) + return self._client.get_by_id(self.data_model.id) + + def reload(self) -> None: + """Reloads the model and tries to get all data from the API""" + bound_model = self._get_self() self.data_model = bound_model.data_model self.complete = True diff --git a/hcloud/zones/client.py b/hcloud/zones/client.py index 2da74d4b..832d76f7 100644 --- a/hcloud/zones/client.py +++ b/hcloud/zones/client.py @@ -406,6 +406,13 @@ def __init__(self, client: ZonesClient, data: dict, complete: bool = True): super().__init__(client, data, complete) + def _get_self(self) -> BoundZoneRRSet: + return self._client.get_rrset( + self.data_model.zone, + self.data_model.name, + self.data_model.type, + ) + def update_rrset( self, *, diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index 78650e53..17c37704 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -188,6 +188,10 @@ def test_method_list(self, bound_model): lambda m: inspect.ismethod(m) and m.__func__ in bound_model.__class__.__dict__.values(), ): + # Ignore private methods + if name.startswith("_"): + continue + # Actions methods are already tested in TestBoundModelActions. if name in ("__init__", "get_actions", "get_actions_list"): continue diff --git a/tests/unit/zones/test_client.py b/tests/unit/zones/test_client.py index e20aaedd..2e966032 100644 --- a/tests/unit/zones/test_client.py +++ b/tests/unit/zones/test_client.py @@ -958,3 +958,25 @@ def test_init(self, resource_client: ZonesClient, bound_model: BoundZoneRRSet): assert isinstance(o.zone, BoundZone) assert o.zone.id == 42 + + def test_reload( + self, + request_mock: mock.MagicMock, + resource_client: ZonesClient, + zone_rrset1, + ): + o = BoundZoneRRSet( + resource_client, + data={"id": "www/A", "zone": 42}, + complete=False, + ) + request_mock.return_value = {"rrset": zone_rrset1} + + o.reload() + + request_mock.assert_called_with( + method="GET", + url="/zones/42/rrsets/www/A", + ) + + assert o.labels is not None