libvirt-python 12.5.0__tar.gz → 12.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/AUTHORS +1 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/ChangeLog +183 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/Makefile +1 -1
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/PKG-INFO +36 -3
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/README +35 -2
- libvirt_python-12.6.0/VERSION +1 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/build/libvirt_python.egg-info/SOURCES.txt +2 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/domstart.py +1 -2
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/esxlist.py +2 -2
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/event-test.py +5 -5
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/nodestats.py +2 -2
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/generator.py +46 -35
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-lxc-override.c +8 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-override-api.xml +1 -1
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-override-virConnect.py +57 -57
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-override-virDomain.py +8 -8
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-override-virDomainCheckpoint.py +1 -1
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-override-virDomainSnapshot.py +1 -1
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-override-virNetwork.py +1 -1
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-override-virStoragePool.py +1 -1
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-override-virStream.py +7 -10
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-override.c +8 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-override.py +14 -14
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-python.spec +1 -1
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-qemu-override.c +8 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-qemu-override.py +4 -4
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirtaio.py +8 -8
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/setup.py +18 -1
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/tests/test_api_coverage.py +10 -11
- libvirt_python-12.6.0/tests/test_domain_config.py +467 -0
- libvirt_python-12.6.0/tests/test_domain_lifecycle.py +421 -0
- libvirt_python-12.6.0/tox.ini +19 -0
- libvirt_python-12.5.0/VERSION +0 -1
- libvirt_python-12.5.0/tox.ini +0 -8
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/CONTRIBUTING.rst +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/COPYING +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/HACKING +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/MANIFEST.in +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/README +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/consolecallback.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/dhcpleases.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/dominfo.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/domipaddrs.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/domrestore.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/domsave.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/guest-vcpus/guest-vcpu-daemon.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/guest-vcpus/guest-vcpu.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/sparsestream.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/examples/topology.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-lxc-override-api.xml +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-qemu-override-api.xml +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-utils.c +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/libvirt-utils.h +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/pyproject.toml +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/requirements-test.txt +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/setup.cfg +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/tests/eventmock.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/tests/test_aio.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/tests/test_conn.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/tests/test_domain.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/tests/test_domain_checkpoint.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/tests/test_domain_snapshot.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/tests/test_interface.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/tests/test_network.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/tests/test_nodedev.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/tests/test_storage.py +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/typewrappers.c +0 -0
- {libvirt_python-12.5.0 → libvirt_python-12.6.0}/typewrappers.h +0 -0
|
@@ -87,6 +87,7 @@ The individual contributors are
|
|
|
87
87
|
Prabodh Agarwal <prabodh1194@users.noreply.github.com>
|
|
88
88
|
Pradipta Kr. Banerjee <pradipta.banerjee@gmail.com>
|
|
89
89
|
Qiaowei Ren <qiaowei.ren@intel.com>
|
|
90
|
+
Radoslaw Smigielski <rsmigiel@redhat.com>
|
|
90
91
|
Radostin Stoyanov <rstoyanov@fedoraproject.org>
|
|
91
92
|
renlei4 <ren.lei4@zte.com.cn>
|
|
92
93
|
Richard W.M. Jones <rjones@redhat.com>
|
|
@@ -1,3 +1,186 @@
|
|
|
1
|
+
2026- 7- 28 Daniel P. Berrangé <berrange@redhat.com>
|
|
2
|
+
|
|
3
|
+
Use lowercase types for collection types
|
|
4
|
+
The uppercase aliases were deprecated since Py 3.9
|
|
5
|
+
|
|
6
|
+
https://docs.python.org/3/library/typing.html#deprecated-aliases
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
2026- 7- 28 Daniel P. Berrangé <berrange@redhat.com>
|
|
11
|
+
|
|
12
|
+
ci: refresh with lcitool manifest
|
|
13
|
+
This replaces OpenSUSE 15 with 16, since 15.6 is now end of life
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
2026- 7- 28 Daniel P. Berrangé <berrange@redhat.com>
|
|
18
|
+
|
|
19
|
+
Remove redundant return type annotation
|
|
20
|
+
The _timer() method does not return any value, so declaring its
|
|
21
|
+
return type is incorrect.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
2026- 7- 28 Daniel P. Berrangé <berrange@redhat.com>
|
|
26
|
+
|
|
27
|
+
Use qualified classname for types in libvirt_qemu/libvirt_lxc
|
|
28
|
+
We must use "libvirt.virDomain" in the type annotation, not a plain
|
|
29
|
+
"virDomain".
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
2026- 7- 28 Daniel P. Berrangé <berrange@redhat.com>
|
|
34
|
+
|
|
35
|
+
Check for stream 'cb' attribute existance
|
|
36
|
+
Instead of accessing self.cb and catching the exception when it does not
|
|
37
|
+
exist, check for it upfront, which makes mypy happier.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
2026- 7- 28 Daniel P. Berrangé <berrange@redhat.com>
|
|
42
|
+
|
|
43
|
+
Fix type for multi-valued return
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
2026- 7- 28 Daniel P. Berrangé <berrange@redhat.com>
|
|
47
|
+
|
|
48
|
+
Stop scoping the domain event callback type
|
|
49
|
+
This leads to incompatible types between the register and deregister
|
|
50
|
+
methods:
|
|
51
|
+
|
|
52
|
+
"Callable[[virConnect, virDomain, int, int, _T@domainEventDeregister], int | None]"
|
|
53
|
+
"Callable[[virConnect, virDomain, int, int, _T@domainEventRegister], int | None]"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
2026- 7- 28 Daniel P. Berrangé <berrange@redhat.com>
|
|
58
|
+
|
|
59
|
+
Use Optiona[..] type annotation for all params with default values
|
|
60
|
+
If a parameter has a default value assigned then by definition it is
|
|
61
|
+
an optional parameter, and the type must reflect that.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
2026- 7- 28 Daniel P. Berrangé <berrange@redhat.com>
|
|
66
|
+
|
|
67
|
+
Use 'bytes' not 'str' for 'unsigned char *' parameters
|
|
68
|
+
Such parameters are all byte arrays, not NUL terminated C strings.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
2026- 7- 28 Daniel P. Berrangé <berrange@redhat.com>
|
|
73
|
+
|
|
74
|
+
Fix override type for virNodeListDevices 'caps' parameter
|
|
75
|
+
The 'caps' parameter is a string capability name, not a set of
|
|
76
|
+
bytes.
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
2026- 7- 20 Radoslaw Smigielski <rsmigiel@redhat.com>
|
|
81
|
+
|
|
82
|
+
tests: add comprehensive domain configuration tests
|
|
83
|
+
Add few new tests in test_domain_config.py covering domain attributes,
|
|
84
|
+
autostart, scheduler parameters, memory, vCPUs, block/network stats,
|
|
85
|
+
CPU stats, suspend/resume, metadata, blkio and NUMA parameters.
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
2026- 7- 10 Radoslaw Smigielski <rsmigiel@redhat.com>
|
|
90
|
+
|
|
91
|
+
tests: add few new tests for domain lifecycle operations
|
|
92
|
+
Add new test file test_domain_lifecycle.py with 30 functional tests
|
|
93
|
+
covering domain lifecycle operations. This significantly expands test
|
|
94
|
+
coverage beyond the existing 2 basic tests in test_domain.py.
|
|
95
|
+
|
|
96
|
+
All new tests use the test:///default driver.
|
|
97
|
+
|
|
98
|
+
These tests verify that Python bindings work correctly with various
|
|
99
|
+
parameters and edge cases, not only that the bindings exist.
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
2026- 7- 9 Radoslaw Smigielski <rsmigiel@redhat.com>
|
|
104
|
+
|
|
105
|
+
tests: run tox tests in parallel
|
|
106
|
+
Use `tox run-parallel` instead of `tox` in the test target so all
|
|
107
|
+
Python versions are exercised concurrently.
|
|
108
|
+
And significantly reduces tox execution time.
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
2026- 7- 8 Radoslaw Smigielski <rsmigiel@redhat.com>
|
|
113
|
+
|
|
114
|
+
docs: add explicit install instructions for pytest and tox in README
|
|
115
|
+
Add dnf and pip install commands for both pytest and tox to the testing
|
|
116
|
+
section of the README, making it clear how to obtain the required tools
|
|
117
|
+
before running the test suite.
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
2026- 7- 8 Jiri Denemark <jdenemar@redhat.com>
|
|
122
|
+
|
|
123
|
+
Post-release version bump to 12.6.0
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
2026- 7- 8 Radoslaw Smigielski <rsmigiel@redhat.com>
|
|
127
|
+
|
|
128
|
+
python: Add support for free-threaded no-GIL CPython
|
|
129
|
+
This is an initial commit to add support for:
|
|
130
|
+
- Python 3.13 (python3.13t)
|
|
131
|
+
- Python 3.14 (python3.14t)
|
|
132
|
+
|
|
133
|
+
Both python3.13t and python3.14t do not support the Stable C API,
|
|
134
|
+
so the only way to get libvirt-python working with no-GIL Python
|
|
135
|
+
is to fall back to the Python Unstable C API. This is the approach
|
|
136
|
+
taken in this change.
|
|
137
|
+
|
|
138
|
+
As the Python community plans to add Stable C API support in Python
|
|
139
|
+
3.15+, we can switch back to it from 3.15 onwards. However, for
|
|
140
|
+
3.13 and 3.14, we must use the Unstable C API.
|
|
141
|
+
(Ref: https://docs.python.org/3/c-api/unstable.html)
|
|
142
|
+
|
|
143
|
+
Following PEP 703 (https://peps.python.org/pep-0703/):
|
|
144
|
+
|
|
145
|
+
1. Add dedicated tox envs: py313t, py314t.
|
|
146
|
+
2. Create dedicated env configurations for new environments.
|
|
147
|
+
This forces no-GIL execution in case any dependency tries to
|
|
148
|
+
silently turn the GIL back on.
|
|
149
|
+
|
|
150
|
+
[testenv:py313t] with basepython = python3.13t
|
|
151
|
+
[testenv:py314t] with basepython = python3.14t
|
|
152
|
+
|
|
153
|
+
3. Explicitly use the free-threaded interpreters and only set
|
|
154
|
+
PYTHON_GIL=0 inside the virtualenv.
|
|
155
|
+
4. Add documentation warning against exporting PYTHON_GIL=0 in the
|
|
156
|
+
shell before running tox. Doing so affects the Python instance
|
|
157
|
+
that launches tox itself, not just the test venv.
|
|
158
|
+
|
|
159
|
+
Fixes: https://gitlab.com/libvirt/libvirt-python/-/work_items/22
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
2026- 7- 3 Radoslaw Smigielski <rsmigiel@redhat.com>
|
|
163
|
+
|
|
164
|
+
tests: add Python 3.14 to tox test environments
|
|
165
|
+
Add py314 to the envlist to support testing with Python 3.14.
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
2026- 7- 2 Radoslaw Smigielski <rsmigiel@redhat.com>
|
|
170
|
+
|
|
171
|
+
docs: clarify build and test dependencies in README
|
|
172
|
+
Add missing installation instructions for required dependencies:
|
|
173
|
+
|
|
174
|
+
- Document that the Python 'build' module must be installed before
|
|
175
|
+
running 'python3 -m build', with examples using both dnf and pip
|
|
176
|
+
- Add instruction to install test dependencies from requirements-test.txt
|
|
177
|
+
before running pytest or tox
|
|
178
|
+
|
|
179
|
+
These additions help new contributors avoid common setup errors when
|
|
180
|
+
building and testing the libvirt Python bindings.
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
1
184
|
2026- 6- 9 Michal Privoznik <mprivozn@redhat.com>
|
|
2
185
|
|
|
3
186
|
Add support for virDomainAnnounceInterface() API
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: libvirt-python
|
|
3
|
-
Version: 12.
|
|
3
|
+
Version: 12.6.0
|
|
4
4
|
Summary: The libvirt virtualization API python binding
|
|
5
5
|
Home-page: http://www.libvirt.org
|
|
6
6
|
Maintainer: Libvirt Maintainers
|
|
@@ -36,6 +36,14 @@ Requirements
|
|
|
36
36
|
To build the libvirt python binary requires the GCC and pkg-config
|
|
37
37
|
tools, and development headers for the libvirt and python libraries.
|
|
38
38
|
|
|
39
|
+
Additionally, the Python build module is required and can be installed via:
|
|
40
|
+
|
|
41
|
+
$ dnf install python3-build
|
|
42
|
+
|
|
43
|
+
or
|
|
44
|
+
|
|
45
|
+
$ python3 -m pip install --user build
|
|
46
|
+
|
|
39
47
|
Building and installing
|
|
40
48
|
-----------------------
|
|
41
49
|
|
|
@@ -54,8 +62,29 @@ without explicit building.
|
|
|
54
62
|
In order to test the package, you'll need either tox or at least pytest,
|
|
55
63
|
depending on whether you want to test an already installed package in which
|
|
56
64
|
case the latter is sufficient or if you wish to test in a virtual
|
|
57
|
-
environment you'd need tox.
|
|
58
|
-
|
|
65
|
+
environment you'd need tox.
|
|
66
|
+
|
|
67
|
+
To install pytest, use one of:
|
|
68
|
+
|
|
69
|
+
$ dnf install python3-pytest
|
|
70
|
+
|
|
71
|
+
or
|
|
72
|
+
|
|
73
|
+
$ python3 -m pip install --user pytest
|
|
74
|
+
|
|
75
|
+
To install tox, use one of:
|
|
76
|
+
|
|
77
|
+
$ dnf install python3-tox
|
|
78
|
+
|
|
79
|
+
or
|
|
80
|
+
|
|
81
|
+
$ python3 -m pip install --user tox
|
|
82
|
+
|
|
83
|
+
Additionally, install the remaining test dependencies:
|
|
84
|
+
|
|
85
|
+
$ python3 -m pip install -r requirements-test.txt
|
|
86
|
+
|
|
87
|
+
Depending on your preferred setup, you can run the tests either as
|
|
59
88
|
|
|
60
89
|
$ python3 -m pytest
|
|
61
90
|
|
|
@@ -63,6 +92,10 @@ or as
|
|
|
63
92
|
|
|
64
93
|
$ tox
|
|
65
94
|
|
|
95
|
+
Free-threaded Python (py313t, py314t) test environments require tox>=4.26
|
|
96
|
+
and the corresponding free-threaded interpreters (python3.13t, python3.14t)
|
|
97
|
+
to be installed.
|
|
98
|
+
|
|
66
99
|
A makefile shim is also provided for your convenience, so that you don't have
|
|
67
100
|
to care about the exact operations mentioned above and instead you simply do
|
|
68
101
|
|
|
@@ -20,6 +20,14 @@ Requirements
|
|
|
20
20
|
To build the libvirt python binary requires the GCC and pkg-config
|
|
21
21
|
tools, and development headers for the libvirt and python libraries.
|
|
22
22
|
|
|
23
|
+
Additionally, the Python build module is required and can be installed via:
|
|
24
|
+
|
|
25
|
+
$ dnf install python3-build
|
|
26
|
+
|
|
27
|
+
or
|
|
28
|
+
|
|
29
|
+
$ python3 -m pip install --user build
|
|
30
|
+
|
|
23
31
|
Building and installing
|
|
24
32
|
-----------------------
|
|
25
33
|
|
|
@@ -38,8 +46,29 @@ without explicit building.
|
|
|
38
46
|
In order to test the package, you'll need either tox or at least pytest,
|
|
39
47
|
depending on whether you want to test an already installed package in which
|
|
40
48
|
case the latter is sufficient or if you wish to test in a virtual
|
|
41
|
-
environment you'd need tox.
|
|
42
|
-
|
|
49
|
+
environment you'd need tox.
|
|
50
|
+
|
|
51
|
+
To install pytest, use one of:
|
|
52
|
+
|
|
53
|
+
$ dnf install python3-pytest
|
|
54
|
+
|
|
55
|
+
or
|
|
56
|
+
|
|
57
|
+
$ python3 -m pip install --user pytest
|
|
58
|
+
|
|
59
|
+
To install tox, use one of:
|
|
60
|
+
|
|
61
|
+
$ dnf install python3-tox
|
|
62
|
+
|
|
63
|
+
or
|
|
64
|
+
|
|
65
|
+
$ python3 -m pip install --user tox
|
|
66
|
+
|
|
67
|
+
Additionally, install the remaining test dependencies:
|
|
68
|
+
|
|
69
|
+
$ python3 -m pip install -r requirements-test.txt
|
|
70
|
+
|
|
71
|
+
Depending on your preferred setup, you can run the tests either as
|
|
43
72
|
|
|
44
73
|
$ python3 -m pytest
|
|
45
74
|
|
|
@@ -47,6 +76,10 @@ or as
|
|
|
47
76
|
|
|
48
77
|
$ tox
|
|
49
78
|
|
|
79
|
+
Free-threaded Python (py313t, py314t) test environments require tox>=4.26
|
|
80
|
+
and the corresponding free-threaded interpreters (python3.13t, python3.14t)
|
|
81
|
+
to be installed.
|
|
82
|
+
|
|
50
83
|
A makefile shim is also provided for your convenience, so that you don't have
|
|
51
84
|
to care about the exact operations mentioned above and instead you simply do
|
|
52
85
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
12.6.0
|
|
@@ -7,13 +7,12 @@ If the domain is not running, create it.
|
|
|
7
7
|
import libvirt
|
|
8
8
|
import libxml2
|
|
9
9
|
from argparse import ArgumentParser
|
|
10
|
-
from typing import Tuple
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
# Parse the XML description of domU from FNAME
|
|
14
13
|
# and return a tuple (name, xmldesc) where NAME
|
|
15
14
|
# is the name of the domain, and xmldesc is the contetn of FNAME
|
|
16
|
-
def read_domain(fname: str) ->
|
|
15
|
+
def read_domain(fname: str) -> tuple[str, str]:
|
|
17
16
|
fp = open(fname, "r")
|
|
18
17
|
xmldesc = fp.read()
|
|
19
18
|
fp.close()
|
|
@@ -8,7 +8,7 @@ import libvirt
|
|
|
8
8
|
import libxml2
|
|
9
9
|
import getpass
|
|
10
10
|
from argparse import ArgumentParser
|
|
11
|
-
from typing import Any
|
|
11
|
+
from typing import Any
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
# This is the callback method passed to libvirt.openAuth() (see below).
|
|
@@ -25,7 +25,7 @@ from typing import Any, List
|
|
|
25
25
|
#
|
|
26
26
|
# The user_data argument is the user data item of the auth argument (see below)
|
|
27
27
|
# passed to libvirt.openAuth().
|
|
28
|
-
def request_credentials(credentials:
|
|
28
|
+
def request_credentials(credentials: list[list], user_data: Any) -> int:
|
|
29
29
|
for credential in credentials:
|
|
30
30
|
if credential[0] == libvirt.VIR_CRED_AUTHNAME:
|
|
31
31
|
# prompt the user to input a authname. display the provided message
|
|
@@ -14,7 +14,7 @@ import errno
|
|
|
14
14
|
import time
|
|
15
15
|
import threading
|
|
16
16
|
from argparse import ArgumentParser
|
|
17
|
-
from typing import Any, Callable,
|
|
17
|
+
from typing import Any, Callable, Optional, TypeVar # noqa F401
|
|
18
18
|
_T = TypeVar("_T")
|
|
19
19
|
_EventCallback = Callable[[int, int, int, _T], None]
|
|
20
20
|
_TimerCallback = Callable[[int, _T], None]
|
|
@@ -114,8 +114,8 @@ class virEventLoopPoll:
|
|
|
114
114
|
self.runningPoll = False
|
|
115
115
|
self.nextHandleID = 1
|
|
116
116
|
self.nextTimerID = 1
|
|
117
|
-
self.handles = [] # type:
|
|
118
|
-
self.timers = [] # type:
|
|
117
|
+
self.handles = [] # type: list[virEventLoopPollHandle]
|
|
118
|
+
self.timers = [] # type: list[virEventLoopPollTimer]
|
|
119
119
|
self.cleanup = []
|
|
120
120
|
self.quit = False
|
|
121
121
|
|
|
@@ -603,7 +603,7 @@ def myDomainEventBlockJob2Callback(conn: libvirt.virConnect, dom: libvirt.virDom
|
|
|
603
603
|
dom.name(), dom.ID(), BLOCK_JOB_TYPES[type], disk, BLOCK_JOB_STATUS[status]))
|
|
604
604
|
|
|
605
605
|
|
|
606
|
-
def myDomainEventTunableCallback(conn: libvirt.virConnect, dom: libvirt.virDomain, params:
|
|
606
|
+
def myDomainEventTunableCallback(conn: libvirt.virConnect, dom: libvirt.virDomain, params: dict[str, Any], opaque: _T) -> None:
|
|
607
607
|
print("myDomainEventTunableCallback: Domain %s(%s) %s" % (
|
|
608
608
|
dom.name(), dom.ID(), params))
|
|
609
609
|
|
|
@@ -623,7 +623,7 @@ def myDomainEventMigrationIteration(conn: libvirt.virConnect, dom: libvirt.virDo
|
|
|
623
623
|
dom.name(), dom.ID(), iteration))
|
|
624
624
|
|
|
625
625
|
|
|
626
|
-
def myDomainEventJobCompletedCallback(conn: libvirt.virConnect, dom: libvirt.virDomain, params:
|
|
626
|
+
def myDomainEventJobCompletedCallback(conn: libvirt.virConnect, dom: libvirt.virDomain, params: dict[str, Any], opaque: _T) -> None:
|
|
627
627
|
print("myDomainEventJobCompletedCallback: Domain %s(%s) %s" % (
|
|
628
628
|
dom.name(), dom.ID(), params))
|
|
629
629
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import libvirt
|
|
8
8
|
from xml.dom import minidom
|
|
9
9
|
import libxml2
|
|
10
|
-
from typing import Any
|
|
10
|
+
from typing import Any # noqa F401
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def xpath_eval(ctxt, path: str) -> str:
|
|
@@ -52,7 +52,7 @@ domsStrict = [
|
|
|
52
52
|
if proc.numaParameters()["numa_mode"] == libvirt.VIR_DOMAIN_NUMATUNE_MEM_STRICT
|
|
53
53
|
]
|
|
54
54
|
|
|
55
|
-
domsStrictCfg = {} # type:
|
|
55
|
+
domsStrictCfg = {} # type: dict[libvirt.virDomain, dict[str, dict[str, Any]]]
|
|
56
56
|
for dom in domsStrict:
|
|
57
57
|
xmlStr = dom.XMLDesc()
|
|
58
58
|
doc = libxml2.parseDoc(xmlStr)
|
|
@@ -9,16 +9,16 @@ import sys
|
|
|
9
9
|
import xml.sax
|
|
10
10
|
from contextlib import closing
|
|
11
11
|
from collections import defaultdict
|
|
12
|
-
from typing import
|
|
13
|
-
ArgumentType =
|
|
14
|
-
FunctionType =
|
|
12
|
+
from typing import IO, Optional, Union # noqa F401
|
|
13
|
+
ArgumentType = tuple[str, str, str]
|
|
14
|
+
FunctionType = tuple[str, ArgumentType, list[ArgumentType], str, str, str]
|
|
15
15
|
EnumValue = Union[str, int]
|
|
16
|
-
EnumType =
|
|
16
|
+
EnumType = dict[str, EnumValue]
|
|
17
17
|
|
|
18
|
-
functions = {} # type:
|
|
19
|
-
enums = defaultdict(dict) # type:
|
|
20
|
-
event_ids = [] # type:
|
|
21
|
-
params = [] # type:
|
|
18
|
+
functions = {} # type: dict[str, FunctionType]
|
|
19
|
+
enums = defaultdict(dict) # type: dict[str, EnumType] # { enumType: { enumConstant: enumValue } }
|
|
20
|
+
event_ids = [] # type: list[str]
|
|
21
|
+
params = [] # type: list[tuple[str, str]] # [ (paramName, paramValue)... ]
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
quiet = True
|
|
@@ -66,7 +66,7 @@ def parse(data: IO[str]) -> None:
|
|
|
66
66
|
|
|
67
67
|
class docParser(xml.sax.handler.ContentHandler):
|
|
68
68
|
def __init__(self) -> None:
|
|
69
|
-
self._data = [] # type:
|
|
69
|
+
self._data = [] # type: list[str]
|
|
70
70
|
self.in_function = False
|
|
71
71
|
|
|
72
72
|
def characters(self, text: str) -> None:
|
|
@@ -74,14 +74,14 @@ class docParser(xml.sax.handler.ContentHandler):
|
|
|
74
74
|
print("data %s" % text)
|
|
75
75
|
self._data.append(text)
|
|
76
76
|
|
|
77
|
-
def startElement(self, tag: str, attrs:
|
|
77
|
+
def startElement(self, tag: str, attrs: dict[str, str]) -> None:
|
|
78
78
|
if debug:
|
|
79
79
|
print("start %s, %s" % (tag, attrs))
|
|
80
80
|
if tag == 'function':
|
|
81
81
|
self._data = []
|
|
82
82
|
self.in_function = True
|
|
83
83
|
self.function_cond = ''
|
|
84
|
-
self.function_args = [] # type:
|
|
84
|
+
self.function_args = [] # type: list[ArgumentType]
|
|
85
85
|
self.function_descr = ''
|
|
86
86
|
self.function_return = None # type: Optional[ArgumentType]
|
|
87
87
|
self.function = attrs.get('name', '')
|
|
@@ -158,7 +158,7 @@ class docParser(xml.sax.handler.ContentHandler):
|
|
|
158
158
|
self.function_cond = str
|
|
159
159
|
|
|
160
160
|
|
|
161
|
-
def function(name: str, desc: str, ret: ArgumentType, args:
|
|
161
|
+
def function(name: str, desc: str, ret: ArgumentType, args: list[ArgumentType], file: str, module: str, cond: str) -> None:
|
|
162
162
|
if onlyOverrides and name not in functions:
|
|
163
163
|
return
|
|
164
164
|
if name == "virConnectListDomains":
|
|
@@ -238,7 +238,7 @@ py_types = {
|
|
|
238
238
|
'unsigned long': ('l', '', "long", "long", "int"),
|
|
239
239
|
'long long': ('L', '', "longlong", "long long", "int"),
|
|
240
240
|
'unsigned long long': ('L', '', "longlong", "long long", "int"),
|
|
241
|
-
'unsigned char *': ('z', '', "charPtr", "char *", "
|
|
241
|
+
'unsigned char *': ('z', '', "charPtr", "char *", "bytes"),
|
|
242
242
|
'char *': ('z', '', "charPtr", "char *", "str"),
|
|
243
243
|
'const char *': ('z', '', "constcharPtr", "const char *", "str"),
|
|
244
244
|
'size_t': ('n', '', "size_t", "size_t", "int"),
|
|
@@ -298,16 +298,16 @@ py_types = {
|
|
|
298
298
|
'virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr", "virDomainSnapshot"),
|
|
299
299
|
'virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr", "virDomainSnapshot"),
|
|
300
300
|
'const virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr", "virDomainSnapshot"),
|
|
301
|
-
} # type:
|
|
301
|
+
} # type: dict[str, tuple[str, str, str, str, str]]
|
|
302
302
|
|
|
303
303
|
|
|
304
304
|
# These C types are used only in generated Python code, so don't need the
|
|
305
305
|
# C-supporting elements from py_types.
|
|
306
306
|
py_types_only = {
|
|
307
307
|
'bool': "bool",
|
|
308
|
-
'const unsigned char *': "
|
|
309
|
-
'const char **': "
|
|
310
|
-
'unsigned int *': "
|
|
308
|
+
'const unsigned char *': "bytes",
|
|
309
|
+
'const char **': "list[str]",
|
|
310
|
+
'unsigned int *': "list[int]",
|
|
311
311
|
'virErrorPtr': "_RawError",
|
|
312
312
|
'virEventAddHandleFunc': "_EventAddHandleFunc[_T]",
|
|
313
313
|
'virEventUpdateHandleFunc': "_EventUpdateHandleFunc",
|
|
@@ -319,7 +319,7 @@ py_types_only = {
|
|
|
319
319
|
'virMemoryParameterPtr': "_MemoryParameter",
|
|
320
320
|
'virSchedParameterPtr': "_SchedParameter",
|
|
321
321
|
'virTypedParameterPtr': "_TypedParameter",
|
|
322
|
-
} # type:
|
|
322
|
+
} # type: dict[str, str]
|
|
323
323
|
|
|
324
324
|
|
|
325
325
|
#######################################################################
|
|
@@ -647,8 +647,8 @@ def validate_function(name):
|
|
|
647
647
|
|
|
648
648
|
|
|
649
649
|
def validate_functions():
|
|
650
|
-
unknown_types = defaultdict(list) # type:
|
|
651
|
-
funcs_failed = [] # type:
|
|
650
|
+
unknown_types = defaultdict(list) # type: dict[str, list[str]]
|
|
651
|
+
funcs_failed = [] # type: list[str]
|
|
652
652
|
|
|
653
653
|
for name in sorted(functions):
|
|
654
654
|
unknown = validate_function(name)
|
|
@@ -1037,7 +1037,7 @@ functions_noexcept = {
|
|
|
1037
1037
|
|
|
1038
1038
|
function_classes = {
|
|
1039
1039
|
"None": []
|
|
1040
|
-
} # type:
|
|
1040
|
+
} # type: dict[str, list[tuple[int, str, str, ArgumentType, list[ArgumentType], str, str]]]
|
|
1041
1041
|
|
|
1042
1042
|
# Functions returning an integral type which need special rules to
|
|
1043
1043
|
# check for errors and raise exceptions.
|
|
@@ -1265,12 +1265,12 @@ def nameFixup(name: str, classe: str, type: str, file: str) -> str:
|
|
|
1265
1265
|
return func
|
|
1266
1266
|
|
|
1267
1267
|
|
|
1268
|
-
def functionSortKey(info:
|
|
1268
|
+
def functionSortKey(info: tuple) -> tuple[str, str]:
|
|
1269
1269
|
(index, func, name, ret, args, filename, mod) = info
|
|
1270
1270
|
return func, filename
|
|
1271
1271
|
|
|
1272
1272
|
|
|
1273
|
-
def writeDoc(module: str, name: str, args:
|
|
1273
|
+
def writeDoc(module: str, name: str, args: list[ArgumentType], indent: str, output: IO) -> None:
|
|
1274
1274
|
if not functions[name][0]:
|
|
1275
1275
|
return
|
|
1276
1276
|
val = functions[name][0]
|
|
@@ -1300,10 +1300,10 @@ def emit_py_code(module: str) -> None:
|
|
|
1300
1300
|
# Build the list of C types to look for ordered to start
|
|
1301
1301
|
# with primary classes
|
|
1302
1302
|
#
|
|
1303
|
-
ctypes = [] # type:
|
|
1304
|
-
classes_list = [] # type:
|
|
1305
|
-
ctypes_processed = set() # type:
|
|
1306
|
-
classes_processed = set() # type:
|
|
1303
|
+
ctypes = [] # type: list[str]
|
|
1304
|
+
classes_list = [] # type: list[str]
|
|
1305
|
+
ctypes_processed = set() # type: set[str]
|
|
1306
|
+
classes_processed = set() # type: set[str]
|
|
1307
1307
|
for classe in primary_classes:
|
|
1308
1308
|
classes_list.append(classe)
|
|
1309
1309
|
classes_processed.add(classe)
|
|
@@ -1391,6 +1391,11 @@ def emit_py_code(module: str) -> None:
|
|
|
1391
1391
|
types_map = {name: types[-1] for name, types in py_types.items()}
|
|
1392
1392
|
types_map.update(py_types_only)
|
|
1393
1393
|
|
|
1394
|
+
if module != "libvirt":
|
|
1395
|
+
for name, types in types_map.items():
|
|
1396
|
+
if types.startswith("vir"):
|
|
1397
|
+
types_map[name] = "libvirt." + types
|
|
1398
|
+
|
|
1394
1399
|
if "None" in function_classes:
|
|
1395
1400
|
flist = function_classes["None"]
|
|
1396
1401
|
oldfile = ""
|
|
@@ -1404,7 +1409,10 @@ def emit_py_code(module: str) -> None:
|
|
|
1404
1409
|
classes.write(", ")
|
|
1405
1410
|
classes.write("%s" % a_name)
|
|
1406
1411
|
if a_type in types_map:
|
|
1407
|
-
|
|
1412
|
+
typ = types_map[a_type]
|
|
1413
|
+
if a_name == "flags" or is_optional_arg(a_info):
|
|
1414
|
+
typ = "Optional[%s]" % typ
|
|
1415
|
+
classes.write(": \"%s\"" % typ)
|
|
1408
1416
|
if a_name == "flags" or is_optional_arg(a_info):
|
|
1409
1417
|
if is_integral_type(a_type):
|
|
1410
1418
|
classes.write("=0")
|
|
@@ -1507,18 +1515,18 @@ def emit_py_code(module: str) -> None:
|
|
|
1507
1515
|
if classname in ["virDomain", "virNetwork", "virInterface", "virStoragePool",
|
|
1508
1516
|
"virStorageVol", "virNodeDevice", "virSecret", "virStream",
|
|
1509
1517
|
"virNWFilter", "virNWFilterBinding"]:
|
|
1510
|
-
classes.write(" def __init__(self, conn: \"virConnect\", _obj: object=None):\n")
|
|
1518
|
+
classes.write(" def __init__(self, conn: \"virConnect\", _obj: Optional[object]=None):\n")
|
|
1511
1519
|
classes.write(" self._conn = conn\n")
|
|
1512
1520
|
elif classname in ["virDomainCheckpoint", "virDomainSnapshot"]:
|
|
1513
|
-
classes.write(" def __init__(self, dom: \"virDomain\", _obj: object=None):\n")
|
|
1521
|
+
classes.write(" def __init__(self, dom: \"virDomain\", _obj: Optional[object]=None):\n")
|
|
1514
1522
|
classes.write(" self._dom = dom\n")
|
|
1515
1523
|
classes.write(" self._conn = dom.connect()\n")
|
|
1516
1524
|
elif classname in ["virNetworkPort"]:
|
|
1517
|
-
classes.write(" def __init__(self, net: \"virNetwork\", _obj: object=None) -> None:\n")
|
|
1525
|
+
classes.write(" def __init__(self, net: \"virNetwork\", _obj: Optional[object]=None) -> None:\n")
|
|
1518
1526
|
classes.write(" self._net = net\n")
|
|
1519
1527
|
classes.write(" self._conn = net.connect()\n")
|
|
1520
1528
|
else:
|
|
1521
|
-
classes.write(" def __init__(self, _obj: object=None):\n")
|
|
1529
|
+
classes.write(" def __init__(self, _obj: Optional[object]=None):\n")
|
|
1522
1530
|
|
|
1523
1531
|
classes.write(" if type(_obj).__name__ not in [\"PyCapsule\", \"PyCObject\"]:\n")
|
|
1524
1532
|
classes.write(" raise Exception(\"Expected a wrapped C Object but got %s\" % type(_obj))\n")
|
|
@@ -1573,7 +1581,10 @@ def emit_py_code(module: str) -> None:
|
|
|
1573
1581
|
if n != index:
|
|
1574
1582
|
classes.write(", %s" % a_name)
|
|
1575
1583
|
if a_type in types_map:
|
|
1576
|
-
|
|
1584
|
+
typ = types_map[a_type]
|
|
1585
|
+
if a_name == "flags" or is_optional_arg(a_info):
|
|
1586
|
+
typ = "Optional[%s]" % typ
|
|
1587
|
+
classes.write(": \"%s\"" % typ)
|
|
1577
1588
|
if a_name == "flags" or is_optional_arg(a_info):
|
|
1578
1589
|
if is_integral_type(a_type):
|
|
1579
1590
|
classes.write("=0")
|
|
@@ -1683,7 +1694,7 @@ def emit_py_code(module: str) -> None:
|
|
|
1683
1694
|
# that don't exist. This code attempts to detect which
|
|
1684
1695
|
# methods to skip by looking at the libvirtmod.XXXX calls
|
|
1685
1696
|
|
|
1686
|
-
def shouldSkip(lines:
|
|
1697
|
+
def shouldSkip(lines: list[str]) -> bool:
|
|
1687
1698
|
for line in lines:
|
|
1688
1699
|
offset = line.find(pymod + ".")
|
|
1689
1700
|
if offset != -1:
|
|
@@ -1781,7 +1792,7 @@ def emit_py_code(module: str) -> None:
|
|
|
1781
1792
|
#
|
|
1782
1793
|
# Generate enum constants
|
|
1783
1794
|
#
|
|
1784
|
-
def enumsSortKey(data:
|
|
1795
|
+
def enumsSortKey(data: tuple[str, EnumValue]) -> tuple[Union[int, float], str]:
|
|
1785
1796
|
try:
|
|
1786
1797
|
value = int(data[1]) # type: Union[int, float]
|
|
1787
1798
|
except ValueError:
|
|
@@ -122,7 +122,15 @@ PyInit_cygvirtmod_lxc
|
|
|
122
122
|
if (virInitialize() < 0)
|
|
123
123
|
return NULL;
|
|
124
124
|
|
|
125
|
+
// PyModule_Create can return NULL if module creation fails
|
|
126
|
+
// https://docs.python.org/3/c-api/module.html#c.PyModule_Create
|
|
125
127
|
module = PyModule_Create(&moduledef);
|
|
128
|
+
if (module == NULL)
|
|
129
|
+
return NULL;
|
|
130
|
+
|
|
131
|
+
#ifdef Py_GIL_DISABLED
|
|
132
|
+
PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED);
|
|
133
|
+
#endif
|
|
126
134
|
|
|
127
135
|
return module;
|
|
128
136
|
}
|