all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH v1 pve-esxi-import-tools 0/5] Type Checking Improvements
@ 2025-07-18 16:19 Max R. Carrara
  2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 1/5] listvms: respect new type hints of pyVmomi package Max R. Carrara
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Max R. Carrara @ 2025-07-18 16:19 UTC (permalink / raw)
  To: pve-devel

Type Checking Improvements - v1
===============================

The pyVmomi (python3-pyvmomi) package received a bunch of new type stubs
in trixie. This series adds explicit type hints where applicable. Note
that because pyVmomi uses a lot of `Optional[Something]` types, which is
quite a nuisance to handle in this regard (as you'll see in patch 01).

Because of these new type stubs we no longer have to ignore missing
imports regarding pyVmomi in mypy.ini and can add it as a build
dependency for mypy's sake. This also eliminates any quirks around mypy
not linting anything regarding pyVmomi types if python3-pyvmomi isn't
installed.

Gave the script a quick smoke test by calling it directly towards a
local ESXi instance I still had lying around to check if I didn't break
anything by accident.

Summary of Changes
------------------

Max R. Carrara (5):
  listvms: respect new type hints of pyVmomi package
  listvms: s/EsxiConnectonArgs/EsxiConnectionArgs
  listvms: run formatter
  d/control: add python3-pyvmomi (>= 8) as build dependency
  .gitignore: ignore .lint-incremental

 .gitignore     |   1 +
 debian/control |   1 +
 listvms.py     | 114 +++++++++++++++++++++++++++++++++++++++----------
 mypy.ini       |   3 --
 4 files changed, 94 insertions(+), 25 deletions(-)

-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [pve-devel] [PATCH v1 pve-esxi-import-tools 1/5] listvms: respect new type hints of pyVmomi package
  2025-07-18 16:19 [pve-devel] [PATCH v1 pve-esxi-import-tools 0/5] Type Checking Improvements Max R. Carrara
@ 2025-07-18 16:19 ` Max R. Carrara
  2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 2/5] listvms: s/EsxiConnectonArgs/EsxiConnectionArgs Max R. Carrara
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Max R. Carrara @ 2025-07-18 16:19 UTC (permalink / raw)
  To: pve-devel

This makes mypy on trixie happy again.

Make the type hints explicit; even though this is a little more
verbose, it should make any typing-related changes more visible in the
future. Also return (hopefully) sane defaults wherever possible.

Note that Python doesn't have something like "null-aware member
access" like JS does, so there isn't really any prettier version of
doing this.

(Besides, I have *never* seen as many `Optional`s in any Python
codebase as in the pyVmomi package's type stubs, let alone their
"on-demand loading" of types.)

Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
---
 listvms.py | 95 ++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 81 insertions(+), 14 deletions(-)

diff --git a/listvms.py b/listvms.py
index 44f207c..221d562 100755
--- a/listvms.py
+++ b/listvms.py
@@ -162,14 +162,29 @@ def get_datacenter_of_vm(vm: vim.VirtualMachine) -> vim.Datacenter | None:
 
 def list_vms(service_instance: vim.ServiceInstance) -> list[vim.VirtualMachine]:
     """List all VMs on the ESXi/vCenter server."""
-    content = service_instance.content
-    vm_view: Any = content.viewManager.CreateContainerView(
+
+    content: vim.ServiceInstanceContent | None = service_instance.content
+
+    if content is None:
+        return []
+
+    view_manager: vim.view.ViewManager | None = content.viewManager
+
+    if view_manager is None:
+        return []
+
+    vm_view = view_manager.CreateContainerView(
         content.rootFolder,
         [vim.VirtualMachine],
         True,
     )
+
+    if vm_view is None:
+        return []
+
     vms = vm_view.view
     vm_view.Destroy()
+
     return vms
 
 
@@ -180,23 +195,42 @@ def parse_file_path(path) -> tuple[str, str]:
     return (datastore_name, relative_path)
 
 
-def get_vm_vmx_info(vm: vim.VirtualMachine) -> VmVmxInfo:
+def get_vm_vmx_info(vm: vim.VirtualMachine) -> VmVmxInfo | None:
     """Extract VMX file path and checksum from a VM object."""
-    datastore_name, relative_vmx_path = parse_file_path(
-        vm.config.files.vmPathName
+
+    config: vim.vm.ConfigInfo | None = vm.config
+
+    if config is None:
+        return None
+
+    files: vim.vm.FileInfo | None = config.files
+
+    if files is None:
+        return None
+
+    vm_path_name: str | None = files.vmPathName
+
+    if vm_path_name is None:
+        return None
+
+    datastore_name, relative_vmx_path = parse_file_path(vm_path_name)
+    checksum = (
+        config.vmxConfigChecksum.hex() if config.vmxConfigChecksum else "N/A"
     )
 
     return VmVmxInfo(
         datastore=datastore_name,
         path=relative_vmx_path,
-        checksum=vm.config.vmxConfigChecksum.hex()
-        if vm.config.vmxConfigChecksum
-        else "N/A",
+        checksum=checksum,
     )
 
 
 def get_vm_disk_info(vm: vim.VirtualMachine) -> list[VmDiskInfo]:
-    disks = []
+    disks: list[VmDiskInfo] = []
+
+    if vm.config is None:
+        return disks
+
     for device in vm.config.hardware.device:
         if isinstance(device, vim.vm.device.VirtualDisk):
             try:
@@ -217,12 +251,27 @@ def get_all_datacenters(
     service_instance: vim.ServiceInstance,
 ) -> list[vim.Datacenter]:
     """Retrieve all datacenters from the ESXi/vCenter server."""
-    content = service_instance.content
-    dc_view: Any = content.viewManager.CreateContainerView(
+
+    content: vim.ServiceInstanceContent | None = service_instance.content
+
+    if content is None:
+        return []
+
+    view_manager: vim.view.ViewManager | None = content.viewManager
+
+    if view_manager is None:
+        return []
+
+    dc_view = view_manager.CreateContainerView(
         content.rootFolder, [vim.Datacenter], True
     )
+
+    if dc_view is None:
+        return []
+
     datacenters = dc_view.view
     dc_view.Destroy()
+
     return datacenters
 
 
@@ -242,13 +291,28 @@ def fetch_and_update_vm_data(vm: vim.VirtualMachine, data: dict[Any, Any]):
     vms = data[datacenter.name].setdefault("vms", {})
     datastores = data[datacenter.name].setdefault("datastores", {})
 
+    config: vim.vm.ConfigInfo | None = vm.config
+
+    if config is None:
+        return
+
+    vm_vmx_info: VmVmxInfo | None = get_vm_vmx_info(vm)
+
+    if vm_vmx_info is None:
+        return
+
+    runtime: vim.vm.RuntimeInfo | None = vm.runtime
+
+    if runtime is None:
+        return
+
     vms[vm.name] = VmInfo(
-        config=get_vm_vmx_info(vm),
+        config=vm_vmx_info,
         disks=get_vm_disk_info(vm),
-        power=str(vm.runtime.powerState),
+        power=str(runtime.powerState),
     )
 
-    datastores.update({ds.name: ds.url for ds in vm.config.datastoreUrl})
+    datastores.update({ds.name: ds.url for ds in config.datastoreUrl})
 
 
 def is_vcls_agent_vm(vm: vim.VirtualMachine) -> bool:
@@ -261,6 +325,9 @@ def is_vcls_agent_vm(vm: vim.VirtualMachine) -> bool:
                for cfg in vm.config.extraConfig)
 
 def is_diskless_vm(vm: vim.VirtualMachine) -> bool:
+    if vm.config is None or vm.config.files is None:
+        return True
+
     datastore_name, _ = parse_file_path(vm.config.files.vmPathName)
 
     return not datastore_name
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [pve-devel] [PATCH v1 pve-esxi-import-tools 2/5] listvms: s/EsxiConnectonArgs/EsxiConnectionArgs
  2025-07-18 16:19 [pve-devel] [PATCH v1 pve-esxi-import-tools 0/5] Type Checking Improvements Max R. Carrara
  2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 1/5] listvms: respect new type hints of pyVmomi package Max R. Carrara
@ 2025-07-18 16:19 ` Max R. Carrara
  2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 3/5] listvms: run formatter Max R. Carrara
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Max R. Carrara @ 2025-07-18 16:19 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
---
 listvms.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/listvms.py b/listvms.py
