Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-hcloud for openSUSE:Factory checked in at 2026-03-26 21:10:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-hcloud (Old) and /work/SRC/openSUSE:Factory/.python-hcloud.new.8177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-hcloud" Thu Mar 26 21:10:10 2026 rev:17 rq:1342829 version:2.17.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-hcloud/python-hcloud.changes 2026-02-05 18:05:49.173247112 +0100 +++ /work/SRC/openSUSE:Factory/.python-hcloud.new.8177/python-hcloud.changes 2026-03-27 06:47:54.106002995 +0100 @@ -1,0 +2,8 @@ +Thu Mar 26 08:55:02 UTC 2026 - John Paul Adrian Glaubitz <[email protected]> + +- Update to 2.17.1 + * missing `__api_properties__` on LoadBalancerService (#639) +- from versiom 2.17.0 + * parse nested load balancer `label_selector` targets (#633) + +------------------------------------------------------------------- Old: ---- hcloud-2.16.0.tar.gz New: ---- hcloud-2.17.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-hcloud.spec ++++++ --- /var/tmp/diff_new_pack.8Gf3un/_old 2026-03-27 06:47:54.818032387 +0100 +++ /var/tmp/diff_new_pack.8Gf3un/_new 2026-03-27 06:47:54.822032552 +0100 @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-hcloud -Version: 2.16.0 +Version: 2.17.1 Release: 0 Summary: Hetzner Cloud Python library License: MIT ++++++ hcloud-2.16.0.tar.gz -> hcloud-2.17.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-2.16.0/CHANGELOG.md new/hcloud-2.17.1/CHANGELOG.md --- old/hcloud-2.16.0/CHANGELOG.md 2026-01-23 13:10:20.000000000 +0100 +++ new/hcloud-2.17.1/CHANGELOG.md 2026-03-23 11:50:49.000000000 +0100 @@ -1,5 +1,17 @@ # Changelog +## [v2.17.1](https://github.com/hetznercloud/hcloud-python/releases/tag/v2.17.1) + +### Bug Fixes + +- missing `__api_properties__` on LoadBalancerService (#639) + +## [v2.17.0](https://github.com/hetznercloud/hcloud-python/releases/tag/v2.17.0) + +### Features + +- parse nested load balancer `label_selector` targets (#633) + ## [v2.16.0](https://github.com/hetznercloud/hcloud-python/releases/tag/v2.16.0) ### Storage Boxes support is now generally available diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-2.16.0/PKG-INFO new/hcloud-2.17.1/PKG-INFO --- old/hcloud-2.16.0/PKG-INFO 2026-01-23 13:10:28.348504300 +0100 +++ new/hcloud-2.17.1/PKG-INFO 2026-03-23 11:50:58.227921200 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: hcloud -Version: 2.16.0 +Version: 2.17.1 Summary: Official Hetzner Cloud python library Home-page: https://github.com/hetznercloud/hcloud-python Author: Hetzner Cloud GmbH @@ -34,7 +34,7 @@ Requires-Dist: coverage<7.14,>=7.13; extra == "test" Requires-Dist: pylint<4.1,>=4; extra == "test" Requires-Dist: pytest<9.1,>=9; extra == "test" -Requires-Dist: pytest-cov<7.1,>=7; extra == "test" +Requires-Dist: pytest-cov<7.2,>=7; extra == "test" Requires-Dist: mypy<1.20,>=1.19; extra == "test" Requires-Dist: types-python-dateutil; extra == "test" Requires-Dist: types-requests; extra == "test" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-2.16.0/hcloud/_version.py new/hcloud-2.17.1/hcloud/_version.py --- old/hcloud-2.16.0/hcloud/_version.py 2026-01-23 13:10:20.000000000 +0100 +++ new/hcloud-2.17.1/hcloud/_version.py 2026-03-23 11:50:49.000000000 +0100 @@ -1,3 +1,3 @@ from __future__ import annotations -__version__ = "2.16.0" # x-releaser-pleaser-version +__version__ = "2.17.1" # x-releaser-pleaser-version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-2.16.0/hcloud/load_balancers/client.py new/hcloud-2.17.1/hcloud/load_balancers/client.py --- old/hcloud-2.16.0/hcloud/load_balancers/client.py 2026-01-23 13:10:20.000000000 +0100 +++ new/hcloud-2.17.1/hcloud/load_balancers/client.py 2026-03-23 11:50:49.000000000 +0100 @@ -93,36 +93,51 @@ ] data["private_net"] = private_nets - targets = data.get("targets") - if targets: - tmp_targets = [] - for target in targets: - tmp_target = LoadBalancerTarget(type=target["type"]) - if target["type"] == "server": - tmp_target.server = BoundServer( - client._parent.servers, data=target["server"], complete=False - ) - tmp_target.use_private_ip = target["use_private_ip"] - elif target["type"] == "label_selector": - tmp_target.label_selector = LoadBalancerTargetLabelSelector( - selector=target["label_selector"]["selector"] + def _load_balancer_targets( + raw_targets: list[dict[str, Any]], + ) -> list[LoadBalancerTarget]: + return [_load_balancer_target(raw_target) for raw_target in raw_targets] + + def _load_balancer_target( + raw_target: dict[str, Any], + ) -> LoadBalancerTarget: + result = LoadBalancerTarget(type=raw_target["type"]) + + if raw_target["type"] == "ip": + result.ip = LoadBalancerTargetIP( + ip=raw_target["ip"]["ip"], + ) + + elif raw_target["type"] == "server": + result.server = BoundServer( + client._parent.servers, # pylint: disable=protected-access + data=raw_target["server"], + complete=False, + ) + result.use_private_ip = raw_target["use_private_ip"] + + elif raw_target["type"] == "label_selector": + result.label_selector = LoadBalancerTargetLabelSelector( + selector=raw_target["label_selector"]["selector"] + ) + result.use_private_ip = raw_target["use_private_ip"] + + if (raw_nested_targets := raw_target.get("targets")) is not None: + result.targets = _load_balancer_targets(raw_nested_targets) + + if (raw_health_status := raw_target.get("health_status")) is not None: + result.health_status = [ + LoadBalancerTargetHealthStatus( + listen_port=item["listen_port"], + status=item["status"], ) - tmp_target.use_private_ip = target["use_private_ip"] - elif target["type"] == "ip": - tmp_target.ip = LoadBalancerTargetIP(ip=target["ip"]["ip"]) - - target_health_status = target.get("health_status") - if target_health_status is not None: - tmp_target.health_status = [ - LoadBalancerTargetHealthStatus( - listen_port=target_health_status_item["listen_port"], - status=target_health_status_item["status"], - ) - for target_health_status_item in target_health_status - ] + for item in raw_health_status + ] + + return result - tmp_targets.append(tmp_target) - data["targets"] = tmp_targets + if (raw_targets := data.get("targets")) is not None: + data["targets"] = _load_balancer_targets(raw_targets) services = data.get("services") if services: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-2.16.0/hcloud/load_balancers/domain.py new/hcloud-2.17.1/hcloud/load_balancers/domain.py --- old/hcloud-2.16.0/hcloud/load_balancers/domain.py 2026-01-23 13:10:20.000000000 +0100 +++ new/hcloud-2.17.1/hcloud/load_balancers/domain.py 2026-03-23 11:50:49.000000000 +0100 @@ -160,6 +160,16 @@ Configuration for http/https protocols, required when protocol is http/https """ + __api_properties__ = ( + "protocol", + "listen_port", + "destination_port", + "proxyprotocol", + "health_check", + "http", + ) + __slots__ = __api_properties__ + def __init__( self, protocol: str | None = None, @@ -411,6 +421,8 @@ use the private IP instead of primary public IP :param health_status: list List of health statuses of the services on this target. Only present for target types "server" and "ip". + :param targets: list + List of resolved label selector targets. Only present for target types "label_selector". """ __api_properties__ = ( @@ -420,6 +432,7 @@ "ip", "use_private_ip", "health_status", + "targets", ) __slots__ = __api_properties__ @@ -431,6 +444,7 @@ ip: LoadBalancerTargetIP | None = None, use_private_ip: bool | None = None, health_status: list[LoadBalancerTargetHealthStatus] | None = None, + targets: list[LoadBalancerTarget] | None = None, ): self.type = type self.server = server @@ -438,6 +452,7 @@ self.ip = ip self.use_private_ip = use_private_ip self.health_status = health_status + self.targets = targets def to_payload(self) -> dict[str, Any]: """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-2.16.0/hcloud.egg-info/PKG-INFO new/hcloud-2.17.1/hcloud.egg-info/PKG-INFO --- old/hcloud-2.16.0/hcloud.egg-info/PKG-INFO 2026-01-23 13:10:28.000000000 +0100 +++ new/hcloud-2.17.1/hcloud.egg-info/PKG-INFO 2026-03-23 11:50:58.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: hcloud -Version: 2.16.0 +Version: 2.17.1 Summary: Official Hetzner Cloud python library Home-page: https://github.com/hetznercloud/hcloud-python Author: Hetzner Cloud GmbH @@ -34,7 +34,7 @@ Requires-Dist: coverage<7.14,>=7.13; extra == "test" Requires-Dist: pylint<4.1,>=4; extra == "test" Requires-Dist: pytest<9.1,>=9; extra == "test" -Requires-Dist: pytest-cov<7.1,>=7; extra == "test" +Requires-Dist: pytest-cov<7.2,>=7; extra == "test" Requires-Dist: mypy<1.20,>=1.19; extra == "test" Requires-Dist: types-python-dateutil; extra == "test" Requires-Dist: types-requests; extra == "test" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-2.16.0/hcloud.egg-info/requires.txt new/hcloud-2.17.1/hcloud.egg-info/requires.txt --- old/hcloud-2.16.0/hcloud.egg-info/requires.txt 2026-01-23 13:10:28.000000000 +0100 +++ new/hcloud-2.17.1/hcloud.egg-info/requires.txt 2026-03-23 11:50:58.000000000 +0100 @@ -11,7 +11,7 @@ coverage<7.14,>=7.13 pylint<4.1,>=4 pytest<9.1,>=9 -pytest-cov<7.1,>=7 +pytest-cov<7.2,>=7 mypy<1.20,>=1.19 types-python-dateutil types-requests diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-2.16.0/setup.py new/hcloud-2.17.1/setup.py --- old/hcloud-2.16.0/setup.py 2026-01-23 13:10:20.000000000 +0100 +++ new/hcloud-2.17.1/setup.py 2026-03-23 11:50:49.000000000 +0100 @@ -7,7 +7,7 @@ setup( name="hcloud", - version="2.16.0", # x-releaser-pleaser-version + version="2.17.1", # x-releaser-pleaser-version keywords="hcloud hetzner cloud", description="Official Hetzner Cloud python library", long_description=readme, @@ -49,7 +49,7 @@ "coverage>=7.13,<7.14", "pylint>=4,<4.1", "pytest>=9,<9.1", - "pytest-cov>=7,<7.1", + "pytest-cov>=7,<7.2", "mypy>=1.19,<1.20", "types-python-dateutil", "types-requests", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-2.16.0/tests/unit/core/test_domain.py new/hcloud-2.17.1/tests/unit/core/test_domain.py --- old/hcloud-2.16.0/tests/unit/core/test_domain.py 2026-01-23 13:10:20.000000000 +0100 +++ new/hcloud-2.17.1/tests/unit/core/test_domain.py 2026-03-23 11:50:49.000000000 +0100 @@ -191,3 +191,9 @@ d2.child = [ActionDomain(id=2, name="child2")] assert d1 != d2 + + +def test_base_domain_subclasses(): + for c in BaseDomain.__subclasses__(): + assert len(c.__api_properties__) > 0 + assert len(c.__slots__) > 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-2.16.0/tests/unit/load_balancers/conftest.py new/hcloud-2.17.1/tests/unit/load_balancers/conftest.py --- old/hcloud-2.16.0/tests/unit/load_balancers/conftest.py 2026-01-23 13:10:20.000000000 +0100 +++ new/hcloud-2.17.1/tests/unit/load_balancers/conftest.py 2026-03-23 11:50:49.000000000 +0100 @@ -86,7 +86,23 @@ "health_status": [{"listen_port": 443, "status": "healthy"}], "label_selector": None, "use_private_ip": False, - } + }, + { + "type": "label_selector", + "label_selector": {"selector": "env=prod"}, + "use_private_ip": True, + "targets": [ + { + "type": "server", + "server": {"id": 105054278}, + "use_private_ip": True, + "health_status": [ + {"listen_port": 443, "status": "healthy"}, + {"listen_port": 3000, "status": "healthy"}, + ], + } + ], + }, ], "algorithm": {"type": "round_robin"}, } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-2.16.0/tests/unit/load_balancers/test_client.py new/hcloud-2.17.1/tests/unit/load_balancers/test_client.py --- old/hcloud-2.16.0/tests/unit/load_balancers/test_client.py 2026-01-23 13:10:20.000000000 +0100 +++ new/hcloud-2.17.1/tests/unit/load_balancers/test_client.py 2026-03-23 11:50:49.000000000 +0100 @@ -19,7 +19,7 @@ ) from hcloud.locations import Location from hcloud.networks import Network -from hcloud.servers import Server +from hcloud.servers import BoundServer, Server from ..conftest import BoundModelTestCase @@ -60,6 +60,30 @@ assert bound_load_balancer.id == 4711 assert bound_load_balancer.name == "Web Frontend" + def test_init_label_selector_nested_targets(self, response_load_balancer): + bound_load_balancer = BoundLoadBalancer( + client=mock.MagicMock(), data=response_load_balancer["load_balancer"] + ) + + label_selector_target = bound_load_balancer.targets[1] + assert label_selector_target.type == "label_selector" + assert label_selector_target.label_selector.selector == "env=prod" + assert label_selector_target.use_private_ip is True + assert label_selector_target.targets is not None + assert len(label_selector_target.targets) == 1 + + nested = label_selector_target.targets[0] + assert nested.type == "server" + assert isinstance(nested.server, BoundServer) + assert nested.server.id == 105054278 + assert nested.use_private_ip is True + assert nested.health_status is not None + assert len(nested.health_status) == 2 + assert nested.health_status[0].listen_port == 443 + assert nested.health_status[0].status == "healthy" + assert nested.health_status[1].listen_port == 3000 + assert nested.health_status[1].status == "healthy" + class TestLoadBalancerslient: @pytest.fixture()
