From 234cf84284d13b8b807e7d2a031ad2f47621ccc7 Mon Sep 17 00:00:00 2001 From: phm07 <22707808+phm07@users.noreply.github.com> Date: Fri, 10 Apr 2026 12:42:17 +0200 Subject: [PATCH 1/3] feat(datacenter, server_type): move available and recommended to server_type --- hcloud/datacenters/domain.py | 26 ++++++++++- hcloud/server_types/domain.py | 8 ++++ tests/unit/datacenters/test_client.py | 61 +++++++++++++------------- tests/unit/server_types/conftest.py | 4 ++ tests/unit/server_types/test_client.py | 4 ++ 5 files changed, 71 insertions(+), 32 deletions(-) diff --git a/hcloud/datacenters/domain.py b/hcloud/datacenters/domain.py index 4867915d..6e95b852 100644 --- a/hcloud/datacenters/domain.py +++ b/hcloud/datacenters/domain.py @@ -1,5 +1,6 @@ from __future__ import annotations +import warnings from typing import TYPE_CHECKING from ..core import BaseDomain, DomainIdentityMixin @@ -25,7 +26,7 @@ class Datacenter(BaseDomain, DomainIdentityMixin): """ __api_properties__ = ("id", "name", "description", "location", "server_types") - __slots__ = __api_properties__ + __slots__ = ("id", "name", "description", "location", "_server_types") def __init__( self, @@ -39,8 +40,29 @@ def __init__( self.name = name self.description = description self.location = location - self.server_types = server_types + self._server_types = server_types + + @property + def server_types(self) -> DatacenterServerTypes | None: + """ + .. deprecated:: 2.18.0 + The 'server_types' property is deprecated and will not be supported after 2026-10-01. + Please use 'server_type.locations[]' instead. + + See https://docs.hetzner.cloud/changelog#2026-04-01-datacenter-deprecations. + """ + warnings.warn( + "The 'server_types' property is deprecated and will not be supported after 2026-10-01. " + "Please use 'server_type.locations[]' instead. " + "See https://docs.hetzner.cloud/changelog#2026-04-01-datacenter-deprecations", + DeprecationWarning, + stacklevel=2, + ) + return self._server_types + @server_types.setter + def server_types(self, value: DatacenterServerTypes | None) -> None: + self._server_types = value class DatacenterServerTypes(BaseDomain): """DatacenterServerTypes Domain diff --git a/hcloud/server_types/domain.py b/hcloud/server_types/domain.py index 279d928d..6c61b907 100644 --- a/hcloud/server_types/domain.py +++ b/hcloud/server_types/domain.py @@ -185,11 +185,15 @@ class ServerTypeLocation(BaseDomain): :param location: Location of the Server Type. :param deprecation: Wether the Server Type is deprecated in this Location. + :param available: True if the Server Type is currently available in this Location. + :param recommended: True if the Server Type is currently recommended in this Location. """ __api_properties__ = ( "location", "deprecation", + "available", + "recommended", ) __slots__ = __api_properties__ @@ -198,8 +202,12 @@ def __init__( *, location: BoundLocation, deprecation: dict[str, Any] | None, + available: bool | None, + recommended: bool | None, ): self.location = location self.deprecation = ( DeprecationInfo.from_dict(deprecation) if deprecation is not None else None ) + self.available = available + self.recommended = recommended diff --git a/tests/unit/datacenters/test_client.py b/tests/unit/datacenters/test_client.py index 7f5ca96b..ace2e7d7 100644 --- a/tests/unit/datacenters/test_client.py +++ b/tests/unit/datacenters/test_client.py @@ -25,36 +25,37 @@ def test_bound_datacenter_init(self, datacenter_response): assert bound_datacenter.location.name == "fsn1" assert bound_datacenter.location.complete is True - assert isinstance(bound_datacenter.server_types, DatacenterServerTypes) - assert len(bound_datacenter.server_types.supported) == 3 - assert bound_datacenter.server_types.supported[0].id == 1 - assert bound_datacenter.server_types.supported[0].complete is False - assert bound_datacenter.server_types.supported[1].id == 2 - assert bound_datacenter.server_types.supported[1].complete is False - assert bound_datacenter.server_types.supported[2].id == 3 - assert bound_datacenter.server_types.supported[2].complete is False - - assert len(bound_datacenter.server_types.available) == 3 - assert bound_datacenter.server_types.available[0].id == 1 - assert bound_datacenter.server_types.available[0].complete is False - assert bound_datacenter.server_types.available[1].id == 2 - assert bound_datacenter.server_types.available[1].complete is False - assert bound_datacenter.server_types.available[2].id == 3 - assert bound_datacenter.server_types.available[2].complete is False - - assert len(bound_datacenter.server_types.available_for_migration) == 3 - assert bound_datacenter.server_types.available_for_migration[0].id == 1 - assert ( - bound_datacenter.server_types.available_for_migration[0].complete is False - ) - assert bound_datacenter.server_types.available_for_migration[1].id == 2 - assert ( - bound_datacenter.server_types.available_for_migration[1].complete is False - ) - assert bound_datacenter.server_types.available_for_migration[2].id == 3 - assert ( - bound_datacenter.server_types.available_for_migration[2].complete is False - ) + with pytest.deprecated_call(): + assert isinstance(bound_datacenter.server_types, DatacenterServerTypes) + assert len(bound_datacenter.server_types.supported) == 3 + assert bound_datacenter.server_types.supported[0].id == 1 + assert bound_datacenter.server_types.supported[0].complete is False + assert bound_datacenter.server_types.supported[1].id == 2 + assert bound_datacenter.server_types.supported[1].complete is False + assert bound_datacenter.server_types.supported[2].id == 3 + assert bound_datacenter.server_types.supported[2].complete is False + + assert len(bound_datacenter.server_types.available) == 3 + assert bound_datacenter.server_types.available[0].id == 1 + assert bound_datacenter.server_types.available[0].complete is False + assert bound_datacenter.server_types.available[1].id == 2 + assert bound_datacenter.server_types.available[1].complete is False + assert bound_datacenter.server_types.available[2].id == 3 + assert bound_datacenter.server_types.available[2].complete is False + + assert len(bound_datacenter.server_types.available_for_migration) == 3 + assert bound_datacenter.server_types.available_for_migration[0].id == 1 + assert ( + bound_datacenter.server_types.available_for_migration[0].complete is False + ) + assert bound_datacenter.server_types.available_for_migration[1].id == 2 + assert ( + bound_datacenter.server_types.available_for_migration[1].complete is False + ) + assert bound_datacenter.server_types.available_for_migration[2].id == 3 + assert ( + bound_datacenter.server_types.available_for_migration[2].complete is False + ) class TestDatacentersClient: diff --git a/tests/unit/server_types/conftest.py b/tests/unit/server_types/conftest.py index 5ff2b5e5..095ab7f4 100644 --- a/tests/unit/server_types/conftest.py +++ b/tests/unit/server_types/conftest.py @@ -41,6 +41,8 @@ def server_type_response(): "id": 1, "name": "nbg1", "deprecation": None, + "available": True, + "recommended": False, }, { "id": 2, @@ -49,6 +51,8 @@ def server_type_response(): "announced": "2023-06-01T00:00:00Z", "unavailable_after": "2023-09-01T00:00:00Z", }, + "available": True, + "recommended": True, }, ], } diff --git a/tests/unit/server_types/test_client.py b/tests/unit/server_types/test_client.py index cdba00f1..b8d266ff 100644 --- a/tests/unit/server_types/test_client.py +++ b/tests/unit/server_types/test_client.py @@ -33,6 +33,8 @@ def test_init(self, server_type_response): assert o.locations[0].location.id == 1 assert o.locations[0].location.name == "nbg1" assert o.locations[0].deprecation is None + assert o.locations[0].available is True + assert o.locations[0].recommended is False assert o.locations[1].location.id == 2 assert o.locations[1].location.name == "fsn1" assert ( @@ -43,6 +45,8 @@ def test_init(self, server_type_response): o.locations[1].deprecation.unavailable_after.isoformat() == "2023-09-01T00:00:00+00:00" ) + assert o.locations[1].available is True + assert o.locations[1].recommended is True with pytest.deprecated_call(): assert o.deprecated is True From 6ed94d81b78626e94a0a4757fec1db5f21bc61b4 Mon Sep 17 00:00:00 2001 From: phm07 <22707808+phm07@users.noreply.github.com> Date: Fri, 10 Apr 2026 12:47:39 +0200 Subject: [PATCH 2/3] fix format --- hcloud/datacenters/domain.py | 1 + tests/unit/datacenters/test_client.py | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/hcloud/datacenters/domain.py b/hcloud/datacenters/domain.py index 6e95b852..e2f05214 100644 --- a/hcloud/datacenters/domain.py +++ b/hcloud/datacenters/domain.py @@ -64,6 +64,7 @@ def server_types(self) -> DatacenterServerTypes | None: def server_types(self, value: DatacenterServerTypes | None) -> None: self._server_types = value + class DatacenterServerTypes(BaseDomain): """DatacenterServerTypes Domain diff --git a/tests/unit/datacenters/test_client.py b/tests/unit/datacenters/test_client.py index ace2e7d7..ef1aa840 100644 --- a/tests/unit/datacenters/test_client.py +++ b/tests/unit/datacenters/test_client.py @@ -46,15 +46,18 @@ def test_bound_datacenter_init(self, datacenter_response): assert len(bound_datacenter.server_types.available_for_migration) == 3 assert bound_datacenter.server_types.available_for_migration[0].id == 1 assert ( - bound_datacenter.server_types.available_for_migration[0].complete is False + bound_datacenter.server_types.available_for_migration[0].complete + is False ) assert bound_datacenter.server_types.available_for_migration[1].id == 2 assert ( - bound_datacenter.server_types.available_for_migration[1].complete is False + bound_datacenter.server_types.available_for_migration[1].complete + is False ) assert bound_datacenter.server_types.available_for_migration[2].id == 3 assert ( - bound_datacenter.server_types.available_for_migration[2].complete is False + bound_datacenter.server_types.available_for_migration[2].complete + is False ) From b2b4029b4c860c19cb0c6eed85d4c61c9c3197d9 Mon Sep 17 00:00:00 2001 From: phm07 <22707808+phm07@users.noreply.github.com> Date: Fri, 10 Apr 2026 13:00:59 +0200 Subject: [PATCH 3/3] apply suggestions --- hcloud/datacenters/domain.py | 5 +++-- hcloud/server_types/domain.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/hcloud/datacenters/domain.py b/hcloud/datacenters/domain.py index e2f05214..a25f2434 100644 --- a/hcloud/datacenters/domain.py +++ b/hcloud/datacenters/domain.py @@ -25,8 +25,9 @@ class Datacenter(BaseDomain, DomainIdentityMixin): :param server_types: :class:`DatacenterServerTypes ` """ - __api_properties__ = ("id", "name", "description", "location", "server_types") - __slots__ = ("id", "name", "description", "location", "_server_types") + __properties__ = ("id", "name", "description", "location") + __api_properties__ = (*__properties__, "server_types") + __slots__ = (*__properties__, "_server_types") def __init__( self, diff --git a/hcloud/server_types/domain.py b/hcloud/server_types/domain.py index 6c61b907..cafa873a 100644 --- a/hcloud/server_types/domain.py +++ b/hcloud/server_types/domain.py @@ -185,8 +185,8 @@ class ServerTypeLocation(BaseDomain): :param location: Location of the Server Type. :param deprecation: Wether the Server Type is deprecated in this Location. - :param available: True if the Server Type is currently available in this Location. - :param recommended: True if the Server Type is currently recommended in this Location. + :param available: Whether the Server Type is currently available in this Location. + :param recommended: Whether the Server Type is currently recommended in this Location. """ __api_properties__ = (