index 221d562..710ac5e 100755
--- a/listvms.py
+++ b/listvms.py
@@ -56,7 +56,7 @@ def parse_args() -> argparse.Namespace:
 
 
 @dataclass
-class EsxiConnectonArgs:
+class EsxiConnectionArgs:
     hostname: str
     port: int
     username: str
@@ -66,7 +66,7 @@ class EsxiConnectonArgs:
 
 @contextmanager
 def connect_to_esxi_host(
-    args: EsxiConnectonArgs,
+    args: EsxiConnectionArgs,
 ) -> Generator[vim.ServiceInstance, None, None]:
     """Opens a connection to an ESXi host with the given username and password
     contained in the password file.
@@ -335,7 +335,7 @@ def is_diskless_vm(vm: vim.VirtualMachine) -> bool:
 def main():
     args = parse_args()
 
-    connection_args = EsxiConnectonArgs(
+    connection_args = EsxiConnectionArgs(
         hostname=args.hostname,
         port=args.port,
         username=args.username,
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [pve-devel] [PATCH v1 pve-esxi-import-tools 3/5] listvms: run formatter
  2025-07-18 16:19 [pve-devel] [PATCH v1 pve-esxi-import-tools 0/5] Type Checking Improvements Max R. Carrara
  2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 1/5] listvms: respect new type hints of pyVmomi package Max R. Carrara
  2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 2/5] listvms: s/EsxiConnectonArgs/EsxiConnectionArgs Max R. Carrara
@ 2025-07-18 16:19 ` Max R. Carrara
  2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 4/5] d/control: add python3-pyvmomi (>= 8) as build dependency Max R. Carrara
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Max R. Carrara @ 2025-07-18 16:19 UTC (permalink / raw)
  To: pve-devel

Like in 1563eddb, run `black -l 80` [0], even though we don't have an
official style guide for Python. This is just to keep the code looking
consistent.

[0]: https://github.com/psf/black

Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
---
 listvms.py | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/listvms.py b/listvms.py
index 710ac5e..a718c41 100755
--- a/listvms.py
+++ b/listvms.py
@@ -31,9 +31,9 @@ def parse_args() -> argparse.Namespace:
     parser.add_argument(
         "--port",
         type=int,
-        metavar='PORT',
+        metavar="PORT",
         default=443,
-        help="Use a port other than 443."
+        help="Use a port other than 443.",
     )
 
     parser.add_argument(
@@ -320,9 +320,11 @@ def is_vcls_agent_vm(vm: vim.VirtualMachine) -> bool:
     if vm.config is None:
         return False
 
-    return any(cfg.key == "HDCS.agent"
-               and cfg.value.lower() == "true"
-               for cfg in vm.config.extraConfig)
+    return any(
+        cfg.key == "HDCS.agent" and cfg.value.lower() == "true"
+        for cfg in vm.config.extraConfig
+    )
+
 
 def is_diskless_vm(vm: vim.VirtualMachine) -> bool:
     if vm.config is None or vm.config.files is None:
@@ -332,6 +334,7 @@ def is_diskless_vm(vm: vim.VirtualMachine) -> bool:
 
     return not datastore_name
 
+
 def main():
     args = parse_args()
 
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [pve-devel] [PATCH v1 pve-esxi-import-tools 4/5] d/control: add python3-pyvmomi (>= 8) as build dependency
  2025-07-18 16:19 [pve-devel] [PATCH v1 pve-esxi-import-tools 0/5] Type Checking Improvements Max R. Carrara
                   ` (2 preceding siblings ...)
  2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 3/5] listvms: run formatter Max R. Carrara
@ 2025-07-18 16:19 ` Max R. Carrara
  2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 5/5] .gitignore: ignore .lint-incremental Max R. Carrara
  2025-07-22 20:14 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 0/5] Type Checking Improvements Thomas Lamprecht
  5 siblings, 0 replies; 7+ messages in thread
From: Max R. Carrara @ 2025-07-18 16:19 UTC (permalink / raw)
  To: pve-devel

... and don't ignore missing imports for pyVmomi in mypy.ini anymore.

python3-pyvmomi >= 8 is available only on trixie, which includes a
bunch of new type stubs that were previously missing. This means that
mypy no longer has to ignore missing imports in regards to pyVmomi.

mypy will therefore now complain when it can't find pyVmomi, so any
strange behavior regarding type checking of pyVmomi's types should
hopefully not happen anymore.

Note that pyVim is part of python3-pyvmomi, but still doesn't provide
any proper type stubs / hints that mypy can use, so we keep it ignored
until it does.

Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
---
 debian/control | 1 +
 mypy.ini       | 3 ---
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/debian/control b/debian/control
index ee74e15..d57b302 100644
--- a/debian/control
+++ b/debian/control
@@ -38,6 +38,7 @@ Build-Depends: cargo:native (>= 0.65.0~),
                librust-tokio-1+time-dev,
                libstd-rust-dev,
                mypy,
+               python3-pyvmomi (>= 8),
                rustc:native,
 Maintainer: Proxmox Support Team <support@proxmox.com>
 Standards-Version: 4.6.2
diff --git a/mypy.ini b/mypy.ini
index e6724c8..0387e66 100644
--- a/mypy.ini
+++ b/mypy.ini
@@ -1,8 +1,5 @@
 [mypy]
 
-[mypy-pyVmomi]
-ignore_missing_imports = True
-
 [mypy-pyVim.*]
 ignore_missing_imports = True
 
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [pve-devel] [PATCH v1 pve-esxi-import-tools 5/5] .gitignore: ignore .lint-incremental
  2025-07-18 16:19 [pve-devel] [PATCH v1 pve-esxi-import-tools 0/5] Type Checking Improvements Max R. Carrara
                   ` (3 preceding siblings ...)
  2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 4/5] d/control: add python3-pyvmomi (>= 8) as build dependency Max R. Carrara
@ 2025-07-18 16:19 ` Max R. Carrara
  2025-07-22 20:14 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 0/5] Type Checking Improvements Thomas Lamprecht
  5 siblings, 0 replies; 7+ messages in thread
From: Max R. Carrara @ 2025-07-18 16:19 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitignore b/.gitignore
index e4e04b8..2c27040 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@
 /target
 Cargo.lock
 pve-esxi-import-tools-[0-9]*/
+.lint-incremental
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [pve-devel] [PATCH v1 pve-esxi-import-tools 0/5] Type Checking Improvements
  2025-07-18 16:19 [pve-devel] [PATCH v1 pve-esxi-import-tools 0/5] Type Checking Improvements Max R. Carrara
                   ` (4 preceding siblings ...)
  2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 5/5] .gitignore: ignore .lint-incremental Max R. Carrara
@ 2025-07-22 20:14 ` Thomas Lamprecht
  5 siblings, 0 replies; 7+ messages in thread
From: Thomas Lamprecht @ 2025-07-22 20:14 UTC (permalink / raw)
  To: pve-devel, Max R. Carrara

On Fri, 18 Jul 2025 18:19:00 +0200, Max R. Carrara wrote:
> Type Checking Improvements - v1
> ===============================
> 
> The pyVmomi (python3-pyvmomi) package received a bunch of new type stubs
> in trixie. This series adds explicit type hints where applicable. Note
> that because pyVmomi uses a lot of `Optional[Something]` types, which is
> quite a nuisance to handle in this regard (as you'll see in patch 01).
> 
> [...]

Applied, thanks!

[1/5] listvms: respect new type hints of pyVmomi package
[2/5] listvms: s/EsxiConnectonArgs/EsxiConnectionArgs
[3/5] listvms: run formatter
[4/5] d/control: add python3-pyvmomi (>= 8) as build dependency
[5/5] .gitignore: ignore .lint-incremental


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-07-22 20:14 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-07-18 16:19 [pve-devel] [PATCH v1 pve-esxi-import-tools 0/5] Type Checking Improvements Max R. Carrara
2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 1/5] listvms: respect new type hints of pyVmomi package Max R. Carrara
2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 2/5] listvms: s/EsxiConnectonArgs/EsxiConnectionArgs Max R. Carrara
2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 3/5] listvms: run formatter Max R. Carrara
2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 4/5] d/control: add python3-pyvmomi (>= 8) as build dependency Max R. Carrara
2025-07-18 16:19 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 5/5] .gitignore: ignore .lint-incremental Max R. Carrara
2025-07-22 20:14 ` [pve-devel] [PATCH v1 pve-esxi-import-tools 0/5] Type Checking Improvements Thomas Lamprecht

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal