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 2023-12-08 22:32:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-hcloud (Old) and /work/SRC/openSUSE:Factory/.python-hcloud.new.25432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-hcloud" Fri Dec 8 22:32:11 2023 rev:5 rq:1131740 version:1.32.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-hcloud/python-hcloud.changes 2023-09-01 14:20:32.287074319 +0200 +++ /work/SRC/openSUSE:Factory/.python-hcloud.new.25432/python-hcloud.changes 2023-12-08 22:32:42.717453693 +0100 @@ -1,0 +2,12 @@ +Thu Dec 7 22:43:47 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 1.32.0: + * allow returning root_password in servers rebuild (#276) + * prepare for iso deprecated field removal (#320) (beae328) + * add deprecation field to Iso (#318) (036b52f) + * support python 3.12 (#311) (7e8cd1d) + * prevent api calls when printing bound models (#305) (c1de7ef) + * add domain attribute type hints to bound models (#300) + * load token from env in examples scripts (#302) (f18c9a6) + +------------------------------------------------------------------- Old: ---- hcloud-1.28.0.tar.gz New: ---- hcloud-1.32.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-hcloud.spec ++++++ --- /var/tmp/diff_new_pack.eFTUpS/_old 2023-12-08 22:32:43.185470914 +0100 +++ /var/tmp/diff_new_pack.eFTUpS/_new 2023-12-08 22:32:43.185470914 +0100 @@ -17,7 +17,7 @@ Name: python-hcloud -Version: 1.28.0 +Version: 1.32.0 Release: 0 Summary: Hetzner Cloud Python library License: MIT ++++++ hcloud-1.28.0.tar.gz -> hcloud-1.32.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/CHANGELOG.md new/hcloud-1.32.0/CHANGELOG.md --- old/hcloud-1.28.0/CHANGELOG.md 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/CHANGELOG.md 2023-11-17 15:09:57.000000000 +0100 @@ -1,5 +1,87 @@ # Changelog +## [1.32.0](https://github.com/hetznercloud/hcloud-python/compare/v1.31.0...v1.32.0) (2023-11-17) + + +### Features + +* allow returning root_password in servers rebuild ([#276](https://github.com/hetznercloud/hcloud-python/issues/276)) ([38e098a](https://github.com/hetznercloud/hcloud-python/commit/38e098a41154e6561578cd723608fcd7577c3d01)) + + +### Dependencies + +* update dependency mypy to >=1.7,<1.8 ([#325](https://github.com/hetznercloud/hcloud-python/issues/325)) ([7b59a2d](https://github.com/hetznercloud/hcloud-python/commit/7b59a2decc9bb5152dc9de435bfe12ce1f34ac1c)) +* update pre-commit hook pre-commit/mirrors-prettier to v3.1.0 ([#326](https://github.com/hetznercloud/hcloud-python/issues/326)) ([213b661](https://github.com/hetznercloud/hcloud-python/commit/213b661d897cdd327f478b52aeb79844826694d8)) +* update pre-commit hook psf/black-pre-commit-mirror to v23.10.1 ([#322](https://github.com/hetznercloud/hcloud-python/issues/322)) ([999afe3](https://github.com/hetznercloud/hcloud-python/commit/999afe37e02a113639930aff6879f50918ac0e89)) +* update pre-commit hook psf/black-pre-commit-mirror to v23.11.0 ([#324](https://github.com/hetznercloud/hcloud-python/issues/324)) ([7b2a24e](https://github.com/hetznercloud/hcloud-python/commit/7b2a24ecf69c0bead7f9113053fda37a0cc31d1b)) + +## [1.31.0](https://github.com/hetznercloud/hcloud-python/compare/v1.30.0...v1.31.0) (2023-10-23) + + +### Features + +* prepare for iso deprecated field removal ([#320](https://github.com/hetznercloud/hcloud-python/issues/320)) ([beae328](https://github.com/hetznercloud/hcloud-python/commit/beae328dd6b9afb8c0db9fa9b44340270db7dd09)) + + +### Dependencies + +* update pre-commit hook psf/black-pre-commit-mirror to v23.10.0 ([#319](https://github.com/hetznercloud/hcloud-python/issues/319)) ([184bbe6](https://github.com/hetznercloud/hcloud-python/commit/184bbe65a736a42d13774b6c29fa7dd8a13ec645)) + +## [1.30.0](https://github.com/hetznercloud/hcloud-python/compare/v1.29.1...v1.30.0) (2023-10-13) + + +### Features + +* add deprecation field to Iso ([#318](https://github.com/hetznercloud/hcloud-python/issues/318)) ([036b52f](https://github.com/hetznercloud/hcloud-python/commit/036b52fe51bcbb6b610c0c99ca224d3c4bbfc68d)) +* support python 3.12 ([#311](https://github.com/hetznercloud/hcloud-python/issues/311)) ([7e8cd1d](https://github.com/hetznercloud/hcloud-python/commit/7e8cd1d92e56d210fe3fb180e403122ef0e7bd7f)) + + +### Dependencies + +* update dependency mypy to >=1.6,<1.7 ([#317](https://github.com/hetznercloud/hcloud-python/issues/317)) ([d248bbd](https://github.com/hetznercloud/hcloud-python/commit/d248bbd4e55f3bcf6a107cfa4f38768df0bf3de5)) +* update dependency pylint to v3 ([#307](https://github.com/hetznercloud/hcloud-python/issues/307)) ([277841d](https://github.com/hetznercloud/hcloud-python/commit/277841dd84ba3b2bbc99a06a3f97e114d1c83dcb)) +* update pre-commit hook asottile/pyupgrade to v3.14.0 ([#308](https://github.com/hetznercloud/hcloud-python/issues/308)) ([07a4513](https://github.com/hetznercloud/hcloud-python/commit/07a4513e284b9ee964bca003d0a9dfd948d39b02)) +* update pre-commit hook asottile/pyupgrade to v3.15.0 ([#312](https://github.com/hetznercloud/hcloud-python/issues/312)) ([c544639](https://github.com/hetznercloud/hcloud-python/commit/c5446394acfa25d23761da4c6b5b75fb6d376b23)) +* update pre-commit hook pre-commit/pre-commit-hooks to v4.5.0 ([#313](https://github.com/hetznercloud/hcloud-python/issues/313)) ([e51eaa9](https://github.com/hetznercloud/hcloud-python/commit/e51eaa990336251c2afc8c83d4c5e6f5e5bb857b)) +* update python docker tag to v3.12 ([#309](https://github.com/hetznercloud/hcloud-python/issues/309)) ([3a1ee67](https://github.com/hetznercloud/hcloud-python/commit/3a1ee675f2c980a4d9e63188e8ffceb64f4797fc)) + +## [1.29.1](https://github.com/hetznercloud/hcloud-python/compare/v1.29.0...v1.29.1) (2023-09-26) + + +### Bug Fixes + +* prevent api calls when printing bound models ([#305](https://github.com/hetznercloud/hcloud-python/issues/305)) ([c1de7ef](https://github.com/hetznercloud/hcloud-python/commit/c1de7efc851b3b10e2a50e66268fc8fb0ff648a8)) + +## [1.29.0](https://github.com/hetznercloud/hcloud-python/compare/v1.28.0...v1.29.0) (2023-09-25) + + +### Features + +* add domain attribute type hints to bound models ([#300](https://github.com/hetznercloud/hcloud-python/issues/300)) ([6d46d06](https://github.com/hetznercloud/hcloud-python/commit/6d46d06c42e2e86e88b32a74d7fbd588911cc8ad)) +* **firewalls:** add `applied_to_resources` to `FirewallResource` ([#297](https://github.com/hetznercloud/hcloud-python/issues/297)) ([55d2b20](https://github.com/hetznercloud/hcloud-python/commit/55d2b2043ec1e3a040eb9e360ca0dc0c299ad60f)) + + +### Bug Fixes + +* missing BaseDomain base class inheritance ([#303](https://github.com/hetznercloud/hcloud-python/issues/303)) ([0ee7598](https://github.com/hetznercloud/hcloud-python/commit/0ee759856cb1352f6cc538b7ef86a91cd20380f2)) + + +### Dependencies + +* update actions/checkout action to v4 ([#295](https://github.com/hetznercloud/hcloud-python/issues/295)) ([c02b446](https://github.com/hetznercloud/hcloud-python/commit/c02b4468f0e499791bbee8fe48fe7a737985df1f)) +* update dependency sphinx to >=7.2.2,<7.3 ([#291](https://github.com/hetznercloud/hcloud-python/issues/291)) ([10234ea](https://github.com/hetznercloud/hcloud-python/commit/10234ea7bf51a427b18f2b5605d9ffa7ac5f5ee8)) +* update dependency sphinx to v7 ([#211](https://github.com/hetznercloud/hcloud-python/issues/211)) ([f635c94](https://github.com/hetznercloud/hcloud-python/commit/f635c94c23b8ae49283b9b7fcb4fe7b948b203b9)) +* update pre-commit hook asottile/pyupgrade to v3.11.0 ([#298](https://github.com/hetznercloud/hcloud-python/issues/298)) ([4bbd0cc](https://github.com/hetznercloud/hcloud-python/commit/4bbd0ccb0f606e2f90f8242951d3f4d9b86d7aea)) +* update pre-commit hook asottile/pyupgrade to v3.11.1 ([#299](https://github.com/hetznercloud/hcloud-python/issues/299)) ([2f9fcd7](https://github.com/hetznercloud/hcloud-python/commit/2f9fcd7bb80efb8da6eafab0ee70a8dda93eb6f1)) +* update pre-commit hook asottile/pyupgrade to v3.13.0 ([#301](https://github.com/hetznercloud/hcloud-python/issues/301)) ([951dbf3](https://github.com/hetznercloud/hcloud-python/commit/951dbf3e3b3816ffaeb44a583251a5a3a4b90b70)) +* update pre-commit hook pre-commit/mirrors-prettier to v3.0.3 ([#294](https://github.com/hetznercloud/hcloud-python/issues/294)) ([381e336](https://github.com/hetznercloud/hcloud-python/commit/381e336ff1259fa26cb6abae3b7341cb16229a4b)) +* update pre-commit hook psf/black to v23.9.1 ([#296](https://github.com/hetznercloud/hcloud-python/issues/296)) ([4374a7b](https://github.com/hetznercloud/hcloud-python/commit/4374a7be9f244a72f1fc0c2dd76357cf63f19bfd)) + + +### Documentation + +* load token from env in examples scripts ([#302](https://github.com/hetznercloud/hcloud-python/issues/302)) ([f18c9a6](https://github.com/hetznercloud/hcloud-python/commit/f18c9a60e045743b26892eeb1fe9e5737a63c11f)) + ## [1.28.0](https://github.com/hetznercloud/hcloud-python/compare/v1.27.2...v1.28.0) (2023-08-17) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/PKG-INFO new/hcloud-1.32.0/PKG-INFO --- old/hcloud-1.28.0/PKG-INFO 2023-08-17 14:46:20.408549000 +0200 +++ new/hcloud-1.32.0/PKG-INFO 2023-11-17 15:10:09.478945300 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: hcloud -Version: 1.28.0 +Version: 1.32.0 Summary: Official Hetzner Cloud python library Home-page: https://github.com/hetznercloud/hcloud-python Author: Hetzner Cloud GmbH @@ -20,11 +20,24 @@ Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 Requires-Python: >=3.8 Description-Content-Type: text/markdown +License-File: LICENSE +Requires-Dist: python-dateutil>=2.7.5 +Requires-Dist: requests>=2.20 Provides-Extra: docs +Requires-Dist: sphinx<7.3,>=7.2.2; extra == "docs" +Requires-Dist: sphinx-rtd-theme<1.4,>=1.3.0; extra == "docs" +Requires-Dist: myst-parser<2.1,>=2.0.0; extra == "docs" +Requires-Dist: watchdog<3.1,>=3.0.0; extra == "docs" Provides-Extra: test -License-File: LICENSE +Requires-Dist: coverage<7.4,>=7.3; extra == "test" +Requires-Dist: pylint<3.1,>=3; extra == "test" +Requires-Dist: pytest<7.5,>=7.4; extra == "test" +Requires-Dist: mypy<1.8,>=1.7; extra == "test" +Requires-Dist: types-python-dateutil; extra == "test" +Requires-Dist: types-requests; extra == "test" # Hetzner Cloud Python diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/__version__.py new/hcloud-1.32.0/hcloud/__version__.py --- old/hcloud-1.28.0/hcloud/__version__.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/__version__.py 2023-11-17 15:09:57.000000000 +0100 @@ -1,3 +1,3 @@ from __future__ import annotations -VERSION = "1.28.0" # x-release-please-version +VERSION = "1.32.0" # x-release-please-version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/_client.py new/hcloud-1.32.0/hcloud/_client.py --- old/hcloud-1.28.0/hcloud/_client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/_client.py 2023-11-17 15:09:57.000000000 +0100 @@ -42,7 +42,7 @@ poll_interval: int = 1, timeout: float | tuple[float, float] | None = None, ): - """Create an new Client instance + """Create a new Client instance :param token: Hetzner Cloud API token :param api_endpoint: Hetzner Cloud API endpoint diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/actions/client.py new/hcloud-1.32.0/hcloud/actions/client.py --- old/hcloud-1.28.0/hcloud/actions/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/actions/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -11,7 +11,7 @@ from .._client import Client -class BoundAction(BoundModelBase): +class BoundAction(BoundModelBase, Action): _client: ActionsClient model = Action @@ -27,6 +27,7 @@ while self.status == Action.STATUS_RUNNING: if max_retries > 0: self.reload() + # pylint: disable=protected-access time.sleep(self._client._client.poll_interval) max_retries = max_retries - 1 else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/certificates/client.py new/hcloud-1.32.0/hcloud/certificates/client.py --- old/hcloud-1.28.0/hcloud/certificates/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/certificates/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -15,7 +15,7 @@ from .._client import Client -class BoundCertificate(BoundModelBase): +class BoundCertificate(BoundModelBase, Certificate): _client: CertificatesClient model = Certificate diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/core/client.py new/hcloud-1.32.0/hcloud/core/client.py --- old/hcloud-1.28.0/hcloud/core/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/core/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -45,6 +45,7 @@ def _get_first_by(self, **kwargs): # type: ignore[no-untyped-def] assert hasattr(self, "get_list") + # pylint: disable=no-member entities, _ = self.get_list(**kwargs) return entities[0] if entities else None @@ -89,3 +90,9 @@ bound_model = self._client.get_by_id(self.data_model.id) self.data_model = bound_model.data_model self.complete = True + + def __repr__(self) -> str: + # Override and reset hcloud.core.domain.BaseDomain.__repr__ method for bound + # models, as they will generate a lot of API call trying to print all the fields + # of the model. + return object.__repr__(self) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/core/domain.py new/hcloud-1.32.0/hcloud/core/domain.py --- old/hcloud-1.28.0/hcloud/core/domain.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/core/domain.py 2023-11-17 15:09:57.000000000 +0100 @@ -6,6 +6,9 @@ @classmethod def from_dict(cls, data: dict): # type: ignore[no-untyped-def] + """ + Build the domain object from the data dict. + """ supported_data = {k: v for k, v in data.items() if k in cls.__slots__} return cls(**supported_data) @@ -22,12 +25,14 @@ @property def id_or_name(self) -> int | str: + """ + Return the first defined value, and fails if none is defined. + """ if self.id is not None: return self.id - elif self.name is not None: + if self.name is not None: return self.name - else: - raise ValueError("id or name must be set") + raise ValueError("id or name must be set") class Pagination(BaseDomain): @@ -65,6 +70,9 @@ @classmethod def parse_meta(cls, response: dict) -> Meta | None: + """ + If present, extract the meta details from the response and return a meta object. + """ meta = None if response and "meta" in response: meta = cls() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/datacenters/client.py new/hcloud-1.32.0/hcloud/datacenters/client.py --- old/hcloud-1.28.0/hcloud/datacenters/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/datacenters/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -11,7 +11,7 @@ from .._client import Client -class BoundDatacenter(BoundModelBase): +class BoundDatacenter(BoundModelBase, Datacenter): _client: DatacentersClient model = Datacenter diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/datacenters/domain.py new/hcloud-1.32.0/hcloud/datacenters/domain.py --- old/hcloud-1.28.0/hcloud/datacenters/domain.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/datacenters/domain.py 2023-11-17 15:09:57.000000000 +0100 @@ -36,7 +36,7 @@ self.server_types = server_types -class DatacenterServerTypes: +class DatacenterServerTypes(BaseDomain): """DatacenterServerTypes Domain :param available: List[:class:`BoundServerTypes <hcloud.server_types.client.BoundServerTypes>`] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/firewalls/__init__.py new/hcloud-1.32.0/hcloud/firewalls/__init__.py --- old/hcloud-1.28.0/hcloud/firewalls/__init__.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/firewalls/__init__.py 2023-11-17 15:09:57.000000000 +0100 @@ -5,6 +5,7 @@ CreateFirewallResponse, Firewall, FirewallResource, + FirewallResourceAppliedToResources, FirewallResourceLabelSelector, FirewallRule, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/firewalls/client.py new/hcloud-1.32.0/hcloud/firewalls/client.py --- old/hcloud-1.28.0/hcloud/firewalls/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/firewalls/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -8,6 +8,7 @@ CreateFirewallResponse, Firewall, FirewallResource, + FirewallResourceAppliedToResources, FirewallResourceLabelSelector, FirewallRule, ) @@ -16,7 +17,7 @@ from .._client import Client -class BoundFirewall(BoundModelBase): +class BoundFirewall(BoundModelBase, Firewall): _client: FirewallsClient model = Firewall @@ -39,29 +40,53 @@ applied_to = data.get("applied_to", []) if applied_to: + # pylint: disable=import-outside-toplevel from ..servers import BoundServer - ats = [] - for a in applied_to: - if a["type"] == FirewallResource.TYPE_SERVER: - ats.append( + data_applied_to = [] + for firewall_resource in applied_to: + applied_to_resources = None + if firewall_resource.get("applied_to_resources"): + applied_to_resources = [ + FirewallResourceAppliedToResources( + type=resource["type"], + server=( + BoundServer( + client._client.servers, + resource.get("server"), + complete=False, + ) + if resource.get("server") is not None + else None + ), + ) + for resource in firewall_resource.get("applied_to_resources") + ] + + if firewall_resource["type"] == FirewallResource.TYPE_SERVER: + data_applied_to.append( FirewallResource( - type=a["type"], + type=firewall_resource["type"], server=BoundServer( - client._client.servers, a["server"], complete=False + client._client.servers, + firewall_resource["server"], + complete=False, ), + applied_to_resources=applied_to_resources, ) ) - elif a["type"] == FirewallResource.TYPE_LABEL_SELECTOR: - ats.append( + elif firewall_resource["type"] == FirewallResource.TYPE_LABEL_SELECTOR: + data_applied_to.append( FirewallResource( - type=a["type"], + type=firewall_resource["type"], label_selector=FirewallResourceLabelSelector( - selector=a["label_selector"]["selector"] + selector=firewall_resource["label_selector"]["selector"] ), + applied_to_resources=applied_to_resources, ) ) - data["applied_to"] = ats + + data["applied_to"] = data_applied_to super().__init__(client, data, complete) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/firewalls/domain.py new/hcloud-1.32.0/hcloud/firewalls/domain.py --- old/hcloud-1.28.0/hcloud/firewalls/domain.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/firewalls/domain.py 2023-11-17 15:09:57.000000000 +0100 @@ -48,7 +48,7 @@ self.created = isoparse(created) if created else None -class FirewallRule: +class FirewallRule(BaseDomain): """Firewall Rule Domain :param direction: str @@ -108,6 +108,9 @@ self.description = description def to_payload(self) -> dict[str, Any]: + """ + Generates the request payload from this domain object. + """ payload: dict[str, Any] = { "direction": self.direction, "protocol": self.protocol, @@ -122,7 +125,7 @@ return payload -class FirewallResource: +class FirewallResource(BaseDomain): """Firewall Used By Domain :param type: str @@ -131,9 +134,11 @@ Server the Firewall is applied to :param label_selector: Optional[FirewallResourceLabelSelector] Label Selector for Servers the Firewall should be applied to + :param applied_to_resources: (read-only) List of effective resources the firewall is + applied to. """ - __slots__ = ("type", "server", "label_selector") + __slots__ = ("type", "server", "label_selector", "applied_to_resources") TYPE_SERVER = "server" """Firewall Used By Type Server""" @@ -145,12 +150,17 @@ type: str, server: Server | BoundServer | None = None, label_selector: FirewallResourceLabelSelector | None = None, + applied_to_resources: list[FirewallResourceAppliedToResources] | None = None, ): self.type = type self.server = server self.label_selector = label_selector + self.applied_to_resources = applied_to_resources def to_payload(self) -> dict[str, Any]: + """ + Generates the request payload from this domain object. + """ payload: dict[str, Any] = {"type": self.type} if self.server is not None: payload["server"] = {"id": self.server.id} @@ -160,6 +170,24 @@ return payload +class FirewallResourceAppliedToResources(BaseDomain): + """Firewall Resource applied to Domain + + :param type: Type of resource referenced + :param server: Server the Firewall is applied to + """ + + __slots__ = ("type", "server") + + def __init__( + self, + type: str, + server: BoundServer | None = None, + ): + self.type = type + self.server = server + + class FirewallResourceLabelSelector(BaseDomain): """FirewallResourceLabelSelector Domain diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/floating_ips/client.py new/hcloud-1.32.0/hcloud/floating_ips/client.py --- old/hcloud-1.28.0/hcloud/floating_ips/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/floating_ips/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -13,12 +13,13 @@ from ..servers import BoundServer, Server -class BoundFloatingIP(BoundModelBase): +class BoundFloatingIP(BoundModelBase, FloatingIP): _client: FloatingIPsClient model = FloatingIP def __init__(self, client: FloatingIPsClient, data: dict, complete: bool = True): + # pylint: disable=import-outside-toplevel from ..servers import BoundServer server = data.get("server") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/hcloud.py new/hcloud-1.32.0/hcloud/hcloud.py --- old/hcloud-1.28.0/hcloud/hcloud.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/hcloud.py 2023-11-17 15:09:57.000000000 +0100 @@ -8,4 +8,5 @@ stacklevel=2, ) +# pylint: disable=wildcard-import,wrong-import-position,unused-wildcard-import from ._client import * # noqa diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/helpers/labels.py new/hcloud-1.32.0/hcloud/helpers/labels.py --- old/hcloud-1.28.0/hcloud/helpers/labels.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/helpers/labels.py 2023-11-17 15:09:57.000000000 +0100 @@ -18,10 +18,10 @@ :return: bool """ - for k, v in labels.items(): - if LabelValidator.KEY_REGEX.match(k) is None: + for key, value in labels.items(): + if LabelValidator.KEY_REGEX.match(key) is None: return False - if LabelValidator.VALUE_REGEX.match(v) is None: + if LabelValidator.VALUE_REGEX.match(value) is None: return False return True @@ -32,9 +32,15 @@ :return: bool, str """ - for k, v in labels.items(): - if LabelValidator.KEY_REGEX.match(k) is None: - return False, f"label key {k} is not correctly formatted" - if LabelValidator.VALUE_REGEX.match(v) is None: - return False, f"label value {v} (key: {k}) is not correctly formatted" + for key, value in labels.items(): + if LabelValidator.KEY_REGEX.match(key) is None: + return ( + False, + f"label key {key} is not correctly formatted", + ) + if LabelValidator.VALUE_REGEX.match(value) is None: + return ( + False, + f"label value {value} (key: {key}) is not correctly formatted", + ) return True, "" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/images/client.py new/hcloud-1.32.0/hcloud/images/client.py --- old/hcloud-1.28.0/hcloud/images/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/images/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -10,12 +10,13 @@ from .._client import Client -class BoundImage(BoundModelBase): +class BoundImage(BoundModelBase, Image): _client: ImagesClient model = Image def __init__(self, client: ImagesClient, data: dict): + # pylint: disable=import-outside-toplevel from ..servers import BoundServer created_from = data.get("created_from") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/images/domain.py new/hcloud-1.32.0/hcloud/images/domain.py --- old/hcloud-1.28.0/hcloud/images/domain.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/images/domain.py 2023-11-17 15:09:57.000000000 +0100 @@ -71,6 +71,7 @@ "deprecated", ) + # pylint: disable=too-many-locals def __init__( self, id: int | None = None, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/isos/client.py new/hcloud-1.32.0/hcloud/isos/client.py --- old/hcloud-1.28.0/hcloud/isos/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/isos/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -10,7 +10,7 @@ from .._client import Client -class BoundIso(BoundModelBase): +class BoundIso(BoundModelBase, Iso): _client: IsosClient model = Iso diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/isos/domain.py new/hcloud-1.32.0/hcloud/isos/domain.py --- old/hcloud-1.28.0/hcloud/isos/domain.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/isos/domain.py 2023-11-17 15:09:57.000000000 +0100 @@ -1,8 +1,10 @@ from __future__ import annotations -from dateutil.parser import isoparse +from datetime import datetime +from warnings import warn from ..core import BaseDomain, DomainIdentityMixin +from ..deprecation import DeprecationInfo class Iso(BaseDomain, DomainIdentityMixin): @@ -19,10 +21,20 @@ :param architecture: str, None CPU Architecture that the ISO is compatible with. None means that the compatibility is unknown. Choices: `x86`, `arm` :param deprecated: datetime, None - ISO 8601 timestamp of deprecation, None if ISO is still available. After the deprecation time it will no longer be possible to attach the ISO to servers. + ISO 8601 timestamp of deprecation, None if ISO is still available. After the deprecation time it will no longer be possible to attach the ISO to servers. This field is deprecated. Use `deprecation` instead. + :param deprecation: :class:`DeprecationInfo <hcloud.deprecation.domain.DeprecationInfo>`, None + Describes if, when & how the resources was deprecated. If this field is set to None the resource is not + deprecated. If it has a value, it is considered deprecated. """ - __slots__ = ("id", "name", "type", "architecture", "description", "deprecated") + __slots__ = ( + "id", + "name", + "type", + "architecture", + "description", + "deprecation", + ) def __init__( self, @@ -31,11 +43,27 @@ type: str | None = None, architecture: str | None = None, description: str | None = None, - deprecated: str | None = None, + deprecated: str | None = None, # pylint: disable=unused-argument + deprecation: dict | None = None, ): self.id = id self.name = name self.type = type self.architecture = architecture self.description = description - self.deprecated = isoparse(deprecated) if deprecated else None + self.deprecation = ( + DeprecationInfo.from_dict(deprecation) if deprecation is not None else None + ) + + @property + def deprecated(self) -> datetime | None: + """ + ISO 8601 timestamp of deprecation, None if ISO is still available. + """ + warn( + "The `deprecated` field is deprecated, please use the `deprecation` field instead.", + DeprecationWarning, + ) + if self.deprecation is None: + return None + return self.deprecation.unavailable_after diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/load_balancer_types/client.py new/hcloud-1.32.0/hcloud/load_balancer_types/client.py --- old/hcloud-1.28.0/hcloud/load_balancer_types/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/load_balancer_types/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -9,7 +9,7 @@ from .._client import Client -class BoundLoadBalancerType(BoundModelBase): +class BoundLoadBalancerType(BoundModelBase, LoadBalancerType): _client: LoadBalancerTypesClient model = LoadBalancerType diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/load_balancers/client.py new/hcloud-1.32.0/hcloud/load_balancers/client.py --- old/hcloud-1.28.0/hcloud/load_balancers/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/load_balancers/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -34,11 +34,12 @@ from ..networks import Network -class BoundLoadBalancer(BoundModelBase): +class BoundLoadBalancer(BoundModelBase, LoadBalancer): _client: LoadBalancersClient model = LoadBalancer + # pylint: disable=too-many-branches,too-many-locals def __init__(self, client: LoadBalancersClient, data: dict, complete: bool = True): algorithm = data.get("algorithm") if algorithm: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/load_balancers/domain.py new/hcloud-1.32.0/hcloud/load_balancers/domain.py --- old/hcloud-1.28.0/hcloud/load_balancers/domain.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/load_balancers/domain.py 2023-11-17 15:09:57.000000000 +0100 @@ -69,6 +69,7 @@ "included_traffic", ) + # pylint: disable=too-many-locals def __init__( self, id: int, @@ -137,7 +138,11 @@ self.health_check = health_check self.http = http + # pylint: disable=too-many-branches def to_payload(self) -> dict[str, Any]: + """ + Generates the request payload from this domain object. + """ payload: dict[str, Any] = {} if self.protocol is not None: @@ -334,6 +339,9 @@ self.health_status = health_status def to_payload(self) -> dict[str, Any]: + """ + Generates the request payload from this domain object. + """ payload: dict[str, Any] = { "type": self.type, } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/locations/client.py new/hcloud-1.32.0/hcloud/locations/client.py --- old/hcloud-1.28.0/hcloud/locations/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/locations/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -9,7 +9,7 @@ from .._client import Client -class BoundLocation(BoundModelBase): +class BoundLocation(BoundModelBase, Location): _client: LocationsClient model = Location diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/networks/client.py new/hcloud-1.32.0/hcloud/networks/client.py --- old/hcloud-1.28.0/hcloud/networks/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/networks/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -10,7 +10,7 @@ from .._client import Client -class BoundNetwork(BoundModelBase): +class BoundNetwork(BoundModelBase, Network): _client: NetworksClient model = Network @@ -26,6 +26,7 @@ routes = [NetworkRoute.from_dict(route) for route in routes] data["routes"] = routes + # pylint: disable=import-outside-toplevel from ..servers import BoundServer servers = data.get("servers", []) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/placement_groups/client.py new/hcloud-1.32.0/hcloud/placement_groups/client.py --- old/hcloud-1.28.0/hcloud/placement_groups/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/placement_groups/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -10,7 +10,7 @@ from .._client import Client -class BoundPlacementGroup(BoundModelBase): +class BoundPlacementGroup(BoundModelBase, PlacementGroup): _client: PlacementGroupsClient model = PlacementGroup diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/primary_ips/client.py new/hcloud-1.32.0/hcloud/primary_ips/client.py --- old/hcloud-1.28.0/hcloud/primary_ips/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/primary_ips/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -11,12 +11,13 @@ from ..datacenters import BoundDatacenter, Datacenter -class BoundPrimaryIP(BoundModelBase): +class BoundPrimaryIP(BoundModelBase, PrimaryIP): _client: PrimaryIPsClient model = PrimaryIP def __init__(self, client: PrimaryIPsClient, data: dict, complete: bool = True): + # pylint: disable=import-outside-toplevel from ..datacenters import BoundDatacenter datacenter = data.get("datacenter", {}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/server_types/client.py new/hcloud-1.32.0/hcloud/server_types/client.py --- old/hcloud-1.28.0/hcloud/server_types/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/server_types/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -9,7 +9,7 @@ from .._client import Client -class BoundServerType(BoundModelBase): +class BoundServerType(BoundModelBase, ServerType): _client: ServerTypesClient model = ServerType diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/servers/client.py new/hcloud-1.32.0/hcloud/servers/client.py --- old/hcloud-1.28.0/hcloud/servers/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/servers/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -1,5 +1,6 @@ from __future__ import annotations +import warnings from typing import TYPE_CHECKING, Any, NamedTuple from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient @@ -9,8 +10,6 @@ from ..floating_ips import BoundFloatingIP from ..images import BoundImage, CreateImageResponse from ..isos import BoundIso -from ..networks import BoundNetwork # noqa -from ..networks import Network # noqa from ..placement_groups import BoundPlacementGroup from ..primary_ips import BoundPrimaryIP from ..server_types import BoundServerType @@ -23,6 +22,7 @@ PrivateNet, PublicNetwork, PublicNetworkFirewall, + RebuildResponse, RequestConsoleResponse, ResetPasswordResponse, Server, @@ -35,6 +35,7 @@ from ..images import Image from ..isos import Iso from ..locations import BoundLocation, Location + from ..networks import BoundNetwork, Network from ..placement_groups import PlacementGroup from ..server_types import ServerType from ..ssh_keys import BoundSSHKey, SSHKey @@ -42,11 +43,12 @@ from .domain import ServerCreatePublicNetwork -class BoundServer(BoundModelBase): +class BoundServer(BoundModelBase, Server): _client: ServersClient model = Server + # pylint: disable=too-many-locals def __init__(self, client: ServersClient, data: dict, complete: bool = True): datacenter = data.get("datacenter") if datacenter is not None: @@ -130,6 +132,9 @@ private_nets = data.get("private_net") if private_nets: + # pylint: disable=import-outside-toplevel + from ..networks import BoundNetwork + private_nets = [ PrivateNet( network=BoundNetwork( @@ -296,13 +301,18 @@ """ return self._client.create_image(self, description, type, labels) - def rebuild(self, image: Image | BoundImage) -> BoundAction: + def rebuild( + self, + image: Image | BoundImage, + *, + return_response: bool = False, + ) -> RebuildResponse | BoundAction: """Rebuilds a server overwriting its disk with the content of an image, thereby destroying all data on the target server. - :param image: :class:`BoundImage <hcloud.images.client.BoundImage>` or :class:`Image <hcloud.servers.domain.Image>` - :return: :class:`BoundAction <hcloud.actions.client.BoundAction>` + :param image: Image to use for the rebuilt server + :param return_response: Whether to return the full response or only the action. """ - return self._client.rebuild(self, image) + return self._client.rebuild(self, image, return_response=return_response) def change_type( self, @@ -540,6 +550,7 @@ """ return self._get_first_by(name=name) + # pylint: disable=too-many-branches,too-many-locals def create( self, name: str, @@ -926,12 +937,14 @@ self, server: Server | BoundServer, image: Image | BoundImage, - ) -> BoundAction: + *, + return_response: bool = False, + ) -> RebuildResponse | BoundAction: """Rebuilds a server overwriting its disk with the content of an image, thereby destroying all data on the target server. - :param server: :class:`BoundServer <hcloud.servers.client.BoundServer>` or :class:`Server <hcloud.servers.domain.Server>` - :param image: :class:`BoundImage <hcloud.images.client.BoundImage>` or :class:`Image <hcloud.servers.domain.Image>` - :return: :class:`BoundAction <hcloud.actions.client.BoundAction>` + :param server: Server to rebuild + :param image: Image to use for the rebuilt server + :param return_response: Whether to return the full response or only the action. """ data: dict[str, Any] = {"image": image.id_or_name} response = self._client.request( @@ -939,7 +952,22 @@ method="POST", json=data, ) - return BoundAction(self._client.actions, response["action"]) + + rebuild_response = RebuildResponse( + action=BoundAction(self._client.actions, response["action"]), + root_password=response.get("root_password"), + ) + + if not return_response: + warnings.warn( + "Returning only the 'action' is deprecated, please set the " + "'return_response' keyword argument to 'True' to return the full " + "rebuild response and update your code accordingly.", + DeprecationWarning, + stacklevel=2, + ) + return rebuild_response.action + return rebuild_response def enable_backup(self, server: Server | BoundServer) -> BoundAction: """Enables and configures the automatic daily backup option for the server. Enabling automatic backups will increase the price of the server by 20%. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/servers/domain.py new/hcloud-1.32.0/hcloud/servers/domain.py --- old/hcloud-1.28.0/hcloud/servers/domain.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/servers/domain.py 2023-11-17 15:09:57.000000000 +0100 @@ -104,6 +104,7 @@ "placement_group", ) + # pylint: disable=too-many-locals def __init__( self, id: int, @@ -243,6 +244,24 @@ self.password = password +class RebuildResponse(BaseDomain): + """Rebuild Response Domain + + :param action: Shows the progress of the server rebuild action + :param root_password: The root password of the server when not using SSH keys + """ + + __slots__ = ("action", "root_password") + + def __init__( + self, + action: BoundAction, + root_password: str | None, + ): + self.action = action + self.root_password = root_password + + class PublicNetwork(BaseDomain): """Public Network Domain diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/ssh_keys/client.py new/hcloud-1.32.0/hcloud/ssh_keys/client.py --- old/hcloud-1.28.0/hcloud/ssh_keys/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/ssh_keys/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -9,7 +9,7 @@ from .._client import Client -class BoundSSHKey(BoundModelBase): +class BoundSSHKey(BoundModelBase, SSHKey): _client: SSHKeysClient model = SSHKey diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud/volumes/client.py new/hcloud-1.32.0/hcloud/volumes/client.py --- old/hcloud-1.28.0/hcloud/volumes/client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/hcloud/volumes/client.py 2023-11-17 15:09:57.000000000 +0100 @@ -13,7 +13,7 @@ from ..servers import BoundServer, Server -class BoundVolume(BoundModelBase): +class BoundVolume(BoundModelBase, Volume): _client: VolumesClient model = Volume @@ -23,6 +23,7 @@ if location is not None: data["location"] = BoundLocation(client._client.locations, location) + # pylint: disable=import-outside-toplevel from ..servers import BoundServer server = data.get("server") @@ -254,7 +255,7 @@ if size <= 0: raise ValueError("size must be greater than 0") - if not (bool(location) ^ bool(server)): + if not bool(location) ^ bool(server): raise ValueError("only one of server or location must be provided") data: dict[str, Any] = {"name": name, "size": size} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud.egg-info/PKG-INFO new/hcloud-1.32.0/hcloud.egg-info/PKG-INFO --- old/hcloud-1.28.0/hcloud.egg-info/PKG-INFO 2023-08-17 14:46:20.000000000 +0200 +++ new/hcloud-1.32.0/hcloud.egg-info/PKG-INFO 2023-11-17 15:10:09.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: hcloud -Version: 1.28.0 +Version: 1.32.0 Summary: Official Hetzner Cloud python library Home-page: https://github.com/hetznercloud/hcloud-python Author: Hetzner Cloud GmbH @@ -20,11 +20,24 @@ Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 Requires-Python: >=3.8 Description-Content-Type: text/markdown +License-File: LICENSE +Requires-Dist: python-dateutil>=2.7.5 +Requires-Dist: requests>=2.20 Provides-Extra: docs +Requires-Dist: sphinx<7.3,>=7.2.2; extra == "docs" +Requires-Dist: sphinx-rtd-theme<1.4,>=1.3.0; extra == "docs" +Requires-Dist: myst-parser<2.1,>=2.0.0; extra == "docs" +Requires-Dist: watchdog<3.1,>=3.0.0; extra == "docs" Provides-Extra: test -License-File: LICENSE +Requires-Dist: coverage<7.4,>=7.3; extra == "test" +Requires-Dist: pylint<3.1,>=3; extra == "test" +Requires-Dist: pytest<7.5,>=7.4; extra == "test" +Requires-Dist: mypy<1.8,>=1.7; extra == "test" +Requires-Dist: types-python-dateutil; extra == "test" +Requires-Dist: types-requests; extra == "test" # Hetzner Cloud Python diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/hcloud.egg-info/requires.txt new/hcloud-1.32.0/hcloud.egg-info/requires.txt --- old/hcloud-1.28.0/hcloud.egg-info/requires.txt 2023-08-17 14:46:20.000000000 +0200 +++ new/hcloud-1.32.0/hcloud.egg-info/requires.txt 2023-11-17 15:10:09.000000000 +0100 @@ -2,14 +2,15 @@ requests>=2.20 [docs] -sphinx<7.0,>=6.2.1 -sphinx-rtd-theme<1.3,>=1.2.2 +sphinx<7.3,>=7.2.2 +sphinx-rtd-theme<1.4,>=1.3.0 myst-parser<2.1,>=2.0.0 watchdog<3.1,>=3.0.0 [test] coverage<7.4,>=7.3 +pylint<3.1,>=3 pytest<7.5,>=7.4 -mypy<1.6,>=1.5 +mypy<1.8,>=1.7 types-python-dateutil types-requests diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/pyproject.toml new/hcloud-1.32.0/pyproject.toml --- old/hcloud-1.28.0/pyproject.toml 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/pyproject.toml 2023-11-17 15:09:57.000000000 +0100 @@ -12,3 +12,27 @@ [build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta" + +[tool.pylint.main] +py-version = "3.8" +recursive = true +jobs = 0 + +[tool.pylint.reports] +output-format = "colorized" + +[tool.pylint."messages control"] +disable = [ + "fixme", + "line-too-long", + "missing-class-docstring", + "missing-module-docstring", + "redefined-builtin", + "duplicate-code", + # Consider disabling line-by-line + "too-few-public-methods", + "too-many-public-methods", + "too-many-arguments", + "too-many-instance-attributes", + "too-many-lines", +] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/setup.py new/hcloud-1.32.0/setup.py --- old/hcloud-1.28.0/setup.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/setup.py 2023-11-17 15:09:57.000000000 +0100 @@ -36,6 +36,7 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ], python_requires=">=3.8", install_requires=[ @@ -44,15 +45,16 @@ ], extras_require={ "docs": [ - "sphinx>=6.2.1,<7.0", - "sphinx-rtd-theme>=1.2.2,<1.3", + "sphinx>=7.2.2,<7.3", + "sphinx-rtd-theme>=1.3.0,<1.4", "myst-parser>=2.0.0,<2.1", "watchdog>=3.0.0,<3.1", ], "test": [ "coverage>=7.3,<7.4", + "pylint>=3,<3.1", "pytest>=7.4,<7.5", - "mypy>=1.5,<1.6", + "mypy>=1.7,<1.8", "types-python-dateutil", "types-requests", ], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/tests/unit/core/test_client.py new/hcloud-1.32.0/tests/unit/core/test_client.py --- old/hcloud-1.28.0/tests/unit/core/test_client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/tests/unit/core/test_client.py 2023-11-17 15:09:57.000000000 +0100 @@ -20,7 +20,7 @@ self.name = name self.description = description - class BoundModel(BoundModelBase): + class BoundModel(BoundModelBase, Model): model = Model return BoundModel diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/tests/unit/isos/conftest.py new/hcloud-1.32.0/tests/unit/isos/conftest.py --- old/hcloud-1.28.0/tests/unit/isos/conftest.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/tests/unit/isos/conftest.py 2023-11-17 15:09:57.000000000 +0100 @@ -13,6 +13,10 @@ "type": "public", "architecture": "x86", "deprecated": "2018-02-28T00:00:00+00:00", + "deprecation": { + "announced": "2018-01-28T00:00:00+00:00", + "unavailable_after": "2018-02-28T00:00:00+00:00", + }, } } @@ -28,6 +32,10 @@ "type": "public", "architecture": "x86", "deprecated": "2018-02-28T00:00:00+00:00", + "deprecation": { + "announced": "2018-01-28T00:00:00+00:00", + "unavailable_after": "2018-02-28T00:00:00+00:00", + }, }, { "id": 4712, @@ -35,7 +43,7 @@ "description": "FreeBSD 11.0 x64", "type": "public", "architecture": "x86", - "deprecated": "2018-02-28T00:00:00+00:00", + "deprecated": None, }, ] } @@ -52,6 +60,10 @@ "type": "public", "architecture": "x86", "deprecated": "2018-02-28T00:00:00+00:00", + "deprecation": { + "announced": "2018-01-28T00:00:00+00:00", + "unavailable_after": "2018-02-28T00:00:00+00:00", + }, } ] } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/tests/unit/isos/test_client.py new/hcloud-1.32.0/tests/unit/isos/test_client.py --- old/hcloud-1.28.0/tests/unit/isos/test_client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/tests/unit/isos/test_client.py 2023-11-17 15:09:57.000000000 +0100 @@ -22,7 +22,14 @@ assert bound_iso.description == "FreeBSD 11.0 x64" assert bound_iso.type == "public" assert bound_iso.architecture == "x86" - assert bound_iso.deprecated == datetime.datetime( + with pytest.deprecated_call(): + assert bound_iso.deprecated == datetime.datetime( + 2018, 2, 28, 0, 0, tzinfo=timezone.utc + ) + assert bound_iso.deprecation.announced == datetime.datetime( + 2018, 1, 28, 0, 0, tzinfo=timezone.utc + ) + assert bound_iso.deprecation.unavailable_after == datetime.datetime( 2018, 2, 28, 0, 0, tzinfo=timezone.utc ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/tests/unit/isos/test_domain.py new/hcloud-1.32.0/tests/unit/isos/test_domain.py --- old/hcloud-1.28.0/tests/unit/isos/test_domain.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/tests/unit/isos/test_domain.py 2023-11-17 15:09:57.000000000 +0100 @@ -1,14 +1,39 @@ from __future__ import annotations -import datetime -from datetime import timezone +from datetime import datetime, timezone + +import pytest from hcloud.isos import Iso class TestIso: - def test_deprecated_is_datetime(self): - iso = Iso(id=1, deprecated="2016-01-30T23:50+00:00") - assert iso.deprecated == datetime.datetime( - 2016, 1, 30, 23, 50, tzinfo=timezone.utc + @pytest.fixture() + def deprecated_iso(self): + return Iso( + **{ + "id": 10433, + "name": "vyos-1.4-rolling-202111150317-amd64.iso", + "description": "VyOS 1.4 (amd64)", + "type": "public", + "deprecation": { + "announced": "2023-10-05T08:27:01Z", + "unavailable_after": "2023-11-05T08:27:01Z", + }, + "architecture": "x86", + "deprecated": "2023-11-05T08:27:01Z", + } + ) + + def test_deprecation(self, deprecated_iso: Iso): + with pytest.deprecated_call(): + assert deprecated_iso.deprecated == datetime( + 2023, 11, 5, 8, 27, 1, tzinfo=timezone.utc + ) + assert deprecated_iso.deprecation is not None + assert deprecated_iso.deprecation.announced == datetime( + 2023, 10, 5, 8, 27, 1, tzinfo=timezone.utc + ) + assert deprecated_iso.deprecation.unavailable_after == datetime( + 2023, 11, 5, 8, 27, 1, tzinfo=timezone.utc ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hcloud-1.28.0/tests/unit/servers/test_client.py new/hcloud-1.32.0/tests/unit/servers/test_client.py --- old/hcloud-1.28.0/tests/unit/servers/test_client.py 2023-08-17 14:46:06.000000000 +0200 +++ new/hcloud-1.32.0/tests/unit/servers/test_client.py 2023-11-17 15:09:57.000000000 +0100 @@ -307,15 +307,19 @@ def test_rebuild(self, hetzner_client, bound_server, generic_action): hetzner_client.request.return_value = generic_action - action = bound_server.rebuild(Image(name="ubuntu-20.04")) + response = bound_server.rebuild( + Image(name="ubuntu-20.04"), + return_response=True, + ) hetzner_client.request.assert_called_with( url="/servers/14/actions/rebuild", method="POST", json={"image": "ubuntu-20.04"}, ) - assert action.id == 1 - assert action.progress == 0 + assert response.action.id == 1 + assert response.action.progress == 0 + assert response.root_password is None or isinstance(response.root_password, str) def test_enable_backup(self, hetzner_client, bound_server, generic_action): hetzner_client.request.return_value = generic_action @@ -1040,15 +1044,25 @@ ) def test_rebuild(self, servers_client, server, generic_action): servers_client._client.request.return_value = generic_action - action = servers_client.rebuild(server, Image(name="ubuntu-20.04")) + response = servers_client.rebuild( + server, + Image(name="ubuntu-20.04"), + return_response=True, + ) servers_client._client.request.assert_called_with( url="/servers/1/actions/rebuild", method="POST", json={"image": "ubuntu-20.04"}, ) - assert action.id == 1 - assert action.progress == 0 + assert response.action.id == 1 + assert response.action.progress == 0 + assert response.root_password is None or isinstance(response.root_password, str) + + def test_rebuild_return_response_deprecation(self, servers_client, generic_action): + servers_client._client.request.return_value = generic_action + with pytest.deprecated_call(): + servers_client.rebuild(Server(id=1), Image(name="ubuntu-20.04")) @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))]